fix(reboot): support windows99 vmx locator via host
Some checks failed
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 2m19s
CD Pipeline / post-deploy-checks (push) Has been cancelled
CD Pipeline / build-and-deploy (push) Has been cancelled

This commit is contained in:
Your Name
2026-07-03 12:51:11 +08:00
parent d74516f2cd
commit 7b02c452e3
5 changed files with 137 additions and 4 deletions

View File

@@ -8,6 +8,8 @@ CONNECT_TIMEOUT="${WINDOWS99_CONNECT_TIMEOUT:-3}"
SSH_TIMEOUT="${WINDOWS99_SSH_TIMEOUT:-3}"
REMOTE_LOCATOR_TIMEOUT="${WINDOWS99_REMOTE_LOCATOR_TIMEOUT:-60}"
SSH_PORT="${WINDOWS99_SSH_PORT:-22}"
VIA_HOST="${WINDOWS99_VIA_HOST:-}"
VIA_HOST_PORT="${WINDOWS99_VIA_PORT:-22}"
MAX_AUTH_USERS="${WINDOWS99_MAX_AUTH_USERS:-}"
MAX_AUTH_USERS_EXPLICIT=0
if [[ -n "${WINDOWS99_MAX_AUTH_USERS:-}" ]]; then
@@ -30,7 +32,7 @@ is_positive_int() {
}
usage() {
printf '%s\n' "usage: $0 [--check|--collect] [--host HOST] [--users 'u1 u2'] [--timeout SECONDS] [--max-auth-users N]"
printf '%s\n' "usage: $0 [--check|--collect] [--host HOST] [--users 'u1 u2'] [--via-host USER@HOST] [--timeout SECONDS] [--max-auth-users N]"
}
while [[ $# -gt 0 ]]; do
@@ -51,6 +53,14 @@ while [[ $# -gt 0 ]]; do
SSH_USERS=(${1:-})
SSH_USERS_EXPLICIT=1
;;
--via-host)
shift
VIA_HOST="${1:-}"
;;
--via-port)
shift
VIA_HOST_PORT="${1:-22}"
;;
--timeout)
shift
CONNECT_TIMEOUT="${1:-5}"
@@ -175,15 +185,48 @@ SSH_OPTS=(
-p "${SSH_PORT}"
)
VIA_SSH_OPTS=(
-o BatchMode=yes
-o PreferredAuthentications=publickey
-o PubkeyAuthentication=yes
-o PasswordAuthentication=no
-o KbdInteractiveAuthentication=no
-o NumberOfPasswordPrompts=0
-o ConnectTimeout="${SSH_TIMEOUT}"
-o ConnectionAttempts=1
-o GSSAPIAuthentication=no
-o LogLevel=ERROR
-o StrictHostKeyChecking=no
-o UserKnownHostsFile="${KNOWN_HOSTS_FILE}"
-p "${VIA_HOST_PORT}"
)
quote_words() {
printf '%q ' "$@"
}
run_ssh_timed() {
local user="$1"
local timeout_seconds="$2"
local timeout_wrapper_seconds="$((timeout_seconds + 1))"
local inner_command=""
shift 2
if ! is_positive_int "${timeout_seconds}"; then
timeout_seconds="${SSH_TIMEOUT}"
timeout_wrapper_seconds="$((SSH_TIMEOUT + 1))"
fi
if [[ -n "${VIA_HOST}" ]]; then
local inner_ssh=(ssh "${SSH_OPTS[@]}" -o ConnectTimeout="${timeout_seconds}" "${user}@${TARGET_HOST}" "$@")
inner_command="$(quote_words "${inner_ssh[@]}")"
if [[ "${SSH_TIMEOUT_WRAPPER}" == "timeout" ]]; then
timeout "${timeout_wrapper_seconds}s" ssh "${VIA_SSH_OPTS[@]}" "${VIA_HOST}" "bash -lc $(printf '%q' "${inner_command}")"
elif [[ "${SSH_TIMEOUT_WRAPPER}" == "gtimeout" ]]; then
gtimeout "${timeout_wrapper_seconds}s" ssh "${VIA_SSH_OPTS[@]}" "${VIA_HOST}" "bash -lc $(printf '%q' "${inner_command}")"
else
ssh "${VIA_SSH_OPTS[@]}" "${VIA_HOST}" "bash -lc $(printf '%q' "${inner_command}")"
fi
return $?
fi
if [[ "${SSH_TIMEOUT_WRAPPER}" == "timeout" ]]; then
timeout "${timeout_wrapper_seconds}s" ssh "${SSH_OPTS[@]}" -o ConnectTimeout="${timeout_seconds}" "${user}@${TARGET_HOST}" "$@"
elif [[ "${SSH_TIMEOUT_WRAPPER}" == "gtimeout" ]]; then
@@ -277,6 +320,7 @@ fi
printf '%s\n' "schema_version=windows99_vmx_source_locator_collector_v1"
printf '%s\n' "dry_run=${DRY_RUN}"
printf '%s\n' "target_host=${TARGET_HOST}"
printf '%s\n' "via_host=${VIA_HOST:-none}"
printf '%s\n' "target_host_alias=99"
printf '%s\n' "target_vm_alias=111"
printf '%s\n' "connect_timeout_seconds=${CONNECT_TIMEOUT}"

View File

@@ -50,6 +50,8 @@ def test_locator_contract_forbids_secret_runtime_actions_and_vmx_content_reads()
assert "PasswordAuthentication=no" in bash_text
assert "KbdInteractiveAuthentication=no" in bash_text
assert "NumberOfPasswordPrompts=0" in bash_text
assert "--via-host" in bash_text
assert "via_host=" in bash_text
assert "in_memory_stdin_scriptblock" in bash_text
assert "[Console]::In.ReadToEnd()" in bash_text
assert "Get-ChildItem" in ps_text
@@ -163,7 +165,7 @@ def test_collect_mode_accepts_valid_remote_locator_stdout(tmp_path: Path) -> Non
"""
#!/usr/bin/env bash
joined="$*"
if [[ "$joined" == *"echo AWOOOI_WINDOWS99_SSH_READY"* ]]; then
if [[ "$joined" == *"AWOOOI_WINDOWS99_SSH_READY"* ]]; then
printf '%s\n' 'AWOOOI_WINDOWS99_SSH_READY'
exit 0
fi
@@ -197,3 +199,65 @@ def test_collect_mode_accepts_valid_remote_locator_stdout(tmp_path: Path) -> Non
assert "remote_locator_output_begin" in result.stdout
assert "source_locator_status=blocked_missing_expected_vmx_source_no_candidate_found" in result.stdout
assert "remote_locator_output_end" in result.stdout
def test_collect_mode_supports_no_secret_via_host_path(tmp_path: Path) -> None:
fake_bin = tmp_path / "bin"
fake_bin.mkdir()
_write_executable(
fake_bin / "nc",
"""
#!/usr/bin/env bash
[[ "${!#}" == "22" ]]
""",
)
_write_executable(
fake_bin / "ssh",
"""
#!/usr/bin/env bash
joined="$*"
if [[ "$joined" == *"AWOOOI_WINDOWS99_SSH_READY"* ]]; then
printf '%s\n' 'AWOOOI_WINDOWS99_SSH_READY'
exit 0
fi
if [[ "$joined" == *"powershell"* ]]; then
cat >/dev/null
printf '%s\n' 'EXPECTED_VMX alias=111 index=1 present=0 fingerprint=abc'
printf '%s\n' 'AWOOOI_WINDOWS99_VMX_SOURCE_LOCATOR=1'
printf '%s\n' 'schema_version=windows99_vmx_source_locator_v1'
printf '%s\n' 'MODE=Check'
printf '%s\n' 'target_host_alias=99'
printf '%s\n' 'target_vm_alias=111'
printf '%s\n' 'expected_vmx_path_count=1'
printf '%s\n' 'expected_vmx_path_present_count=0'
printf '%s\n' 'candidate_source_count=0'
printf '%s\n' 'source_locator_status=blocked_missing_expected_vmx_source_no_candidate_found'
printf '%s\n' 'file_content_read=false'
printf '%s\n' 'remote_write_performed=false'
exit 0
fi
exit 255
""",
)
result = _run_locator(
fake_bin,
"--collect",
"--via-host",
"wooo@192.168.0.110",
"--users",
"wooo",
"--max-auth-users",
"1",
)
assert result.returncode == 0
values = _key_values(result.stdout)
assert values["via_host"] == "wooo@192.168.0.110"
assert values["remote_locator_attempted"] == "1"
assert values["locator_collection_status"] == (
"collected_windows99_vmx_source_locator_stdout"
)
assert values["secret_value_read"] == "false"
assert values["remote_write_performed"] == "false"
assert values["vm_power_change_performed"] == "false"