Esempio n. 1
0
    def _decrypt_image(self, context, encrypted_filename, encrypted_key,
                       encrypted_iv, decrypted_filename):
        elevated = context.elevated()
        try:
            key = self.cert_rpcapi.decrypt_text(
                elevated,
                project_id=context.project_id,
                text=base64.b64encode(encrypted_key))
        except Exception as exc:
            msg = _('Failed to decrypt private key: %s') % exc
            raise exception.PatronException(msg)
        try:
            iv = self.cert_rpcapi.decrypt_text(
                elevated,
                project_id=context.project_id,
                text=base64.b64encode(encrypted_iv))
        except Exception as exc:
            raise exception.PatronException(
                _('Failed to decrypt initialization '
                  'vector: %s') % exc)

        try:
            utils.execute('openssl', 'enc', '-d', '-aes-128-cbc', '-in',
                          '%s' % (encrypted_filename, ), '-K', '%s' % (key, ),
                          '-iv', '%s' % (iv, ), '-out',
                          '%s' % (decrypted_filename, ))
        except processutils.ProcessExecutionError as exc:
            raise exception.PatronException(
                _('Failed to decrypt image file '
                  '%(image_file)s: %(err)s') % {
                      'image_file': encrypted_filename,
                      'err': exc.stdout
                  })
Esempio n. 2
0
    def setup_os_root(self, root):
        LOG.debug("Inspecting guest OS root filesystem %s", root)
        mounts = self.handle.inspect_get_mountpoints(root)

        if len(mounts) == 0:
            raise exception.PatronException(
                _("No mount points found in %(root)s of %(imgfile)s") % {
                    'root': root,
                    'imgfile': self.imgfile
                })

        # the root directory must be mounted first
        mounts.sort(key=lambda mount: mount[0])

        root_mounted = False
        for mount in mounts:
            LOG.debug("Mounting %(dev)s at %(dir)s", {
                'dev': mount[1],
                'dir': mount[0]
            })
            try:
                self.handle.mount_options("", mount[1], mount[0])
                root_mounted = True
            except RuntimeError as e:
                msg = _("Error mounting %(device)s to %(dir)s in image"
                        " %(imgfile)s with libguestfs (%(e)s)") % \
                      {'imgfile': self.imgfile, 'device': mount[1],
                       'dir': mount[0], 'e': e}
                if root_mounted:
                    LOG.debug(msg)
                else:
                    raise exception.PatronException(msg)
Esempio n. 3
0
def create_shadow_table(migrate_engine,
                        table_name=None,
                        table=None,
                        **col_name_col_instance):
    """This method create shadow table for table with name ``table_name``
    or table instance ``table``.
    :param table_name: Autoload table with this name and create shadow table
    :param table: Autoloaded table, so just create corresponding shadow table.
    :param col_name_col_instance:   contains pair column_name=column_instance.
    column_instance is instance of Column. These params are required only for
    columns that have unsupported types by sqlite. For example BigInteger.
    :returns: The created shadow_table object.
    """
    meta = MetaData(bind=migrate_engine)

    if table_name is None and table is None:
        raise exception.PatronException(
            _("Specify `table_name` or `table` "
              "param"))
    if not (table_name is None or table is None):
        raise exception.PatronException(
            _("Specify only one param `table_name` "
              "`table`"))

    if table is None:
        table = Table(table_name, meta, autoload=True)

    columns = []
    for column in table.columns:
        if isinstance(column.type, NullType):
            new_column = oslodbutils._get_not_supported_column(
                col_name_col_instance, column.name)
            columns.append(new_column)
        else:
            columns.append(column.copy())

    shadow_table_name = db._SHADOW_TABLE_PREFIX + table.name
    shadow_table = Table(shadow_table_name,
                         meta,
                         *columns,
                         mysql_engine='InnoDB')
    try:
        shadow_table.create()
        return shadow_table
    except (db_exc.DBError, OperationalError):
        # NOTE(ekudryashova): At the moment there is a case in oslo.db code,
        # which raises unwrapped OperationalError, so we should catch it until
        # oslo.db would wraps all such exceptions
        LOG.info(repr(shadow_table))
        LOG.exception(_LE('Exception while creating table.'))
        raise exception.ShadowTableExists(name=shadow_table_name)
    except Exception:
        LOG.info(repr(shadow_table))
        LOG.exception(_LE('Exception while creating table.'))
