Exemple #1
0
    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 _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())
Exemple #3
0
def fake_InstanceMetadata(stubs,
                          inst_data,
                          address=None,
                          sgroups=None,
                          content=None,
                          extra_md=None,
                          vd_driver=None,
                          network_info=None,
                          network_metadata=None):
    content = content or []
    extra_md = extra_md or {}
    if sgroups is None:
        sgroups = [dict(test_security_group.fake_secgroup, name='default')]

    def sg_get(*args, **kwargs):
        return sgroups

    stubs.Set(api, 'security_group_get_by_instance', sg_get)
    return base.InstanceMetadata(inst_data,
                                 address=address,
                                 content=content,
                                 extra_md=extra_md,
                                 vd_driver=vd_driver,
                                 network_info=network_info,
                                 network_metadata=network_metadata)
Exemple #4
0
    def _create_config_drive(self, context, instance_path, instance,
                             injected_files, admin_password):
        if CONF.config_drive_format not in ['tgz', 'iso9660']:
            msg = (_("Invalid config drive format %s") %
                   CONF.config_drive_format)
            LOG.debug(msg)
            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,
                                                     request_context=context)
        # network_metadata will prevent the hostname of the instance from
        # being set correctly, so clean the value
        inst_md.network_metadata = None

        configdrive_tgz = os.path.join(instance_path, 'cfgdrive.tgz')

        LOG.debug('Creating config drive at %s',
                  configdrive_tgz,
                  instance=instance)
        with zvmconfigdrive.ZVMConfigDriveBuilder(instance_md=inst_md) as cdb:
            cdb.make_drive(configdrive_tgz)

        return configdrive_tgz
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
Exemple #6
0
    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 add_instance_metadata(self):
     inst_md = instance_metadata.InstanceMetadata(self.instance)
     for (path, value) in inst_md.metadata_for_config_drive(self.injected):
         self._add_file(path, value)
         LOG.debug(_('Added %(filepath)s to config drive'),
                   {'filepath': path},
                   instance=self.instance)
Exemple #8
0
    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)

        with configdrive.config_drive_helper(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
Exemple #9
0
    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)
Exemple #10
0
    def test_InstanceMetadata_uses_passed_network_info(self):
        network_info = {"a": "b"}

        self.mox.StubOutWithMock(netutils, "get_injected_network_template")
        netutils.get_injected_network_template(network_info).AndReturn(False)
        self.mox.ReplayAll()

        base.InstanceMetadata(INSTANCES[0], network_info=network_info)
Exemple #11
0
    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)
Exemple #12
0
    def test_InstanceMetadata_uses_passed_network_info(self):
        network_info = []

        self.mox.StubOutWithMock(netutils, "get_injected_network_template")
        netutils.get_injected_network_template(network_info).AndReturn(False)
        self.mox.ReplayAll()

        base.InstanceMetadata(fake_inst_obj(self.context),
                              network_info=network_info)
Exemple #13
0
    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
Exemple #14
0
def fake_InstanceMetadata(stubs, inst_data, address=None, sgroups=None):

    if sgroups is None:
        sgroups = [{'name': 'default'}]

    def sg_get(*args, **kwargs):
        return sgroups

    stubs.Set(api, 'security_group_get_by_instance', sg_get)
    return base.InstanceMetadata(inst_data, address=address)
Exemple #15
0
    def test_InstanceMetadata_queries_network_API_when_needed(self):
        network_info_from_api = []

        self.mox.StubOutWithMock(netutils, "get_injected_network_template")

        netutils.get_injected_network_template(
            network_info_from_api).AndReturn(False)

        self.mox.ReplayAll()

        base.InstanceMetadata(fake_inst_obj(self.context))
Exemple #16
0
    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
Exemple #17
0
    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)
