"""Phase 4/5: boot a real Linux VM under QEMU-TCG inside the HF Space container, then SSH from the container into the VM. Progress -> stdout (hf spaces logs).""" import os, subprocess, sys, threading, time, socket, textwrap, shutil T0 = time.time() LOG = [] IMG_URL = ("https://dl-cdn.alpinelinux.org/alpine/v3.22/releases/cloud/" "nocloud_alpine-3.22.4-x86_64-bios-cloudinit-r0.qcow2") WORK = "/tmp/vm" QCOW = WORK + "/alpine.qcow2" SEED = WORK + "/seed.iso" KEY = WORK + "/id_ed25519" SERIAL = WORK + "/serial.log" def log(msg): line = "[t+%6.1fs] %s" % (time.time() - T0, msg) LOG.append(line) print(line, flush=True) def sh(cmd, timeout=1800, quiet=False): log("$ " + cmd) r = subprocess.run(["bash", "-lc", cmd], capture_output=True, text=True, timeout=timeout) t = (r.stdout + r.stderr).strip() if t and not quiet: tail = "\n".join(t.splitlines()[-25:]) LOG.append(tail); print(tail, flush=True) if r.returncode: log("[exit %d]" % r.returncode) return r.returncode, t def port_open(port, host="127.0.0.1"): s = socket.socket(); s.settimeout(2) try: return s.connect_ex((host, port)) == 0 finally: s.close() def run(): os.makedirs(WORK, exist_ok=True) log("### PHASE 4a: install QEMU ###") sh("apt-get update -qq", timeout=900, quiet=True) rc, _ = sh("DEBIAN_FRONTEND=noninteractive apt-get install -y -qq --no-install-recommends " "qemu-system-x86 qemu-utils cloud-image-utils openssh-client", timeout=1800, quiet=True) if rc: log("!!! apt install FAILED — Phase 4 BLOCKED"); return sh("qemu-system-x86_64 --version | head -2") sh("qemu-system-x86_64 -accel help") log("### PHASE 4b: confirm KVM accel is refused, TCG is available ###") sh("qemu-system-x86_64 -accel kvm -m 128 -display none -no-reboot -kernel /dev/null 2>&1 | head -5 || true") log("### PHASE 4c: fetch Alpine nocloud image ###") if not os.path.exists(QCOW): rc, _ = sh("curl -fsSL -o %s '%s'" % (QCOW, IMG_URL), timeout=1800, quiet=True) if rc: log("!!! image download FAILED"); return sh("ls -lh %s && qemu-img info %s" % (QCOW, QCOW)) sh("qemu-img resize %s 4G" % QCOW) log("### PHASE 5a: cloud-init seed (ssh key injection) ###") sh("rm -f %s %s.pub && ssh-keygen -t ed25519 -N '' -f %s -q" % (KEY, KEY, KEY)) pub = open(KEY + ".pub").read().strip() open(WORK + "/user-data", "w").write(textwrap.dedent("""\ #cloud-config disable_root: false ssh_pwauth: false users: - default - name: root ssh_authorized_keys: - %s ssh_authorized_keys: - %s runcmd: - [ sh, -c, "echo '@@@ CLOUDINIT_DONE @@@' > /dev/console" ] """) % (pub, pub)) open(WORK + "/meta-data", "w").write("instance-id: hfvm-001\nlocal-hostname: hfvm\n") sh("cloud-localds %s %s/user-data %s/meta-data && ls -lh %s" % (SEED, WORK, WORK, SEED)) log("### PHASE 4d: BOOT VM (QEMU TCG, 2 vCPU / 1536 MB) ###") qemu = ("qemu-system-x86_64 -accel tcg,thread=multi -smp 2 -m 1536 " "-drive file=%s,if=virtio,format=qcow2 " "-drive file=%s,if=virtio,format=raw,readonly=on " "-netdev user,id=n0,hostfwd=tcp:127.0.0.1:2222-:22 " "-device virtio-net-pci,netdev=n0 " "-nographic -no-reboot" % (QCOW, SEED)) log("$ " + qemu) sf = open(SERIAL, "wb") proc = subprocess.Popen(["bash", "-lc", qemu], stdin=subprocess.DEVNULL, stdout=sf, stderr=subprocess.STDOUT) boot_t0 = time.time() log("### PHASE 5b: wait for guest sshd on 127.0.0.1:2222 ###") up = False for i in range(120): # up to 20 min if proc.poll() is not None: log("!!! QEMU exited early rc=%s" % proc.returncode); break if port_open(2222): up = True log(">>> GUEST SSH PORT OPEN after %.1fs of TCG boot" % (time.time() - boot_t0)) break if i % 6 == 0: try: tail = subprocess.run(["tail", "-c", "1200", SERIAL], capture_output=True, text=True).stdout log("serial tail: " + tail.replace("\r", "")[-700:]) except Exception: pass time.sleep(10) if not up: log("!!! guest sshd never came up") else: log("### PHASE 5c: SSH container -> VM ###") ssh = ("ssh -i %s -p 2222 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null " "-o ConnectTimeout=15 -o BatchMode=yes" % KEY) for user in ("root", "alpine"): rc, out = sh("%s %s@127.0.0.1 'echo ===IN-VM===; uname -a; id; " "cat /etc/os-release | head -2; free -m | head -2; " "df -h / | tail -1; ip -4 addr show eth0 | grep inet' 2>&1" % (ssh, user), timeout=120) if rc == 0: log(">>> PHASE 5 PASS: SSH into VM succeeded as %s" % user) break else: log("!!! SSH into VM failed for all users") log("### benchmark: TCG throughput inside VM ###") sh("%s root@127.0.0.1 'time dd if=/dev/zero bs=1M count=64 2>&1 | tail -3' 2>&1" % ssh, timeout=180) log("### serial console (last 4000 bytes) ###") sh("tail -c 4000 %s | tr -d '\\r'" % SERIAL) log("### DONE ###") try: proc.terminate() except Exception: pass threading.Thread(target=lambda: (run() if True else None), daemon=True).start() import gradio as gr gr.Interface(lambda: "\n".join(LOG[-400:]), None, gr.Textbox(lines=40, label="phase 4/5 log"), title="QEMU-in-HF-Space experiment").launch(server_name="0.0.0.0", server_port=7860)