예제 #1
0
def _get_vmedia_params():
    """This method returns the parameters passed to the agent through virtual
    media floppy.
    """
    vmedia_mount_point = "/vmedia_mnt"
    parameters_file = "parameters.txt"

    vmedia_device = _get_vmedia_device()
    if not vmedia_device:
        msg = "Unable to find virtual media device"
        raise errors.VirtualMediaBootError(msg)

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

    try:
        stdout, stderr = utils.execute("mount", vmedia_device_file,
                                       vmedia_mount_point)
    except processutils.ProcessExecutionError as e:
        msg = ("Unable to mount virtual media device %(device)s: %(error)s" % {
            'device': vmedia_device_file,
            'error': e
        })
        raise errors.VirtualMediaBootError(msg)

    parameters_file_path = os.path.join(vmedia_mount_point, parameters_file)
    params = _read_params_from_file(parameters_file_path)

    try:
        stdout, stderr = utils.execute("umount", vmedia_mount_point)
    except processutils.ProcessExecutionError as e:
        pass

    return params
예제 #2
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_lower_case = "/dev/disk/by-label/ir-vfd-dev"
    vmedia_device_file_upper_case = "/dev/disk/by-label/IR-VFD-DEV"
    if os.path.exists(vmedia_device_file_lower_case):
        vmedia_device_file = vmedia_device_file_lower_case
    elif os.path.exists(vmedia_device_file_upper_case):
        vmedia_device_file = vmedia_device_file_upper_case
    else:

        # TODO(rameshg87): This block of code is there only for compatibility
        # reasons (so that newer agent can work with older Ironic). Remove
        # this after Liberty release.
        vmedia_device = _get_vmedia_device()
        if not vmedia_device:
            msg = "Unable to find virtual media device"
            raise errors.VirtualMediaBootError(msg)

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

    vmedia_mount_point = tempfile.mkdtemp()
    try:
        try:
            stdout, stderr = execute("mount", vmedia_device_file,
                                     vmedia_mount_point)
        except processutils.ProcessExecutionError as e:
            msg = ("Unable to mount virtual media device %(device)s: "
                   "%(error)s" % {
                       'device': vmedia_device_file,
                       'error': e
                   })
            raise errors.VirtualMediaBootError(msg)

        parameters_file_path = os.path.join(vmedia_mount_point,
                                            parameters_file)
        params = _read_params_from_file(parameters_file_path)

        try:
            stdout, stderr = execute("umount", vmedia_mount_point)
        except processutils.ProcessExecutionError as e:
            pass
    finally:
        try:
            shutil.rmtree(vmedia_mount_point)
        except Exception as e:
            pass

    return params
예제 #3
0
def _poll_interface(_ifacedata):
    ifacedata = json.loads(_ifacedata)
    global dhclient_physIfaces

    physIfaces = []
    if "network_config" in ifacedata:
        for netconfdata in ifacedata["network_config"]:
            if "device" in netconfdata:
                if "bond" not in netconfdata["device"]:
                    # Is (physical) interface
                    LOG.debug('Physical device %s' % netconfdata["device"])
                    physIfaces.append(netconfdata["device"])

            elif "members" in netconfdata:
                # logical interface with member (f.ex bond)
                for _member in netconfdata["members"]:
                    if "type" in _member:
                        if _member["type"] == 'interface':
                            if "name" in _member:
                                LOG.debug('Physical device %s' %
                                          _member["name"])
                                physIfaces.append(_member["name"])
            elif "name" in netconfdata:
                if "type" in netconfdata and netconfdata["type"] == 'interface':
                    LOG.debug('Physical device %s' % netconfdata["name"])
                    physIfaces.append(netconfdata["name"])

    LOG.info('Checking for physical device(s) "%s"' % ', '.join(physIfaces))
    dhclient_physIfaces = list(physIfaces)
    wait_secs = 5
    max_wait_secs = 60

    while len(physIfaces) > 0 and max_wait_secs >= 0:
        missing_devices = []
        max_wait_secs = max_wait_secs - wait_secs

        for _device in physIfaces:
            devicepath = "/sys/class/net/%s/device" % _device
            LOG.debug('Check path "%s"' % devicepath)
            if os.path.exists(devicepath):
                LOG.debug('Device "%s" in known by kernel' % _device)
                physIfaces.remove(_device)
            else:
                LOG.debug('Device "%s" in not (yet) known by kernel' % _device)
                missing_devices.append(_device)

        if len(physIfaces) > 0:
            LOG.info('Device(s) not (yet?) known by kernel: "%s"' %
                     ', '.join(missing_devices))
            time.sleep(wait_secs)

    if len(physIfaces) > 0:
        msg = 'Timeout, Device(s) missing: "%s"' % ', '.join(physIfaces)
        LOG.error(msg)
        raise errors.VirtualMediaBootError(msg)
    else:
        LOG.info('All physical devices found.')

    for _device in dhclient_physIfaces:
        stop_dhclient_process(_device)