Esempio n. 4
0
    def setup_os_inspect(self):
        LOG.debug("Inspecting guest OS image %s", self.imgfile)
        roots = self.handle.inspect_os()

        if len(roots) == 0:
            raise exception.PatronException(
                _("No operating system found in %s") % self.imgfile)

        if len(roots) != 1:
            LOG.debug("Multi-boot OS %(roots)s", {'roots': str(roots)})
            raise exception.PatronException(
                _("Multi-boot operating system found in %s") % self.imgfile)

        self.setup_os_root(roots[0])
Esempio n. 5
0
def get_my_linklocal(interface):
    try:
        if_str = execute('ip', '-f', 'inet6', '-o', 'addr', 'show', interface)
        condition = '\s+inet6\s+([0-9a-f:]+)/\d+\s+scope\s+link'
        links = [re.search(condition, x) for x in if_str[0].split('\n')]
        address = [w.group(1) for w in links if w is not None]
        if address[0] is not None:
            return address[0]
        else:
            msg = _('Link Local address is not found.:%s') % if_str
            raise exception.PatronException(msg)
    except Exception as ex:
        msg = _("Couldn't get Link Local IP of %(interface)s"
                " :%(ex)s") % {'interface': interface, 'ex': ex}
        raise exception.PatronException(msg)
Esempio n. 6
0
        def _wait_for_provision_state():
            node = _validate_instance_and_node(ironicclient, instance)
            if node.provision_state in (ironic_states.NOSTATE,
                                        ironic_states.CLEANING,
                                        ironic_states.CLEANFAIL,
                                        ironic_states.AVAILABLE):
                # From a user standpoint, the node is unprovisioned. If a node
                # gets into CLEANFAIL state, it must be fixed in Ironic, but we
                # can consider the instance unprovisioned.
                LOG.debug(
                    "Ironic node %(node)s is in state %(state)s, "
                    "instance is now unprovisioned.",
                    dict(node=node.uuid, state=node.provision_state),
                    instance=instance)
                raise loopingcall.LoopingCallDone()

            if data['tries'] >= CONF.ironic.api_max_retries:
                msg = (_("Error destroying the instance on node %(node)s. "
                         "Provision state still '%(state)s'.") % {
                             'state': node.provision_state,
                             'node': node.uuid
                         })
                LOG.error(msg)
                raise exception.PatronException(msg)
            else:
                data['tries'] += 1

            _log_ironic_polling('unprovision', node, instance)
Esempio n. 7
0
def find_network_with_bridge(session, bridge):
    """Return the network on which the bridge is attached, if found.
    The bridge is defined in the patron db and can be found either in the
    'bridge' or 'name_label' fields of the XenAPI network record.
    """
    expr = ('field "name__label" = "%s" or field "bridge" = "%s"' %
            (bridge, bridge))
    networks = session.network.get_all_records_where(expr)
    if len(networks) == 1:
        return networks.keys()[0]
    elif len(networks) > 1:
        raise exception.PatronException(
            _('Found non-unique network for bridge %s') % bridge)
    else:
        raise exception.PatronException(
            _('Found no network for bridge %s') % bridge)
Esempio n. 8
0
    def create_secret(self, usage_type, usage_id, password=None):
        """Create a secret.

        usage_type: one of 'iscsi', 'ceph', 'rbd' or 'volume'
                           'rbd' will be converted to 'ceph'.
        usage_id: name of resource in secret
        """
        secret_conf = vconfig.LibvirtConfigSecret()
        secret_conf.ephemeral = False
        secret_conf.private = False
        secret_conf.usage_id = usage_id
        if usage_type in ('rbd', 'ceph'):
            secret_conf.usage_type = 'ceph'
        elif usage_type == 'iscsi':
            secret_conf.usage_type = 'iscsi'
        elif usage_type == 'volume':
            secret_conf.usage_type = 'volume'
        else:
            msg = _("Invalid usage_type: %s")
            raise exception.PatronException(msg % usage_type)

        xml = secret_conf.to_xml()
        try:
            LOG.debug('Secret XML: %s' % xml)
            conn = self.get_connection()
            secret = conn.secretDefineXML(xml)
            if password is not None:
                secret.setValue(password)
            return secret
        except libvirt.libvirtError:
            with excutils.save_and_reraise_exception():
                LOG.error(_LE('Error defining a secret with XML: %s') % xml)
