Add --seed-only to run-windows11.py to build just the seed ISO

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
guofangandClaude Sonnet 5.5 committed 2026-10-23 23:45:02 +08:00
1 parent 69e2141b7c
commit 5bb679f3fe
1 file changed
+40 -24
+40 -24
View File
@@ -81,13 +81,14 @@ daemonize = False
install_from_iso = False
install_from_img = False
download_only = False
seed_only = False
extra_args = []
arch_option = None
def usage(stream=sys.stdout):
stream.write(f"""\
Usage: {Path(sys.argv[0]).name} [--daemon] [--download-only] [--install-from-iso | --install-from-img]
Usage: {Path(sys.argv[0]).name} [--daemon] [--download-only] [--seed-only] [--install-from-iso | --install-from-img]
[--arch ARCH] [--state-dir DIR] [--rdp-port PORT] [--ssh-port PORT] [-- QEMU_ARGUMENT ...]
If the system disk (DIR/disk.qcow2, see --state-dir) is missing, create it from
@@ -106,6 +107,8 @@ Options:
(for --arch) if they are missing, then exit; needs
Node.js and Chromium for the latter, see vm-images/README.md
(the base QCOW2 is supplied manually)
--seed-only Build the seed ISO (answer file and setup scripts) and exit,
without starting the VM or fetching the Windows and VirtIO ISOs
--install-from-iso Install from ISO when the system disk is missing
--install-from-img Like --install-from-iso, but install from the disk image
made by vm-images/build-windows-install-disk.sh, which
@@ -150,6 +153,8 @@ while args:
daemonize = True
elif arg == "--download-only":
download_only = True
elif arg == "--seed-only":
seed_only = True
elif arg == "--install-from-iso":
install_from_iso = True
elif arg == "--install-from-img":
@@ -277,6 +282,39 @@ monitor_socket = state_dir / "qemu-monitor.sock"
guest_agent_socket = state_dir / "qemu-guest-agent.sock"
qemu_config = state_dir / "qemu.ini"
def build_seed_iso(image_downloader, force=False):
"""Build the seed ISO, unless it is newer than all of its sources and not forced."""
seed_dir = script_dir / "seediso" / "windows11"
seed_sources = [seed_dir / "Autounattend.xml", seed_dir / "Configure-Windows.ps1",
*sorted(seed_dir.glob("[0-9][0-9]-*.bat"))]
# build-seed.sh embeds the administrator SSH public key.
ssh_key = os.environ.get("SSH_PUBLIC_KEY_FILE") or next(
(str(k) for n in ("id_ed25519", "id_ecdsa", "id_rsa")
if (k := Path.home() / ".ssh" / f"{n}.pub").is_file()), None)
if ssh_key:
seed_sources.append(Path(ssh_key))
# The seed carries the OpenSSH zip for this architecture; build-seed.sh
# downloads it when missing.
seed_sources.append(Path(capture(
[str(image_downloader), "--print-path", "openssh-win"])))
def newer_than_seed(source):
# Mirrors bash `-nt`: true if source exists and is newer than seed_iso.
return source.exists() and source.stat().st_mtime > seed_iso.stat().st_mtime
if force or not seed_iso.is_file() or not seed_sources[-1].is_file() \
or any(newer_than_seed(s) for s in seed_sources):
run([str(script_dir / "seediso" / "windows11" / "build-seed.sh"), str(seed_iso), host_arch])
if seed_only:
build_seed_iso(find_image_downloader(), force=True)
print(f"Seed ISO is ready: {seed_iso}")
sys.exit(0)
installing = False
installing_from_iso = False
if not disk_image.is_file():
@@ -326,29 +364,7 @@ if installing_from_iso:
if not tools_iso.is_file():
die(f"downloader did not create: {tools_iso}")
seed_dir = script_dir / "seediso" / "windows11"
seed_sources = [seed_dir / "Autounattend.xml", seed_dir / "Configure-Windows.ps1",
*sorted(seed_dir.glob("[0-9][0-9]-*.bat"))]
# build-seed.sh embeds the administrator SSH public key.
ssh_key = os.environ.get("SSH_PUBLIC_KEY_FILE") or next(
(str(k) for n in ("id_ed25519", "id_ecdsa", "id_rsa")
if (k := Path.home() / ".ssh" / f"{n}.pub").is_file()), None)
if ssh_key:
seed_sources.append(Path(ssh_key))
# The seed carries the OpenSSH zip for this architecture; build-seed.sh
# downloads it when missing.
seed_sources.append(Path(capture(
[str(image_downloader), "--print-path", "openssh-win"])))
def newer_than_seed(source):
# Mirrors bash `-nt`: true if source exists and is newer than seed_iso.
return source.exists() and source.stat().st_mtime > seed_iso.stat().st_mtime
if not seed_iso.is_file() or not seed_sources[-1].is_file() \
or any(newer_than_seed(s) for s in seed_sources):
run([str(script_dir / "seediso" / "windows11" / "build-seed.sh"), str(seed_iso), host_arch])
build_seed_iso(image_downloader)
if pid_file.is_file():
old_pid = pid_file.read_text().strip()