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 로 돌린다
This commit is contained in:
44
scripts/win-ci/boot-cd.sh
Executable file
44
scripts/win-ci/boot-cd.sh
Executable file
@@ -0,0 +1,44 @@
|
||||
#!/bin/bash
|
||||
# "Press any key to boot from CD or DVD" 를 넘긴다.
|
||||
#
|
||||
# UEFI 부팅 시 Windows ISO 는 매번 이 프롬프트를 띄우고 약 5초 안에 키가
|
||||
# 없으면 CD 부팅을 포기한다. 무인 설치인데 사람이 눌러줄 수 없으므로
|
||||
# 리셋 직후부터 키를 계속 밀어 넣는다.
|
||||
#
|
||||
# ⚠️ 설치가 시작된 뒤에는 절대 실행하지 말 것. 남는 Enter 가 설치 화면의
|
||||
# Cancel 버튼을 눌러 "Are you sure you want to quit?" 가 뜬다 (실제로 겪음).
|
||||
# 설치가 끝난 뒤 재부팅 때는 키를 안 누르는 게 정답이다 - 그래야 CD 를
|
||||
# 건너뛰고 디스크로 부팅한다.
|
||||
#
|
||||
# 사용법: ./boot-cd.sh [reset] - reset 을 주면 VM 을 먼저 리셋한다
|
||||
set -euo pipefail
|
||||
MODE="${1:-}"
|
||||
python3 - "$MODE" <<'PY'
|
||||
import json, socket, sys, time
|
||||
mode = sys.argv[1] if len(sys.argv) > 1 else ""
|
||||
s = socket.socket(socket.AF_UNIX); s.settimeout(20)
|
||||
s.connect("/home/claude/win-ci/qmp.sock")
|
||||
f = s.makefile("rwb")
|
||||
f.readline()
|
||||
def cmd(o):
|
||||
f.write((json.dumps(o) + "\n").encode()); f.flush()
|
||||
while True:
|
||||
line = f.readline()
|
||||
if not line: raise SystemExit("qmp closed")
|
||||
m = json.loads(line)
|
||||
if "return" in m or "error" in m: return m
|
||||
cmd({"execute": "qmp_capabilities"})
|
||||
if mode == "reset":
|
||||
print(cmd({"execute": "system_reset"}))
|
||||
time.sleep(3)
|
||||
# 프롬프트 창은 5초뿐이지만 펌웨어 POST 시간이 들쭉날쭉하다. 25초면 충분하고,
|
||||
# 그 이상 밀면 설치 화면까지 Enter 가 새어 들어간다.
|
||||
deadline = time.time() + 25
|
||||
n = 0
|
||||
while time.time() < deadline:
|
||||
cmd({"execute": "send-key",
|
||||
"arguments": {"keys": [{"type": "qcode", "data": "ret"}]}})
|
||||
n += 1
|
||||
time.sleep(0.4)
|
||||
print("sent", n, "keys")
|
||||
PY
|
||||
Reference in New Issue
Block a user