Update app.py

This commit is contained in:
Blackwhitebear8 2024-12-09 15:12:32 +01:00
parent 1a23c52404
commit 3a5204d400

364
app.py
View file

@ -1,281 +1,105 @@
#!/bin/bash from flask import Flask, render_template, request, jsonify, url_for
import subprocess
import re
import time
# Vereiste packages installeren app = Flask(__name__)
sudo apt install libguestfs-tools jq -y
# Functie om het eerstvolgende vrije VMID te bepalen # Hier maak je een lijst van VM-taken die aan de gang zijn.
find_next_free_vmid() { vm_status = {}
# Haal de lijst van bestaande VMIDs op uit het JSON-bestand
local existing_ids=$(jq -r '.ids | keys | .[]' /etc/pve/.vmlist | sort -n)
local vmid=100 # Begin bij een standaard VMID, bijvoorbeeld 100
for id in $existing_ids; do def get_network_bridges():
if [[ $vmid -lt $id ]]; then try:
# Als de huidige $vmid kleiner is dan de eerstvolgende in de lijst, is deze vrij result = subprocess.run(['brctl', 'show'], capture_output=True, text=True, check=True)
echo $vmid bridges = []
return for line in result.stdout.splitlines():
fi parts = line.split()
# Anders verhogen we $vmid om naar het volgende te kijken if len(parts) > 0 and not parts[0].startswith(("fwbr", "tap", "enp", "fwpr", "bridge")):
((vmid++)) bridges.append(parts[0])
done return bridges
except subprocess.CalledProcessError as e:
print(f"Fout bij het ophalen van netwerkbridges: {e}")
return []
# Als we geen vrije ID in de lijst vinden, retourneer de volgende beschikbare ID def get_storage_types():
echo $vmid try:
} result = subprocess.run(['pvesm', 'status'], capture_output=True, text=True, check=True)
storage_types = []
for line in result.stdout.splitlines()[1:]:
parts = line.split()
if parts:
storage_types.append(parts[0])
return storage_types
except subprocess.CalledProcessError as e:
print(f"Fout bij het ophalen van storage types: {e}")
return []
# Configuratievariabelen def get_ip_addresses_from_output(output):
VMID=$(find_next_free_vmid) # VM ID # Zoek naar zowel IPv4 als IPv6 adressen van eth0 in de output
VMNAME="test" # Naam van de VM ipv4_addresses = re.findall(r'eth0 - ipv4: (\d+\.\d+\.\d+\.\d+)', output) # Voor IPv4 adressen
VMUSER="test" # Gebruikersnaam ipv6_addresses = re.findall(r'eth0 - ipv6: ([a-f0-9:]+)', output) # Voor IPv6 adressen
VMPASSWORD="test" # Wachtwoord voor de gebruiker (leeg voor alleen SSH-sleutels)
SSH_KEYS_PATH1=""
DISK_SIZE="20" # Disk grootte in GiB
BRIDGE="vmbr0"
MEMORY="4096"
CORES="4"
STORAGE="btrfs" # Opslaglocatie
OSKEUZE="5" # Naam en versie van het besturingssysteem, bijv. "Debian 12"
TEMPLATE="n" # Of de VM als template moet worden ingesteld (j/n)
SSH_KEY_TEXT="" # Combineer beide lijsten van adressen
return ipv4_addresses + ipv6_addresses
# Parseer de argumenten met getopts @app.route('/', methods=['GET'])
while getopts "n:u:p:k:d:b:m:c:s:o:t:" opt; do def index():
case ${opt} in bridges = get_network_bridges()
n) VMNAME="${OPTARG}" ;; storage_types = get_storage_types()
u) VMUSER="${OPTARG}" ;; return render_template('index.html', bridges=bridges, storage_types=storage_types)
p) VMPASSWORD="${OPTARG}" ;;
k) SSH_KEYS_PATH1="${OPTARG}" ;;
d) DISK_SIZE="${OPTARG}" ;;
b) BRIDGE="${OPTARG}" ;;
m) MEMORY="${OPTARG}" ;;
c) CORES="${OPTARG}" ;;
s) STORAGE="${OPTARG}" ;;
o) OSKEUZE="${OPTARG}" ;;
t) TEMPLATE="${OPTARG}" ;;
\?) echo "Usage: $0 [-n vmname] [-u username] [-p password] [-k ssh_key] [-d disk_size] [-b bridge] [-m memory] [-c cores] [-s storage] [-o oskeuze] [-t template]" ;;
esac
done
# Echo de variabelen voor bevestiging @app.route('/check_vm_status/<vmnaam>', methods=['GET'])
echo "VM Name: $VMNAME" def check_vm_status(vmnaam):
echo "VM User: $VMUSER" status = vm_status.get(vmnaam, 'running') # Zet de status op 'running' als deze er nog niet is
echo "VM Password: $VMPASSWORD" return jsonify({'status': status})
echo "SSH Key Path: $SSH_KEYS_PATH1"
echo "Disk Size: $DISK_SIZE"
echo "Bridge: $BRIDGE"
echo "Memory: $MEMORY"
echo "Cores: $CORES"
echo "Storage: $STORAGE"
echo "OS Choice: $OSKEUZE"
echo "Template: $TEMPLATE"
# Controleer verplichte variabelen @app.route('/create_vm', methods=['POST'])
if [[ -z "$VMID" || -z "$VMNAME" || -z "$VMUSER" || -z "$DISK_SIZE" || -z "$STORAGE" || -z "$OSKEUZE" ]]; then def create_vm():
echo "Error: Een of meer verplichte variabelen zijn niet ingesteld. Vul alle vereiste variabelen in." try:
exit 1 vmnaam = request.form['vmnaam']
fi
vm_status[vmnaam] = 'running'
vmgebruiker = request.form['vmgebruiker']
vmwachtwoord = request.form['vmwachtwoord']
ssh_key = request.form.get('ssh_key', '')
vmdisk_size = request.form['vmdisk_size']
network_bridge = request.form['network_bridge']
ram = request.form['ram']
vm_cores = request.form['vm_cores']
storage = request.form['storage']
os = request.form['os']
command = [
'./create.sh',
'-n', vmnaam,
'-u', vmgebruiker,
'-p', vmwachtwoord,
'-k', ssh_key,
'-d', vmdisk_size,
'-b', network_bridge,
'-m', ram,
'-c', vm_cores,
'-s', storage,
'-o', os,
'-t', 'y'
]
# Voer het create.sh script uit en vang de output op
result = subprocess.run(command, capture_output=True, text=True, check=True)
vm_status[vmnaam] = 'completed'
# Verwerk de output van het script en zoek naar IP-adressen
ip_addresses = get_ip_addresses_from_output(result.stdout)
# OS-specificatie en image-toewijzing return jsonify({"success": True, "ip_addresses": ip_addresses})
case "$OSKEUZE" in except Exception as e:
"1") print(f"Fout bij het aanmaken van de VM: {e}")
IMAGE_URL="https://cloud.debian.org/images/cloud/bullseye/latest/debian-11-generic-amd64.qcow2" return jsonify({"success": False, "error": str(e)})
IMAGE_NAME="debian-11-generic-amd64.qcow2"
;; vm_status[vmnaam] = 'failed'
"2") return jsonify({'success': False, 'error': str(e)})
IMAGE_URL="https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-generic-amd64.qcow2"
IMAGE_NAME="debian-12-generic-amd64.qcow2"
;;
"3")
IMAGE_URL="https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img"
IMAGE_NAME="jammy-server-cloudimg-amd64.img"
;;
"4")
IMAGE_URL="https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img"
IMAGE_NAME="noble-server-cloudimg-amd64.img"
;;
"5")
IMAGE_URL="https://repo.almalinux.org/almalinux/9/cloud/x86_64/images/AlmaLinux-9-GenericCloud-latest.x86_64.qcow2"
IMAGE_NAME="AlmaLinux-9-GenericCloud-latest.x86_64.qcow2"
;;
*)
echo "Error: Ongeldige OS-keuze. Controleer de waarde van OSKEUZE."
exit 1
;;
esac
# Download de OS image if __name__ == '__main__':
mkdir -p /tmp app.run(host='0.0.0.0', port=5000, debug=True)
wget -O /tmp/"$IMAGE_NAME" "$IMAGE_URL"
if [ -n "$SSH_KEYS_PATH1" ] && [ -f "$SSH_KEYS_PATH1" ]; then
touch /tmp/temporary_ssh_key.pub
echo "$SSH_KEYS_PATH1" > /tmp/temporary_ssh_key.pub
# Sla de naam van het tijdelijke bestand op in een variabele
SSH_KEYS_PATH="/tmp/temporary_ssh_key.pub"
else
SSH_KEYS_PATH=""
fi
# Controleer de disk type
DISKTYPE=$(pvesm status | awk -v storage="$STORAGE" 'NR>1 && $1 == storage {print $2}')
# Pas de image aan
case $OSKEUZE in
1|2|3|4) # Debian en Ubuntu
virt-customize --run-command "apt update -y" -a /tmp/"$IMAGE_NAME"
virt-customize --install qemu-guest-agent,htop,curl,avahi-daemon,console-setup,cron,cifs-utils,mtr,bash-completion,bind9-utils,lsof,mc,mlocate,screen,sysstat,tmux,wget,zabbix-agent -a /tmp/"$IMAGE_NAME"
virt-customize --run-command "systemctl enable --now qemu-guest-agent" -a /tmp/"$IMAGE_NAME"
virt-customize --run-command "apt upgrade -y" -a /tmp/"$IMAGE_NAME"
case $SSH_KEYS_PATH in
'') # leeg
virt-customize -a /tmp/"$IMAGE_NAME" \
--run-command 'sed -i "s/^#PasswordAuthentication yes/PasswordAuthentication yes/" /etc/ssh/sshd_config' \
--run-command 'sed -i "s/^PasswordAuthentication no/PasswordAuthentication yes/" /etc/ssh/sshd_config' \
--run-command 'systemctl restart sshd'
;;
/tmp/temporary_ssh_key.pub) # iets
;;
esac
virt-customize -a /tmp/"$IMAGE_NAME" --truncate /etc/machine-id --truncate /var/lib/dbus/machine-id
;;
5) # RHEL
virt-customize --install https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm -a /tmp/"$IMAGE_NAME"
virt-customize --run-command "dnf update -y" -a /tmp/"$IMAGE_NAME"
virt-customize --install qemu-guest-agent,htop,curl,cifs-utils,firewalld,mtr,bash-completion,bind-utils,lsof,mc,mlocate,perl,perl-Date-Calc,perl-Data-Dumper,perl-Getopt-Long,perl-libs,screen,sysstat,tmux,wget,zabbix-agent -a /tmp/"$IMAGE_NAME"
virt-customize --selinux-relabel -a /tmp/"$IMAGE_NAME"
virt-customize --run-command "systemctl enable --now firewalld" -a /tmp/"$IMAGE_NAME"
virt-customize --run-command "systemctl enable --now qemu-guest-agent" -a /tmp/"$IMAGE_NAME"
virt-customize --run-command "dnf update -y" -a /tmp/"$IMAGE_NAME"
case $SSH_KEYS_PATH in
'') # leeg
virt-customize -a /tmp/"$IMAGE_NAME" \
--run-command 'sed -i "s/^#PasswordAuthentication yes/PasswordAuthentication yes/" /etc/ssh/sshd_config' \
--run-command 'sed -i "s/^PasswordAuthentication no/PasswordAuthentication yes/" /etc/ssh/sshd_config' \
--run-command 'systemctl restart sshd'
;;
/tmp/temporary_ssh_key.pub) # iets
;;
esac
;;
*) # Anders
;;
esac
virt-customize -a /tmp/"$IMAGE_NAME" --truncate /etc/machine-id --truncate /var/lib/dbus/machine-id
# Maak een nieuwe VM
qm create $VMID --name $VMNAME --memory $MEMORY --cores $CORES --net0 virtio,bridge=$BRIDGE,firewall=1 --agent 1
# Importeer de aangepaste image
qm importdisk $VMID /tmp/"$IMAGE_NAME" $STORAGE
# Configureer de VM disks
case $DISKTYPE in
dir|btrfs) #file en btrfs storage
qm set $VMID --scsihw virtio-scsi-single --scsi0 $STORAGE:$VMID/vm-$VMID-disk-0.raw,discard=on,iothread=1,ssd=1,format=raw
;;
lvm|lvmthin|zfspool) #lvm en zfs storage
qm set $VMID --scsihw virtio-scsi-single --scsi0 $STORAGE:vm-$VMID-disk-0,discard=on,iothread=1,ssd=1,format=raw
;;
esac
qm set $VMID --ide0 $STORAGE:cloudinit,format=raw
qm set $VMID --ide2 none,media=cdrom
qm set $VMID --bios ovmf
qm set $VMID --machine q35
qm set $VMID --tablet 0
qm set $VMID --serial0 socket
# Stel netwerkinstellingen en CPU-configuraties in
qm set $VMID --ipconfig0 ip=dhcp,ip6=auto
qm set $VMID --cpu cputype=host,flags="+md-clear;+spec-ctrl;+aes"
qm set $VMID --numa 1
qm set $VMID --sockets 1
# Configureer Cloud-Init
qm set $VMID --ciuser $VMUSER
qm set $VMID --cipassword $VMPASSWORD
qm set $VMID --ciupgrade 1
qm set $VMID --onboot 1
[[ -n "$SSH_KEYS_PATH" && -f "$SSH_KEYS_PATH" ]] && qm set $VMID --sshkeys "$SSH_KEYS_PATH"
#case $SSH_KEYS_PATH in
# '') # leeg
# ;;
# /tmp/temporary_ssh_key.pub) # iets
# qm set $VMID --sshkeys /tmp/temporary_ssh_key.pub
# ;;
#esac
qm set $VMID --efidisk0 $STORAGE:0,format=raw,pre-enrolled-keys=1
# Stel de bootvolgorde en disk grootte in
qm set $VMID --boot order="scsi0;ide2;net0"
qm resize $VMID scsi0 "${DISK_SIZE}G"
# Zet de VM om in een template als geselecteerd
if [[ "$TEMPLATE" == "j" ]]; then
qm template $VMID
fi
# starten vm
rm -f /tmp/"$IMAGE_NAME"
rm -f /tmp/temporary_ssh_key.pub
qm start $VMID
# ip ophalen
# Maximum aantal pogingen (1 minuut / 5 seconden = 12 pogingen)
MAX_ATTEMPTS=24 # Aantal pogingen voordat de foutmelding wordt weergegeven
ATTEMPT=0
ETH0_STATS="" # Zorg ervoor dat ETH0_STATS wordt geleegd bij elke iteratie
# Probeer om de IP-informatie en statistieken op te halen
while [ -z "$ETH0_STATS" ] && [ $ATTEMPT -lt $MAX_ATTEMPTS ]; do
echo "Trying to retrieve IP and stats information... Attempt $((ATTEMPT + 1)) of $MAX_ATTEMPTS"
# Haal de netwerkinformatie op
IP_INFO=$(qm agent $VMID network-get-interfaces 2>/dev/null)
# Controleer of de QEMU guest agent beschikbaar is
if [[ "$IP_INFO" == *"QEMU guest agent is not running"* ]]; then
echo "QEMU guest agent is not running. Retrying..."
elif [[ -z "$IP_INFO" ]]; then
echo "No network information received. Retrying..."
else
# Controleer specifiek of eth0 bestaat en statistieken bevat
ETH0_STATS=$(echo "$IP_INFO" | jq -r '.[] | select(.name == "eth0" and .statistics != null)')
if [ -n "$ETH0_STATS" ]; then
echo "Valid IP and statistics found for eth0!"
break # Als eth0 statistieken heeft, stop de poging
else
echo "No valid statistics found for eth0. Retrying..."
fi
fi
# Wacht 1 seconde voordat je opnieuw probeert
sleep 1
((ATTEMPT++))
done
# Controleer of we een geldig resultaat hebben gekregen
if [ -z "$ETH0_STATS" ]; then
echo "Unable to retrieve IP or statistics for eth0 after $MAX_ATTEMPTS attempts."
exit 1
else
# Parse en toon IPv4 en IPv6 adressen voor de eth0 interface met statistieken
echo "$ETH0_STATS" | jq -r '.["ip-addresses"][] | [.["ip-address-type"], .["ip-address"]] | @tsv' | \
while IFS=$'\t' read -r ip_type ip; do
echo "eth0 - $ip_type: $ip"
done
fi
# Opruimen
echo "VM $VMNAME met ID $VMID succesvol aangemaakt."