Skip to content

Commit 548765e

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 <[email protected]>
1 parent 081433f commit 548765e

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
@@ -384,26 +384,38 @@ def import_vm(self, uri: str, sr_uuid: str | None = None, use_cache: bool = Fals
384384

385385
params: dict[str, str | bool | dict[str, str]] = {}
386386
msg = "Import VM %s" % uri
387-
if '://' in uri:
388-
params['url'] = uri
389-
else:
390-
params['filename'] = uri
391-
if sr_uuid is not None:
392-
msg += " (SR: %s)" % sr_uuid
393-
params['sr-uuid'] = sr_uuid
394-
logging.info(msg)
395-
vm_uuid = self.xe('vm-import', params)
396-
vm_name = prefix_object_name(self.xe('vm-param-get', {'uuid': vm_uuid, 'param-name': 'name-label'}))
397-
vm = VM(vm_uuid, self)
398-
vm.param_set('name-label', vm_name)
399-
# Set VM VIF networks to the host's management network
400-
for vif in vm.vifs():
401-
vif.move(self.management_network())
402-
if use_cache:
403-
cache_key = self.vm_cache_key(uri)
404-
logging.info(f"Marking VM {vm.uuid} as cached")
405-
vm.param_set('name-description', cache_key)
406-
return vm
387+
download_path = None
388+
389+
try:
390+
if uri.startswith('https://'):
391+
# Direct import from https is broken in xapi. Download HTTPS URL to temporary file on host
392+
download_path = f'/tmp/{uuid.uuid4()}'
393+
logging.info(f"Download VM from {uri}")
394+
self.ssh(f"curl -sSL -o '{download_path}' '{uri}'")
395+
params['filename'] = download_path
396+
elif '://' in uri:
397+
params['url'] = uri
398+
else:
399+
params['filename'] = uri
400+
if sr_uuid is not None:
401+
msg += " (SR: %s)" % sr_uuid
402+
params['sr-uuid'] = sr_uuid
403+
logging.info(msg)
404+
vm_uuid = self.xe('vm-import', params)
405+
vm_name = prefix_object_name(self.xe('vm-param-get', {'uuid': vm_uuid, 'param-name': 'name-label'}))
406+
vm = VM(vm_uuid, self)
407+
vm.param_set('name-label', vm_name)
408+
# Set VM VIF networks to the host's management network
409+
for vif in vm.vifs():
410+
vif.move(self.management_network())
411+
if use_cache:
412+
cache_key = self.vm_cache_key(uri)
413+
logging.info(f"Marking VM {vm.uuid} as cached")
414+
vm.param_set('name-description', cache_key)
415+
return vm
416+
finally:
417+
if download_path:
418+
self.ssh(f'rm -f {download_path}')
407419

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

0 commit comments

Comments
 (0)