This commit is contained in:
parent
bd9eab64ec
commit
55de09d909
4 changed files with 148 additions and 37 deletions
79
.forgejo/workflows/installer.yaml
Normal file
79
.forgejo/workflows/installer.yaml
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
# title: install
|
||||||
|
# desc: generate a guix installer image
|
||||||
|
# adapted from https://github.com/SystemCrafters/guix-installer/
|
||||||
|
|
||||||
|
name: installer
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: docker
|
||||||
|
|
||||||
|
container:
|
||||||
|
image: alpine:3.21
|
||||||
|
options: "--privileged" # needed for guix
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
apk add --no-cache git nodejs util-linux
|
||||||
|
|
||||||
|
- name: Git checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Guix cache
|
||||||
|
uses: actions/cache/restore@v4
|
||||||
|
with:
|
||||||
|
path: ~/.cache/guix
|
||||||
|
key: guix-cache-${{ github.sha }}
|
||||||
|
restore-keys: |
|
||||||
|
guix-cache-
|
||||||
|
|
||||||
|
- name: Install guix
|
||||||
|
run: |
|
||||||
|
SUBSTITUTE_URLS="https://ci.guix.gnu.org https://bordeaux.guix.gnu.org https://substitutes.nonguix.org https://substitutes.freya.cat"
|
||||||
|
|
||||||
|
apk add --no-cache guix openrc udev-init-scripts-openrc sed
|
||||||
|
sed -i 's/#rc_sys=""/rc_sys="docker"/' /etc/rc.conf
|
||||||
|
|
||||||
|
cat <<EOF > /etc/init.d/guix-daemon
|
||||||
|
#!/sbin/openrc-run
|
||||||
|
start(){ guix-daemon --build-users-group=guixbuild --substitute-urls="$SUBSTITUTE_URLS" & }
|
||||||
|
EOF
|
||||||
|
chmod +x /etc/init.d/guix-daemon
|
||||||
|
|
||||||
|
rc-update add guix-daemon
|
||||||
|
openrc boot
|
||||||
|
|
||||||
|
- name: Set environment
|
||||||
|
run: |
|
||||||
|
echo "GUIX_RETRY_NO_PROMPT=yes" >> $GITHUB_ENV
|
||||||
|
echo "GUIX_RETRY_NO_TTY=yes" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Setup channels
|
||||||
|
run: |
|
||||||
|
guix archive --authorize < ./files/keys/nonguix.pub
|
||||||
|
guix archive --authorize < ./files/keys/sakura.pub
|
||||||
|
./scripts/guix-retry guix pull -C ./channels.scm
|
||||||
|
|
||||||
|
- name: Build ISO
|
||||||
|
run: |
|
||||||
|
GUIX_PROFILE="/root/.config/guix/current"
|
||||||
|
. "$GUIX_PROFILE/etc/profile"
|
||||||
|
./scripts/build-installer
|
||||||
|
|
||||||
|
- name: Guix cache save
|
||||||
|
uses: actions/cache/save@v4
|
||||||
|
with:
|
||||||
|
path: ~/.cache/guix
|
||||||
|
key: guix-cache-${{ github.sha }}
|
||||||
|
|
||||||
|
- name: Save artifact
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: installer
|
||||||
|
path: guix-installer-*.iso
|
|
@ -3,7 +3,7 @@
|
||||||
(url "https://git.savannah.gnu.org/git/guix.git")
|
(url "https://git.savannah.gnu.org/git/guix.git")
|
||||||
(branch "master")
|
(branch "master")
|
||||||
(commit
|
(commit
|
||||||
"a9003b8e6b40b59c9545ae87bb441d3549630db7")
|
"2b32a3809883a9b0fc38a79886921f1a53e00425")
|
||||||
(introduction
|
(introduction
|
||||||
(make-channel-introduction
|
(make-channel-introduction
|
||||||
"9edb3f66fd807b096b48283debdcddccfea34bad"
|
"9edb3f66fd807b096b48283debdcddccfea34bad"
|
||||||
|
@ -14,7 +14,7 @@
|
||||||
(url "https://gitlab.com/nonguix/nonguix.git")
|
(url "https://gitlab.com/nonguix/nonguix.git")
|
||||||
(branch "master")
|
(branch "master")
|
||||||
(commit
|
(commit
|
||||||
"5a7e61a0a5bc191d8558a845bd724a0d41e0afbd")
|
"10e3c2bcaedaba121eec0e255d366a080082cf0a")
|
||||||
(introduction
|
(introduction
|
||||||
(make-channel-introduction
|
(make-channel-introduction
|
||||||
"897c1a470da759236cc11798f4e0a5f7d4d59fbc"
|
"897c1a470da759236cc11798f4e0a5f7d4d59fbc"
|
||||||
|
@ -25,7 +25,7 @@
|
||||||
(url "https://g.freya.cat/freya/sakura")
|
(url "https://g.freya.cat/freya/sakura")
|
||||||
(branch "main")
|
(branch "main")
|
||||||
(commit
|
(commit
|
||||||
"3caf3d17b1e5e76f1bf948e6799085b27d204bed")
|
"db9a1e89bf4d730232c5c8ab705a1bab01262a25")
|
||||||
(introduction
|
(introduction
|
||||||
(make-channel-introduction
|
(make-channel-introduction
|
||||||
"8fb2f9c2fa414754c41c1c73665e3e73e12693ab"
|
"8fb2f9c2fa414754c41c1c73665e3e73e12693ab"
|
||||||
|
|
|
@ -1,28 +1,8 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
set -e -o pipefail
|
||||||
retry="$(dirname $0)/guix-retry"
|
retry="$(dirname $0)/guix-retry"
|
||||||
repo="$(realpath "$(dirname $0)/..")"
|
repo="$(realpath "$(dirname $0)/..")"
|
||||||
extra_args=""
|
command="\"$retry\" guix system -L \"$repo/modules\" image -t iso9660 \"$repo/systems/installer.scm\""
|
||||||
|
|
||||||
if [ ! -d /gnu/store ]; then
|
|
||||||
# we are likely in a non guix system
|
|
||||||
# just for building the installer
|
|
||||||
# make sure to authorize the substitute
|
|
||||||
# servers for nonguix and sakura
|
|
||||||
guix archive --authorize < "$repo/files/keys/nonguix.pub"
|
|
||||||
guix archive --authorize < "$repo/files/keys/sakura.pub"
|
|
||||||
substitutes=$(
|
|
||||||
(cat <<EOF
|
|
||||||
https://substitutes.nonguix.org
|
|
||||||
https://substitutes.freya.cat
|
|
||||||
https://bordeaux.guix.gnu.org
|
|
||||||
https://ci.guix.gnu.org
|
|
||||||
EOF
|
|
||||||
) | tr '\n' ' ')
|
|
||||||
extra_args="--substitute-urls=\"$substitutes\""
|
|
||||||
fi
|
|
||||||
|
|
||||||
command="\"$retry\" guix time-machine -C \"$repo/channels.scm\" $extra_args -- system -L \"$repo/modules\" image -t iso9660 \"$repo/systems/installer.scm\""
|
|
||||||
image=$(sh -c "$command")
|
image=$(sh -c "$command")
|
||||||
|
|
||||||
date="$(date -Iseconds)"
|
date="$(date -Iseconds)"
|
||||||
cp $image "guix-installer-$date.iso"
|
cp $image "guix-installer-$date.iso"
|
||||||
|
|
|
@ -1,21 +1,73 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
error="write_to_session_record_port"
|
# fail on errors
|
||||||
|
set -e
|
||||||
|
|
||||||
# create redirection
|
# if the error output matches this regex, auto retry
|
||||||
# file descripters
|
# and dont prompt user.
|
||||||
exec 11>&1 # stdout
|
auto_retry_regex="write_to_session_record_port" # Guix does not know how to
|
||||||
exec 22>&2 # stderr
|
# gracefully reconnect TLS...
|
||||||
|
# run dir
|
||||||
|
run="${XDG_RUNTIME_DIR:-/tmp}/guix-retry/$$"
|
||||||
|
mkdir -p "$run"
|
||||||
|
|
||||||
|
# delete run dir on exit
|
||||||
|
function cleanup {
|
||||||
|
real="$(realpath "$run")"
|
||||||
|
if [[ ! "$real" = "/" ]]; then
|
||||||
|
rm -fr "$real"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
trap cleanup EXIT
|
||||||
|
|
||||||
|
# get error stream
|
||||||
|
stderr="$run/stderr"
|
||||||
|
mkfifo -m 600 "$stderr"
|
||||||
|
|
||||||
|
log="$run/log"
|
||||||
|
|
||||||
|
# unset fail on errors
|
||||||
|
set +e
|
||||||
|
|
||||||
|
# retry command forever
|
||||||
|
# until success or abort
|
||||||
while true; do
|
while true; do
|
||||||
# send stdout to stdout
|
|
||||||
# send stderr though pipe
|
|
||||||
output=$("$@" 2>&1 1>&11 | tee >(cat - >&22)) # return stderr to
|
|
||||||
# normal stderr as well
|
|
||||||
|
|
||||||
# check if error is in stderr
|
# execute command
|
||||||
if echo "$output" | grep -q "$error"; then
|
if [[ ! -z "$GUIX_RETRY_NO_TTY" ]]; then
|
||||||
|
"$@" 2>"$stderr" &
|
||||||
|
else
|
||||||
|
command="$@"
|
||||||
|
script -q -c "$command" 2>"$stderr" "$log" &
|
||||||
|
fi
|
||||||
|
pid="$!"
|
||||||
|
output="$(cat "$stderr" | tee /dev/stderr)"
|
||||||
|
wait "$pid"
|
||||||
|
err="$?"
|
||||||
|
if [[ -z "$GUIX_RETRY_NO_TTY" ]]; then
|
||||||
|
err="$(tail -n1 "$log" | awk -F '"' '{ print $2 }')"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$err" -eq 0 ]]; then
|
||||||
|
# command succeeded, break loop
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$output" =~ "$auto_retry_regex" ]]; then
|
||||||
|
# command errored and is set to auto retry
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
break
|
|
||||||
|
if [[ ! -z "$GUIX_RETRY_NO_PROMPT" ]]; then
|
||||||
|
# do not prompt, just fail
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check if user wants to retry
|
||||||
|
read -p "Command failed. Retry? (y/N): " response
|
||||||
|
if [[ ! "$response" = "y" ]]; then
|
||||||
|
# command failed and told to abort, break loop
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
|
|
Loading…
Reference in a new issue