summaryrefslogtreecommitdiff
path: root/infra/guix/bundle.sh
blob: c6d5bb0978a3260fdbc1c4ae7da075a59fa11a18 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#!/bin/sh
# Copyright (C) 2026 Doan Luu Duc Tai <doan@luuduct.ai>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <https://www.gnu.org/licenses/>.

set -eu
umask 077
[ "$#" = 3 ] || { echo 'Usage: sh infra/guix/bundle.sh BACKUP.tar.gz.gpg RELEASE.tar.gz OUTPUT.tar.gz' >&2; exit 1; }
[ -f "$1" ] || { echo 'Encrypted backup missing.' >&2; exit 1; }
case "$1" in *.tar.gz.gpg) ;; *) echo 'Requires an encrypted stack backup.' >&2; exit 1 ;; esac
[ -f "$2" ] || { echo 'Trusted release missing.' >&2; exit 1; }
case "$2" in *.tar.gz) ;; *) echo 'Requires a trusted public release archive.' >&2; exit 1 ;; esac
case "$3" in *.tar.gz) ;; *) echo 'Output must end in .tar.gz.' >&2; exit 1 ;; esac
[ ! -e "$3" ] || { echo 'Output already exists.' >&2; exit 1; }
STAGE=$(mktemp -d "$(dirname -- "$3")/.recovery.XXXXXX")
trap 'rm -rf -- "$STAGE"' EXIT HUP INT TERM
tar -xOf "$2" stack/bin/stack > "$STAGE/verify"
chmod 700 "$STAGE/verify"
"$STAGE/verify" restore --release "$2" "$STAGE/release"
RELEASE="$STAGE/release"
[ ! -e "$RELEASE/.env" ] && [ ! -e "$RELEASE/var/data" ] || {
    echo 'Release contains private application state; refusing plaintext publication.' >&2; exit 1;
}
for FILE in bin/stack bin/guix-runtime.tar.gz bin/guix-channels.scm \
    bin/chat/server bin/chat/crypto.wasm bin/chat/SOURCE.tar.gz infra/services.toml \
    infra/guix/bootstrap.sh infra/guix/restore.sh infra/guix/run.sh \
    infra/guix/containers.conf var/image-lock.json var/images.tar LICENSE; do
    [ -f "$RELEASE/$FILE" ] || { echo "Release missing $FILE; build a complete release first." >&2; exit 1; }
done
mkdir "$STAGE/stack-recovery"
cp -- "$1" "$STAGE/stack-recovery/backup.tar.gz.gpg"
cp -- "$2" "$STAGE/stack-recovery/release.tar.gz"
cp -- "$RELEASE/bin/stack" "$STAGE/stack-recovery/stack"
cp -- "$RELEASE/bin/guix-runtime.tar.gz" "$STAGE/stack-recovery/runtime.tar.gz"
cp -- "$RELEASE/bin/guix-channels.scm" "$STAGE/stack-recovery/channels.scm"
cp -- "$RELEASE/infra/guix/restore.sh" "$STAGE/stack-recovery/restore"
cp -- "$RELEASE/infra/guix/bootstrap.sh" "$STAGE/stack-recovery/bootstrap"
cp -- "$RELEASE/infra/guix/run.sh" "$STAGE/stack-recovery/run"
cp -- "$RELEASE/infra/guix/containers.conf" "$STAGE/stack-recovery/containers.conf"
cp -- "$RELEASE/LICENSE" "$STAGE/stack-recovery/LICENSE"
chmod 700 "$STAGE/stack-recovery/restore" "$STAGE/stack-recovery/bootstrap" "$STAGE/stack-recovery/run" "$STAGE/stack-recovery/stack"
(cd "$STAGE/stack-recovery" && sha256sum backup.tar.gz.gpg release.tar.gz stack runtime.tar.gz channels.scm restore bootstrap run containers.conf LICENSE > SHA256SUMS)
tar -czf "$STAGE/bundle.tar.gz" -C "$STAGE" stack-recovery
ln -- "$STAGE/bundle.tar.gz" "$3"
printf 'Recovery bundle: %s\n' "$3"