Esempio n. 1
0
def _get_vmedia_params():
    """This method returns the parameters passed through virtual media floppy.

    :returns: a partial dict of potential agent configuration parameters
    :raises: VirtualMediaBootError when it cannot find the virtual media device
    """
    parameters_file = "parameters.txt"
    vmedia_device_file = _find_vmedia_device_by_labels(['ir-vfd-dev'])
    if not vmedia_device_file:
        # This falls back to trying to find a matching device by name/type.
        # if not found, it is likely okay to just fail out and treat it as
        # No device found as there are multiple ways to launch IPA, and all
        # vmedia styles should be treated consistently.
        vmedia_device = _get_vmedia_device()
        if not vmedia_device:
            return {}

        vmedia_device_file = os.path.join("/dev", vmedia_device)

        if not _check_vmedia_device(vmedia_device_file):
            # If the device is not valid, return an empty dictionary.
            return {}

    with ironic_utils.mounted(vmedia_device_file) as vmedia_mount_point:
        parameters_file_path = os.path.join(vmedia_mount_point,
                                            parameters_file)
        params = _read_params_from_file(parameters_file_path)

    return params
Esempio n. 2
0
def partition_with_path(path):
    root_dev = hardware.dispatch_to_managers('get_os_install_device')
    partitions = disk_utils.list_partitions(root_dev)
    local_path = tempfile.mkdtemp()

    for part in partitions:
        if 'esp' in part['flags'] or 'lvm' in part['flags']:
            LOG.debug('Skipping partition %s', part)
            continue

        part_path = partition_index_to_name(root_dev, part['number'])
        try:
            with utils.mounted(part_path) as local_path:
                conf_path = os.path.join(local_path, path)
                LOG.debug('Checking for path %s on %s', conf_path, part_path)
                if not os.path.isdir(conf_path):
                    continue

                LOG.info('Path found: %s on %s', conf_path, part_path)
                yield conf_path
                return
        except processutils.ProcessExecutionError as exc:
            LOG.warning('Failure when inspecting partition %s: %s', part, exc)

    raise RuntimeError("No partition found with path %s, scanned: %s"
                       % (path, partitions))
Esempio n. 3
0
def _find_and_mount_path(path, partition, root_dev):
    """Find the specified path on a device.

    Tries to find the suitable device for the file based on the ``path`` and
    ``partition``, mount the device and provides the actual full path.

    :param path: Path to the file to find.
    :param partition: Device to find the file on or None.
    :param root_dev: Root device from the hardware manager.
    :return: Context manager that yields the full path to the file.
    """
    path = os.path.normpath(path.strip('/'))  # to make path joining work
    if partition:
        try:
            part_num = int(partition)
        except ValueError:
            with ironic_utils.mounted(partition) as part_path:
                yield os.path.join(part_path, path)
        else:
            # TODO(dtantsur): switch to ironic-lib instead:
            # https://review.opendev.org/c/openstack/ironic-lib/+/774502
            part_template = '%s%s'
            if 'nvme' in root_dev:
                part_template = '%sp%s'
            part_dev = part_template % (root_dev, part_num)

            with ironic_utils.mounted(part_dev) as part_path:
                yield os.path.join(part_path, path)
    else:
        try:
            # This turns e.g. etc/sysctl.d/my.conf into etc + sysctl.d/my.conf
            detect_dir, rest_dir = path.split('/', 1)
        except ValueError:
            # Validation ensures that files in / have "partition" present,
            # checking here just in case.
            raise errors.InvalidCommandParamsError(
                "Invalid path %s, must be an absolute path to a file" % path)

        with find_partition_with_path(detect_dir, root_dev) as part_path:
            yield os.path.join(part_path, rest_dir)
Esempio n. 4
0
def find_partition_with_path(path, device=None):
    """Find a partition with the given path.

    :param path: Expected path.
    :param device: Target device. If None, the root device is used.
    :returns: A context manager that will unmount and delete the temporary
        mount point on exit.
    """
    if device is None:
        device = hardware.dispatch_to_managers('get_os_install_device')
    partitions = disk_utils.list_partitions(device)
    # Make os.path.join work as expected
    lookup_path = path.lstrip('/')

    for part in partitions:
        if 'lvm' in part['flags']:
            LOG.debug('Skipping LVM partition %s', part)
            continue

        # TODO(dtantsur): switch to ironic-lib instead:
        # https://review.opendev.org/c/openstack/ironic-lib/+/774502
        part_template = '%s%s'
        if 'nvme' in device:
            part_template = '%sp%s'
        part_path = part_template % (device, part['number'])

        LOG.debug('Inspecting partition %s for path %s', part, path)
        try:
            with ironic_utils.mounted(part_path) as local_path:
                found_path = os.path.join(local_path, lookup_path)
                if not os.path.isdir(found_path):
                    continue

                LOG.info('Path %s has been found on partition %s', path, part)
                yield found_path
                return
        except processutils.ProcessExecutionError as exc:
            LOG.warning('Failure when inspecting partition %s: %s', part, exc)

    raise errors.DeviceNotFound(
        "No partition found with path %s, scanned: %s" % (path, partitions))
Esempio n. 5
0
def copy_config_from_vmedia():
    """Copies any configuration from a virtual media device.

    Copies files under /etc/ironic-python-agent and /etc/ironic-python-agent.d.
    """
    vmedia_device_file = _find_vmedia_device_by_labels(
        ['config-2', 'vmedia_boot_iso'])
    if not vmedia_device_file:
        _early_log('No virtual media device detected')
        return
    if not _booted_from_vmedia():
        _early_log('Cannot use configuration from virtual media as the '
                   'agent was not booted from virtual media.')
        return
    # Determine the device
    mounted = _find_mount_point(vmedia_device_file)
    if mounted:
        _copy_config_from(mounted)
    else:
        with ironic_utils.mounted(vmedia_device_file) as vmedia_mount_point:
            _copy_config_from(vmedia_mount_point)