Esempio n. 9
0
def get_dev_prefix_for_disk_bus(disk_bus):
    """Determine the dev prefix for a disk bus.

       Determine the dev prefix to be combined
       with a disk number to fix a disk_dev.
       eg 'hd' for 'ide' bus can be used to
       form a disk dev 'hda'

       Returns the dev prefix or raises an
       exception if the disk bus is unknown.
    """

    if CONF.libvirt.disk_prefix:
        return CONF.libvirt.disk_prefix
    if disk_bus == "ide":
        return "hd"
    elif disk_bus == "virtio":
        return "vd"
    elif disk_bus == "xen":
        return "xvd"
    elif disk_bus == "scsi":
        return "sd"
    elif disk_bus == "usb":
        return "sd"
    elif disk_bus == "fdc":
        return "fd"
    elif disk_bus == "uml":
        return "ubd"
    elif disk_bus == "lxc":
        return None
    elif disk_bus == "sata":
        return "sd"
    else:
        raise exception.PatronException(
            _("Unable to determine disk prefix for %s") % disk_bus)
Esempio n. 10
0
def find_disk_dev_for_disk_bus(mapping, bus, last_device=False):
    """Identify a free disk dev name for a bus.

       Determines the possible disk dev names for
       the bus, and then checks them in order until
       it identifies one that is not yet used in the
       disk mapping. If 'last_device' is set, it will
       only consider the last available disk dev name.

       Returns the chosen disk_dev name, or raises an
       exception if none is available.
    """

    dev_prefix = get_dev_prefix_for_disk_bus(bus)
    if dev_prefix is None:
        return None

    max_dev = get_dev_count_for_disk_bus(bus)
    if last_device:
        devs = [max_dev - 1]
    else:
        devs = range(max_dev)

    for idx in devs:
        disk_dev = dev_prefix + chr(ord('a') + idx)
        if not has_disk_dev(mapping, disk_dev):
            return disk_dev

    raise exception.PatronException(
        _("No free disk device names for prefix '%s'"), dev_prefix)
Esempio n. 11
0
def get_disk_bus_for_disk_dev(virt_type, disk_dev):
    """Determine the disk bus for a disk device.

       Given a disk device like 'hda', 'sdf', 'xvdb', etc
       guess what the most appropriate disk bus is for
       the currently configured virtualization technology

       Returns the disk bus, or raises an Exception if
       the disk device prefix is unknown.
    """

    if disk_dev[:2] == 'hd':
        return "ide"
    elif disk_dev[:2] == 'sd':
        # Reverse mapping 'sd' is not reliable
        # there are many possible mappings. So
        # this picks the most likely mappings
        if virt_type == "xen":
            return "xen"
        elif virt_type == "parallels":
            return "sata"
        else:
            return "scsi"
    elif disk_dev[:2] == 'vd':
        return "virtio"
    elif disk_dev[:2] == 'fd':
        return "fdc"
    elif disk_dev[:3] == 'xvd':
        return "xen"
    elif disk_dev[:3] == 'ubd':
        return "uml"
    else:
        raise exception.PatronException(
            _("Unable to determine disk bus for '%s'") % disk_dev[:1])
Esempio n. 12
0
        def _parse_pci_device_string(dev_string):
            """Exctract information from the device string about the slot, the
            vendor and the product ID. The string is as follow:
                "Slot:\tBDF\nClass:\txxxx\nVendor:\txxxx\nDevice:\txxxx\n..."
            Return a dictionary with informations about the device.
            """
            slot_regex = _compile_hex(r"Slot:\t"
                                      r"((?:hex{4}:)?"  # Domain: (optional)
                                      r"hex{2}:"  # Bus:
                                      r"hex{2}\."  # Device.
                                      r"hex{1})")  # Function
            vendor_regex = _compile_hex(r"\nVendor:\t(hex+)")
            product_regex = _compile_hex(r"\nDevice:\t(hex+)")

            slot_id = slot_regex.findall(dev_string)
            vendor_id = vendor_regex.findall(dev_string)
            product_id = product_regex.findall(dev_string)

            if not slot_id or not vendor_id or not product_id:
                raise exception.PatronException(
                    _("Failed to parse information about"
                      " a pci device for passthrough"))

            type_pci = self._session.call_plugin_serialized(
                'xenhost', 'get_pci_type', slot_id[0])

            return {
                'label': '_'.join(['label', vendor_id[0], product_id[0]]),
                'vendor_id': vendor_id[0],
                'product_id': product_id[0],
                'address': slot_id[0],
                'dev_id': '_'.join(['pci', slot_id[0]]),
                'dev_type': type_pci,
                'status': 'available'
            }
