Exemplo n.º 1
0
    def make_drive(self, path, image_type=IMAGE_TYPE_RAW):
        """Make the config drive.

        :param path: the path to place the config drive image at
        :param image_type: host side image format

        :raises ProcessExecuteError if a helper process has failed.
        """
        fs_format = CONF.config_drive_format
        if fs_format is None:
            if image_type == IMAGE_TYPE_RAW:
                fs_format = FS_FORMAT_ISO9660

        with utils.tempdir() as tmpdir:
            self._write_md_files(tmpdir)

            if image_type == IMAGE_TYPE_RAW:
                if fs_format not in (FS_FORMAT_VFAT, FS_FORMAT_ISO9660):
                    raise exception.ConfigDriveUnsupportedFormat(
                        format=fs_format,
                        image_type=image_type,
                        image_path=path)
                elif fs_format == FS_FORMAT_ISO9660:
                    self._make_iso9660(path, tmpdir)
                elif fs_format == FS_FORMAT_VFAT:
                    self._make_vfat(path, tmpdir)
            elif image_type == IMAGE_TYPE_PLOOP:
                self._make_ext4_ploop(path, tmpdir)
            else:
                raise exception.ConfigDriveUnsupportedFormat(
                    format=fs_format, image_type=image_type, image_path=path)
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
Exemplo n.º 3
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
Exemplo n.º 4
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
Exemplo n.º 5
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
Exemplo n.º 6
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)
        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