ansible-taler-exchange

Ansible playbook to deploy a production Taler Exchange
Log | Files | Refs | README | LICENSE

commit bab7da1039191a5d6eece5138b2d2c9a7e91f466
parent b39d8deaf83889b6fa9a8c930663faff2cbf13ab
Author: Florian Dold <dold@taler.net>
Date:   Fri, 31 Jul 2026 15:41:51 +0200

fix argument and error handling in the wrapper scripts

restore.sh referenced $HOSTNAME in the "no passphrase" hint before
assigning it, so under "set -u" the script aborted instead of printing
the hint; the hint also pointed at the backup server rather than the
target. Picking the newest archive with "sort -n" over non-numeric
archive names only worked because borg already lists chronologically;
use "borg list --last 1" instead.

The unquoted "[ -z ${1:-} ]" tests are a syntax error for any argument
containing whitespace, and only work for the empty case because test
with a single argument tests for a non-empty string.

contrib/encrypt truncated the .gpg file before running gpg, so a failing
gpg destroyed the committed secret; contrib/decrypt left an empty
plaintext file behind. deploy.sh was the only wrapper not passing
--inventory. BORG_PASSPHRASE and PIXEL_BORG_KEY are now looked up from
the environment instead of being placed on the command line, where every
local user can read them. The CI job no longer runs playbooks/start.yml,
which does not exist. Drop the two .gitignore entries that start with
"./" and therefore never match.

Diffstat:
M.gitignore | 2--
Mbackup.sh | 2+-
Mcontrib/ci/jobs/001-build/build.sh | 3---
Mcontrib/decrypt | 9++++++++-
Mcontrib/encrypt | 8++++++--
Mdeploy.sh | 3++-
Mreboot.sh | 2+-
Mrestore.sh | 8++++----
Msanction-check.sh | 6+++---
Msetup-pixel-borg.sh | 4++--
Mstart-borg-backups.sh | 6+++---
11 files changed, 30 insertions(+), 23 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -1,5 +1,3 @@ -./inventories/production/hosts -./inventories/staging/hosts exports .ansible diff --git a/backup.sh b/backup.sh @@ -2,7 +2,7 @@ set -eu -if [ -z ${1:-} ] +if [ -z "${1:-}" ] then echo "Call with 'spec' or another host/group to select target" exit 1 diff --git a/contrib/ci/jobs/001-build/build.sh b/contrib/ci/jobs/001-build/build.sh @@ -36,9 +36,6 @@ echo -e ' ############################# ############################# ###### Setup finished. ###### - ## Launching services now! ## ############################# ############################# #############################' - -ansible-playbook --verbose -i 127.0.0.1:22, --user root playbooks/start.yml diff --git a/contrib/decrypt b/contrib/decrypt @@ -27,4 +27,11 @@ if ! git check-ignore "$outfile" >/dev/null; then exit 1 fi -gpg -d "$1" > "$outfile" +# Write straight to the gitignored path, so that a plaintext secret +# never exists under a name git would offer to commit. Remove the +# truncated output again if gpg fails. +if ! gpg -d "$1" > "$outfile"; then + rm -f "$outfile" + echo "Decryption of $1 failed" >&2 + exit 1 +fi diff --git a/contrib/encrypt b/contrib/encrypt @@ -16,6 +16,10 @@ if ! git check-ignore "$1" >/dev/null; then exit 1 fi -cat "$1" | gpg --encrypt \ +tmpfile=$(mktemp "$1.gpg.XXXXXX") +trap 'rm -f "$tmpfile"' EXIT + +gpg --encrypt \ --recipient grothoff@gnunet.org \ - --recipient me@fdold.eu > "$1.gpg" + --recipient me@fdold.eu < "$1" > "$tmpfile" +mv "$tmpfile" "$1.gpg" diff --git a/deploy.sh b/deploy.sh @@ -1,13 +1,14 @@ #!/bin/sh set -eu -if [ -z ${1:-} ] +if [ -z "${1:-}" ] then echo "Call with 'spec' or another host/group to select target" exit 1 fi ansible-playbook -v \ + --inventory inventories/default \ --limit "$1" \ playbooks/setup.yml diff --git a/reboot.sh b/reboot.sh @@ -1,7 +1,7 @@ #!/bin/sh set -eu -if [ -z ${1:-} ] +if [ -z "${1:-}" ] then echo "Call with 'spec' or another host/group to select target" exit 1 diff --git a/restore.sh b/restore.sh @@ -5,11 +5,11 @@ set -eu if [ -z "${BORG_PASSPHRASE:-}" ] then echo "You must set the BORG_PASSPHRASE environment variable first!" - echo "You can find it encrypted in the admin-log.git/$HOSTNAME/" + echo "You can find it encrypted in admin-log.git, under the target host" exit 1 fi -if [ -z ${1:-} ] +if [ -z "${1:-}" ] then echo "Call with 'spec' or another host/group to select target" exit 1 @@ -21,10 +21,10 @@ echo "Restoring backup for $TARGET from $HOSTNAME" REPO="ssh://borg@$HOSTNAME/~/$TARGET-backup" -LATEST=$(borg list "${REPO}" | awk '{print $1}' | sort -n | tail -n1) +LATEST=$(borg list --last 1 --format '{archive}' "${REPO}") echo "Latest backup is $LATEST" -if [ -z ${LATEST:-} ] +if [ -z "${LATEST}" ] then echo "No backups found?" exit 1 diff --git a/sanction-check.sh b/sanction-check.sh @@ -2,17 +2,17 @@ set -eu -if [ -z ${1:-} ]; then +if [ -z "${1:-}" ]; then echo "Call with 'spec' or other host/group as target" exit 1 fi -if [ -z ${2:-} ]; then +if [ -z "${2:-}" ]; then echo "Pass sanction list as 2nd argument" exit 1 fi -if [ ! -f ${2:-} ]; then +if [ ! -f "$2" ]; then echo "Sanction list '$2' not found" exit 1 fi diff --git a/setup-pixel-borg.sh b/setup-pixel-borg.sh @@ -2,13 +2,13 @@ set -eu -if [ -z ${PIXEL_BORG_KEY:-} ] +if [ -z "${PIXEL_BORG_KEY:-}" ] then echo "You need to set the PIXEL_BORG_KEY in your environment before running this script (see admin-log/pixel/03-borg.txt)" exit 1 fi ansible-playbook \ - --extra-vars PIXEL_BORG_KEY="$PIXEL_BORG_KEY" \ + --extra-vars "PIXEL_BORG_KEY={{ lookup('env', 'PIXEL_BORG_KEY') }}" \ --inventory inventories/default \ --limit "${1:-spec}" \ --user root \ diff --git a/start-borg-backups.sh b/start-borg-backups.sh @@ -2,20 +2,20 @@ set -eu -if [ -z ${BORG_PASSPHRASE:-} ] +if [ -z "${BORG_PASSPHRASE:-}" ] then echo "You need to set the BORG_PASSPHRASE in your environment before running this script!" exit 1 fi -if [ -z ${1:-} ] +if [ -z "${1:-}" ] then echo "Call with 'spec' or another host/group to select target" exit 1 fi ansible-playbook \ --verbose \ - --extra-vars BORG_PASSPHRASE="$BORG_PASSPHRASE" \ + --extra-vars "BORG_PASSPHRASE={{ lookup('env', 'BORG_PASSPHRASE') }}" \ --inventory inventories/default \ --limit "${1:-spec}" \ playbooks/borg-start.yml