Esempio n. 13
0
    def mount(self):
        """Mount a disk image, using the object attributes.

        The first supported means provided by the mount classes is used.

        True, or False is returned and the 'errors' attribute
        contains any diagnostics.
        """
        if self._mounter:
            raise exception.PatronException(_('image already mounted'))

        if not self.mount_dir:
            self.mount_dir = tempfile.mkdtemp(prefix=self.tmp_prefix)
            self._mkdir = True

        imgfmt = "raw"
        if self.use_cow:
            imgfmt = "qcow2"

        mounter = mount.Mount.instance_for_format(self.image, self.mount_dir,
                                                  self.partition, imgfmt)
        if mounter.do_mount():
            self._mounter = mounter
            return self._mounter.device
        else:
            LOG.debug(mounter.error)
            self._errors.append(mounter.error)
            return None
Esempio n. 14
0
def _max_attempts():
    max_attempts = CONF.scheduler_max_attempts
    if max_attempts < 1:
        raise exception.PatronException(
            _("Invalid value for "
              "'scheduler_max_attempts', must be >= 1"))
    return max_attempts
Esempio n. 15
0
    def __init__(self, source_type, driver_format, is_block_dev=False):
        """Image initialization.

        :source_type: block or file
        :driver_format: raw or qcow2
        :is_block_dev:
        """
        if (CONF.ephemeral_storage_encryption.enabled
                and not self._supports_encryption()):
            raise exception.PatronException(
                _('Incompatible settings: '
                  'ephemeral storage encryption is supported '
                  'only for LVM images.'))

        self.source_type = source_type
        self.driver_format = driver_format
        self.discard_mode = get_hw_disk_discard(CONF.libvirt.hw_disk_discard)
        self.is_block_dev = is_block_dev
        self.preallocate = False

        # NOTE(dripton): We store lines of json (path, disk_format) in this
        # file, for some image types, to prevent attacks based on changing the
        # disk_format.
        self.disk_info_path = None

        # NOTE(mikal): We need a lock directory which is shared along with
        # instance files, to cover the scenario where multiple compute nodes
        # are trying to create a base file at the same time
        self.lock_path = os.path.join(CONF.instances_path, 'locks')
Esempio n. 16
0
    def _get_client(self):
        # If we've already constructed a valid, authed client, just return
        # that.
        if self._cached_client is not None:
            return self._cached_client

        auth_token = CONF.ironic.admin_auth_token
        if auth_token is None:
            kwargs = {
                'os_username': CONF.ironic.admin_username,
                'os_password': CONF.ironic.admin_password,
                'os_auth_url': CONF.ironic.admin_url,
                'os_tenant_name': CONF.ironic.admin_tenant_name,
                'os_service_type': 'baremetal',
                'os_endpoint_type': 'public',
                'ironic_url': CONF.ironic.api_endpoint
            }
        else:
            kwargs = {
                'os_auth_token': auth_token,
                'ironic_url': CONF.ironic.api_endpoint
            }

        try:
            cli = ironic.client.get_client(CONF.ironic.api_version, **kwargs)
            # Cache the client so we don't have to reconstruct and
            # reauthenticate it every time we need it.
            self._cached_client = cli

        except ironic.exc.Unauthorized:
            msg = _("Unable to authenticate Ironic client.")
            LOG.error(msg)
            raise exception.PatronException(msg)

        return cli
Esempio n. 17
0
 def _test_for_malicious_tarball(path, filename):
     """Raises exception if extracting tarball would escape extract path."""
     tar_file = tarfile.open(filename, 'r|gz')
     for n in tar_file.getnames():
         if not os.path.abspath(os.path.join(path, n)).startswith(path):
             tar_file.close()
             raise exception.PatronException(_('Unsafe filenames in image'))
     tar_file.close()