Exemple #18
0
def fake_InstanceMetadata(stubs, inst_data, address=None,
                          sgroups=None, content=[], extra_md={},
                          vd_driver=None):

    if sgroups is None:
        sgroups = [{'name': 'default'}]

    def sg_get(*args, **kwargs):
        return sgroups

    stubs.Set(api, 'security_group_get_by_instance', sg_get)
    return base.InstanceMetadata(inst_data, address=address,
        content=content, extra_md=extra_md,
        vd_driver=vd_driver)
Exemple #19
0
    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
Exemple #20
0
    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)
Exemple #21
0
    def test_InstanceMetadata_queries_network_API_when_needed(self):
        network_info_from_api = []

        self.mox.StubOutWithMock(network_api.API, "get_instance_nw_info")

        network_api.API.get_instance_nw_info(
            mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(network_info_from_api)

        self.mox.StubOutWithMock(netutils, "get_injected_network_template")

        netutils.get_injected_network_template(
            network_info_from_api).AndReturn(False)

        self.mox.ReplayAll()

        base.InstanceMetadata(INSTANCES[0])
Exemple #22
0
    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)
Exemple #23
0
    def _create_config_drive(self, context, instance_path, instance,
                             injected_files, admin_password, commands,
                             linuxdist):
        if CONF.config_drive_format not in ['tgz', 'iso9660']:
            msg = (_("Invalid config drive format %s") %
                   CONF.config_drive_format)
            raise exception.ZVMConfigDriveError(msg=msg)

        LOG.debug('Using config drive', instance=instance)

        extra_md = {}
        if admin_password:
            extra_md['admin_pass'] = admin_password

        udev_settle = linuxdist.get_znetconfig_contents()
        if udev_settle:
            if len(commands) == 0:
                znetconfig = '\n'.join(('#!/bin/bash', udev_settle))
            else:
                znetconfig = '\n'.join(('#!/bin/bash', commands, udev_settle))
            znetconfig += '\nrm -rf /tmp/znetconfig.sh\n'
            # Create a temp file in instance to execute above commands
            net_cmd_file = []
            net_cmd_file.append(('/tmp/znetconfig.sh', znetconfig))  # nosec
            injected_files.extend(net_cmd_file)
            # injected_files.extend(('/tmp/znetconfig.sh', znetconfig))

        inst_md = instance_metadata.InstanceMetadata(instance,
                                                     content=injected_files,
                                                     extra_md=extra_md,
                                                     request_context=context)
        # network_metadata will prevent the hostname of the instance from
        # being set correctly, so clean the value
        inst_md.network_metadata = None

        configdrive_tgz = os.path.join(instance_path, 'cfgdrive.tgz')

        LOG.debug('Creating config drive at %s' % configdrive_tgz,
                  instance=instance)
        with zvmconfigdrive.ZVMConfigDriveBuilder(instance_md=inst_md) as cdb:
            cdb.make_drive(configdrive_tgz)

        return configdrive_tgz
Exemple #24
0
 def test_InstanceMetadata_invoke_metadata_for_config_drive(self):
     inst = self.instance.obj_clone()
     inst_md = base.InstanceMetadata(inst)
     for (path, value) in inst_md.metadata_for_config_drive():
         self.assertIsNotNone(path)
Exemple #25
0
    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)
Exemple #26
0
    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
Exemple #27
0
    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)
Exemple #28
0
 def test_InstanceMetadata_invoke_metadata_for_config_drive(self):
     fakes.stub_out_key_pair_funcs(self.stubs)
     inst = self.instance.obj_clone()
     inst_md = base.InstanceMetadata(inst)
     for (path, value) in inst_md.metadata_for_config_drive():
         self.assertIsNotNone(path)
Exemple #29
0
    def test_InstanceMetadata_gets_network_metadata(self, mock_netutils):
        network_data = {'links': [], 'networks': [], 'services': []}
        mock_netutils.return_value = network_data

        md = base.InstanceMetadata(fake_inst_obj(self.context))
        self.assertEqual(network_data, md.network_metadata)
Exemple #30
0
    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)