예제 #4
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_device_by_labels(['ir-vfd-dev'])
    if not vmedia_device_file:
        # TODO(rameshg87): This block of code is there only for compatibility
        # reasons (so that newer agent can work with older Ironic). Remove
        # this after Liberty release.
        vmedia_device = _get_vmedia_device()
        if not vmedia_device:
            msg = "Unable to find virtual media device"
            raise errors.VirtualMediaBootError(msg)

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

    with _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
예제 #5
0
def _mounted(source):
    """A context manager for a temporary mount."""
    dest = tempfile.mkdtemp()
    try:
        try:
            execute("mount", source, dest)
        except processutils.ProcessExecutionError as e:
            msg = ("Unable to mount virtual media device %(device)s: "
                   "%(error)s" % {
                       'device': source,
                       'error': e
                   })
            raise errors.VirtualMediaBootError(msg)

        yield dest
    finally:
        try:
            execute("umount", dest)
        except processutils.ProcessExecutionError:
            pass

        try:
            shutil.rmtree(dest)
        except Exception:
            pass
예제 #6
0
def wait_for_cd_device():
    """ This function waits for /dev/sr0 device to appear """
    inputiso = '/dev/sr0'
    wait_count = 30
    while not os.path.exists(inputiso) and wait_count:
        LOG.debug('Waiting for %s to appear. Time left = %d secs' %
                  (inputiso, wait_count))
        time.sleep(1)
        wait_count -= 1

    if not wait_count:
        msg = "Unable to find device %s" % (inputiso)
        raise errors.VirtualMediaBootError(msg)
예제 #7
0
def _copy_config_from(path):
    for ext in ('', '.d'):
        src = os.path.join(path, 'etc', 'ironic-python-agent%s' % ext)
        if not os.path.isdir(src):
            _early_log('%s not found', src)
            continue

        dest = '/etc/ironic-python-agent%s' % ext
        _early_log('Copying configuration from %s to %s', src, dest)
        try:
            os.makedirs(dest, exist_ok=True)

            # TODO(dtantsur): use shutil.copytree(.., dirs_exist_ok=True)
            # when the minimum supported Python is 3.8.
            for name in os.listdir(src):
                src_file = os.path.join(src, name)
                dst_file = os.path.join(dest, name)
                shutil.copy(src_file, dst_file)
        except Exception as exc:
            msg = ("Unable to copy vmedia configuration %s to %s: %s"
                   % (src, dest, exc))
            raise errors.VirtualMediaBootError(msg)
예제 #8
0
 def test_error_classes(self):
     cases = [
         (errors.InvalidContentError(DETAILS), SAME_DETAILS),
         (errors.NotFound(), SAME_CL_DETAILS),
         (errors.CommandExecutionError(DETAILS), SAME_DETAILS),
         (errors.InvalidCommandError(DETAILS), SAME_DETAILS),
         (errors.InvalidCommandParamsError(DETAILS), SAME_DETAILS),
         (errors.RequestedObjectNotFoundError('type_descr',
                                              'obj_id'), DIFF_CL_DETAILS),
         (errors.IronicAPIError(DETAILS), SAME_DETAILS),
         (errors.HeartbeatError(DETAILS), SAME_DETAILS),
         (errors.LookupNodeError(DETAILS), SAME_DETAILS),
         (errors.LookupAgentIPError(DETAILS), SAME_DETAILS),
         (errors.LookupAgentInterfaceError(DETAILS), SAME_DETAILS),
         (errors.ImageDownloadError('image_id', DETAILS), DIFF_CL_DETAILS),
         (errors.ImageChecksumError('image_id', '/foo/image_id',
                                    'incorrect',
                                    'correct'), DIFF_CL_DETAILS),
         (errors.ImageWriteError('device', 'exit_code', 'stdout',
                                 'stderr'), DIFF_CL_DETAILS),
         (errors.ConfigDriveTooLargeError('filename',
                                          'filesize'), DIFF_CL_DETAILS),
         (errors.ConfigDriveWriteError('device', 'exit_code', 'stdout',
                                       'stderr'), DIFF_CL_DETAILS),
         (errors.SystemRebootError('exit_code', 'stdout',
                                   'stderr'), DIFF_CL_DETAILS),
         (errors.BlockDeviceEraseError(DETAILS), SAME_DETAILS),
         (errors.BlockDeviceError(DETAILS), SAME_DETAILS),
         (errors.VirtualMediaBootError(DETAILS), SAME_DETAILS),
         (errors.UnknownNodeError(), DEFAULT_DETAILS),
         (errors.UnknownNodeError(DETAILS), SAME_DETAILS),
         (errors.HardwareManagerNotFound(), DEFAULT_DETAILS),
         (errors.HardwareManagerNotFound(DETAILS), SAME_DETAILS),
         (errors.HardwareManagerMethodNotFound('method'), DIFF_CL_DETAILS),
         (errors.IncompatibleHardwareMethodError(), DEFAULT_DETAILS),
         (errors.IncompatibleHardwareMethodError(DETAILS), SAME_DETAILS),
     ]
     for (obj, check_details) in cases:
         self._test_class(obj, check_details)