Esempio n. 18
0
def validate_volume(mnt_base):
    """Wraps execute calls for checking validity of a Quobyte volume"""
    command = ['getfattr', "-n", "quobyte.info", mnt_base]
    try:
        utils.execute(*command)
    except processutils.ProcessExecutionError as exc:
        msg = (_("The mount %(mount_path)s is not a valid"
                 " Quobyte volume. Error: %(exc)s") % {
                     'mount_path': mnt_base,
                     'exc': exc
                 })
        raise patron_exception.PatronException(msg)

    if not os.access(mnt_base, os.W_OK | os.X_OK):
        msg = (_LE("Volume is not writable. Please broaden the file"
                   " permissions. Mount: %s") % mnt_base)
        raise patron_exception.PatronException(msg)
Esempio n. 19
0
def start_transfer(context,
                   read_file_handle,
                   data_size,
                   write_file_handle=None,
                   image_id=None,
                   image_meta=None):
    """Start the data transfer from the reader to the writer.
    Reader writes to the pipe and the writer reads from the pipe. This means
    that the total transfer time boils down to the slower of the read/write
    and not the addition of the two times.
    """

    if not image_meta:
        image_meta = {}

    # The pipe that acts as an intermediate store of data for reader to write
    # to and writer to grab from.
    thread_safe_pipe = io_util.ThreadSafePipe(QUEUE_BUFFER_SIZE, data_size)
    # The read thread. In case of glance it is the instance of the
    # GlanceFileRead class. The glance client read returns an iterator
    # and this class wraps that iterator to provide datachunks in calls
    # to read.
    read_thread = io_util.IOThread(read_file_handle, thread_safe_pipe)

    # In case of Glance - VMware transfer, we just need a handle to the
    # HTTP Connection that is to send transfer data to the VMware datastore.
    if write_file_handle:
        write_thread = io_util.IOThread(thread_safe_pipe, write_file_handle)
    # In case of VMware - Glance transfer, we relinquish VMware HTTP file read
    # handle to Glance Client instance, but to be sure of the transfer we need
    # to be sure of the status of the image on glance changing to active.
    # The GlanceWriteThread handles the same for us.
    elif image_id:
        write_thread = io_util.GlanceWriteThread(context, thread_safe_pipe,
                                                 image_id, image_meta)
    # Start the read and write threads.
    read_event = read_thread.start()
    write_event = write_thread.start()
    try:
        # Wait on the read and write events to signal their end
        read_event.wait()
        write_event.wait()
    except Exception as exc:
        # In case of any of the reads or writes raising an exception,
        # stop the threads so that we un-necessarily don't keep the other one
        # waiting.
        read_thread.stop()
        write_thread.stop()

        # Log and raise the exception.
        LOG.exception(_LE('Transfer data failed'))
        raise exception.PatronException(exc)
    finally:
        # No matter what, try closing the read and write handles, if it so
        # applies.
        read_file_handle.close()
        if write_file_handle:
            write_file_handle.close()
Esempio n. 20
0
def find_network_with_name_label(session, name_label):
    networks = session.network.get_by_name_label(name_label)
    if len(networks) == 1:
        return networks[0]
    elif len(networks) > 1:
        raise exception.PatronException(
            _('Found non-unique network for name_label %s') % name_label)
    else:
        return None
Esempio n. 21
0
def convert_version_to_int(version):
    try:
        if isinstance(version, six.string_types):
            version = convert_version_to_tuple(version)
        if isinstance(version, tuple):
            return reduce(lambda x, y: (x * 1000) + y, version)
    except Exception:
        msg = _("Hypervisor version %s is invalid.") % version
        raise exception.PatronException(msg)
