2024-11-30 20:30:21 +00:00
import os
2024-11-30 08:27:13 +00:00
2024-11-30 20:30:21 +00:00
from pyinfra import host , inventory
from pyinfra . operations import server , apk , files , openrc
from pyinfra . facts . server import Mounts
2024-11-30 08:27:13 +00:00
2024-11-30 20:30:21 +00:00
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 ,
)
2024-11-30 08:27:13 +00:00
# add networking: https://wiki.alpinelinux.org/wiki/KVM#Networking
# modprobe tun
# echo "tun" >> /etc/modules-load.d/tun.conf
# cat /etc/modules | grep tun || echo tun >> /etc/modules
# 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
2024-11-30 20:30:21 +00:00
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