mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-09-09 18:15:50 +00:00
Keep Windows agent update signatures addressable
Change-source: pulse-maintainer
This commit is contained in:
@@ -98,6 +98,15 @@ jobs:
|
||||
set -euo pipefail
|
||||
test "$(readlink /usr/local/bin/pulse-agent)" = "/opt/pulse/bin/pulse-agent-linux-amd64"
|
||||
test -x /usr/local/bin/pulse-agent
|
||||
for arch in amd64 arm64 386; do
|
||||
for suffix in "" .sig .sshsig; do
|
||||
alias="/opt/pulse/bin/pulse-agent-windows-${arch}${suffix}"
|
||||
target="pulse-agent-windows-${arch}.exe${suffix}"
|
||||
test -L "${alias}"
|
||||
test "$(readlink "${alias}")" = "${target}"
|
||||
test -s "${alias}"
|
||||
done
|
||||
done
|
||||
for sidecar in /opt/pulse/bin/*.sig /opt/pulse/bin/*.sshsig; do
|
||||
test ! -x "$sidecar"
|
||||
done
|
||||
|
||||
+14
-1
@@ -369,10 +369,17 @@ RUN if [ "$TARGETARCH" = "arm64" ]; then \
|
||||
|
||||
# Unified agent binaries (all platforms and architectures) plus detached signatures
|
||||
COPY --from=release-assets-builder /app/pulse-agent-* /opt/pulse/bin/
|
||||
# Create symlinks for Windows without .exe extension
|
||||
# Create complete binary/signature aliases for Windows without .exe extension.
|
||||
# The download handler resolves this name and reads detached sidecars beside it.
|
||||
RUN ln -s pulse-agent-windows-amd64.exe /opt/pulse/bin/pulse-agent-windows-amd64 && \
|
||||
ln -s pulse-agent-windows-amd64.exe.sig /opt/pulse/bin/pulse-agent-windows-amd64.sig && \
|
||||
ln -s pulse-agent-windows-amd64.exe.sshsig /opt/pulse/bin/pulse-agent-windows-amd64.sshsig && \
|
||||
ln -s pulse-agent-windows-arm64.exe /opt/pulse/bin/pulse-agent-windows-arm64 && \
|
||||
ln -s pulse-agent-windows-arm64.exe.sig /opt/pulse/bin/pulse-agent-windows-arm64.sig && \
|
||||
ln -s pulse-agent-windows-arm64.exe.sshsig /opt/pulse/bin/pulse-agent-windows-arm64.sshsig && \
|
||||
ln -s pulse-agent-windows-386.exe /opt/pulse/bin/pulse-agent-windows-386 && \
|
||||
ln -s pulse-agent-windows-386.exe.sig /opt/pulse/bin/pulse-agent-windows-386.sig && \
|
||||
ln -s pulse-agent-windows-386.exe.sshsig /opt/pulse/bin/pulse-agent-windows-386.sshsig && \
|
||||
chown -R pulse:pulse /opt/pulse
|
||||
|
||||
# Arch-resolved /usr/local/bin/pulse-agent so the helm chart's agent workload
|
||||
@@ -411,8 +418,14 @@ RUN chmod 755 /opt/pulse/scripts/*.sh /opt/pulse/scripts/*.ps1 && \
|
||||
ln -sf /opt/pulse/bin/pulse-agent-linux-amd64 /usr/local/bin/pulse-agent; \
|
||||
fi && \
|
||||
ln -sf pulse-agent-windows-amd64.exe /opt/pulse/bin/pulse-agent-windows-amd64 && \
|
||||
ln -sf pulse-agent-windows-amd64.exe.sig /opt/pulse/bin/pulse-agent-windows-amd64.sig && \
|
||||
ln -sf pulse-agent-windows-amd64.exe.sshsig /opt/pulse/bin/pulse-agent-windows-amd64.sshsig && \
|
||||
ln -sf pulse-agent-windows-arm64.exe /opt/pulse/bin/pulse-agent-windows-arm64 && \
|
||||
ln -sf pulse-agent-windows-arm64.exe.sig /opt/pulse/bin/pulse-agent-windows-arm64.sig && \
|
||||
ln -sf pulse-agent-windows-arm64.exe.sshsig /opt/pulse/bin/pulse-agent-windows-arm64.sshsig && \
|
||||
ln -sf pulse-agent-windows-386.exe /opt/pulse/bin/pulse-agent-windows-386 && \
|
||||
ln -sf pulse-agent-windows-386.exe.sig /opt/pulse/bin/pulse-agent-windows-386.sig && \
|
||||
ln -sf pulse-agent-windows-386.exe.sshsig /opt/pulse/bin/pulse-agent-windows-386.sshsig && \
|
||||
chown -R pulse:pulse /opt/pulse
|
||||
|
||||
# Unified Agent image assembled from the same immutable candidate payload.
|
||||
|
||||
@@ -987,6 +987,13 @@ artifact-selection behaviour.
|
||||
against their exact `.exe` targets and then omit them, because the image
|
||||
recreates those aliases deterministically and the immutable payload
|
||||
manifest remains regular-file-only.
|
||||
Each alias is a three-member delivery contract: the extensionless binary,
|
||||
`.sig`, and `.sshsig` paths must resolve respectively to the signed `.exe`,
|
||||
`.exe.sig`, and `.exe.sshsig` files. Server archives must create those
|
||||
aliases only after signing the complete cross-platform payload, and both
|
||||
source-built and exact-candidate images must recreate and qualify all three;
|
||||
otherwise the download handler rejects the local Windows agent and falls
|
||||
through to a release asset with the wrong filename identity.
|
||||
Helm Pages convergence must promote the immutable chart artifact produced
|
||||
and qualified by the exact create-release run. It must bind that artifact
|
||||
to the activated source run, tag, commit, and activation marker, and must
|
||||
|
||||
@@ -206,6 +206,32 @@ func TestDownloadUnifiedAgent_LocalReleaseBinaryIncludesSignatureHeader(t *testi
|
||||
assert.Equal(t, encodedTestSSHSignature("signed-local-agent-ssh"), w.Header().Get(sshSignatureHeaderName))
|
||||
}
|
||||
|
||||
func TestDownloadUnifiedAgent_WindowsReleaseAliasIncludesSignatureHeaders(t *testing.T) {
|
||||
router, tempDir := setupUnifiedAgentRouter(t)
|
||||
router.serverVersion = "v6.4.2"
|
||||
router.installScriptClient = newTestInstallScriptClient(t, http.MethodGet, "", 0, "", errors.New("GitHub fallback must not be used"))
|
||||
|
||||
binDir := filepath.Join(tempDir, "bin")
|
||||
baseName := "pulse-agent-windows-amd64"
|
||||
exePath := filepath.Join(binDir, baseName+".exe")
|
||||
binContent := validTestUnifiedAgentBinary("windows-amd64")
|
||||
require.NoError(t, os.WriteFile(exePath, binContent, 0755))
|
||||
require.NoError(t, os.WriteFile(exePath+".sig", []byte("signed-windows-agent"), 0644))
|
||||
require.NoError(t, os.WriteFile(exePath+".sshsig", []byte("signed-windows-agent-ssh"), 0644))
|
||||
for _, suffix := range []string{"", ".sig", ".sshsig"} {
|
||||
require.NoError(t, os.Symlink(baseName+".exe"+suffix, filepath.Join(binDir, baseName+suffix)))
|
||||
}
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/download/pulse-agent?arch=windows-amd64", nil)
|
||||
w := httptest.NewRecorder()
|
||||
router.handleDownloadUnifiedAgent(w, req)
|
||||
|
||||
require.Equal(t, http.StatusOK, w.Code, w.Body.String())
|
||||
assert.Equal(t, string(binContent), w.Body.String())
|
||||
assert.Equal(t, "signed-windows-agent", w.Header().Get(signatureHeaderName))
|
||||
assert.Equal(t, encodedTestSSHSignature("signed-windows-agent-ssh"), w.Header().Get(sshSignatureHeaderName))
|
||||
}
|
||||
|
||||
func TestDownloadUnifiedAgent_SkipsStaleLocalBinaryAndProxies(t *testing.T) {
|
||||
router, tempDir := setupUnifiedAgentRouter(t)
|
||||
router.serverVersion = "v6.0.0-rc.1"
|
||||
|
||||
@@ -396,11 +396,9 @@ esac
|
||||
EOF
|
||||
chmod +x "$universal_dir/bin/pulse-agent"
|
||||
|
||||
# Add VERSION file
|
||||
# Add VERSION file. Sign the completed universal payload only after every
|
||||
# cross-platform agent has been staged below.
|
||||
echo "$VERSION" > "$universal_dir/VERSION"
|
||||
pulse_release_sign_directory_assets "$universal_dir/bin"
|
||||
pulse_release_sign_directory_assets "$universal_dir/scripts"
|
||||
pulse_release_sign_file "$universal_dir/VERSION"
|
||||
|
||||
# Package standalone unified agent binaries (all platforms)
|
||||
# Linux
|
||||
@@ -500,10 +498,12 @@ cp "$BUILD_DIR/pulse-agent-windows-amd64.exe" "$universal_dir/bin/"
|
||||
cp "$BUILD_DIR/pulse-agent-windows-arm64.exe" "$universal_dir/bin/"
|
||||
cp "$BUILD_DIR/pulse-agent-windows-386.exe" "$universal_dir/bin/"
|
||||
|
||||
# Create symlinks for Windows binaries without .exe extension (required for download endpoint)
|
||||
ln -s pulse-agent-windows-amd64.exe "$universal_dir/bin/pulse-agent-windows-amd64"
|
||||
ln -s pulse-agent-windows-arm64.exe "$universal_dir/bin/pulse-agent-windows-arm64"
|
||||
ln -s pulse-agent-windows-386.exe "$universal_dir/bin/pulse-agent-windows-386"
|
||||
# Sign all regular payload files, then create the extensionless Windows aliases
|
||||
# as complete binary/signature triplets required by the download endpoint.
|
||||
pulse_release_sign_directory_assets "$universal_dir/bin"
|
||||
pulse_release_sign_directory_assets "$universal_dir/scripts"
|
||||
pulse_release_sign_file "$universal_dir/VERSION"
|
||||
pulse_release_link_windows_agent_aliases "$universal_dir/bin"
|
||||
|
||||
# Create universal tarball
|
||||
cd "$universal_dir"
|
||||
|
||||
@@ -509,6 +509,9 @@ func TestReleaseContainerTargetsConsumeImmutableCandidate(t *testing.T) {
|
||||
`test "${actual_embedded_agent}" = "${expected_agent}"`,
|
||||
`test "$(readlink /usr/local/bin/pulse-agent)" = "/opt/pulse/bin/pulse-agent-linux-amd64"`,
|
||||
`test -x /usr/local/bin/pulse-agent`,
|
||||
`for arch in amd64 arm64 386; do`,
|
||||
`target="pulse-agent-windows-${arch}.exe${suffix}"`,
|
||||
`test -s "${alias}"`,
|
||||
`test ! -x "$sidecar"`,
|
||||
} {
|
||||
if !strings.Contains(qualifier, needle) {
|
||||
@@ -517,6 +520,54 @@ func TestReleaseContainerTargetsConsumeImmutableCandidate(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestWindowsAgentAliasesCarryDetachedSignatureSidecars(t *testing.T) {
|
||||
commonPath := repoFile("scripts", "release_asset_common.sh")
|
||||
tempDir := t.TempDir()
|
||||
for _, arch := range []string{"amd64", "arm64", "386"} {
|
||||
base := filepath.Join(tempDir, "pulse-agent-windows-"+arch+".exe")
|
||||
for _, suffix := range []string{"", ".sig", ".sshsig"} {
|
||||
if err := os.WriteFile(base+suffix, []byte("packet-"+arch+suffix), 0o644); err != nil {
|
||||
t.Fatalf("write Windows packet fixture: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
cmd := exec.Command("bash", "-c", `source "$1"; pulse_release_link_windows_agent_aliases "$2"`, "windows-agent-alias-test", commonPath, tempDir)
|
||||
if output, err := cmd.CombinedOutput(); err != nil {
|
||||
t.Fatalf("create Windows agent packet aliases: %v\n%s", err, output)
|
||||
}
|
||||
for _, arch := range []string{"amd64", "arm64", "386"} {
|
||||
for _, suffix := range []string{"", ".sig", ".sshsig"} {
|
||||
alias := filepath.Join(tempDir, "pulse-agent-windows-"+arch+suffix)
|
||||
want := "pulse-agent-windows-" + arch + ".exe" + suffix
|
||||
got, err := os.Readlink(alias)
|
||||
if err != nil {
|
||||
t.Fatalf("read Windows agent alias %s: %v", alias, err)
|
||||
}
|
||||
if got != want {
|
||||
t.Fatalf("Windows agent alias %s targets %q, want %q", alias, got, want)
|
||||
}
|
||||
if info, err := os.Stat(alias); err != nil || info.Size() == 0 {
|
||||
t.Fatalf("Windows agent alias %s does not resolve to a non-empty packet member: info=%v err=%v", alias, info, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assertFileContainsAll(t, repoFile("Dockerfile"),
|
||||
`ln -s pulse-agent-windows-amd64.exe.sig /opt/pulse/bin/pulse-agent-windows-amd64.sig`,
|
||||
`ln -s pulse-agent-windows-amd64.exe.sshsig /opt/pulse/bin/pulse-agent-windows-amd64.sshsig`,
|
||||
`ln -sf pulse-agent-windows-amd64.exe.sig /opt/pulse/bin/pulse-agent-windows-amd64.sig`,
|
||||
`ln -sf pulse-agent-windows-amd64.exe.sshsig /opt/pulse/bin/pulse-agent-windows-amd64.sshsig`,
|
||||
)
|
||||
assertFileContainsAll(t, repoFile("scripts", "build-release.sh"),
|
||||
`pulse_release_sign_directory_assets "$universal_dir/bin"`,
|
||||
`pulse_release_link_windows_agent_aliases "$universal_dir/bin"`,
|
||||
)
|
||||
assertFileContainsAll(t, repoFile("scripts", "prepare-release-container-context.sh"),
|
||||
`for suffix in "" .sig .sshsig; do`,
|
||||
`expected_target="pulse-agent-windows-${windows_arch}.exe${suffix}"`,
|
||||
)
|
||||
}
|
||||
|
||||
func TestReleaseContainerContextTreatsServerSignaturesAsArchitectureBound(t *testing.T) {
|
||||
version := "6.3.0-rc.test"
|
||||
releaseDir := t.TempDir()
|
||||
@@ -548,6 +599,11 @@ func TestReleaseContainerContextTreatsServerSignaturesAsArchitectureBound(t *tes
|
||||
"scripts/install.sh.sshsig": "shared-installer-sshsig",
|
||||
"VERSION": version,
|
||||
}
|
||||
for _, windowsArch := range []string{"amd64", "arm64", "386"} {
|
||||
name := "bin/pulse-agent-windows-" + windowsArch + ".exe"
|
||||
files[name+".sig"] = "shared-windows-" + windowsArch + "-signature"
|
||||
files[name+".sshsig"] = "shared-windows-" + windowsArch + "-ssh-signature"
|
||||
}
|
||||
for _, helperTarget := range []string{"linux-amd64", "linux-arm64", "linux-armv7", "linux-armv6", "linux-386"} {
|
||||
name := "bin/pulse-agent-helper-" + helperTarget
|
||||
files[name] = "shared-helper-" + helperTarget
|
||||
@@ -576,11 +632,13 @@ func TestReleaseContainerContextTreatsServerSignaturesAsArchitectureBound(t *tes
|
||||
}
|
||||
}
|
||||
for _, windowsArch := range []string{"amd64", "arm64", "386"} {
|
||||
name := "bin/pulse-agent-windows-" + windowsArch
|
||||
target := "pulse-agent-windows-" + windowsArch + ".exe"
|
||||
header := &tar.Header{Name: name, Mode: 0o777, Typeflag: tar.TypeSymlink, Linkname: target}
|
||||
if err := tarWriter.WriteHeader(header); err != nil {
|
||||
t.Fatalf("write %s alias to %s archive: %v", name, arch, err)
|
||||
for _, suffix := range []string{"", ".sig", ".sshsig"} {
|
||||
name := "bin/pulse-agent-windows-" + windowsArch + suffix
|
||||
target := "pulse-agent-windows-" + windowsArch + ".exe" + suffix
|
||||
header := &tar.Header{Name: name, Mode: 0o777, Typeflag: tar.TypeSymlink, Linkname: target}
|
||||
if err := tarWriter.WriteHeader(header); err != nil {
|
||||
t.Fatalf("write %s alias to %s archive: %v", name, arch, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
if err := tarWriter.Close(); err != nil {
|
||||
@@ -614,9 +672,11 @@ func TestReleaseContainerContextTreatsServerSignaturesAsArchitectureBound(t *tes
|
||||
t.Fatalf("prepared context retained duplicate universal payload: %v", err)
|
||||
}
|
||||
for _, windowsArch := range []string{"amd64", "arm64", "386"} {
|
||||
aliasPath := filepath.Join(outputDir, "amd64", "bin", "pulse-agent-windows-"+windowsArch)
|
||||
if _, err := os.Lstat(aliasPath); !os.IsNotExist(err) {
|
||||
t.Fatalf("prepared context retained recreated Windows alias %s: %v", aliasPath, err)
|
||||
for _, suffix := range []string{"", ".sig", ".sshsig"} {
|
||||
aliasPath := filepath.Join(outputDir, "amd64", "bin", "pulse-agent-windows-"+windowsArch+suffix)
|
||||
if _, err := os.Lstat(aliasPath); !os.IsNotExist(err) {
|
||||
t.Fatalf("prepared context retained recreated Windows alias %s: %v", aliasPath, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -86,18 +86,20 @@ for arch in amd64 arm64; do
|
||||
validate_archive_entries "${archive}"
|
||||
tar --no-same-owner --no-same-permissions -xzf "${archive}" -C "${output_dir}/${arch}"
|
||||
for windows_arch in amd64 arm64 386; do
|
||||
alias_path="${output_dir}/${arch}/bin/pulse-agent-windows-${windows_arch}"
|
||||
expected_target="pulse-agent-windows-${windows_arch}.exe"
|
||||
if [[ ! -L "${alias_path}" ]] || \
|
||||
[[ "$(readlink "${alias_path}")" != "${expected_target}" ]] || \
|
||||
[[ ! -f "${output_dir}/${arch}/bin/${expected_target}" ]]; then
|
||||
echo "Error: ${archive} has an invalid Windows agent alias ${alias_path}." >&2
|
||||
exit 1
|
||||
fi
|
||||
# runtime_prebuilt recreates these aliases after copying the immutable
|
||||
# .exe payloads. Keep the manifest-covered context symlink-free rather
|
||||
# than weakening its canonical-file rule.
|
||||
rm -f "${alias_path}"
|
||||
for suffix in "" .sig .sshsig; do
|
||||
alias_path="${output_dir}/${arch}/bin/pulse-agent-windows-${windows_arch}${suffix}"
|
||||
expected_target="pulse-agent-windows-${windows_arch}.exe${suffix}"
|
||||
if [[ ! -L "${alias_path}" ]] || \
|
||||
[[ "$(readlink "${alias_path}")" != "${expected_target}" ]] || \
|
||||
[[ ! -f "${output_dir}/${arch}/bin/${expected_target}" ]]; then
|
||||
echo "Error: ${archive} has an invalid Windows agent alias ${alias_path}." >&2
|
||||
exit 1
|
||||
fi
|
||||
# runtime_prebuilt recreates these aliases after copying the
|
||||
# immutable .exe payload and sidecars. Keep the manifest-covered
|
||||
# context symlink-free rather than weakening its canonical-file rule.
|
||||
rm -f "${alias_path}"
|
||||
done
|
||||
done
|
||||
for required in \
|
||||
bin/pulse \
|
||||
|
||||
@@ -124,6 +124,20 @@ pulse_release_sign_directory_assets() {
|
||||
done < <(find "${dir}" -maxdepth 1 -type f ! -name '*.sig' ! -name '*.sshsig' -print0)
|
||||
}
|
||||
|
||||
pulse_release_link_windows_agent_aliases() {
|
||||
local dir="$1"
|
||||
local target=""
|
||||
local suffix=""
|
||||
|
||||
for target in windows-amd64 windows-arm64 windows-386; do
|
||||
for suffix in "" .sig .sshsig; do
|
||||
ln -sf \
|
||||
"pulse-agent-${target}.exe${suffix}" \
|
||||
"${dir}/pulse-agent-${target}${suffix}"
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
pulse_release_stage_server_archive() {
|
||||
local archive_path="$1"
|
||||
local staging_dir="$2"
|
||||
@@ -171,13 +185,6 @@ pulse_release_stage_server_archive() {
|
||||
dest="${staging_dir}/bin/pulse-agent-runner-${target}"
|
||||
install -m 0755 "${src}" "${dest}"
|
||||
done
|
||||
(
|
||||
cd "${staging_dir}/bin"
|
||||
ln -sf pulse-agent-windows-amd64.exe pulse-agent-windows-amd64
|
||||
ln -sf pulse-agent-windows-arm64.exe pulse-agent-windows-arm64
|
||||
ln -sf pulse-agent-windows-386.exe pulse-agent-windows-386
|
||||
)
|
||||
|
||||
install -m 0755 "${PULSE_SCRIPTS_DIR}/install-container-agent.sh" "${staging_dir}/scripts/install-container-agent.sh"
|
||||
install -m 0755 "${PULSE_SCRIPTS_DIR}/install-docker.sh" "${staging_dir}/scripts/install-docker.sh"
|
||||
install -m 0755 "${rendered_installers_dir}/install.sh" "${staging_dir}/scripts/install.sh"
|
||||
@@ -189,6 +196,7 @@ pulse_release_stage_server_archive() {
|
||||
pulse_release_sign_directory_assets "${staging_dir}/bin"
|
||||
pulse_release_sign_directory_assets "${staging_dir}/scripts"
|
||||
pulse_release_sign_file "${staging_dir}/VERSION"
|
||||
pulse_release_link_windows_agent_aliases "${staging_dir}/bin"
|
||||
|
||||
mkdir -p "$(dirname "${archive_path}")"
|
||||
(
|
||||
|
||||
@@ -254,7 +254,7 @@ if [ "$SKIP_DOCKER" = false ]; then
|
||||
|
||||
# Validate all required binaries exist and are non-empty
|
||||
info "Checking downloadable binaries in /opt/pulse/bin/..."
|
||||
docker run --rm --entrypoint /bin/sh "$IMAGE" -c 'set -euo pipefail; cd /opt/pulse/bin; required="pulse pulse-agent-linux-amd64 pulse-agent-linux-arm64 pulse-agent-linux-armv7 pulse-agent-linux-armv6 pulse-agent-linux-386 pulse-agent-helper-linux-amd64 pulse-agent-helper-linux-arm64 pulse-agent-helper-linux-armv7 pulse-agent-helper-linux-armv6 pulse-agent-helper-linux-386 pulse-agent-runner-linux-amd64 pulse-agent-runner-linux-arm64 pulse-agent-runner-linux-armv7 pulse-agent-runner-linux-armv6 pulse-agent-runner-linux-386 pulse-agent-darwin-amd64 pulse-agent-darwin-arm64 pulse-agent-windows-amd64.exe pulse-agent-windows-amd64 pulse-agent-windows-arm64.exe pulse-agent-windows-arm64 pulse-agent-windows-386.exe pulse-agent-windows-386 pulse-agent-freebsd-amd64 pulse-agent-freebsd-arm64"; for f in $required; do [ -e "$f" ] || { echo "missing binary $f" >&2; exit 1; }; [ -s "$f" ] || { echo "empty binary $f" >&2; exit 1; }; done; [ "$(readlink pulse-agent-windows-amd64)" = "pulse-agent-windows-amd64.exe" ] || { echo "unified agent windows amd64 symlink broken" >&2; exit 1; }; [ "$(readlink pulse-agent-windows-arm64)" = "pulse-agent-windows-arm64.exe" ] || { echo "unified agent windows arm64 symlink broken" >&2; exit 1; }; [ "$(readlink pulse-agent-windows-386)" = "pulse-agent-windows-386.exe" ] || { echo "unified agent windows 386 symlink broken" >&2; exit 1; }; echo "All binaries present"' || { error "Binary validation failed"; exit 1; }
|
||||
docker run --rm --entrypoint /bin/sh "$IMAGE" -c 'set -euo pipefail; cd /opt/pulse/bin; required="pulse pulse-agent-linux-amd64 pulse-agent-linux-arm64 pulse-agent-linux-armv7 pulse-agent-linux-armv6 pulse-agent-linux-386 pulse-agent-helper-linux-amd64 pulse-agent-helper-linux-arm64 pulse-agent-helper-linux-armv7 pulse-agent-helper-linux-armv6 pulse-agent-helper-linux-386 pulse-agent-runner-linux-amd64 pulse-agent-runner-linux-arm64 pulse-agent-runner-linux-armv7 pulse-agent-runner-linux-armv6 pulse-agent-runner-linux-386 pulse-agent-darwin-amd64 pulse-agent-darwin-arm64 pulse-agent-windows-amd64.exe pulse-agent-windows-amd64 pulse-agent-windows-arm64.exe pulse-agent-windows-arm64 pulse-agent-windows-386.exe pulse-agent-windows-386 pulse-agent-freebsd-amd64 pulse-agent-freebsd-arm64"; for f in $required; do [ -e "$f" ] || { echo "missing binary $f" >&2; exit 1; }; [ -s "$f" ] || { echo "empty binary $f" >&2; exit 1; }; done; for arch in amd64 arm64 386; do for suffix in "" .sig .sshsig; do alias="pulse-agent-windows-${arch}${suffix}"; target="pulse-agent-windows-${arch}.exe${suffix}"; [ -L "$alias" ] || { echo "missing Windows agent alias $alias" >&2; exit 1; }; [ "$(readlink "$alias")" = "$target" ] || { echo "Windows agent alias $alias does not target $target" >&2; exit 1; }; [ -s "$alias" ] || { echo "empty Windows agent alias $alias" >&2; exit 1; }; done; done; echo "All binaries present"' || { error "Binary validation failed"; exit 1; }
|
||||
success "All downloadable binaries present"
|
||||
|
||||
# Validate the arch-resolved /usr/local/bin/pulse-agent symlink. The helm
|
||||
|
||||
Reference in New Issue
Block a user