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 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_iso(self, mock_execute): CONF.set_override('config_drive_format', 'iso9660') imagefile = None try: with configdrive.ConfigDriveBuilder(FakeInstanceMD()) as c: (fd, imagefile) = tempfile.mkstemp(prefix='cd_iso_') os.close(fd) c.make_drive(imagefile) mock_execute.assert_called_once_with('genisoimage', '-o', mock.ANY, '-ldots', '-allow-lowercase', '-allow-multidot', '-l', '-publisher', mock.ANY, '-quiet', '-J', '-r', '-V', 'config-2', mock.ANY, attempts=1, run_as_root=False) finally: if imagefile: fileutils.delete_if_exists(imagefile)
def _generate_configdrive(self, instance, node, network_info, extra_md=None, files=None): """Generate a config drive. :param instance: The instance object. :param node: The node object. :param network_info: Instance network information. :param extra_md: Optional, extra metadata to be added to the configdrive. :param files: Optional, a list of paths to files to be added to the configdrive. """ if not extra_md: extra_md = {} i_meta = instance_metadata.InstanceMetadata(instance, content=files, extra_md=extra_md, network_info=network_info) with tempfile.NamedTemporaryFile() as uncompressed: with configdrive.ConfigDriveBuilder(instance_md=i_meta) as cdb: cdb.make_drive(uncompressed.name) with tempfile.NamedTemporaryFile() as compressed: # compress config drive with gzip.GzipFile(fileobj=compressed, mode='wb') as gzipped: uncompressed.seek(0) shutil.copyfileobj(uncompressed, gzipped) # base64 encode config drive compressed.seek(0) return base64.b64encode(compressed.read())
def _create_config_drive(context, instance_path, instance, injected_files, network_info, admin_password): if CONF.config_drive_format != 'iso9660': raise exception.ConfigDriveUnsupportedFormat( format=CONF.config_drive_format) LOG.debug('Using config drive', instance=instance) extra_md = {} if admin_password: extra_md['admin_pass'] = admin_password inst_md = instance_metadata.InstanceMetadata(instance, content=injected_files, extra_md=extra_md, network_info=network_info, request_context=context) configdrive_iso = os.path.join(instance_path, 'cfgdrive.iso') LOG.debug('Creating config drive at %s', configdrive_iso, instance=instance) with configdrive.ConfigDriveBuilder(instance_md=inst_md) as cdb: cdb.make_drive(configdrive_iso) return configdrive_iso
def _create_config_drive(self, instance, injected_files, admin_password): if CONF.config_drive_format != 'iso9660': vmutils.HyperVException( _('Invalid config_drive_format "%s"') % CONF.config_drive_format) LOG.info(_('Using config drive for instance: %s'), instance=instance) extra_md = {} if admin_password and CONF.config_drive_inject_password: extra_md['admin_pass'] = admin_password inst_md = instance_metadata.InstanceMetadata(instance, content=injected_files, extra_md=extra_md) instance_path = self._pathutils.get_instance_path(instance['name']) configdrive_path_iso = os.path.join(instance_path, 'configdrive.iso') LOG.info(_('Creating config drive at %(path)s'), {'path': configdrive_path_iso}, instance=instance) with configdrive.ConfigDriveBuilder(instance_md=inst_md) as cdb: try: cdb.make_drive(configdrive_path_iso) except exception.ProcessExecutionError, e: LOG.error(_('Creating config drive failed with error: %s'), e, instance=instance) raise
def _setup_spawn_config_drive_mocks(self, use_cdrom): instance_metadata.InstanceMetadata(mox.IgnoreArg(), content=mox.IsA(list), extra_md=mox.IsA(dict)) m = fake.PathUtils.get_instance_dir(mox.IsA(str)) m.AndReturn(self._test_instance_dir) cdb = self._mox.CreateMockAnything() m = configdrive.ConfigDriveBuilder(instance_md=mox.IgnoreArg()) m.AndReturn(cdb) # __enter__ and __exit__ are required by "with" cdb.__enter__().AndReturn(cdb) cdb.make_drive(mox.IsA(str)) cdb.__exit__(None, None, None).AndReturn(None) if not use_cdrom: utils.execute(CONF.hyperv.qemu_img_cmd, 'convert', '-f', 'raw', '-O', 'vpc', mox.IsA(str), mox.IsA(str), attempts=1) fake.PathUtils.remove(mox.IsA(str)) m = vmutils.VMUtils.attach_ide_drive(mox.IsA(str), mox.IsA(str), mox.IsA(int), mox.IsA(int), mox.IsA(str)) m.WithSideEffects(self._add_disk)
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() c = configdrive.ConfigDriveBuilder() 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) c.cleanup() # Check cleanup self.assertFalse(os.path.exists(c.tempdir)) finally: if imagefile: utils.delete_if_exists(imagefile)
def test_create_configdrive_vfat(self, mock_trycmd, mock_execute, mock_mkfs): CONF.set_override('config_drive_format', 'vfat') imagefile = None try: with configdrive.ConfigDriveBuilder(FakeInstanceMD()) as c: (fd, imagefile) = tempfile.mkstemp(prefix='cd_vfat_') os.close(fd) c.make_drive(imagefile) mock_mkfs.assert_called_once_with('vfat', mock.ANY, label='config-2') mock_trycmd.assert_called_once_with('mount', '-o', mock.ANY, mock.ANY, mock.ANY, run_as_root=True) mock_execute.assert_called_once_with('umount', mock.ANY, run_as_root=True) # 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 configure_container_configdrive(self, container_config, instance, injected_files): LOG.debug('Creating LXD config drive') if CONF.config_drive_format not in ('fs', None): msg = (_('Invalid config drive format: %s') % CONF.config_drive_format) raise exception.InstancePowerOnFailure(reason=msg) LOG.info(_LI('Using config drive for instance'), instance=instance) extra_md = {} inst_md = instance_metadata.InstanceMetadata(instance, content=injected_files, extra_md=extra_md) name = instance.name try: with configdrive.ConfigDriveBuilder(instance_md=inst_md) as cdb: container_configdrive = ( self.container_dir.get_container_configdrive(name) ) cdb.make_drive(container_configdrive) container_config = self.configure_disk_path(container_config, 'configdrive', instance) except Exception as e: with excutils.save_and_reraise_exception(): LOG.error(_LE('Creating config drive failed with error: %s'), e, instance=instance) return container_config
def _create_cfg_dr_iso(self, instance, injected_files, network_info, admin_pass=None): """Creates an ISO file that contains the injected files. Used for config drive. :param instance: The VM instance from OpenStack. :param injected_files: A list of file paths that will be injected into the ISO. :param network_info: The network_info from the nova spawn method. :param admin_pass: Optional password to inject for the VM. :return iso_path: The path to the ISO :return file_name: The file name for the ISO """ LOG.info("Creating config drive.", instance=instance) extra_md = {} if admin_pass is not None: extra_md['admin_pass'] = admin_pass # Sanitize the vifs for the network config network_info = self._sanitize_network_info(network_info) inst_md = instance_metadata.InstanceMetadata(instance, content=injected_files, extra_md=extra_md, network_info=network_info) if not os.path.exists(_VOPT_TMPDIR): os.mkdir(_VOPT_TMPDIR) file_name = pvm_util.sanitize_file_name_for_api( instance.name, prefix='cfg_', suffix='.iso', max_len=pvm_const.MaxLen.VOPT_NAME) iso_path = os.path.join(_VOPT_TMPDIR, file_name) with configdrive.ConfigDriveBuilder(instance_md=inst_md) as cdb: LOG.info("Config drive ISO being built in %s.", iso_path, instance=instance) # There may be an OSError exception when create the config drive. # If so, retry the operation before raising. @retrying.retry( retry_on_exception=lambda exc: isinstance(exc, OSError), stop_max_attempt_number=2) def _make_cfg_drive(iso_path): cdb.make_drive(iso_path) try: _make_cfg_drive(iso_path) return iso_path, file_name except OSError: with excutils.save_and_reraise_exception(logger=LOG): LOG.exception("Config drive ISO could not be built", instance=instance)
def _create_ext4_ploop(self, calls): imagefile = None with mock.patch.object(utils, 'execute', return_value=('', '')) as ex: with configdrive.ConfigDriveBuilder(FakeInstanceMD()) as c: imagefile = "/tmp/cd_ext4_" + str(uuid.uuid4())[:8] c.make_drive(imagefile, image_type='ploop') ex.assert_has_calls(calls) return imagefile
def _create_cfg_dr_iso(self, instance, injected_files, network_info, iso_path, admin_pass=None): """Creates an ISO file that contains the injected files. Used for config drive. :param instance: The VM instance from OpenStack. :param injected_files: A list of file paths that will be injected into the ISO. :param network_info: The network_info from the nova spawn method. :param iso_path: The absolute file path for the new ISO :param admin_pass: Optional password to inject for the VM. """ LOG.info("Creating config drive.", instance=instance) extra_md = {} if admin_pass is not None: extra_md['admin_pass'] = admin_pass # Sanitize the vifs for the network config network_info = self._sanitize_network_info(network_info) inst_md = instance_metadata.InstanceMetadata(instance, content=injected_files, extra_md=extra_md, network_info=network_info) # fix instance uuid to match uuid assigned to VM inst_md.uuid = vm.get_pvm_uuid(instance).lower() with configdrive.ConfigDriveBuilder(instance_md=inst_md) as cdb: LOG.info("Config drive ISO building to path %(iso_path)s.", {'iso_path': iso_path}, instance=instance) # In case, if there's an OSError related failure while # creating config drive, retry make drive operation. def _retry_on_oserror(exc): return isinstance(exc, OSError) @retrying.retry(retry_on_exception=_retry_on_oserror, stop_max_attempt_number=2) def _make_cfg_drive(iso_path): cdb.make_drive(iso_path) try: _make_cfg_drive(iso_path) except OSError: with excutils.save_and_reraise_exception(logger=LOG): # If we get here, that means there's an exception during # second attempt, log the same and fail the deploy # operation. LOG.exception("Config drive ISO could not be built.", instance=instance)
def _create_config_drive(self, context, instance, injected_files, admin_password, network_info, rescue=False): if CONF.config_drive_format != 'iso9660': raise exception.ConfigDriveUnsupportedFormat( format=CONF.config_drive_format) LOG.info('Using config drive for instance', instance=instance) extra_md = {} if admin_password and CONF.hyperv.config_drive_inject_password: extra_md['admin_pass'] = admin_password inst_md = instance_metadata.InstanceMetadata(instance, content=injected_files, extra_md=extra_md, network_info=network_info, request_context=context) configdrive_path_iso = self._pathutils.get_configdrive_path( instance.name, constants.DVD_FORMAT, rescue=rescue) LOG.info('Creating config drive at %(path)s', {'path': configdrive_path_iso}, instance=instance) with configdrive.ConfigDriveBuilder(instance_md=inst_md) as cdb: try: cdb.make_drive(configdrive_path_iso) except processutils.ProcessExecutionError as e: with excutils.save_and_reraise_exception(): LOG.error('Creating config drive failed with ' 'error: %s', e, instance=instance) if not CONF.hyperv.config_drive_cdrom: configdrive_path = self._pathutils.get_configdrive_path( instance.name, constants.DISK_FORMAT_VHD, rescue=rescue) utils.execute(CONF.hyperv.qemu_img_cmd, 'convert', '-f', 'raw', '-O', 'vpc', configdrive_path_iso, configdrive_path, attempts=1) self._pathutils.remove(configdrive_path_iso) else: configdrive_path = configdrive_path_iso return configdrive_path
def _create_cfg_dr_iso(self, instance, injected_files, network_info, admin_pass=None): """Creates an ISO file that contains the injected files. Used for config drive. :param instance: The VM instance from OpenStack. :param injected_files: A list of file paths that will be injected into the ISO. :param network_info: The network_info from the nova spawn method. :param admin_pass: Optional password to inject for the VM. :return iso_path: The path to the ISO :return file_name: The file name for the ISO """ LOG.info(_LI("Creating config drive for instance: %s"), instance.name, instance=instance) extra_md = {} if admin_pass is not None: extra_md['admin_pass'] = admin_pass # Sanitize the vifs for the network config network_info = self._sanitize_network_info(network_info) inst_md = instance_metadata.InstanceMetadata(instance, content=injected_files, extra_md=extra_md, network_info=network_info) # Make sure the path exists. im_path = CONF.powervm.image_meta_local_path if not os.path.exists(im_path): os.mkdir(im_path) file_name = pvm_util.sanitize_file_name_for_api( instance.name, prefix=CFG_DRV_PREFIX, suffix=CFG_DRV_SUFFIX, max_len=pvm_const.MaxLen.VOPT_NAME) iso_path = os.path.join(im_path, file_name) with configdrive.ConfigDriveBuilder(instance_md=inst_md) as cdb: LOG.info(_LI("Config drive ISO being built for instance %(inst)s " "building to path %(iso_path)s."), { 'inst': instance.name, 'iso_path': iso_path }, instance=instance) cdb.make_drive(iso_path) return iso_path, file_name
def _create_config_drive(self, instance, injected_files, admin_password): if CONF.config_drive_format != 'iso9660': vmutils.HyperVException( _('Invalid config_drive_format "%s"') % CONF.config_drive_format) LOG.info(_('Using config drive for instance: %s'), instance=instance) extra_md = {} if admin_password and CONF.hyperv.config_drive_inject_password: extra_md['admin_pass'] = admin_password inst_md = instance_metadata.InstanceMetadata(instance, content=injected_files, extra_md=extra_md) instance_path = self._pathutils.get_instance_dir(instance['name']) configdrive_path_iso = os.path.join(instance_path, 'configdrive.iso') LOG.info(_('Creating config drive at %(path)s'), {'path': configdrive_path_iso}, instance=instance) with configdrive.ConfigDriveBuilder(instance_md=inst_md) as cdb: try: cdb.make_drive(configdrive_path_iso) except processutils.ProcessExecutionError as e: with excutils.save_and_reraise_exception(): LOG.error(_('Creating config drive failed with error: %s'), e, instance=instance) if not CONF.hyperv.config_drive_cdrom: drive_type = constants.IDE_DISK configdrive_path = os.path.join(instance_path, 'configdrive.vhd') utils.execute(CONF.hyperv.qemu_img_cmd, 'convert', '-f', 'raw', '-O', 'vpc', configdrive_path_iso, configdrive_path, attempts=1) self._pathutils.remove(configdrive_path_iso) else: drive_type = constants.IDE_DVD configdrive_path = configdrive_path_iso self._vmutils.attach_ide_drive(instance['name'], configdrive_path, 1, 0, drive_type)
def _create_config_drive(self, instance, injected_files, admin_password, network_info): if CONF.config_drive_format != 'iso9660': raise vmutils.UnsupportedConfigDriveFormatException( _('Invalid config_drive_format "%s"') % CONF.config_drive_format) LOG.info(_LI('Using config drive for instance'), instance=instance) extra_md = {} if admin_password and CONF.hyperv.config_drive_inject_password: extra_md['admin_pass'] = admin_password inst_md = instance_metadata.InstanceMetadata(instance, content=injected_files, extra_md=extra_md, network_info=network_info) instance_path = self._pathutils.get_instance_dir(instance.name) configdrive_path_iso = os.path.join(instance_path, 'configdrive.iso') LOG.info(_LI('Creating config drive at %(path)s'), {'path': configdrive_path_iso}, instance=instance) with configdrive.ConfigDriveBuilder(instance_md=inst_md) as cdb: try: cdb.make_drive(configdrive_path_iso) except processutils.ProcessExecutionError as e: with excutils.save_and_reraise_exception(): LOG.error(_LE('Creating config drive failed with ' 'error: %s'), e, instance=instance) if not CONF.hyperv.config_drive_cdrom: configdrive_path = os.path.join(instance_path, 'configdrive.vhd') utils.execute(CONF.hyperv.qemu_img_cmd, 'convert', '-f', 'raw', '-O', 'vpc', configdrive_path_iso, configdrive_path, attempts=1) self._pathutils.remove(configdrive_path_iso) else: configdrive_path = configdrive_path_iso return configdrive_path
def _create_cfg_dr_iso(self, instance, injected_files, network_info, iso_path, admin_pass=None): """Creates an ISO file that contains the injected files. Used for config drive. :param instance: The VM instance from OpenStack. :param injected_files: A list of file paths that will be injected into the ISO. :param network_info: The network_info from the nova spawn method. :param iso_path: The absolute file path for the new ISO :param admin_pass: Optional password to inject for the VM. """ LOG.info("Creating config drive.", instance=instance) extra_md = {} if admin_pass is not None: extra_md['admin_pass'] = admin_pass # Sanitize the vifs for the network config network_info = self._sanitize_network_info(network_info) inst_md = instance_metadata.InstanceMetadata(instance, content=injected_files, extra_md=extra_md, network_info=network_info) with configdrive.ConfigDriveBuilder(instance_md=inst_md) as cdb: LOG.info("Config drive ISO being built in %s.", iso_path, instance=instance) # There may be an OSError exception when create the config drive. # If so, retry the operation before raising. @retrying.retry( retry_on_exception=lambda exc: isinstance(exc, OSError), stop_max_attempt_number=2) def _make_cfg_drive(iso_path): cdb.make_drive(iso_path) try: _make_cfg_drive(iso_path) except OSError: with excutils.save_and_reraise_exception(logger=LOG): LOG.exception("Config drive ISO could not be built", instance=instance)
def _create_config_drive(self, instance, injected_files, admin_password): if CONF.config_drive_format != 'iso9660': vmutils.HyperVException( _('Invalid config_drive_format "%s"') % CONF.config_drive_format) LOG.info(_('Using config drive'), instance=instance) extra_md = {} if admin_password and CONF.config_drive_inject_password: extra_md['admin_pass'] = admin_password inst_md = instance_metadata.InstanceMetadata(instance, content=injected_files, extra_md=extra_md) instance_path = self._vmutils.get_instance_path(instance['name']) configdrive_path_iso = os.path.join(instance_path, 'configdrive.iso') LOG.info(_('Creating config drive at %(path)s'), {'path': configdrive_path_iso}, instance=instance) cdb = configdrive.ConfigDriveBuilder(instance_md=inst_md) try: cdb.make_drive(configdrive_path_iso) finally: cdb.cleanup() if not CONF.config_drive_cdrom: drive_type = constants.IDE_DISK configdrive_path = os.path.join(instance_path, 'configdrive.vhd') utils.execute(CONF.qemu_img_cmd, 'convert', '-f', 'raw', '-O', 'vpc', configdrive_path_iso, configdrive_path, attempts=1) os.remove(configdrive_path_iso) else: drive_type = constants.IDE_DVD configdrive_path = configdrive_path_iso self._attach_ide_drive(instance['name'], configdrive_path, 1, 0, drive_type)
def test_create_configdrive_vfat(self): imagefile = None try: self.mox.StubOutWithMock(virtutils, 'mkfs') self.mox.StubOutWithMock(utils, 'execute') self.mox.StubOutWithMock(utils, 'trycmd') virtutils.mkfs('vfat', mox.IgnoreArg(), label='config-2').AndReturn(None) utils.trycmd('mount', '-o', 'loop', mox.IgnoreArg(), mox.IgnoreArg(), run_as_root=True).AndReturn((None, None)) utils.trycmd('chown', 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() c = configdrive.ConfigDriveBuilder() 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) c.cleanup() # 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: utils.delete_if_exists(imagefile)
def _create_cfg_dr_iso(self, instance, injected_files, network_info, admin_pass=None): """Creates an ISO file that contains the injected files. Used for config drive. :param instance: The VM instance from OpenStack. :param injected_files: A list of file paths that will be injected into the ISO. :param network_info: The network_info from the nova spawn method. :param admin_pass: Optional password to inject for the VM. :return iso_path: The path to the ISO :return file_name: The file name for the ISO """ LOG.info("Creating config drive.", instance=instance) extra_md = {} if admin_pass is not None: extra_md['admin_pass'] = admin_pass # Sanitize the vifs for the network config network_info = self._sanitize_network_info(network_info) inst_md = instance_metadata.InstanceMetadata(instance, content=injected_files, extra_md=extra_md, network_info=network_info) # Make sure the path exists. im_path = CONF.powervm.image_meta_local_path if not os.path.exists(im_path): os.mkdir(im_path) file_name = pvm_util.sanitize_file_name_for_api( instance.name, prefix=CFG_DRV_PREFIX, suffix=CFG_DRV_SUFFIX, max_len=pvm_const.MaxLen.VOPT_NAME) iso_path = os.path.join(im_path, file_name) with configdrive.ConfigDriveBuilder(instance_md=inst_md) as cdb: LOG.info("Config drive ISO building to path %(iso_path)s.", {'iso_path': iso_path}, instance=instance) # In case, if there's an OSError related failure while # creating config drive, retry make drive operation. def _retry_on_oserror(exc): return isinstance(exc, OSError) @retrying.retry(retry_on_exception=_retry_on_oserror, stop_max_attempt_number=2) def _make_cfg_drive(iso_path): cdb.make_drive(iso_path) try: _make_cfg_drive(iso_path) return iso_path, file_name except OSError: with excutils.save_and_reraise_exception(logger=LOG): # If we get here, that means there's an exception during # second attempt, log the same and fail the deploy # operation. LOG.exception("Config drive ISO could not be built.", instance=instance)
def _add_configdrive(self, context, instance, injected_files, admin_password, network_info): """Create configdrive for the instance.""" if CONF.config_drive_format != 'iso9660': raise exception.ConfigDriveUnsupportedFormat( format=CONF.config_drive_format) container = self.client.containers.get(instance.name) container_id_map = container.config[ 'volatile.last_state.idmap'].split(',') storage_id = container_id_map[2].split(':')[1] extra_md = {} if admin_password: extra_md['admin_pass'] = admin_password inst_md = instance_metadata.InstanceMetadata( instance, content=injected_files, extra_md=extra_md, network_info=network_info, request_context=context) iso_path = os.path.join( common.InstanceAttributes(instance).instance_dir, 'configdrive.iso') with configdrive.ConfigDriveBuilder(instance_md=inst_md) as cdb: try: cdb.make_drive(iso_path) except processutils.ProcessExecutionError as e: with excutils.save_and_reraise_exception(): LOG.error('Creating config drive failed with ' 'error: %s', e, instance=instance) configdrive_dir = os.path.join( nova.conf.CONF.instances_path, instance.name, 'configdrive') if not os.path.exists(configdrive_dir): fileutils.ensure_tree(configdrive_dir) with utils.tempdir() as tmpdir: mounted = False try: _, err = utils.execute('mount', '-o', 'loop,uid=%d,gid=%d' % (os.getuid(), os.getgid()), iso_path, tmpdir, run_as_root=True) mounted = True # Copy and adjust the files from the ISO so that we # dont have the ISO mounted during the life cycle of the # instance and the directory can be removed once the instance # is terminated for ent in os.listdir(tmpdir): shutil.copytree(os.path.join(tmpdir, ent), os.path.join(configdrive_dir, ent)) utils.execute('chmod', '-R', '775', configdrive_dir, run_as_root=True) utils.execute('chown', '-R', storage_id, configdrive_dir, run_as_root=True) finally: if mounted: utils.execute('umount', tmpdir, run_as_root=True) return configdrive_dir
def _add_driver_fields(self, node, instance, image_meta, flavor, admin_pass=None, files=None, network_info=None, preserve_ephemeral=None): icli = client_wrapper.IronicClientWrapper() patch = patcher.create(node).get_deploy_patch(instance, image_meta, flavor, preserve_ephemeral) # Associate the node with an instance patch.append({ 'path': '/instance_uuid', 'op': 'add', 'value': instance['uuid'] }) if configdrive.required_by(instance): LOG.info(_('Using config drive'), instance=instance) extra_md = {} if admin_pass: extra_md['admin_pass'] = admin_pass inst_md = instance_metadata.InstanceMetadata( instance, content=files, extra_md=extra_md, network_info=network_info) fd, configdrive_path = tempfile.mkstemp() os.close(fd) with configdrive.ConfigDriveBuilder(instance_md=inst_md) as cdb: try: cdb.make_drive(configdrive_path) except processutils.ProcessExecutionError as e: with excutils.save_and_reraise_exception(): LOG.error(_('Creating config drive failed ' 'with error: %s'), e, instance=instance) # gzip the configdrive. with open(configdrive_path, "rb") as configdrive_fh: configdrive_payload = base64.b64encode( zlib.compress(configdrive_fh.read())) os.remove(configdrive_path) patch.append({ 'path': '/instance_info/config_drive', 'op': 'add', 'value': configdrive_payload }) try: icli.call('node.update', node.uuid, patch) except ironic_exception.BadRequest: msg = (_("Failed to add deploy parameters on node %(node)s " "when provisioning the instance %(instance)s") % { 'node': node.uuid, 'instance': instance['uuid'] }) LOG.error(msg) raise exception.InstanceDeployFailure(msg)
def _add_configdrive(self, instance, injected_files): """Configure the config drive for the container :param instance: nova instance object :param injected_files: instance injected files """ LOG.debug('add_configdrive called for instance', instance=instance) extra_md = {} inst_md = instance_metadata.InstanceMetadata(instance, content=injected_files, extra_md=extra_md) # Create the ISO image so we can inject the contents of the ISO # into the container iso_path = os.path.join(self.instance_dir, 'configdirve.iso') with configdrive.ConfigDriveBuilder(instance_md=inst_md) as cdb: try: cdb.make_drive(iso_path) except Exception as e: with excutils.save_and_reraise_exception(): LOG.error(_LE('Creating config drive failed with error: ' '%s'), e, instance=instance) # Copy the metadata info from the ISO into the container configdrive_dir = \ self.container_dir.get_container_configdrive(instance.name) with utils.tempdir() as tmpdir: mounted = False try: _, err = utils.execute('mount', '-o', 'loop,uid=%d,gid=%d' % (os.getuid(), os.getgid()), iso_path, tmpdir, run_as_root=True) mounted = True # Copy and adjust the files from the ISO so that we # dont have the ISO mounted during the life cycle of the # instance and the directory can be removed once the instance # is terminated for ent in os.listdir(tmpdir): shutil.copytree(os.path.join(tmpdir, ent), os.path.join(configdrive_dir, ent)) utils.execute('chmod', '-R', '775', configdrive_dir, run_as_root=True) utils.execute('chown', '-R', '%s:%s' % (self._uid_map('/etc/subuid').rstrip(), self._uid_map('/etc/subgid').rstrip()), configdrive_dir, run_as_root=True) finally: if mounted: utils.execute('umount', tmpdir, run_as_root=True)
def _add_configdrive(self, context, instance, injected_files, admin_password, network_info): """Create configdrive for the instance.""" if CONF.config_drive_format != 'iso9660': raise exception.ConfigDriveUnsupportedFormat( format=CONF.config_drive_format) container = self.client.containers.get(instance.name) storage_id = 0 """ Determine UID shift used for container uid mapping Sample JSON config from LXD { "volatile.apply_template": "create", ... "volatile.last_state.idmap": "[ { \"Isuid\":true, \"Isgid\":false, \"Hostid\":100000, \"Nsid\":0, \"Maprange\":65536 }, { \"Isuid\":false, \"Isgid\":true, \"Hostid\":100000, \"Nsid\":0, \"Maprange\":65536 }] ", "volatile.tap5fd6808a-7b.name": "eth0" } """ container_id_map = json.loads( container.config['volatile.last_state.idmap']) uid_map = filter(lambda id_map: id_map.get("Isuid"), container_id_map) if uid_map: storage_id = uid_map[0].get("Hostid", 0) else: # privileged containers does not have uid/gid mapping # LXD API return nothing pass extra_md = {} if admin_password: extra_md['admin_pass'] = admin_password inst_md = instance_metadata.InstanceMetadata( instance, content=injected_files, extra_md=extra_md, network_info=network_info, request_context=context) iso_path = os.path.join( common.InstanceAttributes(instance).instance_dir, 'configdrive.iso') with configdrive.ConfigDriveBuilder(instance_md=inst_md) as cdb: try: cdb.make_drive(iso_path) except processutils.ProcessExecutionError as e: with excutils.save_and_reraise_exception(): LOG.error('Creating config drive failed with ' 'error: %s', e, instance=instance) configdrive_dir = os.path.join( nova.conf.CONF.instances_path, instance.name, 'configdrive') if not os.path.exists(configdrive_dir): fileutils.ensure_tree(configdrive_dir) with utils.tempdir() as tmpdir: mounted = False try: _, err = utils.execute('mount', '-o', 'loop,uid=%d,gid=%d' % (os.getuid(), os.getgid()), iso_path, tmpdir, run_as_root=True) mounted = True # Copy and adjust the files from the ISO so that we # dont have the ISO mounted during the life cycle of the # instance and the directory can be removed once the instance # is terminated for ent in os.listdir(tmpdir): shutil.copytree(os.path.join(tmpdir, ent), os.path.join(configdrive_dir, ent)) utils.execute('chmod', '-R', '775', configdrive_dir, run_as_root=True) utils.execute('chown', '-R', '%s:%s' % (storage_id, storage_id), configdrive_dir, run_as_root=True) finally: if mounted: utils.execute('umount', tmpdir, run_as_root=True) return configdrive_dir