Esempio n. 22
0
        def _inner():
            """Function to do the image data transfer through an update
            and thereon checks if the state is 'active'.
            """
            try:
                IMAGE_API.update(self.context,
                                 self.image_id,
                                 self.image_meta,
                                 data=self.input)
                self._running = True
            except exception.ImageNotAuthorized as exc:
                self.done.send_exception(exc)

            while self._running:
                try:
                    image_meta = IMAGE_API.get(self.context, self.image_id)
                    image_status = image_meta.get("status")
                    if image_status == "active":
                        self.stop()
                        self.done.send(True)
                    # If the state is killed, then raise an exception.
                    elif image_status == "killed":
                        self.stop()
                        msg = (_("Glance image %s is in killed state") %
                               self.image_id)
                        LOG.error(msg)
                        self.done.send_exception(
                            exception.PatronException(msg))
                    elif image_status in ["saving", "queued"]:
                        greenthread.sleep(GLANCE_POLL_INTERVAL)
                    else:
                        self.stop()
                        msg = _("Glance image "
                                "%(image_id)s is in unknown state "
                                "- %(state)s") % {
                                    "image_id": self.image_id,
                                    "state": image_status
                                }
                        LOG.error(msg)
                        self.done.send_exception(
                            exception.PatronException(msg))
                except Exception as exc:
                    self.stop()
                    self.done.send_exception(exc)
Esempio n. 23
0
    def setup(self, mount=True):
        LOG.debug("Setting up appliance for %(imgfile)s %(imgfmt)s", {
            'imgfile': self.imgfile,
            'imgfmt': self.imgfmt
        })
        try:
            self.handle = tpool.Proxy(
                guestfs.GuestFS(python_return_dict=False, close_on_exit=False))
        except TypeError as e:
            if ('close_on_exit' in six.text_type(e)
                    or 'python_return_dict' in six.text_type(e)):
                # NOTE(russellb) In case we're not using a version of
                # libguestfs new enough to support parameters close_on_exit
                # and python_return_dict which were added in libguestfs 1.20.
                self.handle = tpool.Proxy(guestfs.GuestFS())
            else:
                raise

        if CONF.guestfs.debug:
            self.configure_debug()

        try:
            if forceTCG:
                self.handle.set_backend_settings("force_tcg")
        except AttributeError as ex:
            # set_backend_settings method doesn't exist in older
            # libguestfs versions, so nothing we can do but ignore
            LOG.warning(
                _LW("Unable to force TCG mode, "
                    "libguestfs too old? %s"), ex)
            pass

        try:
            self.handle.add_drive_opts(self.imgfile, format=self.imgfmt)
            self.handle.launch()

            if mount:
                self.setup_os()
                self.handle.aug_init("/", 0)
                self.mount = True
        except RuntimeError as e:
            # explicitly teardown instead of implicit close()
            # to prevent orphaned VMs in cases when an implicit
            # close() is not enough
            self.teardown()
            raise exception.PatronException(
                _("Error mounting %(imgfile)s with libguestfs (%(e)s)") % {
                    'imgfile': self.imgfile,
                    'e': e
                })
        except Exception:
            # explicitly teardown instead of implicit close()
            # to prevent orphaned VMs in cases when an implicit
            # close() is not enough
            self.teardown()
            raise
Esempio n. 24
0
def check_shadow_table(migrate_engine, table_name):
    """This method checks that table with ``table_name`` and
    corresponding shadow table have same columns.
    """
    meta = MetaData()
    meta.bind = migrate_engine

    table = Table(table_name, meta, autoload=True)
    shadow_table = Table(db._SHADOW_TABLE_PREFIX + table_name,
                         meta,
                         autoload=True)

    columns = {c.name: c for c in table.columns}
    shadow_columns = {c.name: c for c in shadow_table.columns}

    for name, column in columns.iteritems():
        if name not in shadow_columns:
            raise exception.PatronException(
                _("Missing column %(table)s.%(column)s in shadow table") % {
                    'column': name,
                    'table': shadow_table.name
                })
        shadow_column = shadow_columns[name]

        if not isinstance(shadow_column.type, type(column.type)):
            raise exception.PatronException(
                _("Different types in %(table)s.%(column)s and shadow table: "
                  "%(c_type)s %(shadow_c_type)s") % {
                      'column': name,
                      'table': table.name,
                      'c_type': column.type,
                      'shadow_c_type': shadow_column.type
                  })

    for name, column in shadow_columns.iteritems():
        if name not in columns:
            raise exception.PatronException(
                _("Extra column %(table)s.%(column)s in shadow table") % {
                    'column': name,
                    'table': shadow_table.name
                })
    return True
