-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsc_ovaimport.py
131 lines (106 loc) · 4.92 KB
/
sc_ovaimport.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import os
import tarfile
import requests
import json
import time
import xml.etree.ElementTree as ET
from pathlib import Path
from requests.auth import HTTPBasicAuth
def extract_ova(ova_path, tmp_dir):
# Extract OVA file into a temporary directory
if os.path.exists(tmp_dir):
print(f"Removing existing directory {tmp_dir}...")
os.rmdir(tmp_dir) # Remove existing tmp dir
os.makedirs(tmp_dir) # Create a new temp directory
with tarfile.open(ova_path, "r:gz") as tar:
tar.extractall(path=tmp_dir)
return tmp_dir
def wait_scale_task(server_url, task_tag, auth, timeout=300, retry_delay=1):
print(f"Waiting for Task '{task_tag}' to complete...")
start_time = time.time()
while time.time() - start_time < timeout:
response = requests.get(f"{server_url}/TaskTag/{task_tag}", auth=auth, verify=False)
task_status = response.json()
if task_status['state'] == 'ERROR':
raise Exception(f"Task '{task_tag}' failed!")
elif task_status['state'] == 'COMPLETE':
print(f"Task '{task_tag}' completed!")
return
time.sleep(retry_delay)
raise TimeoutError(f"Task '{task_tag}' failed to complete in {timeout} seconds")
def create_vm(server_url, ova_filename, auth):
initial_desc = f"Importing-{ova_filename}"
print(f"Creating VM {initial_desc} on HyperCore...")
# Placeholder for reading OVF file and machine type (this should be extracted from the OVF XML)
ovf_file_path = os.path.join(tmp_dir, [f for f in os.listdir(tmp_dir) if f.endswith('.ovf')][0])
tree = ET.parse(ovf_file_path)
root = tree.getroot()
machine_type = "uefi" if root.find(".//Firmware").text == 'EFI' else "bios"
vm_data = {
"dom": {
"name": initial_desc,
"desc": initial_desc,
"mem": 0, # Will set actual memory later
"numVCPU": 0 # Will set actual vCPU later
},
"options": {
"machineTypeKeyword": machine_type
}
}
response = requests.post(f"{server_url}/VirDomain/", json=vm_data, auth=auth, verify=False)
result = response.json()
vm_uuid = result['createdUUID']
wait_scale_task(server_url, result['taskTag'], auth)
print(f"HyperCore VM {vm_uuid} created for OVA import!")
return vm_uuid
def upload_vmdk_files(server_url, vmdk_list, auth, vm_uuid, use_performance_drivers=False):
for vmdk in vmdk_list:
vmdk_filename = os.path.basename(vmdk)
vmdk_size = os.path.getsize(vmdk)
print(f"Beginning upload of {vmdk_filename}...")
with open(vmdk, "rb") as f:
vmdk_payload = f.read()
response = requests.put(f"{server_url}/VirtualDisk/upload?filename={vmdk_filename}&filesize={vmdk_size}",
data=vmdk_payload, auth=auth, verify=False)
result = response.json()
uploaded_uuid = result['createdUUID']
print(f"Wait 90 seconds for disk to be converted")
time.sleep(90)
print(f"Finished uploading {vmdk_filename} (uuid: {uploaded_uuid})! Attaching as new block device to VM...")
# Attaching disk to VM
json_data = {
"template": {
"virDomainUUID": vm_uuid,
"type": "VIRTIO_DISK" if use_performance_drivers else "IDE_DISK",
"capacity": vmdk_size
},
"options": {
"regenerateDiskID": False
}
}
response = requests.post(f"{server_url}/VirtualDisk/{uploaded_uuid}/attach", json=json_data, auth=auth,
verify=False)
result = response.json()
wait_scale_task(server_url, result['taskTag'], auth)
attached_block_dev_uuid = result['createdUUID']
print(f"Attached uploaded {vmdk_filename} as new block device {attached_block_dev_uuid} to VM!")
def main():
# Server and authentication details
server = input("Enter Scale Computing server IP/hostname: ")
username = input("Enter username: ")
password = input("Enter password: ")
auth = HTTPBasicAuth(username, password)
# OVA path and details
ova_path = input("Enter full path to OVA file: ")
tmp_dir = os.path.join("/tmp", Path(ova_path).stem) # Temporary directory for OVA contents
# Extract OVA and get VMDK list
tmp_dir = extract_ova(ova_path, tmp_dir)
vmdk_list = [os.path.join(tmp_dir, f) for f in os.listdir(tmp_dir) if f.endswith('.vmdk')]
# Create VM
vm_uuid = create_vm(f"https://{server}/rest/v1", Path(ova_path).name, auth)
# Upload and attach VMDK files
use_performance_drivers = input("Use performance drivers? (y/n): ").strip().lower() == "y"
upload_vmdk_files(f"https://{server}/rest/v1", vmdk_list, auth, vm_uuid, use_performance_drivers)
print("OVA Import Completed!")
if __name__ == "__main__":
main()