feat(template): cleanup-after-update + ruff fixes
Move disk cleanup out of the Windows Update loop: - PS scripts: extract Invoke-DiskCleanup function, add -CleanupOnly switch for standalone post-update cleanup pass. - Python command: always pass -SkipCleanup:$true during WU loop; after loop exits 0, run a separate -CleanupOnly invocation (skipped if --skip-cleanup). Fails fast if cleanup-only returns nonzero. - Tests: 3 new tests for cleanup-runs-after-loop, skip-cleanup suppresses it, and cleanup-failure propagates as ClickException. - ruff --fix: remove unused shutil import, sort imports, fix UP037/UP035. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -57,7 +57,6 @@ from __future__ import annotations
|
||||
|
||||
import fnmatch
|
||||
import json
|
||||
import shutil
|
||||
import socket
|
||||
import subprocess
|
||||
import sys
|
||||
@@ -68,8 +67,8 @@ from pathlib import Path
|
||||
|
||||
import click
|
||||
|
||||
from ci_orchestrator.backends.workstation import WorkstationVmrunBackend
|
||||
from ci_orchestrator.backends.protocol import VmHandle
|
||||
from ci_orchestrator.backends.workstation import WorkstationVmrunBackend
|
||||
from ci_orchestrator.config import load_config
|
||||
from ci_orchestrator.transport.errors import TransportError
|
||||
from ci_orchestrator.transport.winrm import WinRmResult, WinRmTransport
|
||||
@@ -324,7 +323,7 @@ def _run_with_heartbeat(
|
||||
def _worker() -> None:
|
||||
try:
|
||||
result_holder.append(transport.run(script, check=check))
|
||||
except BaseException as exc: # noqa: BLE001
|
||||
except BaseException as exc:
|
||||
exc_holder.append(exc)
|
||||
finally:
|
||||
stop_event.set()
|
||||
@@ -507,8 +506,7 @@ def template_prepare_win(
|
||||
args_parts.append("-SkipWindowsUpdate:$true")
|
||||
if skip_tier2:
|
||||
args_parts.append("-SkipTier2:$true")
|
||||
if skip_cleanup:
|
||||
args_parts.append("-SkipCleanup:$true")
|
||||
args_parts.append("-SkipCleanup:$true") # always skip during WU loop; cleanup runs separately after
|
||||
args_str = " ".join(args_parts)
|
||||
|
||||
# Run toolchain script — loop handles Windows Update reboot (exit 3010)
|
||||
@@ -569,6 +567,33 @@ def template_prepare_win(
|
||||
_wait_winrm(transport, winrm_timeout)
|
||||
click.echo("[prepare-win] WinRM ready after reboot.")
|
||||
|
||||
# Post-update disk cleanup — runs once after all WU reboots complete
|
||||
if not skip_cleanup:
|
||||
click.echo("[prepare-win] Running post-update disk cleanup (-CleanupOnly) ...")
|
||||
cleanup_invoke = (
|
||||
"Set-ExecutionPolicy Bypass -Scope Process -Force\n"
|
||||
"$ec = 0\n"
|
||||
"try {\n"
|
||||
f" & '{e(guest_script)}' -BuildPassword '{e(build_password)}'"
|
||||
f" -BuildUsername '{e(build_username)}'"
|
||||
f" -AdminPassword '{e(admin_password)}' -CleanupOnly:$true\n"
|
||||
" $ec = if ($null -eq $LASTEXITCODE) { 0 } else { $LASTEXITCODE }\n"
|
||||
"} catch {\n"
|
||||
" Write-Error $_\n"
|
||||
" $ec = 1\n"
|
||||
"}\n"
|
||||
'"CI_EXITCODE:$ec"\n'
|
||||
)
|
||||
cleanup_result = _run_with_heartbeat(transport, cleanup_invoke, check=False)
|
||||
cleanup_ec = _parse_exit_marker(cleanup_result.stdout)
|
||||
if cleanup_result.stdout.strip():
|
||||
click.echo(cleanup_result.stdout.strip())
|
||||
if cleanup_result.stderr.strip():
|
||||
click.echo(cleanup_result.stderr.strip(), err=True)
|
||||
if cleanup_ec != 0:
|
||||
raise click.ClickException(f"Disk cleanup failed (exit {cleanup_ec}).")
|
||||
click.echo("[prepare-win] Post-update cleanup complete.")
|
||||
|
||||
# Install CI-StaticIp scheduled task
|
||||
if static_ip_path is not None:
|
||||
click.echo("[prepare-win] Installing CI-StaticIp scheduled task ...")
|
||||
|
||||
@@ -39,9 +39,9 @@ from __future__ import annotations
|
||||
|
||||
import json
|
||||
import time
|
||||
from collections.abc import Generator
|
||||
from contextlib import contextmanager
|
||||
from pathlib import Path
|
||||
from typing import Generator
|
||||
|
||||
|
||||
class IpSlotPool:
|
||||
|
||||
Reference in New Issue
Block a user