exit is just a helper for the interactive shell, see: https://stackoverflow.com/questions/6501121/difference-between-exit-and-sys-exit-in-python Signed-off-by: Ondřej Budai <ondrej@budai.cz>
73 lines
2.6 KiB
Python
Executable file
73 lines
2.6 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
|
|
import os
|
|
import shutil
|
|
import subprocess
|
|
import sys
|
|
import tempfile
|
|
|
|
|
|
HELP_TEXT="""deploy-qemu IMAGE USERDATA
|
|
|
|
Starts an ephemeral virtual machine in qemu, injecting configuration via
|
|
cloud-init. Stopping this script stops the VM and discards all data.
|
|
|
|
IMAGE -- An os image that can be booted by qemu and has cloud-init
|
|
installed and enabled. No changes are made to this file.
|
|
|
|
USERDATA -- A cloud-init user-data config file, or a directory of
|
|
configuration as accepted by the `gen-user-data` tool.
|
|
|
|
In addition, if the QEMU_EXTRA_ARGS environment variable is defined, it adds
|
|
its content as additional arguments to qemu."""
|
|
|
|
|
|
if len(sys.argv) != 3:
|
|
print(HELP_TEXT)
|
|
sys.exit(1)
|
|
|
|
script_dir = os.path.dirname(os.path.realpath(__file__))
|
|
image = sys.argv[1]
|
|
userdata = sys.argv[2]
|
|
|
|
qemu_extra_args = os.getenv("QEMU_EXTRA_ARGS")
|
|
qemu_extra_args = qemu_extra_args.split(' ') if qemu_extra_args is not None else []
|
|
|
|
with tempfile.TemporaryDirectory(prefix="qemu-tmp-") as workdir:
|
|
os.mkdir(os.path.join(workdir, "cidata"))
|
|
|
|
if os.path.isdir(userdata):
|
|
gen_user_data = subprocess.run([os.path.join(script_dir, "gen-user-data"), userdata], check=True, capture_output=True, encoding="utf-8")
|
|
with open(os.path.join(workdir, "cidata", "user-data"), "w") as f:
|
|
f.write(gen_user_data.stdout)
|
|
else:
|
|
shutil.copyfile(userdata, os.path.join(workdir, "cidata", "user-data"))
|
|
|
|
with open(os.path.join(workdir, "cidata", "meta-data"), "w") as f:
|
|
f.writelines(["instance-id: nocloud\n", "local-hostname: vm\n"])
|
|
|
|
if sys.platform == "linux":
|
|
subprocess.run(["mkisofs",
|
|
"-input-charset", "utf-8",
|
|
"-output", f"{workdir}/cloudinit.iso",
|
|
"-volid", "cidata",
|
|
"-joliet",
|
|
"-rock",
|
|
"-quiet",
|
|
"-graft-points",
|
|
f"{workdir}/cidata/user-data",
|
|
f"{workdir}/cidata/meta-data"], check=True)
|
|
elif sys.platform == "darwin":
|
|
# conviently uses the last component of source as volumeid, which has to be cidata
|
|
subprocess.run(["hdiutil", "makehybrid", "-iso", "-joliet", "-o", f"{workdir}/cloudinit.iso", f"{workdir}/cidata"], check=True)
|
|
|
|
subprocess.run(["qemu-system-x86_64",
|
|
"-M", "accel=kvm:hvf",
|
|
"-m", "1024",
|
|
"-snapshot",
|
|
"-cpu", "host",
|
|
"-net", "nic,model=virtio",
|
|
"-net", "user,hostfwd=tcp::2222-:22,hostfwd=tcp::4430-:443",
|
|
"-cdrom", f"{workdir}/cloudinit.iso",
|
|
*qemu_extra_args,
|
|
image])
|