Krolyxon
Commit e758199

ferreniumdistinstall.sh

146 lines · 4.6 KB · Bourne Again Shell (bash)

1#!/bin/sh
2# Install or upgrade Ferrenium from its GitHub releases.
3#
4# curl -fsSL https://github.com/krolyxon/ferrenium/releases/latest/download/install.sh | sudo sh
5#
6# Options, as environment variables (put them after `sudo`):
7# FERRENIUM_DOMAIN=git.example.com fill in base_url and clone URLs (fresh config only)
8# FERRENIUM_USER=git user that owns the repositories (created if missing)
9# FERRENIUM_VERSION=v0.1.0 a specific release instead of the latest
10#
11# `sh -s -- --uninstall` removes the binary and the unit, and keeps
12# /etc/ferrenium, the user and the repositories.
13#
14# Upgrades replace the binary and the unit and restart the service; the
15# config is never overwritten. Customize the unit with `systemctl edit
16# ferrenium`, not by editing the file.
17
18set -eu
19
20REPO=krolyxon/ferrenium
21BIN=/usr/local/bin/ferrenium
22ETC=/etc/ferrenium
23CONFIG=$ETC/ferrenium.toml
24UNIT=/etc/systemd/system/ferrenium.service
25
26say() { printf '%s\n' "$*"; }
27die() { printf 'ferrenium install: %s\n' "$*" >&2; exit 1; }
28has() { command -v "$1" >/dev/null 2>&1; }
29
30fetch() {
31 if has curl; then
32 curl -fsSL -o "$2" "$1"
33 elif has wget; then
34 wget -qO "$2" "$1"
35 else
36 die "curl or wget is required"
37 fi
38}
39
40uninstall() {
41 if [ -d /run/systemd/system ]; then
42 systemctl disable --now ferrenium 2>/dev/null || true
43 fi
44 rm -f "$UNIT" "$BIN"
45 if [ -d /run/systemd/system ]; then
46 systemctl daemon-reload
47 fi
48 say "Removed $BIN and $UNIT. Kept $ETC and the repositories."
49}
50
51main() {
52 [ "$(id -u)" -eq 0 ] || die "run as root (… | sudo sh)"
53 if [ "${1:-}" = "--uninstall" ]; then
54 uninstall
55 return
56 fi
57
58 [ "$(uname -s)" = Linux ] || die "only Linux is supported"
59 case "$(uname -m)" in
60 x86_64 | amd64) arch=x86_64 ;;
61 aarch64 | arm64) arch=aarch64 ;;
62 *) die "no release build for $(uname -m); build from source instead" ;;
63 esac
64 has sha256sum || die "sha256sum is required"
65 has git || say "warning: git is not installed; HTTPS clone needs it (apt install git)"
66
67 version=${FERRENIUM_VERSION:-latest}
68 if [ -n "${FERRENIUM_BASE_URL:-}" ]; then
69 base=$FERRENIUM_BASE_URL
70 elif [ "$version" = latest ]; then
71 base=https://github.com/$REPO/releases/latest/download
72 else
73 base=https://github.com/$REPO/releases/download/$version
74 fi
75 asset=ferrenium-$arch-linux.tar.gz
76
77 tmp=$(mktemp -d)
78 trap 'rm -rf "$tmp"' EXIT
79 say "Downloading $asset ($version)"
80 fetch "$base/$asset" "$tmp/$asset" || die "download failed: $base/$asset"
81 fetch "$base/SHA256SUMS" "$tmp/SHA256SUMS" || die "download failed: $base/SHA256SUMS"
82 (cd "$tmp" && grep " $asset\$" SHA256SUMS | sha256sum -c - >/dev/null) ||
83 die "checksum mismatch for $asset"
84 tar -xzf "$tmp/$asset" -C "$tmp" ferrenium
85 "$tmp/ferrenium" --version >/dev/null 2>&1 ||
86 die "the downloaded binary does not run here (needs glibc 2.28 or newer)"
87
88 # The service runs as the user that owns the repositories.
89 user=${FERRENIUM_USER:-git}
90 if ! id "$user" >/dev/null 2>&1; then
91 shell=$(command -v git-shell || echo /usr/sbin/nologin)
92 useradd --system --create-home --home-dir "/home/$user" --shell "$shell" "$user"
93 say "Created user $user (home /home/$user, shell $shell)"
94 fi
95 group=$(id -gn "$user")
96 home=$(getent passwd "$user" | cut -d: -f6)
97
98 install -m 755 "$tmp/ferrenium" "$BIN.new"
99 mv -f "$BIN.new" "$BIN"
100 say "Installed $("$BIN" --version) to $BIN"
101
102 if [ -e "$CONFIG" ]; then
103 say "Kept $CONFIG"
104 else
105 mkdir -p "$ETC"
106 "$BIN" example config | sed "s|^scan_path = .*|scan_path = \"$home\"|" >"$tmp/config"
107 if [ -n "${FERRENIUM_DOMAIN:-}" ]; then
108 d=$FERRENIUM_DOMAIN
109 sed -i \
110 -e "s|^# base_url = .*|base_url = \"https://$d\"|" \
111 -e "s|^# clone_urls = .*|clone_urls = [\"https://$d/{name}\", \"$user@$d:{name}\"]|" \
112 "$tmp/config"
113 fi
114 install -m 644 "$tmp/config" "$CONFIG"
115 say "Wrote $CONFIG"
116 fi
117
118 fresh=yes
119 [ -e "$UNIT" ] && fresh=no
120 "$BIN" example systemd |
121 sed -e "s/^User=.*/User=$user/" -e "s/^Group=.*/Group=$group/" >"$tmp/unit"
122 install -m 644 "$tmp/unit" "$UNIT"
123
124 if [ ! -d /run/systemd/system ]; then
125 say "systemd is not running; start it yourself:"
126 say " $BIN serve --config $CONFIG"
127 return
128 fi
129 systemctl daemon-reload
130 "$BIN" check --config "$CONFIG" >/dev/null || die "$CONFIG is invalid; fix it, then run: systemctl enable --now ferrenium"
131 if [ "$fresh" = yes ]; then
132 systemctl enable --now ferrenium
133 say "Started ferrenium.service"
134 elif systemctl is-active --quiet ferrenium; then
135 systemctl restart ferrenium
136 say "Restarted ferrenium.service"
137 fi
138
139 say ""
140 say "Repositories: bare repos under $home"
141 say "Config: $CONFIG (then: systemctl reload ferrenium)"
142 say "Logs: journalctl -u ferrenium"
143 say "Proxy: ferrenium example caddy"
144}
145
146main "$@"