Esempio n. 25
0
    def register(self, ext):
        # Do nothing if the extension doesn't check out
        if not self._check_extension(ext):
            return

        alias = ext.alias
        if alias in self.extensions:
            raise exception.PatronException("Found duplicate extension: %s" %
                                            alias)
        self.extensions[alias] = ext
        self.sorted_ext_list = None
Esempio n. 26
0
    def unplug(self, instance, vif):
        vif_type = vif['type']

        LOG.debug('vif_type=%(vif_type)s instance=%(instance)s '
                  'vif=%(vif)s', {
                      'vif_type': vif_type,
                      'instance': instance,
                      'vif': vif
                  })

        if vif_type is None:
            raise exception.PatronException(
                _("vif_type parameter must be present "
                  "for this vif_driver implementation"))
        vif_slug = self._normalize_vif_type(vif_type)
        func = getattr(self, 'unplug_%s' % vif_slug, None)
        if not func:
            raise exception.PatronException(
                _("Unexpected vif_type=%s") % vif_type)
        func(instance, vif)
Esempio n. 27
0
    def inspect_capabilities(self):
        """Determines whether guestfs is well configured."""
        try:
            g = guestfs.GuestFS()
            g.add_drive("/dev/null")  # sic
            g.launch()
        except Exception as e:
            raise exception.PatronException(
                _("libguestfs installed but not usable (%s)") % e)

        return self
Esempio n. 28
0
    def create_image(self, prepare_template, base, size, *args, **kwargs):
        def encrypt_lvm_image():
            dmcrypt.create_volume(
                self.path.rpartition('/')[2], self.lv_path,
                CONF.ephemeral_storage_encryption.cipher,
                CONF.ephemeral_storage_encryption.key_size, key)

        filename = self._get_lock_name(base)

        @utils.synchronized(filename, external=True, lock_path=self.lock_path)
        def create_lvm_image(base, size):
            base_size = disk.get_disk_size(base)
            self.verify_base_size(base, size, base_size=base_size)
            resize = size > base_size
            size = size if resize else base_size
            lvm.create_volume(self.vg, self.lv, size, sparse=self.sparse)
            if self.ephemeral_key_uuid is not None:
                encrypt_lvm_image()
            images.convert_image(base, self.path, 'raw', run_as_root=True)
            if resize:
                disk.resize2fs(self.path, run_as_root=True)

        generated = 'ephemeral_size' in kwargs
        if self.ephemeral_key_uuid is not None:
            if 'context' in kwargs:
                try:
                    # NOTE(dgenin): Key manager corresponding to the
                    # specific backend catches and reraises an
                    # an exception if key retrieval fails.
                    key = self.key_manager.get_key(
                        kwargs['context'],
                        self.ephemeral_key_uuid).get_encoded()
                except Exception:
                    with excutils.save_and_reraise_exception():
                        LOG.error(
                            _LE("Failed to retrieve ephemeral encryption"
                                " key"))
            else:
                raise exception.PatronException(
                    _("Instance disk to be encrypted but no context provided"))
        # Generate images with specified size right on volume
        if generated and size:
            lvm.create_volume(self.vg, self.lv, size, sparse=self.sparse)
            with self.remove_volume_on_error(self.path):
                if self.ephemeral_key_uuid is not None:
                    encrypt_lvm_image()
                prepare_template(target=self.path, *args, **kwargs)
        else:
            if not os.path.exists(base):
                prepare_template(target=base, max_size=size, *args, **kwargs)
            with self.remove_volume_on_error(self.path):
                create_lvm_image(base, size)
Esempio n. 29
0
    def __init__(self, imgfile, imgfmt='raw', partition=None):
        super(VFSGuestFS, self).__init__(imgfile, imgfmt, partition)

        global guestfs
        if guestfs is None:
            try:
                guestfs = importutils.import_module('guestfs')
            except Exception as e:
                raise exception.PatronException(
                    _("libguestfs is not installed (%s)") % e)

        self.handle = None
        self.mount = False
Esempio n. 30
0
def db_sync(version=None, database='main'):
    if version is not None:
        try:
            version = int(version)
        except ValueError:
            raise exception.PatronException(_("version should be an integer"))

    current_version = db_version(database)
    repository = _find_migrate_repo(database)
    if version is None or version > current_version:
        return versioning_api.upgrade(get_engine(database), repository,
                                      version)
    else:
        return versioning_api.downgrade(get_engine(database), repository,
                                        version)