115 lines
4.4 KiB
Python
Executable File
115 lines
4.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
||
|
||
import subprocess
|
||
import yaml
|
||
from pathlib import Path
|
||
import urllib.request
|
||
|
||
|
||
with open('vars.yaml') as data:
|
||
vars_dict = yaml.safe_load(data)
|
||
|
||
# параметры хоста Proxmox
|
||
proxmox_node = vars_dict['proxmox_node']['name']
|
||
pve_host = vars_dict['proxmox_node']['host']
|
||
pve_port = vars_dict['proxmox_node']['port']
|
||
pve_admin = vars_dict['proxmox_node']['username']
|
||
pve_passwd = vars_dict['proxmox_node']['password']
|
||
pve_storage = vars_dict['proxmox_node']['storage']
|
||
pve_vmbr = vars_dict['proxmox_node']['vmbr']
|
||
|
||
# параметры создаваемого шаблона
|
||
tmpl_id = vars_dict['template']['id']
|
||
tmpl_name = vars_dict['template']['name']
|
||
tmpl_cores = vars_dict['template']['cores']
|
||
tmpl_memory = vars_dict['template']['memory']
|
||
tmpl_user = vars_dict['template']['username']
|
||
tmpl_passwd = vars_dict['template']['password']
|
||
|
||
# ссылка на образ
|
||
img_url = vars_dict['img']['url']
|
||
img_name = vars_dict['img']['name']
|
||
|
||
|
||
def download_img(name, url):
|
||
"""
|
||
Проверка наличия образа в текущей директории.
|
||
Если образа нет, он скачивается.
|
||
|
||
:param name: (str), имя образа;
|
||
:param url: (str), url-ссылка на директорию с образом.
|
||
:return: None.
|
||
"""
|
||
if Path(name).is_file():
|
||
print(f'Файл с именем "{name}" присутствует в текущей директории')
|
||
else:
|
||
print(f'Образа "{name}" нет в текущей директории, скачиваю..')
|
||
urllib.request.urlretrieve(f'{url}/{name}', name)
|
||
print('Скачивание завершено.')
|
||
|
||
|
||
def del_img(name):
|
||
"""
|
||
Удаление образа из текущей директории.
|
||
|
||
:param name: (str), имя образа.
|
||
:return: None
|
||
"""
|
||
if Path(name).is_file():
|
||
proc = subprocess.run(f'rm -rf {name}'.split(), capture_output=True, text=True)
|
||
print(f'Образ "{name}" удалён из текущей директории')
|
||
if proc.stderr:
|
||
print(f'Команда - "rm -rf {name}"')
|
||
print(proc.stderr)
|
||
exit(1)
|
||
else:
|
||
print(f'Образа "{name}" нет в текущей директории, скачиваю..')
|
||
|
||
|
||
def deploy_template(list_commands):
|
||
"""
|
||
Функция поочерёдно выполняет shell команды, переданные списком.
|
||
|
||
:param list_commands: (list), список команд, которые необходимо выполнить.
|
||
:return: None
|
||
"""
|
||
print(f'Создаю шаблон ВМ из образа')
|
||
for com in list_commands:
|
||
proc = subprocess.run(com.split(), capture_output=True, text=True)
|
||
if proc.stderr:
|
||
print(f'Команда - "{com}"')
|
||
print(proc.stderr)
|
||
exit(1)
|
||
# else:
|
||
# print(proc.stdout)
|
||
print('Шаблон создан.')
|
||
|
||
|
||
def check_vm(id):
|
||
proc = subprocess.run(f'qm status {id}'.split(), capture_output=True, text=True)
|
||
if proc.stderr:
|
||
print(f'Вероятно ВМ с идентификатором - {id} существует')
|
||
print(proc.stderr)
|
||
exit(1)
|
||
|
||
|
||
if __name__ == "__main__":
|
||
# в зависимости от типа и нахождения хранилища
|
||
# путь к создаваемому в процессе импорта диску указывается по-разному
|
||
# см. в WEB-интерфейсе примеры с других ВМ
|
||
commands = [f'qm create {tmpl_id} --name {tmpl_name}',
|
||
f'qm set {tmpl_id} --memory {tmpl_memory} --cores {tmpl_cores}',
|
||
f'qm set {tmpl_id} --net0 virtio,bridge={pve_vmbr} --scsihw virtio-scsi-pci',
|
||
f'qm disk import {tmpl_id} {img_name} {pve_storage} --format qcow2',
|
||
f'qm set {tmpl_id} --scsi0 {pve_storage}:{tmpl_id}/vm-{tmpl_id}-disk-0.qcow2',
|
||
f'qm set {tmpl_id} --bootdisk scsi0',
|
||
f'qm set {tmpl_id} --ide0 {pve_storage}:cloudinit --ide2 none,media=cdrom',
|
||
f'qm set {tmpl_id} --vga qxl --agent 1',
|
||
f'qm set {tmpl_id} --ciuser={tmpl_user} --cipassword={tmpl_passwd}',
|
||
f'qm template {tmpl_id}']
|
||
|
||
check_vm(tmpl_id)
|
||
download_img(img_name, img_url)
|
||
deploy_template(commands)
|
||
del_img(img_name)
|