Skip to content

Commit

Permalink
Fix/initial setup (#20)
Browse files Browse the repository at this point in the history
* update new navigation path in readme

* save history of postgresql15 migration

* add broken postgresql14 bin, fix reset admin user action, fix backups, reorganize

* increase health check timeout

* fix backups to spersist database; cleanup

* update release notes
  • Loading branch information
elvece authored Dec 10, 2022

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 5d6daca commit 8b539b5
Showing 11 changed files with 129 additions and 64 deletions.
17 changes: 11 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -18,19 +18,24 @@ VOLUME $POSTGRES_DATADIR
VOLUME $POSTGRES_CONFIG

# Install mariadb mysql database server
RUN apt-get update \
&& apt-get install -y mariadb-server wget sqlite3 apache2-utils curl \
postgresql \
RUN apt-get update -y \
&& apt-get install -y mariadb-server wget sqlite3 apache2-utils curl wget gnupg ca-certificates \
# Cleanup
&& apt-get autoremove -y \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

RUN sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt bookworm-pgdg main" > /etc/apt/sources.list.d/postgresql.list' \
&& curl https://www.postgresql.org/media/keys/ACCC4CF8.asc \
| gpg --dearmor \
| tee /etc/apt/trusted.gpg.d/apt.postgresql.org.gpg >/dev/null \
&& apt-get update -y && apt-get install postgresql-14 -y

RUN wget https://github.com/mikefarah/yq/releases/download/v4.6.3/yq_linux_${PLATFORM}.tar.gz -O - |\
tar xz && mv yq_linux_${PLATFORM} /usr/bin/yq

ADD ./example.env /app/.env
ADD ./reset-admin.sh /usr/local/bin/reset-admin.sh
ADD ./utils/example.env /app/.env
ADD ./utils/scripts/reset-admin.sh /usr/local/bin/reset-admin.sh
ADD ./docker_entrypoint.sh /usr/local/bin/docker_entrypoint.sh
ADD ./migration-from-lt-2-3-9.sh /usr/local/bin/migration-from-lt-2-3-9.sh
ADD ./utils/scripts/migration-from-lt-2-3-9.sh /usr/local/bin/migration-from-lt-2-3-9.sh
RUN chmod a+x /usr/local/bin/*.sh
8 changes: 5 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
PKG_ID := $(shell yq e ".id" manifest.yaml)
PKG_VERSION := $(shell yq e ".version" manifest.yaml)
TS_FILES := $(shell find ./ -name \*.ts)
UTILS_SRC := $(shell find ./utils/**/*)
ASSET_PATHS := $(shell find ./assets/*)

# delete the target of a rule if it has changed and its recipe exits with a nonzero exit status
.DELETE_ON_ERROR:
@@ -22,14 +24,14 @@ clean:
scripts/embassy.js: $(TS_FILES)
deno bundle scripts/embassy.ts scripts/embassy.js

docker-images/x86_64.tar: Dockerfile docker_entrypoint.sh example.env
docker-images/x86_64.tar: Dockerfile docker_entrypoint.sh $(UTILS_SRC)
mkdir -p docker-images
docker buildx build --tag start9/$(PKG_ID)/main:$(PKG_VERSION) --platform=linux/amd64 --build-arg PLATFORM=amd64 -o type=docker,dest=docker-images/x86_64.tar .

docker-images/aarch64.tar: Dockerfile docker_entrypoint.sh example.env
docker-images/aarch64.tar: Dockerfile docker_entrypoint.sh $(UTILS_SRC)
mkdir -p docker-images
docker buildx build --tag start9/$(PKG_ID)/main:$(PKG_VERSION) --platform=linux/arm64 --build-arg PLATFORM=arm64 -o type=docker,dest=docker-images/aarch64.tar .

$(PKG_ID).s9pk: manifest.yaml instructions.md LICENSE icon.png scripts/embassy.js docker-images/aarch64.tar docker-images/x86_64.tar
$(PKG_ID).s9pk: manifest.yaml instructions.md LICENSE icon.png scripts/embassy.js docker-images/aarch64.tar docker-images/x86_64.tar $(ASSET_PATHS)
if ! [ -z "$(ARCH)" ]; then cp docker-images/$(ARCH).tar image.tar; fi
embassy-sdk pack
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -92,7 +92,7 @@ If you already have your `embassy-cli` config file setup with a default `host`,
make install
```

> **Tip:** You can also install the photoview.s9pk using **Sideload Service** under the **Embassy > Settings** section.
> **Tip:** You can also install the photoview.s9pk using **Sideload Service** under the **System > Manage** section.
### Verify Install

Go to your Embassy Services page, select **Photoview**, and start the service. Then, verify its interfaces are accessible.
24 changes: 24 additions & 0 deletions assets/compat/backup-x.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/bin/sh

set -ea

case "$1" in
backup-create)
mkdir -p /mnt/backup/media
compat duplicity create /mnt/backup/media /media

mkdir -p /mnt/backup/database
compat duplicity create /mnt/backup/database /var/lib/postgresql/14

mkdir -p /mnt/backup/dbconfig
compat duplicity create /mnt/backup/dbconfig /etc/postgresql/14
;;
backup-restore)
compat duplicity restore /mnt/backup/media /media
compat duplicity restore /mnt/backup/database /var/lib/postgresql/14
compat duplicity restore /mnt/backup/dbconfig /etc/postgresql/14
;;
*)
esac

exit 0
37 changes: 23 additions & 14 deletions docker_entrypoint.sh
Original file line number Diff line number Diff line change
@@ -7,18 +7,31 @@ _term() {
kill -TERM "$photoview_child" 2>/dev/null
}

# set permissions for postgres folders
chown -R postgres:postgres $POSTGRES_DATADIR
chown -R postgres:postgres $POSTGRES_CONFIG
chmod -R 700 $POSTGRES_DATADIR
chmod -R 700 $POSTGRES_CONFIG
mkdir -p /media/start9
service postgresql start
if test -f /etc/postgresql/14/photoview/postgresql.conf
then
# restart
echo "postgresql already initialized"
echo "starting postgresql..."
service postgresql start
else
# fresh install
echo 'setting up postgresql...'
# set permissions for postgres folders
chown -R postgres:postgres $POSTGRES_DATADIR
chown -R postgres:postgres $POSTGRES_CONFIG
chmod -R 700 $POSTGRES_DATADIR
chmod -R 700 $POSTGRES_CONFIG
mkdir -p /media/start9
su - postgres -c "pg_createcluster 14 photoview"
echo "starting postgresql..."
service postgresql start
fi


echo 'checking for existing admin user...'
export USERS=$(sqlite3 $PHOTOVIEW_SQLITE_PATH 'select * from users;')
export NEW_USERS=$(su - postgres -c 'psql -d '$POSTGRES_DB' -c "select * from users"')
sleep 1
export USERS=$(sqlite3 $PHOTOVIEW_SQLITE_PATH 'select * from users;')
export NEW_USERS=$(su - postgres -c 'psql -d '$POSTGRES_DB' -c "select * from users"')
sleep 1

if [ -f /media/start9/config.yaml ] && ! [ -z "$NEW_USERS" ]; then
echo 'loading existing admin credentials...'
@@ -64,10 +77,6 @@ if [ -z "$NEW_USERS" ]; then
fi

echo 'applying database permissions...'
su - postgres -c "pg_createcluster 14 photoview"
service postgresql start
sleep 5

su - postgres -c 'psql -c "UPDATE pg_database SET datistemplate = FALSE WHERE datname = '"'"template1"'"';"'
su - postgres -c 'psql -c "DROP DATABASE template1;"'
su - postgres -c 'psql -c "CREATE DATABASE template1 WITH TEMPLATE = template0 ENCODING = '"'"UTF8"'"';"'
37 changes: 22 additions & 15 deletions manifest.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
id: photoview
title: Photoview
version: 2.3.13.3
release-notes: Update to run on x86 architecture
release-notes: |
* Update to run on x86 architecture
* Fix reset admin user action
* Fix backups
license: gnu
wrapper-repo: "https://github.com/Start9Labs/embassyos-photoview-wrapper"
upstream-repo: "https://github.com/photoview/photoview/tree/master"
@@ -74,6 +77,8 @@ volumes:
type: data
dbconfig:
type: data
compat:
type: assets
alerts: {}
interfaces:
main:
@@ -95,34 +100,34 @@ backup:
type: docker
image: compat
system: true
entrypoint: compat
args:
- duplicity
- create
- /mnt/backup
- /media
entrypoint: /mnt/assets/backup-x.sh
args:
- backup-create
mounts:
BACKUP: /mnt/backup
main: /media
db: /var/lib/postgresql/14
dbconfig: /etc/postgresql/14
compat: /mnt/assets
io-format: yaml
restore:
type: docker
image: compat
system: true
entrypoint: compat
args:
- duplicity
- restore
- /mnt/backup
- /media
entrypoint: /mnt/assets/backup-x.sh
args:
- backup-restore
mounts:
BACKUP: /mnt/backup
main: /media
db: /var/lib/postgresql/14
dbconfig: /etc/postgresql/14
compat: /mnt/assets
io-format: yaml
actions:
reset-admin:
name: Reset Root User
description: Resets your root user (the first user) to username "admin" and a random password; restores any lost admin privileges.
name: Reset Admin User
description: Restores lost admin privileges by resetting your root user with the username "admin" and a random password.
warning: This will invalidate existing sessions and password managers if you have them set up.
allowed-statuses:
- stopped
@@ -134,4 +139,6 @@ actions:
args: []
mounts:
main: /media
db: /var/lib/postgresql/14
dbconfig: /etc/postgresql/14
io-format: json
48 changes: 31 additions & 17 deletions scripts/procedures/health.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { types as T, checkWebUrl, catchError } from "../deps.ts";
import { types as T, checkWebUrl, catchError, ok, isKnownError, errorCode, error } from "../deps.ts";

export const health: T.ExpectedExports.health = {
// deno-lint-ignore require-await
@@ -13,15 +13,32 @@ export const health: T.ExpectedExports.health = {
},
};

// deno-lint-ignore require-await
const healthWeb: T.ExpectedExports.health[""] = async (effects, duration) => {
return checkWebUrl("http://photoview.embassy")(effects, duration).catch(catchError(effects))
const url = 'http://photoview.embassy'
let errorValue
if (
// deno-lint-ignore no-cond-assign
errorValue = guardDurationAboveMinimum({ duration, minimumTime: 20000 })
) return errorValue

return await effects.fetch(url)
.then((_) => ok)
.catch((e) => {
effects.warn(`Error while fetching URL: ${url}`);
effects.error(JSON.stringify(e));
effects.error(e.toString());
return error(`Error while fetching URL: ${url}`);
});
};

const healthApi: T.ExpectedExports.health[""] = async (effects, duration) => {
await guardDurationAboveMinimum({ duration, minimumTime: 15000 });
let errorValue
if (
// deno-lint-ignore no-cond-assign
errorValue = guardDurationAboveMinimum({ duration, minimumTime: 20000 })
) return errorValue

return effects.fetch("http://photoview.embassy:80/api/graphql", {
return await effects.fetch("http://photoview.embassy:80/api/graphql", {
method: 'POST',
headers: {
'Content-Type': 'application/json'
@@ -37,16 +54,13 @@ const healthApi: T.ExpectedExports.health[""] = async (effects, duration) => {

// *** HELPER FUNCTIONS *** //

// Ensure the starting duration is pass a minimum
const guardDurationAboveMinimum = (
// Ensure the starting duration is past a minimum
export const guardDurationAboveMinimum = (
input: { duration: number; minimumTime: number },
) =>
(input.duration <= input.minimumTime)
? Promise.reject(errorCode(60, "Starting"))
: null;

const errorCode = (code: number, error: string) => ({
"error-code": [code, error] as const,
});
const error = (error: string) => ({ error });
const ok = { result: null };
) => (input.duration <= input.minimumTime) ? errorCode(60, "Starting") : null;

export const catchError_ = (effects: T.Effects) => (e: unknown) => {
if (isKnownError(e)) return e;
effects.error(`Health check failed: ${e}`);
return error("Error while running health check");
}
Empty file removed select * from users;
Empty file.
File renamed without changes.
File renamed without changes.
20 changes: 12 additions & 8 deletions reset-admin.sh → utils/scripts/reset-admin.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/bin/bash

# ensure start9 directory exists if action is run before first run of service
mkdir /media/start9
mkdir -p /media/start9
export PASS=$(cat /dev/urandom | base64 | head -c 16)
echo 'version: 2' > /media/start9/stats.yaml
echo 'data:' >> /media/start9/stats.yaml
@@ -21,17 +21,21 @@ echo ' masked: true' >> /media/start9/stats.yaml
echo ' qr: false' >> /media/start9/stats.yaml

export PASS_HASH=$(htpasswd -bnBC 12 "" $PASS | tr -d ':\n' | sed 's/$2y/$2a/')
export PHOTOVIEW_SQLITE_PATH="/media/photoview.db"

USERS=$(sqlite3 $PHOTOVIEW_SQLITE_PATH "select * from users where id = 1;")
service postgresql start &>/dev/null
USERS=$(su - postgres -c 'psql -d '$POSTGRES_DB' -c "select * from users"')
if [ -z $USERS ]; then
sqlite3 $PHOTOVIEW_SQLITE_PATH "insert into users (id, created_at, updated_at, username, password, admin) values (1, datetime('now'), datetime('now'), 'admin', '$PASS_HASH', true);"
PASS_HASH=$(htpasswd -bnBC 12 "" $PASS | tr -d ':\n' | sed 's/$2y/$2a/')
PATH_MD5=$(echo -n /mnt/filebrowser | md5sum | head -c 32)
sqlite3 $PHOTOVIEW_SQLITE_PATH "insert or ignore into albums (id, created_at, updated_at, title, parent_album_id, path, path_hash) values (1, datetime('now'), datetime('now'), 'filebrowser', NULL, '/mnt/filebrowser', '$PATH_MD5');"
sqlite3 $PHOTOVIEW_SQLITE_PATH "insert or ignore into user_albums (album_id, user_id) values (1,1);"
sqlite3 $PHOTOVIEW_SQLITE_PATH "update site_info set initial_setup = false;"
USER_INSERT="INSERT INTO users (id, created_at, updated_at, username, password, admin) VALUES (21, current_timestamp, current_timestamp, 'admin', '$PASS_HASH', true);"
ALBUM_INSERT="INSERT INTO albums (id, created_at, updated_at, title, parent_album_id, path, path_hash) VALUES (21, current_timestamp, current_timestamp, 'filebrowser', NULL, '/mnt/filebrowser', '$PATH_MD5');"
JOIN_INSERT="INSERT INTO user_albums (album_id, user_id) VALUES (21, 21);"
INFO_UPDATE="update site_info set initial_setup = false;"
echo "begin; $USER_INSERT $ALBUM_INSERT $JOIN_INSERT $INFO_UPDATE commit;" | su - postgres -c "psql -d '$POSTGRES_DB'" &>/dev/null
fi
sqlite3 $PHOTOVIEW_SQLITE_PATH "update users set password = '$PASS_HASH', username = 'admin' where id = 1;"
SET_PW="UPDATE users SET password = '$PASS_HASH', username = 'admin' WHERE id = 21;"
echo $SET_PW | su - postgres -c "psql -d '$POSTGRES_DB'" &>/dev/null
service postgresql stop &>/dev/null
action_result=" {
\"version\": \"0\",
\"message\": \"Here is your new password. This will also be reflected in the Properties page for this service.\",

0 comments on commit 8b539b5

Please sign in to comment.