146 lines
4.7 KiB
Python
146 lines
4.7 KiB
Python
import os
|
|
|
|
from pyinfra import host, inventory
|
|
from pyinfra.operations import server, apk, files, openrc
|
|
from pyinfra.facts.server import Mounts
|
|
|
|
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
|
|
server.modprobe(
|
|
name="activate tun kernel module",
|
|
module="tun",
|
|
)
|
|
# echo "tun" >> /etc/modules-load.d/tun.conf
|
|
files.line(
|
|
name="autostart tun",
|
|
path="/etc/modules-load.d/tun.conf",
|
|
line="tun",
|
|
)
|
|
# cat /etc/modules | grep tun || echo tun >> /etc/modules
|
|
#files.line(path="/etc/modules",line="tun")
|
|
# add VMs to public network:
|
|
virsh_network_guests = []
|
|
for vm in inventory.groups.get("debian_vms"):
|
|
#sudo ip addr add 65.109.242.20 dev eth0
|
|
ipv4 = vm.data.get("ipv4")
|
|
mac_address = '52:54:00:6c:3c:%02x'%vm.data.get("id")
|
|
files.template(
|
|
name=f"Add {ipv4} for {vm} to ararat",
|
|
src="ararat/files/floating-ip.cfg.j2",
|
|
dest=f"/etc/network/interfaces.d/60-{vm}-floating-up.cfg", # doesn't work, interfaces.d isn't included
|
|
vm=vm,
|
|
ipv4=ipv4,
|
|
)
|
|
#server.shell(name=f"Add {ipv4} for {vm} to ararat", commands=[f"ip addr add {ipv4} dev eth{vm}"],)
|
|
virsh_network_guests.append(f"<host mac='{mac_address}' name='{vm}' ip='{ipv4}' />")
|
|
openrc.service(
|
|
service="networking",
|
|
restarted=True,
|
|
)
|
|
|
|
# create public kvm network
|
|
files.template(
|
|
name="Generate libvirt public network XML",
|
|
src="ararat/files/public.network.j2",
|
|
dest="/tmp/public.network",
|
|
guests='\n '.join(virsh_network_guests),
|
|
host_ipv4=host.name,
|
|
)
|
|
server.shell(
|
|
name="Update libvirt public network",
|
|
commands=[
|
|
"virsh net-destroy public ; virsh net-undefine public || true",
|
|
"virsh net-define /tmp/public.network",
|
|
"virsh net-start public",
|
|
]
|
|
)
|
|
# disable ipv6 in a bridge if necessary
|
|
|
|
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,
|
|
)
|
|
mac_address = '52:54:00:6c:3c:%02x' % vm.data.get("id")
|
|
memory = 1024
|
|
vcpus = 1
|
|
disk_size = 4
|
|
server.shell(
|
|
name=f"virt-install {vm}",
|
|
commands=[
|
|
f"virsh list -all | grep {vm} || " # only run virt-install if VM doesn't exist yet
|
|
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 "
|
|
f"--network 'bridge=virbr0,network=public,mac_address={mac_address}' --osinfo=debian12 || true",
|
|
]
|
|
)
|