def test_create_configdrive_iso(self): imagefile = None try: self.mox.StubOutWithMock(utils, 'execute') utils.execute('genisoimage', '-o', mox.IgnoreArg(), '-ldots', '-allow-lowercase', '-allow-multidot', '-l', '-publisher', mox.IgnoreArg(), '-quiet', '-J', '-r', '-V', 'config-2', mox.IgnoreArg(), attempts=1, run_as_root=False).AndReturn(None) self.mox.ReplayAll() with configdrive.ConfigDriveBuilder() as c: c._add_file('this/is/a/path/hello', 'This is some content') (fd, imagefile) = tempfile.mkstemp(prefix='cd_iso_') os.close(fd) c._make_iso9660(imagefile) # Check cleanup self.assertFalse(os.path.exists(c.tempdir)) finally: if imagefile: fileutils.delete_if_exists(imagefile)
def test_create_configdrive_iso(self): CONF.set_override('config_drive_format', 'iso9660') imagefile = None try: self.mox.StubOutWithMock(utils, 'execute') utils.execute('genisoimage', '-o', mox.IgnoreArg(), '-ldots', '-allow-lowercase', '-allow-multidot', '-l', '-publisher', mox.IgnoreArg(), '-quiet', '-J', '-r', '-V', 'config-2', mox.IgnoreArg(), attempts=1, run_as_root=False).AndReturn(None) self.mox.ReplayAll() with configdrive.ConfigDriveBuilder(FakeInstanceMD()) as c: (fd, imagefile) = tempfile.mkstemp(prefix='cd_iso_') os.close(fd) c.make_drive(imagefile) finally: if imagefile: fileutils.delete_if_exists(imagefile)
def test_create_configdrive_vfat(self): imagefile = None try: self.mox.StubOutWithMock(utils, 'mkfs') self.mox.StubOutWithMock(utils, 'execute') self.mox.StubOutWithMock(utils, 'trycmd') utils.mkfs('vfat', mox.IgnoreArg(), label='config-2').AndReturn(None) utils.trycmd('mount', '-o', mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg(), run_as_root=True).AndReturn((None, None)) utils.execute('umount', mox.IgnoreArg(), run_as_root=True).AndReturn(None) self.mox.ReplayAll() with configdrive.ConfigDriveBuilder() as c: c._add_file('this/is/a/path/hello', 'This is some content') (fd, imagefile) = tempfile.mkstemp(prefix='cd_vfat_') os.close(fd) c._make_vfat(imagefile) # Check cleanup self.assertFalse(os.path.exists(c.tempdir)) # NOTE(mikal): we can't check for a VFAT output here because the # filesystem creation stuff has been mocked out because it # requires root permissions finally: if imagefile: fileutils.delete_if_exists(imagefile)
def unrescue_instance(self, instance): self.power_off(instance) root_vhd_path = self._pathutils.lookup_root_vhd_path(instance.name) rescue_vhd_path = self._pathutils.lookup_root_vhd_path(instance.name, rescue=True) if (instance.vm_state == vm_states.RESCUED and not (rescue_vhd_path and root_vhd_path)): err_msg = _('Missing instance root and/or rescue image. ' 'The instance cannot be unrescued.') raise vmutils.HyperVException(err_msg) vm_gen = self._vmutils.get_vm_gen(instance.name) controller_type = VM_GENERATIONS_CONTROLLER_TYPES[vm_gen] self._vmutils.detach_vm_disk(instance.name, root_vhd_path, is_physical=False) if rescue_vhd_path: self._vmutils.detach_vm_disk(instance.name, rescue_vhd_path, is_physical=False) fileutils.delete_if_exists(rescue_vhd_path) self._attach_drive(instance.name, root_vhd_path, 0, self._ROOT_DISK_CTRL_ADDR, controller_type) self._detach_config_drive(instance.name, rescue=True, delete=True) # Reattach the configdrive, if exists. configdrive_path = self._pathutils.lookup_configdrive_path( instance.name) if configdrive_path: self.attach_config_drive(instance, configdrive_path, vm_gen) self.power_on(instance)
def test_create_configdrive_vfat(self): CONF.set_override('config_drive_format', 'vfat') imagefile = None try: self.mox.StubOutWithMock(utils, 'mkfs') self.mox.StubOutWithMock(utils, 'execute') self.mox.StubOutWithMock(utils, 'trycmd') utils.mkfs('vfat', mox.IgnoreArg(), label='config-2').AndReturn(None) utils.trycmd('mount', '-o', mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg(), run_as_root=True).AndReturn((None, None)) utils.execute('umount', mox.IgnoreArg(), run_as_root=True).AndReturn(None) self.mox.ReplayAll() with configdrive.ConfigDriveBuilder(FakeInstanceMD()) as c: (fd, imagefile) = tempfile.mkstemp(prefix='cd_vfat_') os.close(fd) c.make_drive(imagefile) # NOTE(mikal): we can't check for a VFAT output here because the # filesystem creation stuff has been mocked out because it # requires root permissions finally: if imagefile: fileutils.delete_if_exists(imagefile)
def cleanup(self): if self.imagefile: fileutils.delete_if_exists(self.imagefile) try: shutil.rmtree(self.tempdir) except OSError as e: LOG.error(_('Could not remove tmpdir: %s'), str(e))
def temporary_file(*args, **kwargs): tmp = None try: tmp = create_temporary_file(*args, **kwargs) yield tmp finally: if tmp: fileutils.delete_if_exists(tmp)
def _delete_vm_console_log(self, instance): console_log_files = self._pathutils.get_vm_console_log_paths(instance["name"]) vm_log_writer = self._vm_log_writers.get(instance["uuid"]) if vm_log_writer: vm_log_writer.join() for log_file in console_log_files: fileutils.delete_if_exists(log_file)
def _delete_vm_console_log(self, instance): console_log_files = self._pathutils.get_vm_console_log_paths( instance.name) vm_log_writer = self._vm_log_writers.get(instance.uuid) if vm_log_writer: vm_log_writer.join() for log_file in console_log_files: fileutils.delete_if_exists(log_file)
def _remove_image_on_exec(context, image_href, user_id, project_id, imagehandler_args, image_path): for handler, loc, image_meta in imagehandler.handle_image(context, image_href, user_id, project_id, image_path): # The loop will stop when the handle function returns success. handler.remove_image(context, image_href, image_meta, image_path, user_id, project_id, loc, **imagehandler_args) fileutils.delete_if_exists(image_path)
def _can_fallocate(self): """Check once per class, whether fallocate(1) is available, and that the instances directory supports fallocate(2). """ can_fallocate = getattr(self.__class__, "can_fallocate", None) if can_fallocate is None: _out, err = utils.trycmd("fallocate", "-n", "-l", "1", self.path + ".fallocate_test") fileutils.delete_if_exists(self.path + ".fallocate_test") can_fallocate = not err self.__class__.can_fallocate = can_fallocate if not can_fallocate: LOG.error(_LE("Unable to preallocate image at path: " "%(path)s"), {"path": self.path}) return can_fallocate
def convert_image(source, dest, out_format, run_as_root=False, **kwargs): """Convert image to other format.""" cmd = ('qemu-img', 'convert', '-O', out_format, source, dest) utils.execute(*cmd, run_as_root=run_as_root) if kwargs.has_key('subformat'): if kwargs.get('subformat') == 'streamoptimized': dir_name = os.path.dirname(dest) base_name = os.path.basename(dest) ovf_name = '%s/%s.ovf' % (dir_name,base_name) vmx_name_temp = '%s/vmx/template.vmx' % CONF.provider_opts.conversion_dir vmx_name = '%s/template.vmx' % dir_name shutil.copy2(vmx_name_temp,vmx_name) mk_ovf_cmd = ('ovftool', '-o',vmx_name, ovf_name) convert_file = '%s/converted-file.vmdk' % dir_name os.rename(dest, convert_file) utils.execute(*mk_ovf_cmd, run_as_root=run_as_root) vmdk_file_name = '%s/%s-disk1.vmdk' % (dir_name,base_name) fileutils.delete_if_exists(dest) os.rename(vmdk_file_name, dest) fileutils.delete_if_exists(ovf_name) fileutils.delete_if_exists('%s/%s.mf' % (dir_name,base_name)) fileutils.delete_if_exists(convert_file)
def _can_fallocate(self): """Check once per class, whether fallocate(1) is available, and that the instances directory supports fallocate(2). """ can_fallocate = getattr(self.__class__, 'can_fallocate', None) if can_fallocate is None: _out, err = utils.trycmd('fallocate', '-n', '-l', '1', self.path + '.fallocate_test') fileutils.delete_if_exists(self.path + '.fallocate_test') can_fallocate = not err self.__class__.can_fallocate = can_fallocate if not can_fallocate: LOG.error('Unable to preallocate_images=%s at path: %s' % (CONF.preallocate_images, self.path)) return can_fallocate
def snapshot(self, context, instance, image_id, update_task_state): update_task_state(task_state=task_states.IMAGE_PENDING_UPLOAD) # 1. get vmdk url vapp_name = self._get_vcloud_vapp_name(instance) the_vapp = self._get_vcloud_vapp(vapp_name) remote_vmdk_url = self._query_vmdk_url(the_vapp) # 2. download vmdk temp_dir = CONF.vcloud.vcloud_conversion_dir vmdk_name = remote_vmdk_url.split('/')[-1] local_file_name = '%s/%s' % (temp_dir, vmdk_name) self._download_vmdk_from_vcloud( context, remote_vmdk_url, local_file_name) # 3. convert vmdk to qcow2 converted_file_name = temp_dir + '/converted-file.qcow2' convert_commond = "qemu-img convert -f %s -O %s %s %s" % \ ('vmdk', 'qcow2', local_file_name, converted_file_name) convert_result = subprocess.call([convert_commond], shell=True) if convert_result != 0: # do something, change metadata LOG.error('converting file failed') # 4. upload qcow2 to image repository\ update_task_state(task_state=task_states.IMAGE_UPLOADING, expected_state=task_states.IMAGE_PENDING_UPLOAD) self._upload_image_to_glance( context, converted_file_name, image_id, instance) # 5. delete temporary files fileutils.delete_if_exists(local_file_name) fileutils.delete_if_exists(converted_file_name)
def snapshot(self, context, instance, image_id, update_task_state): update_task_state(task_state=task_states.IMAGE_PENDING_UPLOAD) # 1. get vmdk url vapp_name = self._get_vcloud_vapp_name(instance) the_vapp = self._get_vcloud_vapp(vapp_name) remote_vmdk_url = self._query_vmdk_url(the_vapp) # 2. download vmdk temp_dir = CONF.vcloud.vcloud_conversion_dir vmdk_name = remote_vmdk_url.split('/')[-1] local_file_name = '%s/%s' % (temp_dir, vmdk_name) self._download_vmdk_from_vcloud(context, remote_vmdk_url, local_file_name) # 3. convert vmdk to qcow2 converted_file_name = temp_dir + '/converted-file.qcow2' convert_commond = "qemu-img convert -f %s -O %s %s %s" % \ ('vmdk', 'qcow2', local_file_name, converted_file_name) convert_result = subprocess.call([convert_commond], shell=True) if convert_result != 0: # do something, change metadata LOG.error('converting file failed') # 4. upload qcow2 to image repository\ update_task_state(task_state=task_states.IMAGE_UPLOADING, expected_state=task_states.IMAGE_PENDING_UPLOAD) self._upload_image_to_glance(context, converted_file_name, image_id, instance) # 5. delete temporary files fileutils.delete_if_exists(local_file_name) fileutils.delete_if_exists(converted_file_name)
def _add_mac_address_to_ovf(self, ovf_name, mac_address): tree = etree.parse(ovf_name) root = tree.getroot() namespace_ovf = 'http://schemas.dmtf.org/ovf/envelope/1' namespace_cim = "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/"\ "CIM_ResourceAllocationSettingData" eth_tag = 'Item' resource_type_tag = 'ResourceType' mac_tag = 'Address' eth_resource_type_id = '10' xpath_eth = ".//{%s}%s[{%s}%s='%s']" % ( namespace_ovf, eth_tag, namespace_cim, resource_type_tag, eth_resource_type_id) elmt_eth = root.find(xpath_eth) xpath_mac = "{%s}%s" % (namespace_cim, mac_tag) elmt_eth.insert(0, etree.Element(xpath_mac)) elmt_eth[0].text = mac_address fileutils.delete_if_exists(ovf_name) tree.write(ovf_name)
def test_create_configdrive_iso(self): CONF.set_override("config_drive_format", "iso9660") imagefile = None try: self.mox.StubOutWithMock(utils, "execute") utils.execute( "genisoimage", "-o", mox.IgnoreArg(), "-ldots", "-allow-lowercase", "-allow-multidot", "-l", "-publisher", mox.IgnoreArg(), "-quiet", "-J", "-r", "-V", "config-2", mox.IgnoreArg(), attempts=1, run_as_root=False, ).AndReturn(None) self.mox.ReplayAll() with configdrive.ConfigDriveBuilder(FakeInstanceMD()) as c: (fd, imagefile) = tempfile.mkstemp(prefix="cd_iso_") os.close(fd) c.make_drive(imagefile) finally: if imagefile: fileutils.delete_if_exists(imagefile)
def _add_mac_address_to_ovf(self, ovf_name, mac_address): tree = etree.parse(ovf_name) root = tree.getroot() namespace_ovf = 'http://schemas.dmtf.org/ovf/envelope/1' namespace_cim = "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/"\ "CIM_ResourceAllocationSettingData" eth_tag = 'Item' resource_type_tag = 'ResourceType' mac_tag = 'Address' eth_resource_type_id = '10' xpath_eth = ".//{%s}%s[{%s}%s='%s']" % (namespace_ovf, eth_tag, namespace_cim, resource_type_tag, eth_resource_type_id) elmt_eth = root.find(xpath_eth) xpath_mac = "{%s}%s" % (namespace_cim, mac_tag) elmt_eth.insert(0, etree.Element(xpath_mac)) elmt_eth[0].text = mac_address fileutils.delete_if_exists(ovf_name) tree.write(ovf_name)
def _remove_image(self, context, image_id, image_meta, path, user_id=None, project_id=None, location=None, **kwargs): fileutils.delete_if_exists(path) return not os.path.exists(path)
def cleanup(self): if self.imagefile: fileutils.delete_if_exists(self.imagefile)
def spawn(self, context, instance, image_meta, injected_files, admin_password, network_info=None, block_device_info=None): mac_address = '' if len(network_info) > 0: mac_address = network_info[0]['address'] name = instance['name'] state = power_state.BUILDING # 0.get vorg, user name,password vdc from configuration file (only one # org) node_name = instance.node vorg_name = self._session.org user_name = self._session.username password = self._session.password vdc_name = self._session.vdc vcloud_host = self._session.host_ip # 1.1 get image id, vm info ,flavor info # image_uuid = instance.image_ref if 'id' in image_meta: # create from image image_uuid = image_meta['id'] else: # create from volume image_uuid = image_meta['properties']['image_id'] vm_uuid = instance.uuid vm_name = instance.name vm_hostname = instance.hostname vm_flavor_id = instance.get_flavor().flavorid # 1.3 (optional) is_poweron = True # 2~3 get vmdk file. if boot from volume ,check if the vmdk file exist os.chdir(CONF.vcloud.vcloud_conversion_dir) converted_file_name = CONF.vcloud.vcloud_conversion_dir + '/converted-file.vmdk' image_vmdk_file_name = '%s/%s.vmdk' % (CONF.vcloud.vcloud_conversion_dir,image_uuid) orig_file_name = CONF.vcloud.vcloud_conversion_dir + '/' + image_uuid +'.tmp' block_device_mapping = driver.block_device_info_get_mapping(block_device_info) volume_file_name = '' if len(block_device_mapping) > 0: volume_id = block_device_mapping[0][ 'connection_info']['data']['volume_id'] volume_file_name = '%s/%s.vmdk' % ( CONF.vcloud.vcloud_volumes_dir, volume_id) if os.path.exists(volume_file_name): shutil.move(volume_file_name,converted_file_name) elif os.path.exists(image_vmdk_file_name): os.rename(image_vmdk_file_name,converted_file_name) else: # 2. download qcow2 file from glance to local # tmp_dir = '/hctemp' metadata = IMAGE_API.get(context, image_uuid) file_size = int(metadata['size']) read_iter = IMAGE_API.download(context, image_uuid) glance_file_handle = util.GlanceFileRead(read_iter) orig_file_name = CONF.vcloud.vcloud_conversion_dir + \ '/' + image_uuid + '.tmp' orig_file_handle = open(orig_file_name, "wb") util.start_transfer(context, glance_file_handle, file_size, write_file_handle=orig_file_handle) # 3. convert to vmdk if metadata["disk_format"] == 'qcow2': convert_commond = "qemu-img convert -f %s -O %s %s %s" % \ ('qcow2', 'vmdk', orig_file_name, converted_file_name) convert_result = subprocess.call([convert_commond], shell=True) if convert_result != 0: LOG.error('convert qcow2 to vmdk failed') # do something, change metadata # file_size = os.path.getsize(converted_file_name) elif metadata["disk_format"] == 'raw': convert_commond = "qemu-img convert -f %s -O %s %s %s" % \ ('raw', 'vmdk', orig_file_name, converted_file_name) convert_result = subprocess.call([convert_commond], shell=True) if convert_result != 0: LOG.error('convert qcow2 to vmdk failed') # do something, change metadata # file_size = os.path.getsize(converted_file_name) else: os.rename(orig_file_name, converted_file_name) # 4. vmdk to ovf ovf_name = '%s/%s.ovf' % (CONF.vcloud.vcloud_conversion_dir, vm_uuid) vmx_name = '%s/base-%s.vmx' % ( CONF.vcloud.vcloud_conversion_dir, vm_flavor_id) mk_ovf_cmd = "ovftool -o %s %s" % (vmx_name, ovf_name) mk_ovf_result = subprocess.call(mk_ovf_cmd, shell=True) if mk_ovf_result != 0: LOG.error('make ovf faild!') return # add mac address to ovf if mac_address != '': self._add_mac_address_to_ovf(ovf_name, mac_address) # 5. upload ovf to vcloud template, using image's uuid as template name # 6. create vm from template self.create_networks(network_info) for vif in network_info: net_name = vif['id'] self.plug_vifs(instance, network_info) if is_poweron: create_vapp_cmd =\ 'ovftool --powerOn --net:"VM Network=%s"' \ ' %s "vcloud://%s:%s@%s?org=%s&vdc=%s&vapp=%s"' % \ (net_name, ovf_name, user_name, password, vcloud_host, vorg_name, vdc_name, vm_uuid) else: create_vapp_cmd = 'ovftool --net:"VM Network=%s" %s ' \ '"vcloud://%s:%s@%s?org=%s&vdc=%s&vapp=%s"' % \ (net_name, ovf_name, user_name, password, vcloud_host, vorg_name, vdc_name, vm_uuid) create_vapp_cmd_result = subprocess.call(create_vapp_cmd, shell=True) if mk_ovf_result != 0: LOG.error('create vapp faild!') return # 7. clean os.chdir(CONF.vcloud.vcloud_conversion_dir) fileutils.delete_if_exists(orig_file_name) fileutils.delete_if_exists(ovf_name) fileutils.delete_if_exists(vm_uuid + '-disk1.vmdk') os.rename(converted_file_name, image_vmdk_file_name)
def _setup_delete_vm_log_mocks(self): m = fake.PathUtils.get_vm_console_log_paths(mox.IsA(str)) m.AndReturn(('fake_vm_log_path', 'fake_vm_log_path.1')) fileutils.delete_if_exists(mox.IsA(str)) fileutils.delete_if_exists(mox.IsA(str))
def spawn(self, context, instance, image_meta, injected_files, admin_password, network_info=None, block_device_info=None): #import pdb # pdb.set_trace() LOG.debug('[vcloud nova driver] spawn: %s' % instance.uuid) mac_address = '' if len(network_info) > 0: mac_address = network_info[0]['address'] name = instance['name'] state = power_state.BUILDING # 0.get vorg, user name,password vdc from configuration file (only one # org) node_name = instance.node vorg_name = self._session.org user_name = self._session.username password = self._session.password vdc_name = self._session.vdc vcloud_host = self._session.host_ip # 1.1 get image id, vm info ,flavor info # image_uuid = instance.image_ref if 'id' in image_meta: # create from image image_uuid = image_meta['id'] else: # create from volume image_uuid = image_meta['properties']['image_id'] vm_uuid = instance.uuid vm_name = instance.name vm_hostname = instance.hostname #vm_flavor_id = instance.get_flavor().flavorid vm_flavor_name = instance.get_flavor().name vcloud_flavor_id = CONF.vcloud.vcloud_flavor_map[vm_flavor_name] vm_task_state = instance.task_state # 1.3 (optional) is_poweron = True # 2~3 get vmdk file. check if the image or volume vmdk file cached first image_cache_dir = CONF.vcloud.vcloud_conversion_dir volume_cache_dir = CONF.vcloud.vcloud_volumes_dir this_conversion_dir = '%s/%s' % (CONF.vcloud.vcloud_conversion_dir, vm_uuid) fileutils.ensure_tree(this_conversion_dir) os.chdir(this_conversion_dir) converted_file_name = this_conversion_dir + \ '/converted-file.vmdk' block_device_mapping = driver.block_device_info_get_mapping( block_device_info) image_vmdk_file_name = '%s/%s.vmdk' % ( image_cache_dir, image_uuid) volume_file_name = '' if len(block_device_mapping) > 0: volume_id = block_device_mapping[0][ 'connection_info']['data']['volume_id'] volume_file_name = '%s/%s.vmdk' % ( volume_cache_dir, volume_id) # 2.1 check if the image or volume vmdk file cached if os.path.exists(volume_file_name): # if volume cached, move the volume file to conversion dir shutil.move(volume_file_name, converted_file_name) elif os.path.exists(image_vmdk_file_name): # if image cached, copy ghe image file to conversion dir shutil.copy2(image_vmdk_file_name, converted_file_name) else: # if NOT cached, download qcow2 file from glance to local, then convert it to vmdk # tmp_dir = '/hctemp' self._update_vm_task_state( instance, task_state=vcloud_task_states.DOWNLOADING) metadata = IMAGE_API.get(context, image_uuid) file_size = int(metadata['size']) read_iter = IMAGE_API.download(context, image_uuid) glance_file_handle = util.GlanceFileRead(read_iter) orig_file_name = this_conversion_dir + \ '/' + image_uuid + '.tmp' orig_file_handle = fileutils.file_open(orig_file_name, "wb") util.start_transfer(context, glance_file_handle, file_size, write_file_handle=orig_file_handle, task_state=vcloud_task_states.DOWNLOADING, instance=instance) # 2.2. convert to vmdk self._update_vm_task_state( instance, task_state=vcloud_task_states.CONVERTING) if metadata["disk_format"] == 'qcow2': convert_commond = "qemu-img convert -f %s -O %s %s %s" % \ ('qcow2', 'vmdk', orig_file_name, converted_file_name) convert_result = subprocess.call([convert_commond], shell=True) if convert_result != 0: LOG.error('convert qcow2 to vmdk failed') # do something, change metadata # file_size = os.path.getsize(converted_file_name) elif metadata["disk_format"] == 'raw': convert_commond = "qemu-img convert -f %s -O %s %s %s" % \ ('raw', 'vmdk', orig_file_name, converted_file_name) convert_result = subprocess.call([convert_commond], shell=True) if convert_result != 0: LOG.error('convert qcow2 to vmdk failed') # do something, change metadata # file_size = os.path.getsize(converted_file_name) else: os.rename(orig_file_name, converted_file_name) shutil.copy2(converted_file_name,image_vmdk_file_name) # 3. vmdk to ovf self._update_vm_task_state( instance, task_state=vcloud_task_states.PACKING) vmx_file_dir = '%s/%s' % (CONF.vcloud.vcloud_conversion_dir,'vmx') vmx_name = 'base-%s.vmx' % vcloud_flavor_id vmx_cache_full_name = '%s/%s' % (vmx_file_dir, vmx_name) vmx_full_name = '%s/%s' % (this_conversion_dir, vmx_name) shutil.copy2(vmx_cache_full_name, vmx_full_name) ovf_name = '%s/%s.ovf' % (this_conversion_dir,vm_uuid) mk_ovf_cmd = "ovftool -o %s %s" % (vmx_full_name, ovf_name) mk_ovf_result = subprocess.call(mk_ovf_cmd, shell=True) if mk_ovf_result != 0: LOG.error('make ovf faild!') self._update_vm_task_state(instance, task_state=vm_task_state) return # add mac address to ovf if mac_address != '': self._add_mac_address_to_ovf(ovf_name, mac_address) # 5~6: UPLOAD ovf to vcloud and create a vm # todo:5. upload ovf to vcloud template, using image's uuid as template name # todo:6. create vm from template self._update_vm_task_state( instance, task_state=vcloud_task_states.NETWORK_CREATING) self.create_networks(network_info) net_name = None for vif in network_info: net_name = vif['id'] self.plug_vifs(instance, network_info) self._update_vm_task_state( instance, task_state=vcloud_task_states.IMPORTING) vapp_name = self._get_vcloud_vapp_name(instance) if not net_name: if is_poweron: create_vapp_cmd = 'ovftool --powerOn' \ ' %s "vcloud://%s:%s@%s?org=%s&vdc=%s&vapp=%s"' % \ (ovf_name, user_name, password, vcloud_host, vorg_name, vdc_name, vapp_name) else: create_vapp_cmd = 'ovftool %s "vcloud://%s:%s@%s?org=%s&vdc=%s&vapp=%s"' % \ (ovf_name, user_name, password, vcloud_host, vorg_name, vdc_name, vapp_name) else: if is_poweron: create_vapp_cmd = 'ovftool --powerOn --net:"VM Network=%s"' \ ' %s "vcloud://%s:%s@%s?org=%s&vdc=%s&vapp=%s"' % \ (net_name, ovf_name, user_name, password, vcloud_host, vorg_name, vdc_name, vapp_name) else: create_vapp_cmd = 'ovftool --net:"VM Network=%s" %s "vcloud://%s:%s@%s?org=%s&vdc=%s&vapp=%s"' % \ (net_name, ovf_name, user_name, password, vcloud_host, vorg_name, vdc_name, vapp_name) fileutils.delete_if_exists( '%s/%s.mf' % (this_conversion_dir, vm_uuid)) create_vapp_cmd_result = subprocess.call(create_vapp_cmd, shell=True) if create_vapp_cmd_result != 0: LOG.error('create vapp faild!') self._update_vm_task_state(instance, task_state=vm_task_state) return self._update_vm_task_state( instance, task_state=vcloud_task_states.VM_CREATING) # import pdb # pdb.set_trace() if is_poweron: expected_vapp_status = VCLOUD_STATUS.POWERED_ON else: expected_vapp_status = VCLOUD_STATUS.POWERED_OFF vapp_name = self._get_vcloud_vapp_name(instance) vapp_status = self._get_vcloud_vapp_status(vapp_name) LOG.debug('vapp status: %s' % vapp_status) retry_times = 60 while vapp_status != expected_vapp_status and retry_times > 0: time.sleep(3) vapp_status = self._get_vcloud_vapp_status(vapp_name) LOG.debug('vapp status: %s' % vapp_status) retry_times = retry_times - 1 # 7. clean up self._update_vm_task_state(instance, task_state=vm_task_state) shutil.rmtree(this_conversion_dir, ignore_errors=True)
def spawn(self, context, instance, image_meta, injected_files, admin_password, network_info=None, block_device_info=None): #import pdb #pdb.set_trace() LOG.debug('[vcloud nova driver] spawn: %s' % instance.uuid) mac_address = '' if len(network_info) > 0: mac_address = network_info[0]['address'] name = instance['name'] state = power_state.BUILDING # 0.get vorg, user name,password vdc from configuration file (only one # org) node_name = instance.node vorg_name = self._session.org user_name = self._session.username password = self._session.password vdc_name = self._session.vdc vcloud_host = self._session.host_ip # 1.1 get image id, vm info ,flavor info # image_uuid = instance.image_ref if 'id' in image_meta: # create from image image_uuid = image_meta['id'] else: # create from volume image_uuid = image_meta['properties']['image_id'] vm_uuid = instance.uuid vm_name = instance.name vm_hostname = instance.hostname #vm_flavor_id = instance.get_flavor().flavorid vm_flavor_name = instance.get_flavor().name vcloud_flavor_id = CONF.vcloud.vcloud_flavor_map[vm_flavor_name] vm_task_state = instance.task_state # 1.3 (optional) is_poweron = True # 2~3 get vmdk file. if boot from volume ,check if the vmdk file exist os.chdir(CONF.vcloud.vcloud_conversion_dir) converted_file_name = CONF.vcloud.vcloud_conversion_dir + \ '/converted-file.vmdk' image_vmdk_file_name = '%s/%s.vmdk' % ( CONF.vcloud.vcloud_conversion_dir, image_uuid) orig_file_name = CONF.vcloud.vcloud_conversion_dir + \ '/' + image_uuid + '.tmp' block_device_mapping = driver.block_device_info_get_mapping( block_device_info) volume_file_name = '' if len(block_device_mapping) > 0: volume_id = block_device_mapping[0]['connection_info']['data'][ 'volume_id'] volume_file_name = '%s/%s.vmdk' % (CONF.vcloud.vcloud_volumes_dir, volume_id) if os.path.exists(volume_file_name): shutil.move(volume_file_name, converted_file_name) elif os.path.exists(image_vmdk_file_name): os.rename(image_vmdk_file_name, converted_file_name) else: # 2. download qcow2 file from glance to local # tmp_dir = '/hctemp' self._update_vm_task_state( instance, task_state=vcloud_task_states.DOWNLOADING) metadata = IMAGE_API.get(context, image_uuid) file_size = int(metadata['size']) read_iter = IMAGE_API.download(context, image_uuid) glance_file_handle = util.GlanceFileRead(read_iter) orig_file_name = CONF.vcloud.vcloud_conversion_dir + \ '/' + image_uuid + '.tmp' orig_file_handle = fileutils.file_open(orig_file_name, "wb") util.start_transfer(context, glance_file_handle, file_size, write_file_handle=orig_file_handle, task_state=vcloud_task_states.DOWNLOADING, instance=instance) # 3. convert to vmdk self._update_vm_task_state( instance, task_state=vcloud_task_states.CONVERTING) if metadata["disk_format"] == 'qcow2': convert_commond = "qemu-img convert -f %s -O %s %s %s" % \ ('qcow2', 'vmdk', orig_file_name, converted_file_name) convert_result = subprocess.call([convert_commond], shell=True) if convert_result != 0: LOG.error('convert qcow2 to vmdk failed') # do something, change metadata # file_size = os.path.getsize(converted_file_name) elif metadata["disk_format"] == 'raw': convert_commond = "qemu-img convert -f %s -O %s %s %s" % \ ('raw', 'vmdk', orig_file_name, converted_file_name) convert_result = subprocess.call([convert_commond], shell=True) if convert_result != 0: LOG.error('convert qcow2 to vmdk failed') # do something, change metadata # file_size = os.path.getsize(converted_file_name) else: os.rename(orig_file_name, converted_file_name) # 4. vmdk to ovf self._update_vm_task_state(instance, task_state=vcloud_task_states.PACKING) ovf_name = '%s/%s.ovf' % (CONF.vcloud.vcloud_conversion_dir, vm_uuid) vmx_name = '%s/base-%s.vmx' % (CONF.vcloud.vcloud_conversion_dir, vcloud_flavor_id) mk_ovf_cmd = "ovftool -o %s %s" % (vmx_name, ovf_name) mk_ovf_result = subprocess.call(mk_ovf_cmd, shell=True) if mk_ovf_result != 0: LOG.error('make ovf faild!') self._update_vm_task_state(instance, task_state=vm_task_state) return # add mac address to ovf if mac_address != '': self._add_mac_address_to_ovf(ovf_name, mac_address) # 5~6: UPLOAD ovf to vcloud and create a vm #todo:5. upload ovf to vcloud template, using image's uuid as template name #todo:6. create vm from template self._update_vm_task_state( instance, task_state=vcloud_task_states.NETWORK_CREATING) self.create_networks(network_info) for vif in network_info: net_name = vif['id'] self.plug_vifs(instance, network_info) self._update_vm_task_state(instance, task_state=vcloud_task_states.IMPORTING) vapp_name = self._get_vcloud_vapp_name(instance) if not net_name: if is_poweron: create_vapp_cmd = 'ovftool --powerOn' \ ' %s "vcloud://%s:%s@%s?org=%s&vdc=%s&vapp=%s"' % \ (ovf_name, user_name, password, vcloud_host, vorg_name, vdc_name, vapp_name) else: create_vapp_cmd = 'ovftool %s "vcloud://%s:%s@%s?org=%s&vdc=%s&vapp=%s"' % \ (ovf_name, user_name, password, vcloud_host, vorg_name, vdc_name, vapp_name) else: if is_poweron: create_vapp_cmd = 'ovftool --powerOn --net:"VM Network=%s"' \ ' %s "vcloud://%s:%s@%s?org=%s&vdc=%s&vapp=%s"' % \ (net_name, ovf_name, user_name, password, vcloud_host, vorg_name, vdc_name, vapp_name) else: create_vapp_cmd = 'ovftool --net:"VM Network=%s" %s "vcloud://%s:%s@%s?org=%s&vdc=%s&vapp=%s"' % \ (net_name, ovf_name, user_name, password, vcloud_host, vorg_name, vdc_name, vapp_name) fileutils.delete_if_exists( '%s/%s.mf' % (CONF.vcloud.vcloud_conversion_dir, vm_uuid)) create_vapp_cmd_result = subprocess.call(create_vapp_cmd, shell=True) if create_vapp_cmd_result != 0: LOG.error('create vapp faild!') self._update_vm_task_state(instance, task_state=vm_task_state) return self._update_vm_task_state(instance, task_state=vcloud_task_states.VM_CREATING) # import pdb # pdb.set_trace() if is_poweron: expected_vapp_status = VCLOUD_STATUS.POWERED_ON else: expected_vapp_status = VCLOUD_STATUS.POWERED_OFF vapp_name = self._get_vcloud_vapp_name(instance) vapp_status = self._get_vcloud_vapp_status(vapp_name) LOG.debug('vapp status: %s' % vapp_status) retry_times = 60 while vapp_status != expected_vapp_status and retry_times > 0: time.sleep(3) vapp_status = self._get_vcloud_vapp_status(vapp_name) LOG.debug('vapp status: %s' % vapp_status) retry_times = retry_times - 1 # 7. clean self._update_vm_task_state(instance, task_state=vm_task_state) os.chdir(CONF.vcloud.vcloud_conversion_dir) fileutils.delete_if_exists(orig_file_name) fileutils.delete_if_exists(ovf_name) fileutils.delete_if_exists(vm_uuid + '-disk1.vmdk') os.rename(converted_file_name, image_vmdk_file_name)
def spawn(self, context, instance, image_meta, injected_files, admin_password, network_info=None, block_device_info=None): mac_address = '' if len(network_info) > 0: mac_address = network_info[0]['address'] name = instance['name'] state = power_state.BUILDING # 0.get vorg, user name,password vdc from configuration file (only one # org) node_name = instance.node vorg_name = self._session.org user_name = self._session.username password = self._session.password vdc_name = self._session.vdc vcloud_host = self._session.host_ip # 1.1 get image id, vm info ,flavor info # image_uuid = instance.image_ref if 'id' in image_meta: # create from image image_uuid = image_meta['id'] else: # create from volume image_uuid = image_meta['properties']['image_id'] vm_uuid = instance.uuid vm_name = instance.name vm_hostname = instance.hostname vm_flavor_id = instance.get_flavor().flavorid # 1.3 (optional) is_poweron = True # 2~3 get vmdk file. if boot from volume ,check if the vmdk file exist os.chdir(CONF.vcloud.vcloud_conversion_dir) converted_file_name = CONF.vcloud.vcloud_conversion_dir + '/converted-file.vmdk' image_vmdk_file_name = '%s/%s.vmdk' % ( CONF.vcloud.vcloud_conversion_dir, image_uuid) orig_file_name = CONF.vcloud.vcloud_conversion_dir + '/' + image_uuid + '.tmp' block_device_mapping = driver.block_device_info_get_mapping( block_device_info) volume_file_name = '' if len(block_device_mapping) > 0: volume_id = block_device_mapping[0]['connection_info']['data'][ 'volume_id'] volume_file_name = '%s/%s.vmdk' % (CONF.vcloud.vcloud_volumes_dir, volume_id) if os.path.exists(volume_file_name): shutil.move(volume_file_name, converted_file_name) elif os.path.exists(image_vmdk_file_name): os.rename(image_vmdk_file_name, converted_file_name) else: # 2. download qcow2 file from glance to local # tmp_dir = '/hctemp' metadata = IMAGE_API.get(context, image_uuid) file_size = int(metadata['size']) read_iter = IMAGE_API.download(context, image_uuid) glance_file_handle = util.GlanceFileRead(read_iter) orig_file_name = CONF.vcloud.vcloud_conversion_dir + \ '/' + image_uuid + '.tmp' orig_file_handle = open(orig_file_name, "wb") util.start_transfer(context, glance_file_handle, file_size, write_file_handle=orig_file_handle) # 3. convert to vmdk if metadata["disk_format"] == 'qcow2': convert_commond = "qemu-img convert -f %s -O %s %s %s" % \ ('qcow2', 'vmdk', orig_file_name, converted_file_name) convert_result = subprocess.call([convert_commond], shell=True) if convert_result != 0: LOG.error('convert qcow2 to vmdk failed') # do something, change metadata # file_size = os.path.getsize(converted_file_name) elif metadata["disk_format"] == 'raw': convert_commond = "qemu-img convert -f %s -O %s %s %s" % \ ('raw', 'vmdk', orig_file_name, converted_file_name) convert_result = subprocess.call([convert_commond], shell=True) if convert_result != 0: LOG.error('convert qcow2 to vmdk failed') # do something, change metadata # file_size = os.path.getsize(converted_file_name) else: os.rename(orig_file_name, converted_file_name) # 4. vmdk to ovf ovf_name = '%s/%s.ovf' % (CONF.vcloud.vcloud_conversion_dir, vm_uuid) vmx_name = '%s/base-%s.vmx' % (CONF.vcloud.vcloud_conversion_dir, vm_flavor_id) mk_ovf_cmd = "ovftool -o %s %s" % (vmx_name, ovf_name) mk_ovf_result = subprocess.call(mk_ovf_cmd, shell=True) if mk_ovf_result != 0: LOG.error('make ovf faild!') return # add mac address to ovf if mac_address != '': self._add_mac_address_to_ovf(ovf_name, mac_address) # 5. upload ovf to vcloud template, using image's uuid as template name # 6. create vm from template self.create_networks(network_info) for vif in network_info: net_name = vif['id'] self.plug_vifs(instance, network_info) if is_poweron: create_vapp_cmd =\ 'ovftool --powerOn --net:"VM Network=%s"' \ ' %s "vcloud://%s:%s@%s?org=%s&vdc=%s&vapp=%s"' % \ (net_name, ovf_name, user_name, password, vcloud_host, vorg_name, vdc_name, vm_uuid) else: create_vapp_cmd = 'ovftool --net:"VM Network=%s" %s ' \ '"vcloud://%s:%s@%s?org=%s&vdc=%s&vapp=%s"' % \ (net_name, ovf_name, user_name, password, vcloud_host, vorg_name, vdc_name, vm_uuid) create_vapp_cmd_result = subprocess.call(create_vapp_cmd, shell=True) if mk_ovf_result != 0: LOG.error('create vapp faild!') return # 7. clean os.chdir(CONF.vcloud.vcloud_conversion_dir) fileutils.delete_if_exists(orig_file_name) fileutils.delete_if_exists(ovf_name) fileutils.delete_if_exists(vm_uuid + '-disk1.vmdk') os.rename(converted_file_name, image_vmdk_file_name)