Files
live-app-translator/scripts/win-ci/build.sh
EJClaw e41d0cb441 ci: .9 안 Windows CI VM 무인 구축 자동화
Windows 설치 화면을 사람이 클릭할 수 없으므로 전 과정을 무인으로 짰다.
autounattend.xml 이 설치와 OOBE 를 끝내고, provision.ps1 이 virtio 드라이버를
오프라인으로 넣어 네트워크를 살리고, 상주 agent.ps1 이 호스트 HTTP 에서
stage2.ps1 을 받아 Git/pwsh7/Python/Node/CMake/act_runner 를 설치한다.

설치 내용을 ISO 에 박지 않고 호스트가 HTTP 로 내려주는 구조로 한 이유는
ISO 를 한 번 구우면 못 고쳐서, 한 줄 고칠 때마다 Windows 재설치가 되기
때문이다. stage2.ps1 만 고치면 게스트가 20초 안에 반영한다.

- 시스템 디스크는 SATA. virtio-blk 로 하면 Setup 이 디스크를 못 봐서
  WinPE 드라이버 주입이 필요해진다
- VM 은 systemd --user 트랜지언트 유닛으로 띄워 봇 cgroup 밖에 둔다
  (MemoryHigh=16G 안에 8G VM 이 들어가면 봇이 OOM 으로 죽는 전례)
- Node 포함. act_runner host 모드가 JS 액션을 PATH 의 node 로 돌린다
2026-09-25 22:13:55 +09:00

54 lines
2.4 KiB
Bash
Executable File

#!/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/"
cp "$HERE/unattend/setup/"*.ps1 "$D/unattend-root/setup/"
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"