proxmox-install: fetch prebuilt bundle from Gitea package registry
CI / Lint + build + test (push) Has been cancelled
Release / release (push) Has been cancelled

Drops the per-install Go toolchain dance + source build. The installer
now just curls the bundle from
${REGISTRY_URL}/api/packages/${PACKAGE_OWNER}/generic/vetting/${VETTING_VERSION}/vetting-bundle.tar.gz,
extracts it, and hands off to the bundled install.sh with explicit
--binary / --agent-binary paths so the in-bundle layout is picked up.

Default version is `latest` (rolling alias, overwritten by release.yml
on each push to main). Pin via `VETTING_VERSION=sha-abc1234 curl ... |
bash` when rolling back or testing a specific commit.

Removes the `apt install build-essential git` + Go toolchain download
+ templ install + `make orchestrator-linux agent-linux` path — the CI
workflow already produced all of that. Install time on a cold LXC
drops from minutes to under a minute, and live-image kernel/initrd
now arrive with every install instead of requiring a separate WSL
build.

Also rewrites docs/operations.md's install section around the
one-liner, keeps the `make release` + scp path as the offline
fallback, and swaps the upgrade section to just "rerun the one-liner."

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-04-18 02:16:02 -04:00
parent 609ad2e383
commit f188c7add4
2 changed files with 101 additions and 96 deletions
+53 -67
View File
@@ -1,93 +1,79 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# proxmox-install.sh — one-shot fetch + build + install for a fresh # proxmox-install.sh — one-shot installer for a fresh Proxmox LXC (or
# Proxmox LXC (or any Debian/Ubuntu host). Designed to be piped # any Debian/Ubuntu host). Fetches a prebuilt release bundle from the
# straight from the repo: # Gitea package registry, extracts it, and hands off to install.sh.
# #
# Usage:
# curl -fsSL https://gitea.thewrightserver.net/josh/Vetting/raw/branch/main/deploy/proxmox-install.sh | sudo bash # curl -fsSL https://gitea.thewrightserver.net/josh/Vetting/raw/branch/main/deploy/proxmox-install.sh | sudo bash
# #
# What it does: # To pin a specific build instead of "latest":
# 1. apt-installs build prereqs (git, curl, build-essential). # VETTING_VERSION=sha-abc1234 curl -fsSL .../proxmox-install.sh | sudo bash
# 2. Drops Go into /usr/local/go if a recent enough toolchain isn't
# already present.
# 3. Clones the repo to /opt/vetting-src (or pulls latest if already
# there), then `make orchestrator-linux agent-linux`. The agent
# binary isn't run on the LXC — it's only built so the LXC can
# serve it at /assets/vetting-agent-linux-amd64 for target hosts
# to fetch via the quick-register one-liner.
# 4. Hands off to deploy/install.sh to lay down the orchestrator
# binary, the agent binary (into /var/lib/vetting/assets for
# serving), the systemd unit, the example config, and the
# vetting user.
# #
# Override via env: GO_VERSION, TEMPL_VERSION, SRC_DIR, BRANCH, REPO_URL. # Env overrides:
# REGISTRY_URL base URL of the Gitea instance hosting the package
# registry (default: https://gitea.thewrightserver.net)
# PACKAGE_OWNER Gitea owner who owns the `vetting` package
# (default: josh)
# VETTING_VERSION package version — either "latest" (rolling) or
# "sha-<short-sha>" (immutable). Default: "latest".
set -euo pipefail set -euo pipefail
GO_VERSION="${GO_VERSION:-1.23.4}" REGISTRY_URL="${REGISTRY_URL:-https://gitea.thewrightserver.net}"
TEMPL_VERSION="${TEMPL_VERSION:-v0.3.1001}" PACKAGE_OWNER="${PACKAGE_OWNER:-josh}"
SRC_DIR="${SRC_DIR:-/opt/vetting-src}" VETTING_VERSION="${VETTING_VERSION:-latest}"
BRANCH="${BRANCH:-main}"
REPO_URL="${REPO_URL:-https://gitea.thewrightserver.net/josh/Vetting.git}" BUNDLE_URL="${REGISTRY_URL}/api/packages/${PACKAGE_OWNER}/generic/vetting/${VETTING_VERSION}/vetting-bundle.tar.gz"
if [[ $EUID -ne 0 ]]; then if [[ $EUID -ne 0 ]]; then
echo "proxmox-install.sh must be run as root (try: sudo bash)" >&2 echo "proxmox-install.sh must be run as root (try: sudo bash)" >&2
exit 1 exit 1
fi fi
echo "==> installing build prerequisites" echo "==> installing prerequisites"
export DEBIAN_FRONTEND=noninteractive export DEBIAN_FRONTEND=noninteractive
apt-get update -qq apt-get update -qq
apt-get install -y --no-install-recommends \ apt-get install -y --no-install-recommends \
git curl ca-certificates build-essential curl ca-certificates
need_go=1
if command -v go >/dev/null 2>&1; then
have="$(go env GOVERSION 2>/dev/null || true)"
# Accept any go1.23+ toolchain already on the host.
if [[ "${have}" =~ ^go1\.(2[3-9]|[3-9][0-9]) ]]; then
echo "==> using existing ${have}"
need_go=0
fi
fi
if [[ ${need_go} -eq 1 ]]; then
echo "==> installing Go ${GO_VERSION} into /usr/local/go"
tmp="$(mktemp -d)" tmp="$(mktemp -d)"
curl -fsSL "https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz" -o "${tmp}/go.tgz" trap 'rm -rf "${tmp}"' EXIT
rm -rf /usr/local/go
tar -C /usr/local -xzf "${tmp}/go.tgz" echo "==> fetching bundle (${VETTING_VERSION}) from ${BUNDLE_URL}"
rm -rf "${tmp}" curl -fsSL "${BUNDLE_URL}" -o "${tmp}/vetting-bundle.tar.gz"
ln -sf /usr/local/go/bin/go /usr/local/bin/go
echo "==> extracting"
tar -C "${tmp}" -xzf "${tmp}/vetting-bundle.tar.gz"
# Bundle extracts to vetting-bundle-<sha>/; glob-match the single
# top-level directory.
shopt -s nullglob
candidates=( "${tmp}"/vetting-bundle-* )
shopt -u nullglob
if [[ ${#candidates[@]} -ne 1 || ! -d "${candidates[0]}" ]]; then
echo "unexpected bundle layout: expected exactly one vetting-bundle-*/ dir" >&2
exit 1
fi fi
bundle_dir="${candidates[0]}"
echo "==> fetching source into ${SRC_DIR}" echo "==> handing off to install.sh (bundle ${bundle_dir##*/})"
if [[ -d "${SRC_DIR}/.git" ]]; then cd "${bundle_dir}"
git -C "${SRC_DIR}" fetch --depth=1 origin "${BRANCH}" bash install.sh \
# Discard any local mods — the previous build leaves regenerated --binary "${bundle_dir}/bin/vetting-linux-amd64" \
# _templ.go files with build-dir-dependent strings in them, and --agent-binary "${bundle_dir}/bin/vetting-agent.linux-amd64"
# those block a plain checkout. /opt/vetting-src is managed entirely
# by this script, so there's nothing here worth preserving.
git -C "${SRC_DIR}" reset --hard "origin/${BRANCH}"
else
install -d -m 0755 "$(dirname "${SRC_DIR}")"
git clone --depth=1 --branch "${BRANCH}" "${REPO_URL}" "${SRC_DIR}"
fi
echo "==> installing templ ${TEMPL_VERSION}"
GOBIN=/usr/local/bin go install "github.com/a-h/templ/cmd/templ@${TEMPL_VERSION}"
echo "==> building orchestrator + agent (make orchestrator-linux agent-linux)"
cd "${SRC_DIR}"
make orchestrator-linux agent-linux
echo "==> running deploy/install.sh"
bash deploy/install.sh --binary "bin/vetting-linux-amd64"
cat <<EOF cat <<EOF
vetting source is at ${SRC_DIR}. vetting is installed from bundle $(cat "${bundle_dir}/VERSION" 2>/dev/null || echo unknown).
To upgrade later, rerun this one-liner, or from the source dir: To upgrade later, just rerun this one-liner; it always pulls "latest"
cd ${SRC_DIR} && git pull && make orchestrator-linux agent-linux \\ unless VETTING_VERSION is set.
&& sudo ./deploy/install.sh --binary bin/vetting-linux-amd64 \\
&& sudo systemctl restart vetting To pin a specific build:
VETTING_VERSION=sha-abc1234 curl -fsSL \\
${REGISTRY_URL}/${PACKAGE_OWNER}/Vetting/raw/branch/main/deploy/proxmox-install.sh \\
| sudo bash
For PXE support, the bundle also ships deploy/pxe-setup.sh — see
docs/operations.md for the flow.
EOF EOF
+45 -26
View File
@@ -11,32 +11,50 @@ Target: a Debian/Ubuntu LXC on the Proxmox host that holds the cluster
you're vetting for. The LXC must be on the same L2 segment as the you're vetting for. The LXC must be on the same L2 segment as the
repaired nodes so DHCP and WoL work. repaired nodes so DHCP and WoL work.
### One-shot release bundle (recommended) ### One-liner install (recommended)
On your dev workstation (Linux, or WSL on Windows): Every push to `main` kicks off a Gitea Actions run that builds a full
release bundle (orchestrator + agent + live image + install scripts +
pinned iPXE SHAs) and publishes it to the Gitea package registry. The
LXC installer fetches the prebuilt tarball — no source clone, no Go
toolchain, no `make`, no WSL.
On the LXC:
``` ```
make release curl -fsSL https://gitea.thewrightserver.net/josh/Vetting/raw/branch/main/deploy/proxmox-install.sh \
| sudo bash
``` ```
Produces `bin/vetting-bundle-<sha>.tar.gz` containing the orchestrator To pin a specific build instead of the rolling `latest`:
binary, agent binary, live image (`vmlinuz` + `initrd.img`), install
scripts, `vetting.service`, the production yaml, and the pinned iPXE
SHA256 file.
Ship it to the LXC:
``` ```
VETTING_VERSION=sha-abc1234 curl -fsSL .../proxmox-install.sh | sudo bash
```
`proxmox-install.sh` curls the bundle from
`${REGISTRY_URL}/api/packages/${PACKAGE_OWNER}/generic/vetting/${VETTING_VERSION}/vetting-bundle.tar.gz`,
extracts it, and hands off to the bundled `install.sh` for the base
install (user, binaries, config, systemd unit).
If you don't need PXE (e.g. host-mode reporter only, no automated
live-boots), you can stop here — edit `/etc/vetting/vetting.yaml` to
tune `server.bind` / `public_url`, then
`sudo systemctl enable --now vetting`.
### Offline / air-gapped install
If the LXC can't reach the registry, build the tarball locally and
`scp` it across:
```
make release # on a Linux/WSL workstation
scp bin/vetting-bundle-<sha>.tar.gz lxc:/tmp/ scp bin/vetting-bundle-<sha>.tar.gz lxc:/tmp/
ssh lxc 'cd /tmp && tar xzf vetting-bundle-*.tar.gz' ssh lxc 'cd /tmp && tar xzf vetting-bundle-*.tar.gz \
ssh lxc 'cd /tmp/vetting-bundle-<sha> && sudo ./install.sh' && cd vetting-bundle-* && sudo ./install.sh'
``` ```
`install.sh` does the base install (user, binaries, config, systemd Same bundle layout either way.
unit). If you don't need PXE (e.g. host-mode reporter only, no
automated live-boots), you can stop here — edit
`/etc/vetting/vetting.yaml` to tune `server.bind` / `public_url`,
then `sudo systemctl enable --now vetting`.
### PXE enablement ### PXE enablement
@@ -90,9 +108,9 @@ silently when a host first PXE-boots.
`pxe-setup.sh` is idempotent — safe to re-run. Pass `--force` to `pxe-setup.sh` is idempotent — safe to re-run. Pass `--force` to
overwrite a hand-edited `pxe:` block. overwrite a hand-edited `pxe:` block.
### Manual install (no release tarball) ### Dev-loop install (from a source checkout)
For dev-loop iteration on the LXC itself: For iterating on the orchestrator without waiting for a CI publish:
1. On your workstation: `make orchestrator-linux && make agent-linux` 1. On your workstation: `make orchestrator-linux && make agent-linux`
2. Copy the repo tree (or just `bin/` + `deploy/`) onto the LXC 2. Copy the repo tree (or just `bin/` + `deploy/`) onto the LXC
@@ -197,14 +215,15 @@ auth is independent and keeps working either way.
## Upgrading ## Upgrading
1. `make orchestrator-linux` on your workstation. Rerun the registry-fetch one-liner on the LXC:
2. `scp bin/vetting-linux-amd64 lxc:/tmp/vetting.new`
3. On the LXC:
``` ```
sudo systemctl stop vetting curl -fsSL https://gitea.thewrightserver.net/josh/Vetting/raw/branch/main/deploy/proxmox-install.sh \
sudo install -m 0755 /tmp/vetting.new /usr/local/bin/vetting | sudo bash
sudo systemctl start vetting sudo systemctl restart vetting
``` ```
The DB migration runs at startup and is append-only — no manual schema Pin to a specific build with `VETTING_VERSION=sha-abc1234` if you
work unless a release's notes call it out. need to roll back or test a commit. The DB migration runs at startup
and is append-only — no manual schema work unless a release's notes
call it out.