Complete implementation of OVA handling
Add functions for uploading, listing, and removing OVA images to the API and CLI interfaces. Includes improved parsing of the OVF and creation of a system_template and profile for each OVA. Also modifies some behaviour around profiles, making most components option at creation to support both profile types (and incomplete profiles generally). Implementation part 2/3 - remaining: OVA VM creation References #71
This commit is contained in:
@ -38,6 +38,8 @@ import daemon_lib.ceph as pvc_ceph
|
||||
|
||||
import pvcapid.libvirt_schema as libvirt_schema
|
||||
|
||||
from pvcapid.ova import list_ova
|
||||
|
||||
#
|
||||
# Exceptions (used by Celery tasks)
|
||||
#
|
||||
@ -197,14 +199,14 @@ def template_list(limit):
|
||||
#
|
||||
# Template Create functions
|
||||
#
|
||||
def create_template_system(name, vcpu_count, vram_mb, serial=False, vnc=False, vnc_bind=None, node_limit=None, node_selector=None, node_autostart=False):
|
||||
def create_template_system(name, vcpu_count, vram_mb, serial=False, vnc=False, vnc_bind=None, node_limit=None, node_selector=None, node_autostart=False, ova=None):
|
||||
if list_template_system(name, is_fuzzy=False)[-1] != 404:
|
||||
retmsg = { 'message': 'The system template "{}" already exists'.format(name) }
|
||||
retcode = 400
|
||||
return retmsg, retcode
|
||||
|
||||
query = "INSERT INTO system_template (name, vcpu_count, vram_mb, serial, vnc, vnc_bind, node_limit, node_selector, node_autostart) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s);"
|
||||
args = (name, vcpu_count, vram_mb, serial, vnc, vnc_bind, node_limit, node_selector, node_autostart)
|
||||
query = "INSERT INTO system_template (name, vcpu_count, vram_mb, serial, vnc, vnc_bind, node_limit, node_selector, node_autostart, ova) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s);"
|
||||
args = (name, vcpu_count, vram_mb, serial, vnc, vnc_bind, node_limit, node_selector, node_autostart, ova)
|
||||
|
||||
conn, cur = open_database(config)
|
||||
try:
|
||||
@ -661,10 +663,6 @@ def delete_script(name):
|
||||
close_database(conn, cur)
|
||||
return retmsg, retcode
|
||||
|
||||
#
|
||||
# OVA functions
|
||||
#
|
||||
|
||||
#
|
||||
# Profile functions
|
||||
#
|
||||
@ -703,7 +701,8 @@ def list_profile(limit, is_fuzzy=True):
|
||||
cur.execute(query, args)
|
||||
try:
|
||||
name = cur.fetchone()['name']
|
||||
except:
|
||||
except Exception as e:
|
||||
print(e)
|
||||
name = "N/A"
|
||||
profile_data[etype] = name
|
||||
# Split the arguments back into a list
|
||||
@ -722,8 +721,8 @@ def create_profile(name, profile_type, system_template, network_template, storag
|
||||
retcode = 400
|
||||
return retmsg, retcode
|
||||
|
||||
if profile_type not in ['script', 'clone', 'ova']:
|
||||
retmsg = { 'message': 'A valid profile type (script, clone, ova) must be specified' }
|
||||
if profile_type not in ['provisioner', 'ova']:
|
||||
retmsg = { 'message': 'A valid profile type (provisioner, ova) must be specified' }
|
||||
retcode = 400
|
||||
return retmsg, retcode
|
||||
|
||||
@ -742,7 +741,7 @@ def create_profile(name, profile_type, system_template, network_template, storag
|
||||
for template in network_templates:
|
||||
if template['name'] == network_template:
|
||||
network_template_id = template['id']
|
||||
if not network_template_id:
|
||||
if not network_template_id and profile_type != 'ova':
|
||||
retmsg = { 'message': 'The network template "{}" for profile "{}" does not exist'.format(network_template, name) }
|
||||
retcode = 400
|
||||
return retmsg, retcode
|
||||
@ -752,7 +751,7 @@ def create_profile(name, profile_type, system_template, network_template, storag
|
||||
for template in storage_templates:
|
||||
if template['name'] == storage_template:
|
||||
storage_template_id = template['id']
|
||||
if not storage_template_id:
|
||||
if not storage_template_id and profile_type != 'ova':
|
||||
retmsg = { 'message': 'The storage template "{}" for profile "{}" does not exist'.format(storage_template, name) }
|
||||
retcode = 400
|
||||
return retmsg, retcode
|
||||
@ -782,7 +781,7 @@ def create_profile(name, profile_type, system_template, network_template, storag
|
||||
|
||||
conn, cur = open_database(config)
|
||||
try:
|
||||
query = "INSERT INTO profile (name, type, system_template, network_template, storage_template, userdata, script, ova, arguments) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s);"
|
||||
query = "INSERT INTO profile (name, profile_type, system_template, network_template, storage_template, userdata, script, ova, arguments) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s);"
|
||||
args = (name, profile_type, system_template_id, network_template_id, storage_template_id, userdata_id, script_id, ova_id, arguments_formatted)
|
||||
cur.execute(query, args)
|
||||
retmsg = { "message": 'Created VM profile "{}"'.format(name) }
|
||||
@ -802,8 +801,8 @@ def modify_profile(name, profile_type, system_template, network_template, storag
|
||||
fields = []
|
||||
|
||||
if profile_type is not None:
|
||||
if profile_type not in ['script', 'clone', 'ova']:
|
||||
retmsg = { 'message': 'A valid profile type (script, clone, ova) must be specified' }
|
||||
if profile_type not in ['provisioner', 'ova']:
|
||||
retmsg = { 'message': 'A valid profile type (provisioner, ova) must be specified' }
|
||||
retcode = 400
|
||||
return retmsg, retcode
|
||||
fields.append({'field': 'type', 'data': profile_type})
|
||||
|
Reference in New Issue
Block a user