~tieong/pulumi-kimsufi

c7160d6b6d95842afeae7509adac9eb6cc7cdc50 — Thomas Ieong 1 year, 2 months ago 7eda4ef
Removed cloud-init
3 files changed, 52 insertions(+), 98 deletions(-)

M __main__.py
M group.py
M vm.py
M __main__.py => __main__.py +4 -5
@@ 20,15 20,14 @@ def domains_use_1GB_memory(
        args.props["memory"] = 1024
        return ResourceTransformationResult(props=args.props, opts=args.opts)


vmGroup = group.new_vm_group(
    "ubuntu",
    "guix",
    "/home/user/cluster_storage",
    (
        "https://cloud-images.ubuntu.com"
        "/releases/focal/release"
        "/ubuntu-20.04-server-cloudimg-amd64.img"
        "/home/user/projects/kimsufi-infra/guix-images/router.qcow2"
    ),
    "192.168.10.0/24",
    ["192.168.15.0/24"],
    1,
    ResourceOptions(transformations=[domains_use_1GB_memory]),
)

M group.py => group.py +24 -71
@@ 1,4 1,4 @@
from typing import Optional
from typing import Optional, List

from vm import new_vm



@@ 20,20 20,19 @@ class VMGroup(ComponentResource):


def new_vm_group(
    groupName: str,
    hostStoragePoolPath: str,
    vmImageSource: str,
    ipCIDR: str,
    numberOfVMs: int,
    group_name: str,
    pool_path: str,
    image: str,
    addresses: List[str],
    vm_num: int,
    opts: Optional[ResourceOptions] = None,
):
    resource = VMGroup(groupName, opts=opts)
    resource = VMGroup(group_name, opts=opts)

    # A pool for all cluster volumes
    cluster = libvirt.Pool(
        "cluster",
        "guix-pool",
        type="dir",
        path=hostStoragePoolPath,
        path=pool_path,
        opts=ResourceOptions(
            parent=resource,
            delete_before_replace=True,


@@ 41,9 40,9 @@ def new_vm_group(
    )

    network = libvirt.Network(
        "network",
        "default",
        libvirt.NetworkArgs(
            addresses=[ipCIDR],
            addresses=addresses,
            mode="nat",
            autostart=True,
            bridge="virbr0",


@@ 55,82 54,36 @@ def new_vm_group(
        ),
    )

    ubuntu = libvirt.Volume(
        "ubuntu",
    guix = libvirt.Volume(
        "guix-qcow2-base",
        pool=cluster.name,
        source=vmImageSource,
        source=image,
        format="qcow2",
        opts=ResourceOptions(
            parent=resource,
        ),
    )

    cloud_init_network_config = """\
version: 2
ethernets:
  ens3:
    dhcp4: true
"""

    HOSTNAME = "test"
    FQDN = HOSTNAME + "." + "example.com"

    cloud_init_user_data = f"""\
#cloud-config
disable_root: false
ssh_pwauth: True
chpasswd:
  list: |
        ubuntu:ubuntu
  expire: False
packages:
    - qemu-guest-agent
    - python3

hostname: "{HOSTNAME}"
fqdn: "{FQDN}"
final_message: "The system is finall up, after $UPTIME seconds"

power_state:
  delay: "+30"
  mode: reboot
  message: Bye Bye
  timeout: 30
  condition: True
"""

    cloud_init = libvirt.CloudInitDisk(
        "cloud-init",
        libvirt.CloudInitDiskArgs(
            network_config=cloud_init_network_config,
            pool=cluster.name,
            user_data=cloud_init_user_data,
        ),
        opts=ResourceOptions(
            parent=resource,
        ),
    )

    vmOutputs = []
    vm_outputs = []

    for i in range(numberOfVMs):
        vm_name = f"{groupName}-{i}"
    for i in range(vm_num):
        vm_name = f"{group_name}-{i}"

        vm = new_vm(
            vm_name,
            cluster.name,
            ubuntu.id,
            cloud_init.id,
            guix.id,
            network.id,
            ResourceOptions(
            opts=ResourceOptions(
                parent=resource,
            ),
        )

        vmOutputs.append({"ip": vm.ip, "name": vm.name})
        vm_outputs.append({"ip": vm.ip, "name": vm.name})

    resource.name = groupName
    resource.vms = vmOutputs
    resource.name = group_name
    resource.vms = vm_outputs

    resource.register_outputs({"name": groupName, "vms": vmOutputs})
    resource.register_outputs({"name": resource.name, "vms": resource.vms})

    return resource

M vm.py => vm.py +24 -22
@@ 1,43 1,47 @@
from typing import Optional
from dataclasses import dataclass

from pulumi import Output, ResourceOptions, ComponentResource
import pulumi_libvirt as libvirt


class VM(ComponentResource):
    def __init__(self, name: str, opts: ResourceOptions = None):
        # Change pkg something something to my state
        super().__init__('kimsufi-infra:pkg/vm:vm', name, None, opts)
        super().__init__("kimsufi-infra:pkg/vm:vm", name, None, opts)


def gigabytes_to_bytes(gigabytes: int):
    return gigabytes * 1_000_000_000


def new_vm(
        name: str,
        pool_name: Output[str],
        base_volume_id: Output[str],
        cloud_init_disk_id: Output[str],
        network_id: Output[str],
        opts: Optional[ResourceOptions] = None,
    name: str,
    pool_name: Output[str],
    base_volume_id: Output[str],
    network_id: Output[str],
    size: int = gigabytes_to_bytes(11),
    opts: Optional[ResourceOptions] = None,
) -> VM:
    resource = VM(name, opts=opts)

    # create a filesystem volume for our VM
    # This filesystem will be based on the `ubuntu` volume above
    # we'll use a size of 10GB

    filesystem = libvirt.Volume(
        f"{name}-filesystem",
        base_volume_id=base_volume_id,
        pool=pool_name,
        size=10000000000,
        opts=ResourceOptions(parent=resource)
        size=size,
        format="qcow2",
        opts=ResourceOptions(parent=resource),
    )

    # create a VM that has a name starting with ubuntu
    domain = libvirt.Domain(
        f"{name}-domain",
        cloudinit=cloud_init_disk_id,
        autostart=True,
        # Don't really know what's happening when set to True
        # but the addresses field is empty.
        # My guess is that since the guest-agent is already up & running
        # in the guest il reports back immediately even if no ip configured?
        qemu_agent=False,
        consoles=[
            libvirt.DomainConsoleArgs(
                type="pty",


@@ 48,8 52,7 @@ def new_vm(
        disks=[libvirt.DomainDiskArgs(volume_id=filesystem.id)],
        network_interfaces=[
            libvirt.DomainNetworkInterfaceArgs(
                network_id=network_id,
                wait_for_lease=True
                network_id=network_id, wait_for_lease=True
            )
        ],
        opts=ResourceOptions(


@@ 60,10 63,9 @@ def new_vm(
    )

    resource.name = domain.name
    resource.ip = domain.network_interfaces[0].addresses[0]
    resource.register_outputs({
        "ip": domain.network_interfaces[0].addresses[0],
        "name": domain.name
    })
    resource.ip = domain.network_interfaces[0].addresses
    resource.register_outputs(
        {"ip": resource.ip, "name": resource.name}
    )

    return resource