fix(agent99): terminate remote stdin with sentinel
All checks were successful
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 2m34s
CD Pipeline / build-and-deploy (push) Successful in 14m3s
CD Pipeline / post-deploy-checks (push) Successful in 1m59s
All checks were successful
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 2m34s
CD Pipeline / build-and-deploy (push) Successful in 14m3s
CD Pipeline / post-deploy-checks (push) Successful in 1m59s
This commit is contained in:
@@ -11,6 +11,7 @@ readonly GITEA_ORIGIN_SSH_INTERNAL="ssh://git@192.168.0.110:2222/wooo/awoooi.git
|
||||
readonly RECEIVER_RELATIVE="scripts/reboot-recovery/agent99-remote-atomic-deploy-receiver.ps1"
|
||||
readonly PREFLIGHT_RELATIVE="scripts/reboot-recovery/agent99-live-preflight.ps1"
|
||||
readonly WRAPPER_RELATIVE="scripts/reboot-recovery/deploy-agent99-via-windows99-ssh.sh"
|
||||
readonly REMOTE_STDIN_SENTINEL="__AWOOOI_AGENT99_REMOTE_BOOTSTRAP_END_V1__"
|
||||
|
||||
RUNTIME_FILES=(
|
||||
"agent99-bootstrap.ps1"
|
||||
@@ -303,7 +304,8 @@ PY
|
||||
|
||||
python3 - \
|
||||
"${BOOTSTRAP_PATH}" \
|
||||
"${BOOTSTRAP_PAYLOAD_PATH}" <<'PY'
|
||||
"${BOOTSTRAP_PAYLOAD_PATH}" \
|
||||
"${REMOTE_STDIN_SENTINEL}" <<'PY'
|
||||
from __future__ import annotations
|
||||
|
||||
import base64
|
||||
@@ -312,13 +314,14 @@ import sys
|
||||
from pathlib import Path
|
||||
|
||||
bootstrap_path, output_path = map(Path, sys.argv[1:3])
|
||||
sentinel = sys.argv[3]
|
||||
compressed = gzip.compress(
|
||||
bootstrap_path.read_bytes(),
|
||||
compresslevel=9,
|
||||
mtime=0,
|
||||
)
|
||||
output_path.write_text(
|
||||
base64.b64encode(compressed).decode("ascii"),
|
||||
base64.b64encode(compressed).decode("ascii") + "\n" + sentinel + "\n",
|
||||
encoding="ascii",
|
||||
)
|
||||
PY
|
||||
@@ -349,7 +352,27 @@ from __future__ import annotations
|
||||
|
||||
import base64
|
||||
|
||||
decoder = r'''$payload = [Console]::In.ReadToEnd()
|
||||
decoder = r'''$sentinel = "__AWOOOI_AGENT99_REMOTE_BOOTSTRAP_END_V1__"
|
||||
$lines = New-Object System.Collections.Generic.List[string]
|
||||
$lineCount = 0
|
||||
$charCount = 0
|
||||
$terminated = $false
|
||||
while (($line = [Console]::In.ReadLine()) -ne $null) {
|
||||
if ($line -ceq $sentinel) {
|
||||
$terminated = $true
|
||||
break
|
||||
}
|
||||
$lineCount += 1
|
||||
$charCount += $line.Length + 2
|
||||
if ($lineCount -gt 8 -or $charCount -gt 1048576) {
|
||||
throw "remote_bootstrap_input_limit_exceeded"
|
||||
}
|
||||
[void]$lines.Add($line)
|
||||
}
|
||||
if (-not $terminated) {
|
||||
throw "remote_bootstrap_sentinel_missing"
|
||||
}
|
||||
$payload = [string]::Join("", $lines)
|
||||
$compressed = [Convert]::FromBase64String(($payload -replace '\s', ''))
|
||||
$inputStream = New-Object IO.MemoryStream(,$compressed)
|
||||
$gzip = New-Object IO.Compression.GzipStream($inputStream, [IO.Compression.CompressionMode]::Decompress)
|
||||
|
||||
@@ -148,7 +148,14 @@ def test_sender_builds_sha256_envelope_and_streams_it_without_remote_cli_data()
|
||||
assert "IO.Compression.GzipStream" in source
|
||||
assert 'decoder.encode("utf-16le")' in source
|
||||
assert "-EncodedCommand" in source
|
||||
assert "[Console]::In.ReadToEnd()" in source
|
||||
assert "[Console]::In.ReadToEnd()" not in source
|
||||
assert "$reader.ReadToEnd()" in source
|
||||
assert "__AWOOOI_AGENT99_REMOTE_BOOTSTRAP_END_V1__" in source
|
||||
assert "[Console]::In.ReadLine()" in source
|
||||
assert "remote_bootstrap_input_limit_exceeded" in source
|
||||
assert "remote_bootstrap_sentinel_missing" in source
|
||||
assert "$lineCount -gt 8" in source
|
||||
assert "$charCount -gt 1048576" in source
|
||||
assert '<"${BOOTSTRAP_PAYLOAD_PATH}"' in source
|
||||
assert "rawEnvelope" not in source
|
||||
assert "sshpass" not in source
|
||||
|
||||
Reference in New Issue
Block a user