diff options
author | EuAndreh <eu@euandre.org> | 2024-08-18 18:26:58 -0300 |
---|---|---|
committer | EuAndreh <eu@euandre.org> | 2024-08-18 18:26:58 -0300 |
commit | 5cabb11e012365096bea22bbb5014dd031537c42 (patch) | |
tree | 6b5b108fe996f6ae54f32b2fbcdc065b71baac55 | |
parent | system.scm: Use configuration from syskeep and upstream "packages" repository (diff) | |
download | toph-5cabb11e012365096bea22bbb5014dd031537c42.tar.gz toph-5cabb11e012365096bea22bbb5014dd031537c42.tar.xz |
rm -rf src/infrastructure/{ci,config,scripts}/
-rwxr-xr-x | src/infrastructure/ci/git-post-receive.sh | 178 | ||||
-rwxr-xr-x | src/infrastructure/ci/git-pre-receive.sh | 14 | ||||
-rw-r--r-- | src/infrastructure/config/conf.env | 14 | ||||
-rw-r--r-- | src/infrastructure/config/gitconfig | 11 | ||||
-rw-r--r-- | src/infrastructure/config/init.scm | 6 | ||||
-rw-r--r-- | src/infrastructure/config/known_hosts.txt | 27 | ||||
-rw-r--r-- | src/infrastructure/config/profile.sh | 5 | ||||
-rw-r--r-- | src/infrastructure/config/rc.sh | 80 | ||||
-rw-r--r-- | src/infrastructure/config/ssh.conf | 6 | ||||
-rwxr-xr-x | src/infrastructure/scripts/backup.sh | 149 | ||||
-rwxr-xr-x | src/infrastructure/scripts/check.sh | 92 | ||||
-rwxr-xr-x | src/infrastructure/scripts/cicd.sh | 168 | ||||
-rwxr-xr-x | src/infrastructure/scripts/cronjob.sh | 169 | ||||
-rwxr-xr-x | src/infrastructure/scripts/deploy.sh | 72 | ||||
-rwxr-xr-x | src/infrastructure/scripts/gc.sh | 146 | ||||
-rwxr-xr-x | src/infrastructure/scripts/reconfigure.sh | 147 | ||||
-rwxr-xr-x | src/infrastructure/scripts/report.sh | 260 |
17 files changed, 0 insertions, 1544 deletions
diff --git a/src/infrastructure/ci/git-post-receive.sh b/src/infrastructure/ci/git-post-receive.sh deleted file mode 100755 index 46bf5a5..0000000 --- a/src/infrastructure/ci/git-post-receive.sh +++ /dev/null @@ -1,178 +0,0 @@ -#!/bin/sh -# shellcheck source=/dev/null disable=2317 -. /etc/rc -set -eu - - -# shellcheck disable=2034 -read -r _oldrev SHA REFNAME - -if [ "$SHA" = '0000000000000000000000000000000000000000' ]; then - exit -fi - - -SKIP_DEPLOY=false -for n in $(seq 0 $((GIT_PUSH_OPTION_COUNT - 1))); do - opt="$(eval "printf '%s' \"\$GIT_PUSH_OPTION_$n\"")" - case "$opt" in - ci.skip) - cat <<-EOF - - "$opt" option detected, not running CI. - - EOF - exit - ;; - deploy.skip) - SKIP_DEPLOY=true - ;; - *) - ;; - esac -done - - -epoch() { - awk 'BEGIN { srand(); print(srand()); }' -} - -now() { - date '+%Y-%m-%dT%H:%M:%S%:z' -} - -NAME="$(basename "$PWD" .git)" -LOGS_DIR=/var/log/ci/"$NAME"/ -TIMESTAMP="$(now)" -FILENAME="$TIMESTAMP-$SHA.log" -LOGFILE="$LOGS_DIR/$FILENAME" -mkdir -p "$LOGS_DIR" - - -END_MARKER='\033[0m' -LIGHT_BLUE_B='\033[1;36m' -YELLOW='\033[1;33m' - -blue() { - printf "${LIGHT_BLUE_B}%s${END_MARKER}" "$1" -} - -yellow() { - printf "${YELLOW}%s${END_MARKER}" "$1" -} - -info() { - sed "s|^\(.\)|$(blue 'CI'): \1|" -} - - -uuid() { - od -xN20 /dev/urandom | - head -n1 | - awk '{OFS="-"; print $2$3,$4,$5,$6,$7$8$9}' -} - -tmpname() { - printf '%s/uuid-tmpname with spaces.%s' "${TMPDIR:-/tmp}" "$(uuid)" -} - -mkdtemp() { - name="$(tmpname)" - mkdir -- "$name" - printf '%s' "$name" -} - - -{ - cat <<-EOF | info - Starting CI job at: $(now) - EOF - START="$(epoch)" - - duration() { - if [ "$RUN_DURATION" -gt 60 ]; then - cat <<-EOF - $(yellow 'WARNING'): run took more than 1 minute! ($RUN_DURATION seconds) - EOF - else - cat <<-EOF - Run took $RUN_DURATION seconds. - EOF - fi - } - - finish() { - STATUS="$?" - END="$(epoch)" - RUN_DURATION=$((END - START)) - cat <<-EOF | info - Finishing CI job at: $(now) - Exit status was $STATUS - Re-run with: - \$ $CMD - $(duration) - EOF - - NOTE="$( - cat <<-EOF - See CI logs with: - git notes --ref=refs/notes/ci-logs show $SHA - git notes --ref=refs/notes/ci-data show $SHA - - Exit status: $STATUS - Duration: $RUN_DURATION - EOF - )" - git notes --ref=refs/notes/ci-data add -f -m "$( - cat <<-EOF - status $STATUS - sha $SHA - filename $FILENAME - duration $RUN_DURATION - timestamp $TIMESTAMP - to-prod $TO_PROD - refname $REFNAME - EOF - )" "$SHA" - git notes --ref=refs/notes/ci-logs add -f -F "$LOGFILE" "$SHA" - git notes add -f -m "$NOTE" "$SHA" - - { - printf 'Git CI HTML report for %s (%s) started.\n' "$NAME" "$SHA" >&2 - DIR="$(mkdtemp)" - report -o "$DIR" - sudo -u deployer rsync \ - --chmod=D775,F664 \ - --chown=deployer:deployer \ - --delete \ - -a \ - "$DIR"/ "$HTML_OUTDIR_CI"/ - rm -rf "$DIR" - printf 'Git CI HTML report for %s (%s) finished.\n' "$NAME" "$SHA" >&2 - } 2>&1 | logger -i -p local0.warn -t git-ci 1>/dev/null 2>&1 & - } - trap finish EXIT - - unset GIT_DIR - - if [ "$REFNAME" = 'refs/heads/main' ] && [ "$SKIP_DEPLOY" = false ]; then - cat <<-EOF | info - In branch "main", running deploy for $SHA. - EOF - TO_PROD=true - CMD="sudo reconfigure $SHA" - else - if [ "$SKIP_DEPLOY" = true ]; then - cat <<-EOF | info - "deploy.skip" option detected, skipping deploy for $SHA. - EOF - else - cat <<-EOF | info - Not on branch "main", skipping deploy for $SHA. - EOF - fi - TO_PROD=false - CMD="sudo reconfigure -n $SHA" - fi - $CMD -} 2>&1 | ts -s '%.s' | tee "$LOGFILE" diff --git a/src/infrastructure/ci/git-pre-receive.sh b/src/infrastructure/ci/git-pre-receive.sh deleted file mode 100755 index 8cd83ee..0000000 --- a/src/infrastructure/ci/git-pre-receive.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh -set -eu - -read -r _oldrev SHA _refname -unset GIT_DIR - -if [ "$SHA" = '0000000000000000000000000000000000000000' ]; then - exit -fi - -printf 'Upgrading post-receive hook...' >&2 -git show "$SHA":src/infrastructure/ci/git-post-receive.sh > hooks/post-receive -chmod +x hooks/post-receive -printf 'done.\n' >&2 diff --git a/src/infrastructure/config/conf.env b/src/infrastructure/config/conf.env deleted file mode 100644 index bbdab48..0000000 --- a/src/infrastructure/config/conf.env +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -NAME='server' -TLD='euandre.org' -RSYNC_ACCT='zh3051@zh3051' -OUT_SUFFIX="s/$NAME" -CI_SUFFIX="ci" - -HTML_OUTDIR_TOP="/srv/www/$OUT_SUFFIX" -HTML_OUTDIR_CI="$HTML_OUTDIR_TOP/$CI_SUFFIX" -RSYNC_ADDR="$RSYNC_ACCT.rsync.net" -HOMEPAGE="https://$TLD/$OUT_SUFFIX/" -CGIT_URL="https://$TLD/git/$NAME/commit/?id=" -REPO_NAME="$NAME.git" diff --git a/src/infrastructure/config/gitconfig b/src/infrastructure/config/gitconfig deleted file mode 100644 index f1f1eb3..0000000 --- a/src/infrastructure/config/gitconfig +++ /dev/null @@ -1,11 +0,0 @@ -[init] - defaultBranch = main -[user] - email = ci@$TLD - name = "Git CI" -[advice] - detachedHead = false -[receive] - advertisePushOptions = true -[uploadpack] - allowAnySHA1InWant = true diff --git a/src/infrastructure/config/init.scm b/src/infrastructure/config/init.scm deleted file mode 100644 index 9e962e8..0000000 --- a/src/infrastructure/config/init.scm +++ /dev/null @@ -1,6 +0,0 @@ -(use-modules - (ice-9 colorized) - (ice-9 readline)) - -(activate-colorized) -(activate-readline) diff --git a/src/infrastructure/config/known_hosts.txt b/src/infrastructure/config/known_hosts.txt deleted file mode 100644 index e63c372..0000000 --- a/src/infrastructure/config/known_hosts.txt +++ /dev/null @@ -1,27 +0,0 @@ -# rsync.net public keys -# Verified in 2023-03-08 at: -# https://www.rsync.net/resources/fingerprints.txt - -zh3051.rsync.net ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJtclizeBy1Uo3D86HpgD3LONGVH0CJ0NT+YfZlldAJd -zh3051.rsync.net ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLR2uz+YLn2KiQK0Luu8rhfWS6LHgUfGAWB1j8rM2MKn4KZ2/LhIX1CYkPKMTPxHr6mzayeL1T1hyJIylxXv0BY= -zh3051.rsync.net ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDPgHxQyaDaVxUefoUJZO/lITh0Gp0sqbP7HejQcCfZi7gAcuM6/IAuUXLHFImefCHh52x6T/cHxgL1qz26GKgdxykl06WRXlRIuE45QFSy/cd9JKr6l58fKq30ApmXRsCNwFrMlFPoEpCTqxzddZ9cLXs1Yt9dRxvFlQVEuAzw7ayvt8DE6RP9/CHYVp54wbbvUToECGwu70sxY1vFg51K+vNpvJ3J0t5j3s4c1Wls4BrIwqi2U8kqCq9Nj2CUIQqjM+93CSqEacR3qOGvG/6QMzd733wzpJ/iZee+lcyTYzA0YNMosnaF01hrv7NMwtZ6xRFLlJZtMZ7JpfySrOBr - - -# -# velhinho, available at: -# /etc/ssh/ssh_host_ed25519_key.pub -# - -velhinho ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAII9jxIXM2FSYeZmY2uLWkQUJQLNIQQJyJdc7P4eEPhEU -velhinho ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDCy5uC7oLo0I0fSpKi2y/6/Oti8R5pYJInN3UPrgq2Qtm5+70rPRxgrO1Cv1m48YXV0rat7YzrrDnIZ3nPIjUKmKQkOsecX9pnFt5B8mwo7HGcc6XbukyLObHJG9VlxStIuUFg+9ourv2gBheR+kPa3uBfwbEk6m8pnfiJ1MCO93ohML/xKIffaEEPIfwE2O8WLe5Sr/rBV7XsH4PRZDctAnib8tApEqGb2Kg/D9Q04mJxDhMEe08pMJCPEAAJiXW9rV9ARjQbVfnTUWUO1VlOcrw4IM3I0WROMO0nffOtKmU6t6k5uwI/HPZmjyLnOQmAKWuilLKLMgcs4pyDdn9w+Z1TV7kO4aapFG/R3ER+QvGsDAJNt9uvEQeh9H/EhGFQGDXZZJTPKBV8LVbeDRlm2RgEZPheDPqpG8wdrzCiYGOcfSiglv/FjQG7ES95e2UXp51mvsdX/FgjMfKXGOC9JR5bVr9GPuiNhwc2FtBHYNROy3wEgMLYbIQqrYPS6vU= -velhinho ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBNK3jI24/I20ADSlWrTrOItfGfVxtCfDDXhdovsu7aUxCS1VsCrEBdx3iuqkLc5OxDwItlCMSzp0/SqiC+++JdQ= - - -# -# azula, available at: -# /etc/ssh/ssh_host_ed25519_key.pub -# - -azula ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINpI9q3w1+ARFtRE0ON5L4LrqicGjdp8F7OEv/mQpVfp -azula ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC9LRtK0aRI7eZv0Coy9v/Gsce0wv/L2WzDEuAp+LpZXnPb01U7/kO6kVfUHDafe99WyIJ8UHeS3r0WqDPfecohb1HGck5w3fZ6hgxkCOt2lFbRcJoEztm3JKkx1LNG7HZHgBdiHpMwWAsOnccXTmhO0djqGtA4F9FiOPaT/bnoZPMtE+yYWqKxuRbbmmrQSwxM8xZOmORoJsK9I5osW2c6xyv3KHASc+4j9Ys19KFSU7frX3RgSaw2g0cbdmpes6d48bSh/BH0QHSyalta+CNdK/+d/9eOG/JoZelnWUGoJv8TaSC3cF45n5Vx2FtGPv+bTAwCov+VcIdUZZwU5+F2fRIskVugux3zy3iMPh+n/WU4UGE1HT4ZDSh8DVpaxRIdTSzXz+YPg2kAyy5jRUAr1mtEHGmWsiLT44efaXjLRVZngKmknF7MAOBQUyIndGwbbPj6EEtR3i2JuxBf+P3TAPO2pzX30cmGTsQ219HztfZPRoPJ34wmpcPs8Dc6Bx0= -azula ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBAgHd5yHQ7lU38De87bVy+Mcs8oti/pLhyvCiSOYU98Ro2QqZypq70CVzSZ8IgL59ahDXYfQKS7oMMnU7ApBVtA= diff --git a/src/infrastructure/config/profile.sh b/src/infrastructure/config/profile.sh deleted file mode 100644 index 1dca8b2..0000000 --- a/src/infrastructure/config/profile.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh - -# shellcheck source=/dev/null -. /etc/rc -ln -fs .profile .bashrc diff --git a/src/infrastructure/config/rc.sh b/src/infrastructure/config/rc.sh deleted file mode 100644 index abb966b..0000000 --- a/src/infrastructure/config/rc.sh +++ /dev/null @@ -1,80 +0,0 @@ -#!/bin/sh - -# shellcheck source=/dev/null -. /etc/profile -. /etc/conf.env - -export XDG_PREFIX=~/.usr -export XDG_CACHE_HOME="$XDG_PREFIX"/var/cache -export XDG_CONFIG_HOME="$XDG_PREFIX"/etc -export XDG_DATA_HOME="$XDG_PREFIX"/share -export XDG_STATE_HOME="$XDG_PREFIX"/state -export XDG_LOG_HOME="$XDG_PREFIX"/var/log - - -HOME_PARENT="$(dirname "$HOME")" -if [ "$HOME_PARENT" = '/home' ] || [ "$HOME_PARENT" = '/' ]; then - mkdir -p \ - "$XDG_CONFIG_HOME" \ - "$XDG_CACHE_HOME" \ - "$XDG_DATA_HOME" \ - "$XDG_LOG_HOME" \ - "$XDG_STATE_HOME"/ssh/conn -fi - - -GUIX_PROFILE="$XDG_CONFIG_HOME"/guix/current -if [ -r "$GUIX_PROFILE"/etc/profile ]; then - # shellcheck source=/dev/null - . "$GUIX_PROFILE"/etc/profile -fi - -export ENV=~/.profile -export HISTSIZE=-1 -export HISTCONTROL=ignorespace:ignoredups -export EDITOR=vi -export VISUAL="$EDITOR" -export PAGER='less -R' - -export EXINIT=' - " set number - " set autoindent - set ruler - set showmode - set showmatch -' - -export HISTFILE="$XDG_STATE_HOME"/bash-history -export LESSHISTFILE="$XDG_STATE_HOME"/lesshst -export RLWRAP_HOME="$XDG_CACHE_HOME"/rlwrap -export GUILE_HISTORY="$XDG_STATE_HOME"/guile-history - -HOSTNAME="$(hostname)" -export BORG_REPO="$RSYNC_ADDR:borg/$HOSTNAME" -export BORG_REMOTE_PATH='borg1' -export BORG_PASSCOMMAND='cat /opt/secrets/borg-passphrase.txt' - -export GIT_CONFIG_GLOBAL=/etc/gitconfig - -unalias -a -alias l='ls -lahF --color' -alias grep='grep --color=auto' -alias diff='diff --color=auto' -alias watch='watch --color ' -alias man='MANWIDTH=$((COLUMNS > 80 ? 80 : COLUMNS)) man' -alias less='less -R' -alias tree='tree -aC' -alias mv='mv -i' -alias e='vi' - -alias sqlite='rlwrap sqlite3' -alias guile='guile -l /etc/init.scm' - -error_marker() { - STATUS=$? - if [ "$STATUS" != 0 ]; then - printf ' (!! %s !!) ' "$STATUS" - fi -} -export PS1='`error_marker`\T \w/ -\u@\H\$ ' diff --git a/src/infrastructure/config/ssh.conf b/src/infrastructure/config/ssh.conf deleted file mode 100644 index ca41df0..0000000 --- a/src/infrastructure/config/ssh.conf +++ /dev/null @@ -1,6 +0,0 @@ -Host * - ServerAliveInterval 30 - ServerAliveCountMax 20 - ControlMaster auto - ControlPath ${XDG_STATE_HOME}/ssh/conn/%r@%h:%p - ControlPersist 1h diff --git a/src/infrastructure/scripts/backup.sh b/src/infrastructure/scripts/backup.sh deleted file mode 100755 index bea63b2..0000000 --- a/src/infrastructure/scripts/backup.sh +++ /dev/null @@ -1,149 +0,0 @@ -#!/bin/sh -set -eu - -usage() { - cat <<-'EOF' - Usage: - backup [-q] [-C COMMENT] [-x] [ARCHIVE_TAG] - backup -h - EOF -} - -help() { - cat <<-'EOF' - - - Options: - -q disable verbose mode, useful for batch sessions - -C COMMENT the comment text to be attached to the archive - -x enable checking the repository after creating the backup - -h, --help show this message - - ARCHIVE_TAG the tag used to create the new - backup (default: "manual") - - - The repository is expected to have been create with: - - $ borg init -e repokey-blake2 - - The following environment variables are expected to be exported: - - $BORG_PASSCOMMAND - $BORG_REPO - $BORG_REMOTE_PATH - - Password-less SSH access is required, usually done via adding - /root/.ssh/id_rsa.pub to the ssh remote's - $THE_REMOTE:.ssh/authorized_keys - - Root permission is also required. - - - Examples: - - Run backup from cronjob: - - $ backup - - - Run backup from cronjob: - - $ backup -q cronjob - - - Create backup with a comment, a tag, and verbose mode active, and do - verify the repository afterwards: - - $ backup -xC 'The backup has a comment' - EOF -} - - -for flag in "$@"; do - case "$flag" in - --) - break - ;; - --help) - usage - help - exit - ;; - *) - ;; - esac -done - -VERBOSE_FLAGS='--verbose --progress' -COMMENT=' ' -CHECK=false -while getopts 'qC:xh' flag; do - case "$flag" in - q) - VERBOSE_FLAGS='' - ;; - C) - COMMENT="$OPTARG" - ;; - x) - CHECK=true - ;; - h) - usage - help - exit - ;; - *) - usage >&2 - exit 2 - ;; - esac -done -shift $((OPTIND - 1)) - -ARCHIVE_TAG="${1:-manual}" - - -if [ "$(id -un)" != 'root' ]; then - printf 'This script must be run as root.\n\n' >&2 - usage >&2 - exit 2 -fi - - -run() { - STATUS=0 - set -x - # shellcheck disable=2086 - sudo -i borg create \ - $VERBOSE_FLAGS \ - --comment "$COMMENT" \ - --stats \ - --compression lzma,9 \ - "$BORG_REPO::$(hostname)-{now}-$ARCHIVE_TAG" \ - /mnt/production/ \ - /root/ \ - /home/ \ - /etc/ \ - /var/ \ - /opt/ \ - /srv/ || STATUS=$? - set +x - - if [ "$STATUS" = 0 ]; then - return 0 - elif [ "$STATUS" = 1 ]; then - printf 'WARNING, but no ERROR.\n' >&2 - return 0 - else - return "$STATUS" - fi -} - -run - -if [ "$CHECK" = true ]; then - # shellcheck disable=2086 - sudo -i borg check $VERBOSE_FLAGS --verify-data "$BORG_REPO" -fi diff --git a/src/infrastructure/scripts/check.sh b/src/infrastructure/scripts/check.sh deleted file mode 100755 index 5c63816..0000000 --- a/src/infrastructure/scripts/check.sh +++ /dev/null @@ -1,92 +0,0 @@ -#!/bin/sh -set -eu - -usage() { - cat <<-'EOF' - Usage: - check - check -h - EOF -} - -help() { - cat <<-'EOF' - - - Options: - -h, --help show this message - - - Run system sanity checks, such as email reachability, alarms - reachability, filesystem checks, etc. - - - Examples: - - Just run it - - $ check - EOF -} - - -for flag in "$@"; do - case "$flag" in - --) - break - ;; - --help) - usage - help - exit - ;; - *) - ;; - esac -done - -while getopts 'h' flag; do - case "$flag" in - h) - usage - help - exit - ;; - *) - usage >&2 - exit 2 - ;; - esac -done -shift $((OPTIND - 1)) - - -if [ "$(id -un)" != 'root' ]; then - printf 'This script must be run as root.\n\n' >&2 - usage >&2 - exit 2 -fi - - -uuid() { - od -xN20 /dev/urandom | - head -n1 | - awk '{OFS="-"; print $2$3,$4,$5,$6,$7$8$9}' -} - -for alias in abuse admin postmaster hostmaster; do - uuid | mail -s "\"$alias\" alias test from $(id -un)@$(hostname)" "$alias@$(hostname)" -done - - -PARTITIONS=' -/dev/vda3 -/dev/vdb1 -/dev/vdc1 -' -set -x - -for part in $PARTITIONS; do - btrfs scrub start -B "$part" - btrfs check --force -p "$part" -done diff --git a/src/infrastructure/scripts/cicd.sh b/src/infrastructure/scripts/cicd.sh deleted file mode 100755 index 58f4fce..0000000 --- a/src/infrastructure/scripts/cicd.sh +++ /dev/null @@ -1,168 +0,0 @@ -#!/bin/sh -set -eu - -usage() { - cat <<-'EOF' - Usage: - cicd [-n] NAME [SHA] - cicd -h - EOF -} - -help() { - cat <<-'EOF' - - - Options: - -n build the system, but don't switch to it (dry-run) - -h, --help show this message - - NAME the name of the project - SHA the repository SHA to checkout (default: main) - - - Do a CI/CD run of the project called NAME, located at - /srv/git/$NAME.git. If -n is given, only build, otherwise - also do the deploy when the build is successfull. - - A "build" consists of: - - doing a fresh clone of the project on a temporary directory; - - checkout the project to version $SHA; - - when a "manifest.scm" file exists in the root of the project, - use it to launch a containerized Guix shell; otherwise use a - fallback template for a containerized Guix shell; - - build the "dev" target of the Makefile via "make dev". - - A "deploy" consists of: - - copying the "description" metadata file to - /srv/git/$NAME.git/description, in order to update the project - repository's description; - - upgrading the "pre-receive" Git hook, so that future runs are - affected by it; - - copying the "public/" directory that the "dev" target built to - the /srv/www/s/$NAME/ directory, so that the projects "public/" - directory is accessible via the web address - "https://euandre.org/s/$NAME/". - - This command must be ran as root. - - - Examples: - - Build and deploy the "remembering" project on the default branch: - - $ sudo cicd remembering - - - Build the "urubu" project on a specific commit, but don't deploy: - - $ sudo cicd -n urubu 916dafc092f797349a54515756f2c8e477326511 - EOF -} - - -for flag in "$@"; do - case "$flag" in - --) - break - ;; - --help) - usage - help - exit - ;; - *) - ;; - esac -done - -DRY_RUN=false -while getopts 'nh' flag; do - case "$flag" in - n) - DRY_RUN=true - ;; - h) - usage - help - exit - ;; - *) - usage >&2 - exit 2 - ;; - esac -done -shift $((OPTIND - 1)) - -NAME="${1:-}" -SHA="${2:-main}" -REPO="/srv/git/$NAME.git" - -if [ -z "$NAME" ]; then - printf 'Missing NAME.\n\n' >&2 - usage >&2 - exit 2 -fi - -if [ "$(id -un)" != 'root' ]; then - printf 'This script must be run as root.\n\n' >&2 - usage >&2 - exit 2 -fi - - -set +eu -# shellcheck source=/dev/null -. /etc/rc -set -eu - - -uuid() { - od -xN20 /dev/urandom | - head -n1 | - awk '{OFS="-"; print $2$3,$4,$5,$6,$7$8$9}' -} - -tmpname() { - printf '%s/uuid-tmpname with spaces.%s' "${TMPDIR:-/tmp}" "$(uuid)" -} - -mkdtemp() { - name="$(tmpname)" - mkdir -- "$name" - printf '%s' "$name" -} - - -TMP="$(mkdtemp)" -trap 'rm -rf "$TMP"' EXIT - - -set -x -chown deployer:deployer "$TMP" -cd "$TMP" -sudo -u deployer git clone "$REPO" . -sudo -u deployer --preserve-env=GIT_CONFIG_GLOBAL git checkout "$SHA" -guix system describe - -if [ -f manifest.scm ]; then - guix shell -Cv3 -m manifest.scm -- make dev -else - guix shell -Cv3 -- make dev -fi - -if [ "$DRY_RUN" = false ]; then - # COMMENT: pre-receive is always running the previous version! - # The same is true for the reconfigure script itself. - sudo cp description "$REPO"/description - sudo cp aux/ci/git-pre-receive.sh "$REPO"/hooks/pre-receive - - sudo -u deployer rsync \ - --delete \ - --chmod=D775,F664 \ - --chown=deployer:deployer \ - --exclude 'ci/*' \ - -a \ - public/ /srv/www/s/"$NAME"/ -fi diff --git a/src/infrastructure/scripts/cronjob.sh b/src/infrastructure/scripts/cronjob.sh deleted file mode 100755 index 8abe510..0000000 --- a/src/infrastructure/scripts/cronjob.sh +++ /dev/null @@ -1,169 +0,0 @@ -#!/bin/sh -set -eu - -usage() { - cat <<-'EOF' - Usage: - cronjob COMMAND... - cronjob -h - EOF -} - -help() { - cat <<-'EOF' - - - Options: - -h, --help show this message - - COMMAND the command to be executed - - - Execute the given command, and send the output to email, with - special treatment to the status code. It kills the job it it - lasts more than one hour. - - It load the appropriate files, so that the actual cron - declaration is smaller. - - - Examples: - - Run a backup: - - $ cronjob backup -q cron - EOF -} - - -for flag in "$@"; do - case "$flag" in - --) - break - ;; - --help) - usage - help - exit - ;; - *) - ;; - esac -done - -while getopts 'h' flag; do - case "$flag" in - h) - usage - help - exit - ;; - *) - usage >&2 - exit 2 - ;; - esac -done -shift $((OPTIND - 1)) - -if [ -z "${1:-}" ]; then - printf 'Missing COMMAND.\n\n' >&2 - usage >&2 - exit 2 -fi - -if [ "$(id -un)" != 'root' ]; then - printf 'This script must be run as root.\n\n' >&2 - usage >&2 - exit 2 -fi - - -set +eu -# shellcheck source=/dev/null -. /etc/rc -set -eu - - - -epoch() { - awk 'BEGIN { srand(); print(srand()); }' -} - -now() { - date '+%Y-%m-%dT%H:%M:%S%:z' -} - - -uuid() { - od -xN20 /dev/random | - head -n1 | - awk '{OFS="-"; print $2$3,$4,$5,$6,$7$8$9}' -} - -mkstemp() { - name="${TMPDIR:-/tmp}/uuid-tmpname with spaces.$(uuid)" - touch "$name" - printf '%s' "$name" -} - -pre() { - # Same as: - # sed -u "s|^|[$CMD]: |" - # but the "-u" option is not POSIX - IFS='' - while read -r line; do - printf '[%s]: %s\n' "$CMD" "$line" - done -} - -duration() { - minutes=$((${1} / 60)) - seconds=$((${1} % 60)) - printf '%sm%ss' "$minutes" "$seconds" -} - - -CMD="$*" -HOSTNAME="$(hostname)" -FROM="cronjob@$HOSTNAME" -TIMEOUT='14400' # four hours -STATUS_F="$(mkstemp)" -OUT="$(mkstemp)" - -email() { - { - cat <<-EOF - Content-Type: text/plain; charset=UTF-8 - Content-Transfer-Encoding: 8bit - From: $FROM - To: root@localhost - Subject: (exit status: $(cat "$STATUS_F")) - $HOSTNAME: $CMD - - EOF - cat "$OUT" - } | sendmail -t -f "$FROM" - rm -f "$OUT" "$STATUS_F" -} -trap email EXIT - -{ - cat <<-EOF - Running commad: $CMD - Starting at: $(now) - - EOF - - START="$(epoch)" - STATUS=0 - timeout "$TIMEOUT" "$@" || STATUS=$? - printf '%s' "$STATUS" > "$STATUS_F" - END="$(epoch)" - DURATION_SECONDS=$((END - START)) - - cat <<-EOF - - Finished at: $(now) - Duration: $(duration "$DURATION_SECONDS") - EOF -} 2>&1 | pre | ts '%Y-%m-%dT%H:%M:%S' | tee "$OUT" >> /var/log/cronjobs.log diff --git a/src/infrastructure/scripts/deploy.sh b/src/infrastructure/scripts/deploy.sh deleted file mode 100755 index 7b3f0f4..0000000 --- a/src/infrastructure/scripts/deploy.sh +++ /dev/null @@ -1,72 +0,0 @@ -#!/bin/sh -set -eu - -usage() { - cat <<-'EOF' - Usage: - deploy - deploy -h - EOF -} - -help() { - cat <<-'EOF' - - - Options: - -h, --help show this message - - - Do a blue/green deployment of the relevant service. It makes - sure that the new service is up and running before shutting - down the old one. - - - Examples: - - Just do the deploy: - - $ deploy - EOF -} - - -for flag in "$@"; do - case "$flag" in - --) - break - ;; - --help) - usage - help - exit - ;; - *) - ;; - esac -done - -while getopts 'h' flag; do - case "$flag" in - h) - usage - help - exit - ;; - *) - usage >&2 - exit 2 - ;; - esac -done -shift $((OPTIND - 1)) - - -if [ "$(id -un)" != 'root' ]; then - printf 'This script must be run as root.\n\n' >&2 - usage >&2 - exit 2 -fi - - -: sudo herd restart a-service diff --git a/src/infrastructure/scripts/gc.sh b/src/infrastructure/scripts/gc.sh deleted file mode 100755 index e037f3c..0000000 --- a/src/infrastructure/scripts/gc.sh +++ /dev/null @@ -1,146 +0,0 @@ -#!/bin/sh -set -eu - -usage() { - cat <<-'EOF' - Usage: - gc [TYPE] - gc -h - EOF -} - -help() { - cat <<-'EOF' - - - Options: - -h, --help show this message - - TYPE what to do GC on (default: all): - - guix - - deploy - - trash - - tmpdir - - logs - - - GC the server, deleting old, unusable data, in order to free - disk space system-wide. - - - Examples: - - Just run it, for all: - - $ gc - - - Cleanup tmpdir: - - $ gc tmpdir - EOF -} - - -for flag in "$@"; do - case "$flag" in - --) - break - ;; - --help) - usage - help - exit - ;; - *) - ;; - esac -done - -while getopts 'h' flag; do - case "$flag" in - h) - usage - help - exit - ;; - *) - usage >&2 - exit 2 - ;; - esac -done -shift $((OPTIND - 1)) - - -if [ "$(id -un)" != 'root' ]; then - printf 'This script must be run as root.\n\n' >&2 - usage >&2 - exit 2 -fi - - -disk() { - df -h / /mnt/backup/ | - tail -n +2 | - awk '{ printf "%s\t%s/%s\t%s\n", $4, $3, $2, $6 }' -} - -today() { - date '+%Y-%m-%d' -} - -gc_guix() { - sudo -i guix system delete-generations 1m - sudo -i guix gc -d 1m -} - -gc_deploy() { - find /opt/deploy \ - ! -path /opt/deploy -prune \ - -type d \ - -not -name "$(today)*" \ - -exec rm -rvf "{}" ';' -} - -gc_trash() { - yes | sudo -i trash-empty -} - -gc_tmpdir() { - find "${TMPDIR:-/tmp}" -atime +10 -exec rm -vf "{}" ';' -} - -gc_logs() { - find /var/log/ci/ -atime +10 -exec rm -vf "{}" ';' -} - - -gc_all() { - gc_guix - gc_deploy - gc_trash - gc_tmpdir - gc_logs -} - - -TYPE="${1:-all}" -CMD=gc_"$TYPE" -if ! command -v "$CMD" >/dev/null; then - printf 'Invalid TYPE: "%s".\n\n' "$TYPE" >&2 - usage >&2 - exit 2 -fi - -BEFORE="$(disk)" -set -x -"$CMD" -set +x -AFTER="$(disk)" - -cat <<-EOF - Disk space: - before: $BEFORE - after: $AFTER -EOF diff --git a/src/infrastructure/scripts/reconfigure.sh b/src/infrastructure/scripts/reconfigure.sh deleted file mode 100755 index 7a3b84e..0000000 --- a/src/infrastructure/scripts/reconfigure.sh +++ /dev/null @@ -1,147 +0,0 @@ -#!/bin/sh -set -eu - -usage() { - cat <<-'EOF' - Usage: - reconfigure [-n] [-U] [SHA] - reconfigure -h - EOF -} - -help() { - cat <<-'EOF' - - - Options: - -n build the system, but don't switch to it (dry-run) - -U pull the latest channels before reconfiguring - -h, --help show this message - - SHA the repository SHA to checkout (default: main) - - - Run a "guix system reconfigure" as root via "sudo -i". If a -U - flag is given, perform a "guix pull" (in root profile) prior to - the reconfigure. The user must be able to become the "deployer" - user, either via "sudo reconfigure" or by being member of the - "become-deployer" group. - - - Examples: - - Reconfigure the system: - - $ reconfigure - - - Build the system on a custom SHA, but don't switch to it: - - $ reconfigure -n 916dafc092f797349a54515756f2c8e477326511 - - - Update and upgrade: - - $ reconfigure -U - EOF -} - - -for flag in "$@"; do - case "$flag" in - --) - break - ;; - --help) - usage - help - exit - ;; - *) - ;; - esac -done - -UPDATE=false -DRY_RUN=false -while getopts 'nUh' flag; do - case "$flag" in - n) - DRY_RUN=true - ;; - U) - UPDATE=true - ;; - h) - usage - help - exit - ;; - *) - usage >&2 - exit 2 - ;; - esac -done -shift $((OPTIND - 1)) - -# shellcheck source=/dev/null -. /etc/conf.env -SHA="${1:-main}" -REPO="/srv/git/$REPO_NAME" -NOW="$(date '+%Y-%m-%dT%H:%M:%S%:z')" -NOW_DIR=/opt/deploy/"$NOW" -NPROC=$(($(nproc) * 2 + 1)) - - -if [ "$(id -un)" != 'root' ]; then - printf 'This script must be run as root.\n\n' >&2 - usage >&2 - exit 2 -fi - - -set +eu -# shellcheck source=/dev/null -. /etc/rc -set -eu - - -if [ "$UPDATE" = true ] && [ "$DRY_RUN" = false ]; then - sudo -i guix pull -v3 -fi - -set -x -sudo -u deployer git clone --depth=1 "file://$REPO" "$NOW_DIR" -sudo -u deployer rm -f /opt/deploy/current -sudo -u deployer ln -rs "$NOW_DIR" /opt/deploy/current -cd /opt/deploy/current -sudo -u deployer git fetch --depth=1 "file://$REPO" "$SHA" -sudo -u deployer --preserve-env=GIT_CONFIG_GLOBAL git checkout "$SHA" -guix system describe - -if [ "$DRY_RUN" = true ]; then - sudo -i guix system -c$NPROC -v3 build "$PWD"/src/infrastructure/guix/system.scm -else - # COMMENT: pre-receive is always running the previous version! - # The same is true for the reconfigure script itself. - sudo cp description "$REPO"/description - sudo cp src/infrastructure/ci/git-pre-receive.sh "$REPO"/hooks/pre-receive - sudo rm -f /etc/guix/channels.scm /etc/guix/system.scm - sudo cp \ - src/infrastructure/guix/channels.scm \ - src/infrastructure/guix/system.scm \ - /etc/guix/ - - sudo -i guix system -c$NPROC -v3 reconfigure /etc/guix/system.scm - - sudo -u deployer rsync \ - --delete \ - --chmod=D775,F664 \ - --chown=deployer:deployer \ - --exclude "$CI_SUFFIX/*" \ - -a \ - /run/current-system/profile/share/doc/"$NAME"/ "$HTML_OUTDIR_TOP"/ - - deploy -fi diff --git a/src/infrastructure/scripts/report.sh b/src/infrastructure/scripts/report.sh deleted file mode 100755 index e14e40a..0000000 --- a/src/infrastructure/scripts/report.sh +++ /dev/null @@ -1,260 +0,0 @@ -#!/bin/sh -set -eu - -usage() { - cat <<-'EOF' - Usage: - report [-C REPO] -o DIRECTORY - report -h - EOF -} - -help() { - cat <<-'EOF' - - - Options: - -C REPO change to REPO when doing Git operations (default: $PWD) - -o DIRECTORY the directory where to place the generated files - -h, --help show this message - - - Gather data from Git Notes, and generate an HTML report on CI runs. - - Two refs with notes are expected: - 1. refs/notes/ci-data: contains metadata abount the CI runs, - with timestamps, filenames and exit status; - 2. refs/notes/ci-logs: contains the content of the log. - - When reconstructing the CI run, the $FILENAME present in - the refs/notes/ci-data ref names the file, and its content comes - from refs/notes/ci-logs. - - On a CI run that generated the numbers from 1 to 10, for a file named - 'my-ci-run-2020-01-01-deadbeef.log' that exited successfully, the - expected output on the target directory "public" is: - - $ tree public/ - public/ - index.html - data/ - my-ci-run-2020-01-01-deadbeef.log - ... - logs/ - my-ci-run-2020-01-01-deadbeef.log - ... - - $ cat public/data/my-ci-run-2020-01-01-deadbeef.log - 0 deadbeef my-ci-run-2020-01-01-deadbeef.log - - $ cat public/logs/my-ci-run-2020-01-01-deadbeef.log - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - - The generated 'index.html' is a webpage with the list of all known - CI runs, their status, a link to the commit and a link to the - log file. - - To enable fetching these refs by default, do so in the git config: - - $ git config --add remote.origin.fetch '+refs/notes/*:refs/notes/*' - - - Examples: - - Generate the report on the 'www' directory: - - $ report -o www - EOF -} - - -for flag in "$@"; do - case "$flag" in - --) - break - ;; - --help) - usage - help - exit - ;; - *) - ;; - esac -done - -REPO="$PWD" -while getopts 'C:o:h' flag; do - case "$flag" in - C) - REPO="$OPTARG" - ;; - o) - OUTDIR="$OPTARG" - ;; - h) - usage - help - exit - ;; - *) - exit 2 - ;; - esac -done -shift $((OPTIND - 1)) - -if [ -z "${OUTDIR:-}" ]; then - printf 'Missing -o OUTDIR.\n\n' >&2 - usage >&2 - exit 2 -fi - -if [ -r src/infrastructure/config/conf.env ]; then - CONF=src/infrastructure/config/conf.env -else - CONF=/etc/conf.env -fi - -# shellcheck source=/dev/null -. "$CONF" - - -esc() { - sed \ - -e 's|&|\&|g' \ - -e 's|<|\<|g' \ - -e 's|>|\>|g' \ - -e 's|"|\"|g' \ - -e "s|'|\'|g" -} - -mkdir -p "$OUTDIR" -cd "$OUTDIR" -mkdir -p logs data - -for c in $(git -C "$REPO" notes list | cut -d' ' -f2); do - git -C "$REPO" notes --ref=refs/notes/ci-data show "$c" > data/FILENAME-tmp - FILENAME="$(grep '^filename ' data/FILENAME-tmp | cut -d' ' -f2-)" - mv data/FILENAME-tmp data/"$FILENAME" - git -C "$REPO" notes --ref=refs/notes/ci-logs show "$c" > logs/"$FILENAME" -done - -{ - cat <<-EOF - <!DOCTYPE html> - <html lang="en"> - <head> - <meta charset="UTF-8" /> - <meta name="viewport" content="width=device-width, initial-scale=1" /> - <meta name="description" content="CI logs for $NAME" /> - <link rel="icon" type="image/svg+xml" href="/favicon.svg" /> - <title>$NAME - CI logs</title> - <style> - body { - max-width: 800px; - margin: 0 auto; - } - - code { - display: block; - margin: 1em 0em 3em 3em; - overflow: auto; - } - - pre { - display: inline; - } - - ol { - list-style-type: disc; - } - - pre, code { - background-color: #ddd; - } - - @media(prefers-color-scheme: dark) { - :root { - color: white; - background-color: black; - } - - a { - color: hsl(211, 100%, 60%); - } - - a:visited { - color: hsl(242, 100%, 80%); - } - - pre, code { - background-color: #222; - } - } - </style> - </head> - <body> - <main> - <h1> - CI logs for - <a href="$HOMEPAGE">$NAME</a> - </h1> - <ol> - EOF - - - PASS='✅' # ✅ - WARN='🐌' # 🐌 - FAIL='❌' # ❌ - find data/ -type f | LANG=C.UTF-8 sort -r | while read -r f; do - STATUS="$( grep '^status ' "$f" | cut -d' ' -f2- | esc)" - SHA="$( grep '^sha ' "$f" | cut -d' ' -f2- | esc)" - FILENAME="$(grep '^filename ' "$f" | cut -d' ' -f2- | esc)" - DURATION="$(grep '^duration ' "$f" | cut -d' ' -f2- | cut -d'"' -f1 | esc)" - MESSAGE="$({ - git -C "$REPO" log -1 --format=%B "$SHA" || { - git fetch origin "$SHA" - git -C "$REPO" log -1 --format=%B "$SHA" - } - } | esc)" - - if [ "$STATUS" = 0 ]; then - if [ "$DURATION" -le 60 ]; then - STATUS_MARKER="$PASS" - else - STATUS_MARKER="$WARN" - fi - else - STATUS_MARKER="$FAIL" - fi - - cat <<-EOF - <li id="$FILENAME"> - <a href="#$FILENAME"><pre>#</pre></a> - $STATUS_MARKER - <pre>${DURATION:-?}s</pre> - <pre>(<a href="${CGIT_URL}${SHA}">commit</a>)</pre> - <a href="logs/$FILENAME"><pre>$FILENAME</pre></a> - <pre>(<a href="data/$FILENAME">data</a>)</pre> - <br /> - <code><pre>$MESSAGE</pre></code> - </li> - EOF - done - - cat <<-EOF - </ol> - </main> - </body> - </html> - EOF -} > index.html |