Deploy: make the LXC updater a real file so existing containers can bootstrap it
ci / build-test (push) Successful in 1m28s
ci / build-test (push) Successful in 1m28s
The updater was emitted from a heredoc inside the installer, so a container provisioned before it existed had no way to obtain /usr/bin/update — 'update' just reported command not found, with no path forward short of reinstalling. Ship it as deploy/install/metervault-update.sh and have the installer install(1) it from the checkout it just built. An already-provisioned container can now bootstrap from its own source tree after a git pull, and the updater refreshes itself (atomic rename, since bash reads a running script lazily) so the same stranding does not recur. Uses echo rather than msg_warn for the missing-file case: msg_warn is not otherwise relied on in this script, and an undefined function under the framework ERR trap would abort an otherwise-successful install. Claude-Session: https://claude.ai/code/session_01V6joyergfvVLFEizH1hJLd
This commit is contained in:
@@ -224,27 +224,17 @@ WantedBy=multi-user.target
|
|||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
# A self-contained in-container updater: pull the latest source and rebuild, no host round-trip and
|
# Install the in-container updater from the checkout we just built, rather than emitting it from a
|
||||||
# no re-fetch of the community-scripts framework (safer + simpler than re-running the ct script).
|
# heredoc here. Keeping it a real file in the repo means an already-provisioned container can
|
||||||
|
# bootstrap /usr/bin/update itself after a git pull, instead of being stranded on whatever the
|
||||||
|
# installer wrote the day it ran.
|
||||||
write_update_command() {
|
write_update_command() {
|
||||||
cat <<'EOF' >/usr/bin/update
|
local src="${SOURCE_DIR}/deploy/install/metervault-update.sh"
|
||||||
#!/usr/bin/env bash
|
if [[ ! -f "${src}" ]]; then
|
||||||
set -euo pipefail
|
echo "Updater script not found at ${src} — skipping 'update' command." >&2
|
||||||
if ! systemd-detect-virt --container --quiet 2>/dev/null; then
|
return 0
|
||||||
echo "Run 'update' inside the MeterVault LXC, not on the Proxmox host." >&2
|
fi
|
||||||
exit 1
|
install -m 0755 "${src}" /usr/bin/update
|
||||||
fi
|
|
||||||
export DOTNET_CLI_TELEMETRY_OPTOUT=1 DOTNET_NOLOGO=1
|
|
||||||
echo "Stopping metervault…"; systemctl stop metervault || true
|
|
||||||
echo "Pulling latest source…"
|
|
||||||
git -C /opt/metervault-src fetch --depth 1 origin master
|
|
||||||
git -C /opt/metervault-src reset --hard origin/master
|
|
||||||
echo "Rebuilding (dotnet publish)…"
|
|
||||||
dotnet publish /opt/metervault-src/src/App/MeterVault.App.csproj -c Release -o /opt/metervault /p:UseAppHost=false
|
|
||||||
echo "Starting metervault…"; systemctl start metervault
|
|
||||||
echo "MeterVault updated."
|
|
||||||
EOF
|
|
||||||
chmod +x /usr/bin/update
|
|
||||||
}
|
}
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# MeterVault in-container updater — installed to /usr/bin/update by metervault-install.sh.
|
||||||
|
# Pulls the latest source and rebuilds in place: no host round-trip and no re-fetch of the
|
||||||
|
# community-scripts framework (safer + simpler than re-running the ct script).
|
||||||
|
#
|
||||||
|
# Kept as a standalone file rather than a heredoc in the installer so an already-provisioned
|
||||||
|
# container can bootstrap it straight from its own checkout:
|
||||||
|
# git -C /opt/metervault-src fetch --depth 1 origin master
|
||||||
|
# git -C /opt/metervault-src reset --hard origin/master
|
||||||
|
# install -m 0755 /opt/metervault-src/deploy/install/metervault-update.sh /usr/bin/update
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
: "${SOURCE_DIR:=/opt/metervault-src}"
|
||||||
|
: "${INSTALL_DIR:=/opt/metervault}"
|
||||||
|
: "${METERVAULT_BRANCH:=master}"
|
||||||
|
|
||||||
|
# SAFETY GUARD — this must run INSIDE the MeterVault LXC, never on the Proxmox host.
|
||||||
|
if ! systemd-detect-virt --container --quiet 2>/dev/null; then
|
||||||
|
echo "Run 'update' inside the MeterVault LXC, not on the Proxmox host." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -d "${SOURCE_DIR}/.git" ]]; then
|
||||||
|
echo "No source checkout at ${SOURCE_DIR} — cannot rebuild. Reinstall to restore it." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
export DOTNET_CLI_TELEMETRY_OPTOUT=1 DOTNET_NOLOGO=1
|
||||||
|
|
||||||
|
echo "Stopping metervault…"
|
||||||
|
systemctl stop metervault || true
|
||||||
|
|
||||||
|
echo "Pulling latest source…"
|
||||||
|
git -C "${SOURCE_DIR}" fetch --depth 1 origin "${METERVAULT_BRANCH}"
|
||||||
|
git -C "${SOURCE_DIR}" reset --hard "origin/${METERVAULT_BRANCH}"
|
||||||
|
|
||||||
|
echo "Rebuilding (dotnet publish — this can take a few minutes)…"
|
||||||
|
dotnet publish "${SOURCE_DIR}/src/App/MeterVault.App.csproj" -c Release -o "${INSTALL_DIR}" /p:UseAppHost=false
|
||||||
|
|
||||||
|
echo "Starting metervault…"
|
||||||
|
systemctl start metervault
|
||||||
|
|
||||||
|
# Refresh this script from the checkout we just pulled, so a change to the updater itself lands
|
||||||
|
# without stranding the container again. Atomic rename, never an in-place write: bash reads the
|
||||||
|
# running script lazily, so truncating it mid-run would corrupt the remainder of this execution.
|
||||||
|
self="${SOURCE_DIR}/deploy/install/metervault-update.sh"
|
||||||
|
if [[ -f "${self}" ]] && ! cmp -s "${self}" /usr/bin/update; then
|
||||||
|
install -m 0755 "${self}" /usr/bin/.update.new && mv /usr/bin/.update.new /usr/bin/update
|
||||||
|
echo "Updater itself refreshed — the new version applies from the next run."
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "MeterVault updated."
|
||||||
Reference in New Issue
Block a user