Skip to content

Commit a40d78b

Browse files
committed
Fix HTTPS VM import by downloading image to host first
When importing a VM from an HTTPS URL, xe vm-import fails because it doesn't properly support HTTPS URLs. This change downloads the image to a temporary file on the host before importing it. HTTP URLs remain unchanged and continue to use the url= parameter directly, avoiding unnecessary local storage of potentially large images. Signed-off-by: Gaëtan Lehmann <gaetan.lehmann@vates.tech>
1 parent fa46069 commit a40d78b

1 file changed

Lines changed: 32 additions & 20 deletions

File tree

lib/host.py

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -353,26 +353,38 @@ def import_vm(self, uri, sr_uuid=None, use_cache=False) -> VM:
353353

354354
params = {}
355355
msg = "Import VM %s" % uri
356-
if '://' in uri:
357-
params['url'] = uri
358-
else:
359-
params['filename'] = uri
360-
if sr_uuid is not None:
361-
msg += " (SR: %s)" % sr_uuid
362-
params['sr-uuid'] = sr_uuid
363-
logging.info(msg)
364-
vm_uuid = self.xe('vm-import', params)
365-
vm_name = prefix_object_name(self.xe('vm-param-get', {'uuid': vm_uuid, 'param-name': 'name-label'}))
366-
vm = VM(vm_uuid, self)
367-
vm.param_set('name-label', vm_name)
368-
# Set VM VIF networks to the host's management network
369-
for vif in vm.vifs():
370-
vif.move(self.management_network())
371-
if use_cache:
372-
cache_key = self.vm_cache_key(uri)
373-
logging.info(f"Marking VM {vm.uuid} as cached")
374-
vm.param_set('name-description', cache_key)
375-
return vm
356+
download_path = None
357+
358+
try:
359+
if uri.startswith('https://'):
360+
# Direct import from https is broken in xapi. Download HTTPS URL to temporary file on host
361+
download_path = f'/tmp/{uuid.uuid4()}'
362+
logging.info(f"Download VM from {uri}")
363+
self.ssh(f"curl -sSL -o '{download_path}' '{uri}'")
364+
params['filename'] = download_path
365+
elif '://' in uri:
366+
params['url'] = uri
367+
else:
368+
params['filename'] = uri
369+
if sr_uuid is not None:
370+
msg += " (SR: %s)" % sr_uuid
371+
params['sr-uuid'] = sr_uuid
372+
logging.info(msg)
373+
vm_uuid = self.xe('vm-import', params)
374+
vm_name = prefix_object_name(self.xe('vm-param-get', {'uuid': vm_uuid, 'param-name': 'name-label'}))
375+
vm = VM(vm_uuid, self)
376+
vm.param_set('name-label', vm_name)
377+
# Set VM VIF networks to the host's management network
378+
for vif in vm.vifs():
379+
vif.move(self.management_network())
380+
if use_cache:
381+
cache_key = self.vm_cache_key(uri)
382+
logging.info(f"Marking VM {vm.uuid} as cached")
383+
vm.param_set('name-description', cache_key)
384+
return vm
385+
finally:
386+
if download_path:
387+
self.ssh(['rm', '-f', download_path])
376388

377389
def import_iso(self, uri, sr: SR) -> VDI:
378390
random_name = str(uuid.uuid4())

0 commit comments

Comments
 (0)