summaryrefslogtreecommitdiff
path: root/create-vm
blob: e085598b5f9fbd3e439cccad857c975d7e726ec4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#!/usr/bin/env python3

import os
import shutil
import socket
import subprocess
import sys
import tempfile
import time
import yaml


def cloud_init_iso(iso, hostname, pubkey):
    tmp = tempfile.mkdtemp()

    with open(os.path.join(tmp, "meta-data"), "w") as f:
        f.write(
            f"""\
# Amazon EC2 style metadata
local-hostname: {hostname}
"""
        )

    with open(os.path.join(tmp, "user-data"), "w") as f:
        f.write(
            f"""\
#cloud-config
ssh_authorized_keys:
- {pubkey}
"""
        )

    subprocess.check_call(
        [
            "genisoimage",
            "-quiet",
            "-volid",
            "cidata",
            "-joliet",
            "-rock",
            "-output",
            iso,
            tmp,
        ]
    )
    shutil.rmtree(tmp)


def create_vm(vm, image, iso, memory=1024, cpus=1):
    subprocess.check_call(
        [
            "virt-install",
            "--name",
            vm,
            "--memory",
            str(memory),
            "--vcpus",
            str(cpus),
            f"--disk=path={image},cache=none",
            f"--disk=path={iso},readonly=on",
            "--network=network=default",
            "--connect",
            "qemu:///system",
            "--cpu=host-passthrough",
            "--os-variant=debian9",
            "--import",
            "--graphics=spice",
            "--noautoconsole",
            "--quiet",
        ]
    )


def wait_for_ssh(hostname):
    ssh_port = 22
    while True:
        time.sleep(5)
        try:
            conn = socket.create_connection((hostname, ssh_port), timeout=1)
        except Exception:
            continue
        conn.close()
        break


def main():
    config = yaml.safe_load(open(sys.argv[1]))

    base = config["base_image"]
    vm = config["name"]
    img = config["image_file"]
    size = config["image_size"]
    pubkey = config["public_key"]
    memory = config.get("memory", 1024)
    cpus = config.get("cpus", 1)

    memory = int(memory)
    cpus = int(cpus)
    pubkey = open(pubkey).read()

    iso = f"{vm}.iso"
    cloud_init_iso(iso, vm, pubkey)

    if os.path.exists(img):
        os.remove(img)
    shutil.copy(base, img)

    subprocess.check_call(["qemu-img", "resize", "-q", img, size])

    create_vm(vm, img, iso, memory=memory, cpus=cpus)
    wait_for_ssh(vm)
    os.remove(iso)


main()