feat: add TallyNote local reimbursement ledger
TallyNote release / linux-x64 (push) Failing after 2m41s
TallyNote release / linux-x64 (push) Failing after 2m41s
This commit is contained in:
Executable
+95
@@ -0,0 +1,95 @@
|
||||
#!/usr/bin/env bash
|
||||
set -Eeuo pipefail
|
||||
|
||||
PATH=/usr/sbin:/usr/bin:/sbin:/bin
|
||||
export PATH
|
||||
umask 077
|
||||
|
||||
# Manual updater for operators without using the web control. The same
|
||||
# verified TypeScript updater used by the systemd queue performs download,
|
||||
# extraction and atomic release switching.
|
||||
PREFIX=${TALLYNOTE_INSTALL_PREFIX:-${TALLYNOTE_PREFIX:-/opt/tallynote}}
|
||||
DATA_DIR=${TALLYNOTE_DATA_DIR:-/var/lib/tallynote}
|
||||
REQUEST_FILE=${TALLYNOTE_UPDATE_REQUEST_FILE:-$DATA_DIR/update-request.json}
|
||||
NODE=${TALLYNOTE_NODE:-}
|
||||
|
||||
die() { printf 'tallynote update: %s\n' "$*" >&2; exit 1; }
|
||||
version_sort_desc() {
|
||||
if sort -V </dev/null >/dev/null 2>&1; then
|
||||
sort -V -r
|
||||
return
|
||||
fi
|
||||
awk -F'[.-]' '{ printf "%020d.%020d.%020d.%s\t%s\n", $1, $2, $3, ($4 == "" ? "~" : $4), $0 }' \
|
||||
| sort -r | cut -f2-
|
||||
}
|
||||
[[ ${EUID:-$(id -u)} -eq 0 ]] || die 'must run as root'
|
||||
|
||||
if [[ "${1:-}" == "--rollback" ]]; then
|
||||
current="$PREFIX/current"
|
||||
[[ -L "$current" ]] || die 'current release is not a symlink'
|
||||
current_target=$(readlink -f -- "$current")
|
||||
current_name=$(basename -- "$current_target")
|
||||
[[ "$current_name" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?(\+[0-9A-Za-z.-]+)?$ ]] || die 'current release version is invalid'
|
||||
mapfile -t releases < <(
|
||||
find "$PREFIX/releases" -mindepth 1 -maxdepth 1 -type d -printf '%p\n' \
|
||||
| awk -F/ '$NF ~ /^[0-9]+\.[0-9]+\.[0-9]+([.-][0-9A-Za-z.-]+)?$/' \
|
||||
| version_sort_desc
|
||||
)
|
||||
previous=''
|
||||
found_current=0
|
||||
for release in "${releases[@]}"; do
|
||||
release_target=$(readlink -f -- "$release")
|
||||
if [[ "$release_target" == "$current_target" ]]; then
|
||||
found_current=1
|
||||
continue
|
||||
fi
|
||||
if (( found_current )); then
|
||||
previous=$release
|
||||
break
|
||||
fi
|
||||
done
|
||||
[[ -n "$previous" && -d "$previous" ]] || die 'no previous release available'
|
||||
was_active=0
|
||||
if systemctl is-active --quiet tallynote.service; then was_active=1; fi
|
||||
if (( was_active )); then systemctl stop tallynote.service; fi
|
||||
tmp="$PREFIX/.current-rollback-$$-${RANDOM}"
|
||||
[[ ! -e "$tmp" && ! -L "$tmp" ]] || die 'rollback temporary path already exists'
|
||||
ln -s -- "$previous" "$tmp"
|
||||
mv -Tf -- "$tmp" "$current"
|
||||
if (( was_active )); then systemctl start tallynote.service; fi
|
||||
printf 'rolled back to %s\n' "$(basename -- "$previous")"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
[[ -f "$REQUEST_FILE" ]] || die "no queued update request at $REQUEST_FILE"
|
||||
[[ -L "$PREFIX/current" ]] || die 'current release is not a symlink'
|
||||
|
||||
# Prefer the systemd runner, which performs the post-switch health check and
|
||||
# rollback. The fallback remains useful in development installations where the
|
||||
# privileged helper has not been installed yet.
|
||||
if [[ -x /usr/local/libexec/tallynote-update-runner ]]; then
|
||||
exec /usr/local/libexec/tallynote-update-runner
|
||||
fi
|
||||
if [[ -z "$NODE" ]]; then
|
||||
NODE="$PREFIX/current/runtime/bin/node"
|
||||
[[ -x "$NODE" ]] || NODE=$(command -v node || true)
|
||||
fi
|
||||
[[ -n "$NODE" ]] || die 'node runtime not found'
|
||||
CLI="$PREFIX/current/dist/server/cli/update.js"
|
||||
[[ -f "$CLI" ]] || die 'update CLI not found'
|
||||
|
||||
was_active=0
|
||||
if systemctl is-active --quiet tallynote.service; then was_active=1; fi
|
||||
if (( was_active )); then systemctl stop tallynote.service; fi
|
||||
set +e
|
||||
"$NODE" "$CLI" --request-file "$REQUEST_FILE"
|
||||
result=$?
|
||||
set -e
|
||||
if (( result != 0 )); then
|
||||
rm -f -- "$REQUEST_FILE"
|
||||
if (( was_active )); then systemctl start tallynote.service || true; fi
|
||||
die 'update failed; the previous release remains active'
|
||||
fi
|
||||
if (( was_active )); then systemctl start tallynote.service || { rm -f -- "$REQUEST_FILE"; die 'updated service failed to start'; }; fi
|
||||
rm -f -- "$REQUEST_FILE"
|
||||
printf 'update completed; inspect the update page for details\n'
|
||||
Reference in New Issue
Block a user