From d796928969b0b557ef5ed2d48e0e6f5e5a197df3 Mon Sep 17 00:00:00 2001 From: rcourtman Date: Sun, 28 Jun 2026 03:26:13 +0100 Subject: [PATCH] Install signature verifier dependencies --- .../subsystems/deployment-installability.md | 7 +++++++ install.sh | 10 ++++++---- scripts/installtests/root_install_sh_test.go | 19 +++++++++++++++++++ 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/docs/release-control/v6/internal/subsystems/deployment-installability.md b/docs/release-control/v6/internal/subsystems/deployment-installability.md index 412d43498..ea86b7455 100644 --- a/docs/release-control/v6/internal/subsystems/deployment-installability.md +++ b/docs/release-control/v6/internal/subsystems/deployment-installability.md @@ -315,6 +315,13 @@ TLS floor in the dynamic config. `scripts/validate-release.sh` at build time and re-verified by `install-sh-smoke.yml` against the served asset. 3. Add or change root server installer, shell installer, Docker bootstrap installer, Windows installer, container-agent installer, repo-root compose defaults, or auto-update script behavior through `install.sh`, `scripts/install.sh`, `scripts/install-docker.sh`, `scripts/install.ps1`, `scripts/install-container-agent.sh`, `docker-compose.yml`, and `scripts/pulse-auto-update.sh` + The root `install.sh` server installer owns its fresh-host dependency + bootstrap for supported Debian, Ubuntu, and Proxmox targets. It must install + `curl`, `wget`, `ca-certificates`, and `openssh-client` before installing + release archives, with `jq` as an optional reliability dependency; release + signature verification depends on `ssh-keygen` from `openssh-client` and + must not fail on a minimal supported host solely because that package was + absent before installation started. The top-level `install.sh` asset published on GitHub Releases must be the root Pulse SERVER installer (the LXC / systemd / Proxmox VE installer that accepts `--version vX.Y.Z`, `--rc`, `--stable`, and friends). The rendered diff --git a/install.sh b/install.sh index c9696c8ad..39652d7a1 100755 --- a/install.sh +++ b/install.sh @@ -2720,10 +2720,12 @@ install_dependencies() { print_info "Installing dependencies..." apt-get update -qq >/dev/null 2>&1 - # Install essential dependencies plus jq for reliable JSON handling - apt-get install -y -qq curl wget jq >/dev/null 2>&1 || { - # If jq fails to install, just install the essentials - apt-get install -y -qq curl wget >/dev/null 2>&1 + # Install essential dependencies plus jq for reliable JSON handling. + # openssh-client provides ssh-keygen, which signed release verification + # requires before installing downloaded or local release archives. + apt-get install -y -qq curl wget ca-certificates openssh-client jq >/dev/null 2>&1 || { + # If jq fails to install, keep the installer-critical dependencies. + apt-get install -y -qq curl wget ca-certificates openssh-client >/dev/null 2>&1 } } diff --git a/scripts/installtests/root_install_sh_test.go b/scripts/installtests/root_install_sh_test.go index feb54e0b3..1f2904f8d 100644 --- a/scripts/installtests/root_install_sh_test.go +++ b/scripts/installtests/root_install_sh_test.go @@ -89,6 +89,25 @@ func TestRootInstallScriptArchiveSupportContract(t *testing.T) { } } +func TestRootInstallScriptInstallsSignatureVerificationDependencies(t *testing.T) { + content, err := os.ReadFile(filepath.Join("..", "..", "install.sh")) + if err != nil { + t.Fatalf("read root install.sh: %v", err) + } + + script := string(content) + required := []string{ + `apt-get install -y -qq curl wget ca-certificates openssh-client jq`, + `apt-get install -y -qq curl wget ca-certificates openssh-client`, + `ssh-keygen is required to verify signed Pulse release assets.`, + } + for _, needle := range required { + if !strings.Contains(script, needle) { + t.Fatalf("install.sh missing signature verification dependency contract: %s", needle) + } + } +} + func TestRootInstallScriptInfersPrivateProArchiveVersion(t *testing.T) { script := ` set -euo pipefail