#!/bin/bash # win-ci Windows VM 을 처음부터 만든다 (.9 안 중첩 KVM, 무인 설치). # # ./build.sh ISO 내려받기 + 무인설치 ISO 굽기 + 디스크 생성 # ./start-vm.sh VM + 제어 서버 기동 (systemd 트랜지언트 유닛) # ./boot-cd.sh reset "Press any key to boot from CD" 넘기기 (최초 1회만) # ./status.sh 진행 상황 # ./shot.sh out.png 화면 스냅샷 # # 사람이 클릭할 일은 없다. autounattend.xml 이 설치를 끝내고, provision.ps1 이 # virtio 드라이버를 넣고, agent.ps1 이 호스트에서 stage2.ps1 을 받아 개발도구와 # act_runner 를 깐다. # # 필요 패키지: qemu-system-x86 ovmf swtpm swtpm-tools xorriso # 그리고 실행 계정이 kvm 그룹에 있어야 한다 (없으면 sg kvm -c '...' 로 감싼다). set -euo pipefail D="${WIN_CI_DIR:-/home/claude/win-ci}" HERE="$(cd "$(dirname "$0")" && pwd)" WIN_ISO_URL='https://go.microsoft.com/fwlink/p/?linkid=2289029' # Win11 Ent LTSC 2024 평가판(90일, 키 불필요) VIRTIO_URL='https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso' mkdir -p "$D/iso" "$D/serve" "$D/swtpm" "$D/unattend-root/setup" fetch() { # url dest 최소크기MB if [ -f "$2" ] && [ "$(stat -c%s "$2")" -gt $(( $3 * 1024 * 1024 )) ]; then echo "이미 있음: $2"; return fi echo "다운로드: $2" curl -fL --retry 3 -o "$2" "$1" } fetch "$WIN_ISO_URL" "$D/iso/win11-ltsc.iso" 4000 fetch "$VIRTIO_URL" "$D/iso/virtio-win.iso" 500 # 무인 설치 미디어. Windows Setup 이 붙어 있는 모든 드라이브 루트에서 # autounattend.xml 을 찾으므로 CD 로 물려주면 된다. cp "$HERE/unattend/autounattend.xml" "$D/unattend-root/" # ⚠️ .ps1 은 반드시 UTF-8 BOM 으로 넣는다. # Windows PowerShell 5.1 은 BOM 이 없으면 현재 ANSI 코드페이지(en-US -> CP1252)로 # 읽는다. 한글 주석의 UTF-8 바이트가 CP1252 에서 스마트따옴표(“ ” ‘)로 변하고, # PowerShell 은 그걸 문자열 시작으로 보고 스크립트 뒤를 전부 삼킨다. 증상은 # 엉뚱하게도 "Missing closing '}' in statement block" 이다. 실제로 이것 때문에 # 첫 설치의 provision.ps1 이 통째로 안 돌았다. for f in "$HERE/unattend/setup/"*.ps1; do out="$D/unattend-root/setup/$(basename "$f")" printf '\xef\xbb\xbf' > "$out" cat "$f" >> "$out" done xorriso -as mkisofs -V UNATTEND -J -joliet-long -R -o "$D/unattend.iso" "$D/unattend-root/" # 호스트 제어 채널이 내려줄 스크립트 cp "$HERE/serve/stage2.ps1" "$D/serve/" cp "$HERE"/*.sh "$HERE"/serve-host.py "$D/" chmod +x "$D"/*.sh [ -f "$D/win-ci.qcow2" ] || qemu-img create -f qcow2 "$D/win-ci.qcow2" 80G # SecureBoot 용 - MS 키가 미리 들어 있는 변수 이미지여야 Windows 부트로더가 통과한다 [ -f "$D/OVMF_VARS.fd" ] || cp /usr/share/OVMF/OVMF_VARS_4M.ms.fd "$D/OVMF_VARS.fd" echo echo "준비 끝. 다음: $D/start-vm.sh 그리고 $D/boot-cd.sh reset"