fix: guard provider gateway runtime dependencies
Pipelines as Code CI / hwlab-web-probe-sentinel-jd01- Failed

This commit is contained in:
Codex
2026-07-05 16:55:38 +00:00
parent f1cf43b42e
commit 41414b8211
2 changed files with 31 additions and 2 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
FROM oven/bun:1-alpine
FROM oven/bun:1.2.22-alpine
ARG ALPINE_REPOSITORY=
RUN if [ -n "$ALPINE_REPOSITORY" ]; then printf '%s\n' "$ALPINE_REPOSITORY/main" "$ALPINE_REPOSITORY/community" > /etc/apk/repositories; fi
RUN apk add --no-cache bash docker-cli docker-cli-compose openssh-client
+30 -1
View File
@@ -1,4 +1,5 @@
import { spawnSync } from "node:child_process";
import { createHash } from "node:crypto";
import { existsSync, readFileSync, readdirSync } from "node:fs";
import { createConnection, type Socket } from "node:net";
import {
@@ -1974,6 +1975,7 @@ function startHostSshSession(message: CoreHostSshOpenMessage): void {
}
try {
const command = typeof message.command === "string" && message.command.length > 0 ? message.command : null;
const commandDigest = command === null ? null : createHash("sha256").update(command).digest("hex").slice(0, 16);
const allocateTty = typeof message.tty === "boolean" ? message.tty : command === null;
const remoteScript = hostSshRemoteScript(command, message.cwd ?? null, allocateTty, message.cols, message.rows);
const proc = Bun.spawn(["ssh", ...hostSshArgs(remoteScript, allocateTty)], {
@@ -2009,7 +2011,16 @@ function startHostSshSession(message: CoreHostSshOpenMessage): void {
hostSshSessions.delete(message.sessionId);
releaseSshDataChannel(message.dataChannelId, message.sessionId);
});
logger("info", "host_ssh_session_started", { sessionId: message.sessionId, hasCommand: command !== null, tty: allocateTty, cwd: message.cwd ?? null, transport: "tcp-pool", dataChannelId: message.dataChannelId });
logger("info", "host_ssh_session_started", {
sessionId: message.sessionId,
hasCommand: command !== null,
commandBytes: command === null ? 0 : Buffer.byteLength(command),
commandDigest,
tty: allocateTty,
cwd: message.cwd ?? null,
transport: "tcp-pool",
dataChannelId: message.dataChannelId,
});
} catch (error) {
sendHostSshError(message.sessionId, error);
releaseSshDataChannel(message.dataChannelId, message.sessionId);
@@ -2155,6 +2166,21 @@ function upgradePlan(taskId: string): Record<string, JsonValue> {
` echo "rollback_to_last_known_good restored old gateway container name=$old_name image=$old_image reason=$reason" >&2`,
`}`,
].join("\n");
const runtimeDependencyGuardScript = [
`validate_gateway_runtime_dependencies() {`,
` container="$1"`,
` phase="$2"`,
` docker exec "$container" /bin/sh -lc 'set -eu`,
`test -x /bin/sh`,
`test -x /usr/bin/ssh`,
`/usr/bin/ssh -V >/tmp/unidesk-provider-ssh-version 2>&1 || { cat /tmp/unidesk-provider-ssh-version >&2; exit 41; }`,
`command -v docker >/dev/null`,
`docker version --format "{{.Client.Version}}" >/dev/null`,
`test -e /lib/libz.so.1 -o -e /usr/lib/libz.so.1`,
`command -v bun >/dev/null' || { echo "$phase provider-gateway runtime dependency guard failed" >&2; return 1; }`,
` echo "$phase provider-gateway runtime dependency guard passed: container=$container"`,
`}`,
].join("\n");
const script = [
"set -eu",
`cd ${shellQuote(workspace)}`,
@@ -2174,6 +2200,7 @@ function upgradePlan(taskId: string): Record<string, JsonValue> {
`first_network=""`,
`network_arg=""`,
rollbackToLastKnownGoodScript,
runtimeDependencyGuardScript,
`if [ -n "$old_ids" ]; then docker update --restart always $old_ids >/dev/null 2>&1 || true; fi`,
`if [ -z "$first_old" ]; then echo "no existing provider-gateway compose container found; cannot perform safe in-place upgrade" >&2; exit 1; fi`,
`old_name=$(docker inspect --format '{{.Name}}' "$first_old")`,
@@ -2211,6 +2238,7 @@ function upgradePlan(taskId: string): Record<string, JsonValue> {
`candidate_restart=$(docker inspect --format '{{.HostConfig.RestartPolicy.Name}}' ${shellQuote(candidateName)})`,
`candidate_pid_mode=$(docker inspect --format '{{.HostConfig.PidMode}}' ${shellQuote(candidateName)})`,
`if [ "$candidate_pid_mode" != "host" ]; then echo "candidate runtime guard failed: restart=$candidate_restart pid=$candidate_pid_mode" >&2; docker rm -f ${shellQuote(candidateName)} >/dev/null 2>&1 || true; rm -f "$candidate_env_file"; exit 1; fi`,
`validate_gateway_runtime_dependencies ${shellQuote(candidateName)} candidate || { docker logs ${shellQuote(candidateName)} >&2 || true; docker rm -f ${shellQuote(candidateName)} >/dev/null 2>&1 || true; rm -f "$candidate_env_file"; exit 1; }`,
`if [ -n "$old_ids" ]; then docker rm -f $old_ids; fi`,
`docker rm -f ${shellQuote(candidateName)} >/dev/null 2>&1 || true`,
composeUpCommand.map(shellQuote).join(" "),
@@ -2221,6 +2249,7 @@ function upgradePlan(taskId: string): Record<string, JsonValue> {
`final_restart=$(docker inspect --format '{{.HostConfig.RestartPolicy.Name}}' "$final_container")`,
`final_pid_mode=$(docker inspect --format '{{.HostConfig.PidMode}}' "$final_container")`,
`if [ "$final_restart" != "always" ] || [ "$final_pid_mode" != "host" ]; then echo "final provider-gateway runtime guard failed: restart=$final_restart pid=$final_pid_mode" >&2; rollback_to_last_known_good "final-runtime-guard-failed" || true; rm -f "$candidate_env_file"; exit 1; fi`,
`if ! validate_gateway_runtime_dependencies "$final_container" final; then rollback_to_last_known_good "final-runtime-dependency-guard-failed" || true; rm -f "$candidate_env_file"; exit 1; fi`,
`final_attempt=0`,
`final_validated=0`,
`while [ "$final_attempt" -lt "${finalValidationAttempts}" ]; do final_logs=$(docker logs "$final_container" 2>&1 || true); final_has_open=0; final_has_ack=0; final_has_ok=0; case "$final_logs" in *${shellQuote(validationNeedleOpen)}*) final_has_open=1;; esac; case "$final_logs" in *${shellQuote(validationNeedleAck)}*) final_has_ack=1;; esac; case "$final_logs" in *${shellQuote(validationNeedleOk)}*) final_has_ok=1;; esac; if [ "$final_has_open" = "1" ] && [ "$final_has_ack" = "1" ] && [ "$final_has_ok" = "1" ]; then final_validated=1; break; fi; final_running=$(docker inspect --format '{{.State.Running}}' "$final_container" 2>/dev/null || true); if [ "$final_running" != "true" ]; then break; fi; final_attempt=$((final_attempt + 1)); sleep 2; done`,