diff --git a/ararat/deploy.py b/ararat/deploy.py index 06a505d..d0e52a7 100644 --- a/ararat/deploy.py +++ b/ararat/deploy.py @@ -1,9 +1,56 @@ +import os -# if it doesn't exist, create encrypted data partition -# mount encrypted data partition +from pyinfra import host, inventory +from pyinfra.operations import server, apk, files, openrc +from pyinfra.facts.server import Mounts -# apk add kvm virsh -# rc-update add libvirtd +from pyinfra_util import get_pass + + +files.replace( + name="Enable TCP forwarding via SSH server", + path="/etc/ssh/sshd_config", + text="AllowTcpForwarding no", + replace="AllowTcpForwarding yes", +) +openrc.service( + name="Restart sshd", + service="sshd", + restarted=True, +) + +files.replace( + name="Enable community repository", + path="/etc/apk/repositories", + text="#http://dl-cdn.alpinelinux.org/alpine/v3.20/community", + replace="http://dl-cdn.alpinelinux.org/alpine/v3.20/community", +) +apk.update() +apk.packages( + packages=["cryptsetup", "vim"] +) + +mounts = host.get_fact(Mounts) +if "/var/lib/libvirt" not in mounts: + decryption_password = get_pass('0x90/ararat/sdb-crypt').strip() + if decryption_password: + server.shell( + name="Decrypt and mount /data", + commands=[ + f" echo -n '{decryption_password}' | cryptsetup luksOpen --key-file - /dev/sdb1 sdb_crypt || true", + "mount /dev/mapper/sdb_crypt /var/lib/libvirt", + ] + ) + +apk.packages( + packages=["libvirt-daemon", "qemu-img", "qemu-system-x86_64", "virt-install"] +) +openrc.service( + name="Start libvirtd", + service="libvirtd", + running=True, + enabled=False, +) # add networking: https://wiki.alpinelinux.org/wiki/KVM#Networking # modprobe tun @@ -12,5 +59,42 @@ # if it doesn't exist, create debian base image (later: and other base images): https://mop.koeln/blog/creating-a-local-debian-vm-using-cloud-init-and-libvirt/#download-the-image # for every active VM, if no image exists, run virt-install with the chosen base image and their cloud-init.yml file: https://mop.koeln/blog/creating-a-local-debian-vm-using-cloud-init-and-libvirt/#preparing-a-cloud-init-file -# for every active VM, make sure an IP is assigned and traffic is passed to it - +debian_image_path = "/var/lib/libvirt/images/debian-12-generic-amd64.qcow2" +files.download( + name="Download Debian 12 base image", + src="https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-generic-amd64.qcow2", + dest=debian_image_path, +) +for vm in inventory.groups.get("debian_vms"): + if os.path.isfile(f"{vm}/files/cloud-init.yml"): + files.put( + name=f"Upload {vm}-cloud-init.yml", + src=f"{vm}/files/cloud-init.yml", + dest=f"/root/{vm}-cloud-init.yml", + ) + #virt-install + else: + if vm.data.get("authorized_keys"): + authorized_keys = "ssh_authorized_keys:\n - " + " - ".join( + [get_pass(f"0x90/ssh_keys/{admin}.pub") for admin in vm.data.get("authorized_keys")] + ) + else: + authorized_keys = "" + files.template( + name=f"Upload {vm}-cloud-init.yml", + src="ararat/files/cloud-init.yml.j2", + dest=f"/root/{vm}-cloud-init.yml", + ssh_authorized_keys=authorized_keys, + ) + memory = 1024 + vcpus = 1 + disk_size = 4 + server.shell( + name=f"virt-install {vm}", + commands=[ + f"virt-install --name {vm} --disk=size={disk_size},backing_store={debian_image_path} " + f"--memory {memory} --vcpus {vcpus} --cloud-init user-data=/root/{vm}-cloud-init.yml,disable=on " + "--network bridge=virbr0 --osinfo=debian12 || true", + ] + ) + # for every active VM, make sure an IP is assigned and traffic is passed to it diff --git a/ararat/files/cloud-init.yml.j2 b/ararat/files/cloud-init.yml.j2 new file mode 100644 index 0000000..84d57b0 --- /dev/null +++ b/ararat/files/cloud-init.yml.j2 @@ -0,0 +1,25 @@ +#cloud-config + +keyboard: + layout: de + variant: nodeadkeys + +locale: en_US + +timezone: UTC + +disable_root: false + +users: + - name: root + shell: /bin/bash + {{ ssh_authorized_keys }} + - name: mop + # so our user can just sudo without any password + sudo: ALL=(ALL) NOPASSWD:ALL + shell: /bin/bash + # content from $HOME/.ssh/id_rsa.pub on your host system + ssh_authorized_keys: + - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKZYJ91RLXRCQ4ZmdW6ucIltzukQ/k+lDOqlRIYwxNRv missytake@systemli.org + +# Examples: https://cloudinit.readthedocs.io/en/latest/reference/examples_library.html#examples-library