From ada3064008a030803bb282812766836f2f7e35ce Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Sun, 4 Oct 2020 16:17:56 +0300 Subject: create-vm in py --- create-vm | 169 +++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 96 insertions(+), 73 deletions(-) diff --git a/create-vm b/create-vm index 3fe4544..454db06 100755 --- a/create-vm +++ b/create-vm @@ -1,83 +1,106 @@ -#!/bin/bash +#!/usr/bin/env python3 -set -eu -o pipefail +import os +import shutil +import socket +import subprocess +import sys +import tempfile +import time -cloud_init_iso() -{ - local iso="$1" - local hostname="$2" - local pubkey="$3" - local dir="$(mktemp -d)" - cat < "$dir/meta-data" +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 -EOF +local-hostname: {hostname} +""" + ) - cat < "$dir/user-data" + with open(os.path.join(tmp, "user-data"), "w") as f: + f.write( + f"""\ #cloud-config ssh_authorized_keys: -- $pubkey -EOF - - genisoimage -quiet -volid cidata -joliet -rock -output "$iso" "$dir" - rm -rf "$dir" -} - - -create_vm() -{ - local name="$1" - local memory="$2" - local cpus="$3" - local image="$4" - local iso="$5" - - virt-install \ - --name="$name" \ - --memory "$memory" \ - --vcpus "$cpus" \ - --disk="path=$image,cache=none" \ - --disk="path=$iso,readonly=on" \ - --network=network=default \ - --quiet \ - --connect qemu:///system \ - --cpu=host-passthrough \ - --os-variant=debian9 \ - --import \ - --graphics=spice \ - --noautoconsole -} - -wait_for_ssh() -{ - local host="$1" - while ! nc -w 1 "$host" 22 < /dev/null > /dev/null - do - sleep 5 - done -} +- {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(): + base, vm, memory, cpus, img, size, pubkey = sys.argv[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() -{ - local base="$1" - local vm="$2" - local memory="$3" - local cpus="$4" - local img="$5" - local size="$6" - local pubkey="$(cat "$7")" - - local iso="$vm.iso" - - cloud_init_iso "$vm.iso" "$vm" "$pubkey" - cp "$base" "$img" - qemu-img resize -q "$img" "$size" - create_vm "$vm" "$memory" "$cpus" "$img" "$iso" - wait_for_ssh "$vm" - rm -f "$iso" -} - - -main "$@" -- cgit v1.2.1