2024-05-26 08:37:52 +03:00
#!/usr/bin/python3
2023-10-24 21:09:53 +03:00
import os
2024-09-05 21:13:37 +03:00
import sys
2023-10-13 15:30:35 +03:00
import logging
2024-04-29 03:55:10 +03:00
from typing import Callable
2023-03-27 21:13:36 +03:00
from time import sleep
2023-03-24 16:31:22 +03:00
2023-10-24 12:22:14 +03:00
import yaml
2024-04-29 04:02:22 +03:00
import urllib3
from dotenv import load_dotenv
2023-03-24 16:31:22 +03:00
from proxmoxer import ProxmoxAPI
2023-10-24 21:12:38 +03:00
from functions import clone_template , delete_vm , get_vm_ip
2023-03-24 16:31:22 +03:00
2023-10-11 14:38:56 +03:00
urllib3 . disable_warnings ( )
2023-10-24 12:21:21 +03:00
FORMAT = " %(asctime)s %(name)s %(levelname)s %(message)s "
logging . basicConfig ( format = FORMAT )
2023-10-13 15:30:35 +03:00
logger = logging . getLogger ( __name__ )
2024-05-26 08:37:52 +03:00
logger . setLevel ( logging . DEBUG )
2023-10-11 14:38:56 +03:00
2024-04-29 04:02:22 +03:00
load_dotenv ( )
PROXMOX_HOST : str | None = os . environ . get ( ' PROXMOX_HOST ' )
PROXMOX_USER : str | None = os . environ . get ( ' PROXMOX_USER ' )
PROXMOX_USER_FULL : str | None = os . environ . get ( ' PROXMOX_USER_FULL ' )
PROXMOX_PASSWORD : str | None = os . environ . get ( ' PROXMOX_PASSWORD ' )
2023-03-24 16:31:22 +03:00
2023-03-27 15:51:32 +03:00
2024-04-29 04:03:52 +03:00
def wait_status ( funcs : list [ Callable [ [ ] , dict [ str , str ] ] ] , status : str , sleep_time : float = 60 ) - > None :
2023-10-13 15:30:35 +03:00
statuses = [ False ] * len ( funcs )
while not all ( statuses ) :
logger . debug ( statuses )
2024-04-29 04:03:52 +03:00
sleep ( sleep_time )
2023-10-13 15:30:35 +03:00
for i in range ( len ( funcs ) ) :
statuses [ i ] = funcs [ i ] ( ) [ ' status ' ] == status
2023-03-24 16:31:22 +03:00
2024-04-29 04:02:22 +03:00
def main ( ) - > None :
assert PROXMOX_HOST is not None
assert PROXMOX_USER is not None
assert PROXMOX_USER_FULL is not None
assert PROXMOX_PASSWORD is not None
2023-03-24 16:31:22 +03:00
proxmox = ProxmoxAPI (
2023-10-24 12:22:52 +03:00
PROXMOX_HOST , user = PROXMOX_USER_FULL , password = PROXMOX_PASSWORD , verify_ssl = False
2023-03-24 16:31:22 +03:00
)
2024-04-29 03:55:10 +03:00
nodes : list [ dict [ str , str | int ] ] = proxmox . nodes . get ( ) # pyright: ignore
2023-03-27 21:13:36 +03:00
nodes = list ( filter ( lambda node : node [ ' status ' ] == ' online ' , nodes ) )
2024-04-29 03:55:10 +03:00
# node = min(nodes, key=lambda node: node['disk'])['node']
node : str = ' pve05 '
2024-09-05 21:13:37 +03:00
assert len ( sys . argv ) > = 2
branch : str = sys . argv [ 1 ]
match branch :
case " sisyphus " :
template_id : int = 374
case " p10 " :
template_id : int = 520
case " c10f2 " :
template_id : int = 374
case _ :
assert False
2024-04-29 03:55:10 +03:00
prefix : str = PROXMOX_USER + ' -test-k8s '
vm_names : dict [ str , str ] = {
2023-10-13 16:48:05 +03:00
' master ' : f ' { prefix } -master ' ,
' worker1 ' : f ' { prefix } -node1 ' ,
' worker2 ' : f ' { prefix } -node2 ' ,
}
2024-05-26 08:37:52 +03:00
# vm_ids = {
# 'master': 500,
# 'worker1': 501,
# 'worker2': 502,
# }
vm_ids : dict [ str , int ] = {
' master ' : 510 ,
' worker1 ' : 511 ,
' worker2 ' : 512 ,
2023-10-24 21:08:11 +03:00
}
2023-03-27 21:13:36 +03:00
2024-04-29 04:02:22 +03:00
delete : str = os . environ [ ' DELETE_VMS ' ]
assert delete in ( ' 0 ' , ' 1 ' )
if delete != ' 0 ' :
2023-10-24 21:12:38 +03:00
logger . info ( ' Stopping VMs %s ... ' , vm_ids )
proxmox . nodes ( node ) . qemu ( vm_ids [ ' master ' ] ) . status . stop . post ( )
proxmox . nodes ( node ) . qemu ( vm_ids [ ' worker1 ' ] ) . status . stop . post ( )
proxmox . nodes ( node ) . qemu ( vm_ids [ ' worker2 ' ] ) . status . stop . post ( )
sleep ( 15 )
logger . info ( ' Deleting VMs %s ... ' , vm_ids )
delete_vm ( proxmox , node , vm_ids [ ' master ' ] )
delete_vm ( proxmox , node , vm_ids [ ' worker1 ' ] )
delete_vm ( proxmox , node , vm_ids [ ' worker2 ' ] )
sleep ( 15 )
2023-10-13 15:30:35 +03:00
vm_id_master , upid_master = clone_template (
2023-03-27 21:13:36 +03:00
proxmox ,
node ,
template_id ,
2023-10-24 21:08:11 +03:00
newid = vm_ids [ ' master ' ] ,
2023-10-13 16:48:05 +03:00
name = vm_names [ ' master ' ] ,
2023-03-27 21:13:36 +03:00
)
2023-10-24 21:08:11 +03:00
assert vm_id_master == vm_ids [ ' master ' ]
2023-03-24 16:31:22 +03:00
2023-10-13 15:30:35 +03:00
vm_id_worker1 , upid_worker1 = clone_template (
2023-03-27 21:13:36 +03:00
proxmox ,
node ,
template_id ,
2023-10-24 21:08:11 +03:00
newid = vm_ids [ ' worker1 ' ] ,
2023-10-13 16:48:05 +03:00
name = vm_names [ ' worker1 ' ] ,
2023-03-27 21:13:36 +03:00
)
2023-10-24 21:08:11 +03:00
assert vm_id_worker1 == vm_ids [ ' worker1 ' ]
2023-03-27 21:13:36 +03:00
2023-10-13 15:30:35 +03:00
vm_id_worker2 , upid_worker2 = clone_template (
2023-03-27 21:13:36 +03:00
proxmox ,
node ,
template_id ,
2023-10-24 21:08:11 +03:00
newid = vm_ids [ ' worker2 ' ] ,
2023-10-13 16:48:05 +03:00
name = vm_names [ ' worker2 ' ] ,
2023-03-27 21:13:36 +03:00
)
2023-10-24 21:08:11 +03:00
assert vm_id_worker2 == vm_ids [ ' worker2 ' ]
2023-03-27 21:13:36 +03:00
2023-10-24 21:11:32 +03:00
logger . info ( ' Waiting for cloning to complete... ' )
2023-10-13 15:30:35 +03:00
wait_status (
[
proxmox . nodes ( node ) . tasks ( upid_master ) . status . get ,
proxmox . nodes ( node ) . tasks ( upid_worker1 ) . status . get ,
proxmox . nodes ( node ) . tasks ( upid_worker2 ) . status . get ,
2024-04-29 04:03:52 +03:00
] , # pyright: ignore
' stopped ' ,
2024-08-08 22:40:17 +03:00
sleep_time = 40 ,
2023-10-13 15:30:35 +03:00
)
2023-10-24 21:11:32 +03:00
logger . info ( ' Cloning completed! ' )
2023-10-13 15:30:35 +03:00
logger . info ( ' Starting VMs... ' )
2023-10-24 21:08:11 +03:00
proxmox . nodes ( node ) . qemu ( vm_ids [ ' master ' ] ) . status . start . post ( )
proxmox . nodes ( node ) . qemu ( vm_ids [ ' worker1 ' ] ) . status . start . post ( )
proxmox . nodes ( node ) . qemu ( vm_ids [ ' worker2 ' ] ) . status . start . post ( )
2023-10-13 15:30:35 +03:00
wait_status (
[
2023-10-24 21:08:11 +03:00
proxmox . nodes ( node ) . qemu ( vm_ids [ ' master ' ] ) . status . current . get ,
proxmox . nodes ( node ) . qemu ( vm_ids [ ' worker1 ' ] ) . status . current . get ,
proxmox . nodes ( node ) . qemu ( vm_ids [ ' worker2 ' ] ) . status . current . get ,
2024-04-29 04:03:52 +03:00
] , # pyright: ignore
' running ' ,
sleep_time = 10 ,
2023-10-13 15:30:35 +03:00
)
2023-10-11 14:38:56 +03:00
2023-10-13 15:30:35 +03:00
sleep ( 40 )
logger . info ( ' VMs are running! ' )
2023-03-27 21:13:36 +03:00
2024-04-29 03:55:10 +03:00
vm_ip_master : str = get_vm_ip ( proxmox , node , vm_ids [ ' master ' ] )
vm_ip_worker1 : str = get_vm_ip ( proxmox , node , vm_ids [ ' worker1 ' ] )
vm_ip_worker2 : str = get_vm_ip ( proxmox , node , vm_ids [ ' worker2 ' ] )
2023-10-24 12:24:28 +03:00
proxmox . logout ( )
2023-03-27 21:13:36 +03:00
2024-04-29 03:55:10 +03:00
tmp_path : str = ' ./tmp '
2023-10-24 21:09:53 +03:00
if not os . path . exists ( tmp_path ) :
os . makedirs ( tmp_path )
2023-03-27 21:13:36 +03:00
2023-10-24 21:09:53 +03:00
with open ( f ' { tmp_path } /vm_ids ' , ' w ' ) as ofile :
vm_ids_file = f ' { vm_ids [ " master " ] } \t { vm_names [ " master " ] } \n '
vm_ids_file + = f ' { vm_ids [ " worker1 " ] } \t { vm_names [ " worker1 " ] } \n '
vm_ids_file + = f ' { vm_ids [ " worker2 " ] } \t { vm_names [ " worker2 " ] } \n '
logger . info ( vm_ids_file )
ofile . write ( vm_ids_file )
with open ( f ' { tmp_path } /hosts ' , ' w ' ) as ofile :
2023-10-13 16:48:05 +03:00
hosts = f ' { vm_ip_master } \t { vm_names [ " master " ] } \n '
hosts + = f ' { vm_ip_worker1 } \t { vm_names [ " worker1 " ] } \n '
hosts + = f ' { vm_ip_worker2 } \t { vm_names [ " worker2 " ] } \n '
2023-10-13 15:30:35 +03:00
logger . info ( hosts )
2023-03-27 21:13:36 +03:00
ofile . write ( hosts )
2023-03-24 16:31:22 +03:00
2023-10-24 12:22:14 +03:00
inventory = {
' workers ' : {
' hosts ' : {
' worker1 ' : {
' ansible_host ' : vm_ip_worker1 ,
} ,
' worker2 ' : {
' ansible_host ' : vm_ip_worker2 ,
} ,
} ,
} ,
' all_vms ' : {
' hosts ' : {
' master ' : {
' ansible_host ' : vm_ip_master ,
} ,
} ,
' children ' : {
2023-10-24 21:13:57 +03:00
' workers ' : None
2023-10-24 12:22:14 +03:00
} ,
2024-08-08 22:40:17 +03:00
' vars ' : {
' ansible_user ' : ' root '
}
2023-10-24 12:22:14 +03:00
} ,
}
2023-03-24 16:31:22 +03:00
2023-10-24 21:09:53 +03:00
with open ( f ' { tmp_path } /generated_inventory.yaml ' , ' w ' ) as ofile :
2023-10-24 12:22:14 +03:00
yaml . dump ( inventory , ofile )
2023-03-24 16:31:22 +03:00
if __name__ == ' __main__ ' :
main ( )