Exemple #1
0
def _parse_df_output(output):
    """
    This method parses the output of 'df -hT' command.
    :param output: Parsed output of the 'df -hT' command
    :return:list containing filesystems information
    """

    try:
        output = output.splitlines()
        out_list = []
        for fs in output[1:]:
            fs_dict = {}
            fs_list = fs.split()
            fs_dict['filesystem'] = fs_list[0]
            fs_dict['type'] = fs_list[1]
            fs_dict['size'] = int(fs_list[2])
            fs_dict['used'] = fs_list[3]
            fs_dict['avail'] = int(fs_list[4])
            fs_dict['use%'] = fs_list[5]
            fs_dict['mounted_on'] = fs_list[6]

            out_list.append(fs_dict)
    except:
        wok_log.error("Parsing df output failed")
        raise OperationFailed("GINFS00003E")

    return out_list
Exemple #2
0
def upgrade_objectstore_data(item, old_uri, new_uri):
    """
        Upgrade the value of a given JSON's item of all Template and VM entries
        of the objectstore from old_uri to new_uri.
    """
    total = 0
    try:
        conn = sqlite3.connect(config.get_object_store(), timeout=10)
        cursor = conn.cursor()
        sql = "SELECT id, json FROM objects WHERE type='template' OR type='vm'"
        cursor.execute(sql)
        for row in cursor.fetchall():
            # execute update here
            template = json.loads(row[1])
            path = template[item] if item in template else 'none'
            if path.startswith(old_uri):
                template[item] = new_uri + path
                sql = 'UPDATE objects SET json=?, version=? WHERE id=?'
                cursor.execute(
                    sql, (json.dumps(template),
                          config.get_kimchi_version(), row[0])
                )
                conn.commit()
                total += 1
    except sqlite3.Error as e:
        if conn:
            conn.rollback()
        wok_log.error('Error while upgrading objectstore data: %s', e.args[0])
        raise OperationFailed('KCHUTILS0006E')
    finally:
        if conn:
            conn.close()
        wok_log.info("%d '%s' entries upgraded in objectstore.", total, item)
Exemple #3
0
 def activate(self, ifacename):
     wok_log.info('Bring up an interface ' + ifacename)
     iface_type = netinfo.get_interface_type(ifacename)
     if iface_type == "Ethernet":
         cmd_ipup = ['ip', 'link', 'set', '%s' % ifacename, 'up']
         out, error, returncode = run_command(cmd_ipup)
         if returncode != 0:
             wok_log.error(
                 'Unable to bring up the interface on ' + ifacename +
                 ', ' + error)
             raise OperationFailed('GINNET0059E', {'name': ifacename,
                                                   'error': error})
         # Some times based on system load, it takes few seconds to
         # reflect the  /sys/class/net files upon execution of 'ip link
         # set' command.  Following snippet is to wait util files get
         # reflect.
         timeout = self.wait_time(ifacename)
         if timeout == 5:
             wok_log.warn("Time-out has happened upon execution of 'ip "
                          "link set <interface> up', hence behavior of "
                          "activating an interface may not as expected.")
         else:
             wok_log.info(
                 'Successfully brought up the interface ' + ifacename)
     wok_log.info('Activating an interface ' + ifacename)
     cmd_ifup = ['ifup', '%s' % ifacename]
     out, error, returncode = run_command(cmd_ifup)
     if returncode != 0:
         wok_log.error(
             'Unable to activate the interface on ' + ifacename +
             ', ' + error)
         raise OperationFailed('GINNET0016E',
                               {'name': ifacename, 'error': error})
     wok_log.info(
         'Connection successfully activated for the interface ' + ifacename)
Exemple #4
0
 def lookup(self, path):
     try:
         path_components = utils.validate_lun_path(path)
         return utils.get_lun_info(*path_components)
     except ValueError:
         wok_log.error("Fetching LUN info failed, %s", path)
         raise NotFoundError("GS390XSTG00008", {'path': path})
Exemple #5
0
 def delete(self, name):
     try:
         fs_utils.unpersist_swap_dev(name)
         utils._swapoff_device(name)
     except Exception as e:
         wok_log.error("Error deleting a swap device, %s", e.message)
         raise OperationFailed("GINSP00009E", {'err': e.message})
Exemple #6
0
def parse_lsblk_out(lsblk_out):
    """
    Parse the output of 'lsblk -Po'
    :param lsblk_out: output of 'lsblk -Po'
    :return: Dictionary containing information about
            disks on the system
    """
    try:
        out_list = lsblk_out.splitlines()

        return_dict = {}

        for disk in out_list:
            disk_info = {}
            disk_attrs = disk.split()

            disk_type = disk_attrs[1]
            if not disk_type == 'TYPE="disk"':
                continue

            if len(disk_attrs) == 4:
                disk_info['transport'] = disk_attrs[3].split("=")[1][1:-1]
            else:
                disk_info['transport'] = "unknown"

            disk_info['size'] = disk_attrs[2].split("=")[1][1:-1]
            return_dict[disk_attrs[0].split("=")[1][1:-1]] = disk_info

    except Exception as e:
        wok_log.error("Error parsing 'lsblk -Po")
        raise OperationFailed("GINSD00004E", {'err': e.message})

    return return_dict
Exemple #7
0
 def stop(self, params=None):
     cmd = ['systemctl', 'stop', 'sepctl']
     output, error, rc = run_command(cmd)
     if rc != 0:
         wok_log.error('Error stopping SEP service: %s - %s - %s' % (cmd,
                       rc, error))
         raise OperationFailed('GINSEP0009E', {'error': error})
Exemple #8
0
    def _get_subscriber(self):

        activation_info = []
        entry = {}
        cmd = ['/opt/ibm/seprovider/bin/getSubscriber']
        output, error, rc = run_command(cmd)

        # no subscriber: return empty
        if rc == 1:
            return activation_info

        # error: report
        if rc != 0:
            wok_log.error('SEP execution error: %s - %s - %s' % (cmd, rc,
                          error))
            raise OperationFailed('GINSEP0007E')

        if len(output) > 1:

            # iterate over lines and parse to dict
            for line in output.splitlines():
                if len(line) > 0:
                    entry = SUBSCRIBER.search(line).groupdict()
                    activation_info.append(entry["hostname"])

        return activation_info
Exemple #9
0
    def lookup(self, subscription):
        """
        Returns a dictionary with all SEP information.
        """
        cmd = ['/opt/ibm/seprovider/bin/getSubscriber']
        output, error, rc = run_command(cmd)

        # error: report
        if rc != 0:
            wok_log.error('SEP execution error: %s - %s - %s' % (cmd, rc,
                          error))
            raise OperationFailed('GINSEP0005E', {'error': error})

        if len(output) > 1:

            # iterate over lines and parse to dict
            for line in output.splitlines():
                if len(line) > 0:
                    entry = SUBSCRIBER.search(line).groupdict()

                    # subscriber found
                    if entry["hostname"] == subscription:
                        return entry

        raise NotFoundError("GINSEP0006E", {'hostname': subscription})
Exemple #10
0
 def start(self, params=None):
     cmd = ['systemctl', 'start', 'sepctl']
     output, error, rc = run_command(cmd)
     if rc != 0:
         wok_log.error('SEP service initialization error: %s - %s - %s'
                       % (cmd, rc, error))
         raise OperationFailed('GINSEP0008E', {'error': error})
Exemple #11
0
 def get_list(self, _configured=None):
     """
     :param _configured: True will list only the network devices
     which are configured. znetconf -c will be used
     False will list only network devices which are not configured yet.
     znetconf -u will be used
     If not given then it will fetch both the list of devices.
     :return: network OSA device info list.
     """
     wok_log.info('Fetching network devices. _configured '
                  '= %s' % _configured)
     if _configured is None:
         devices = _get_configured_devices()
         devices.extend(_get_unconfigured_devices())
     elif _configured in ['True', 'true']:
         devices = _get_configured_devices()
     elif _configured in ['False', 'false']:
         devices = _get_unconfigured_devices()
     else:
         wok_log.error("Invalid _configured given. _configured: %s"
                       % _configured)
         raise InvalidParameter("GS390XINVTYPE",
                                {'supported_type': 'True/False'})
     wok_log.info('Successfully retrieved network devices')
     return devices
Exemple #12
0
def get_disk_used_by(objstore, conn, path):
    try:
        with objstore as session:
            try:
                used_by = session.get("storagevolume", path)["used_by"]
            except (KeyError, NotFoundError):
                wok_log.info("Volume %s not found in obj store." % path)
                used_by = []
                # try to find this volume in existing vm
                vms_list = VMsModel.get_vms(conn)
                for vm in vms_list:
                    dom = VMModel.get_vm(vm, conn)
                    storages = get_vm_disks(dom)
                    for disk in storages.keys():
                        d_info = get_vm_disk_info(dom, disk)
                        if path == d_info["path"]:
                            used_by.append(vm)
                try:
                    session.store("storagevolume", path, {"used_by": used_by}, get_kimchi_version())
                except Exception as e:
                    # Let the exception be raised. If we allow disks'
                    #   used_by to be out of sync, data corruption could
                    #   occour if a disk is added to two guests
                    #   unknowingly.
                    wok_log.error("Unable to store storage volume id in" " objectstore due error: %s", e.message)
                    raise OperationFailed("KCHVOL0017E", {"err": e.message})
    except Exception as e:
        # This exception is going to catch errors returned by 'with',
        # specially ones generated by 'session.store'. It is outside
        # to avoid conflict with the __exit__ function of 'with'
        raise OperationFailed("KCHVOL0017E", {"err": e.message})
    return used_by
Exemple #13
0
def _create_ifcfg_file(interface):
    """
    method to create ifcfg-enccw<device_id> file in
    /etc/sysconfig/network-scripts/ folder and change
    persmission of that file to 644 to be in sync with
    other files in directory

    :param interface: network device id
    :return: None
    """
    wok_log.info('creating ifcfg file for %s', interface)
    ifcfg_file_path = '/' + ifcfg_path.replace('<deviceid>', interface)
    try:
        ifcfg_file = open(ifcfg_file_path, 'w+')
        ifcfg_file.close()
        os.system('chmod 644 ' + ifcfg_file_path)
        wok_log.info('created file %s for network device %s'
                     % (ifcfg_file_path, interface))
    except Exception as e:
        wok_log.error('failed to create file %s for network device %s. '
                      'Error: %s' % (ifcfg_file_path, interface, e.__str__()))
        raise OperationFailed("GS390XIONW005E",
                              {'ifcfg_file_path': ifcfg_file_path,
                               'device': interface,
                               'error': e.__str__()})
Exemple #14
0
def _validate_device(interface):
    """
    validate the device id. Valid device Ids should have
    <single digitnumber>.<single digitnumber>.<4 digit hexadecimalnumber>
    or <4 digit hexadecimal number>
    :param interface: device id
    """
    wok_log.info('Validating network interface %s' % interface)
    pattern_with_dot = r'^\d\.\d\.[0-9a-fA-F]{4}$'
    if interface and not str(interface).isspace():
        interface = str(interface).strip()
        if ENCCW in interface:
            interface = interface.strip(ENCCW)
        out = re.search(pattern_with_dot, interface)
        if out is None:
            wok_log.error("Invalid interface id. interface: %s" % interface)
            raise InvalidParameter("GS390XINVINPUT",
                                   {'reason': 'invalid interface id: %s'
                                              % interface})
        wok_log.info('Successfully validated network interface')
    else:
        wok_log.error("interface id is empty. interface: %s" % interface)
        raise InvalidParameter("GS390XINVINPUT",
                               {'reason': 'device id is required. '
                                          'device id: %s' % interface})
Exemple #15
0
def _format_znetconf(device):
    """
    method to reform dictionary with new keys for znetconf devices
    :param device: device dictionary with keys "
            ZNETCONF_STATE, ZNETCONF_DEV_IDS, ZNETCONF_CARDTYPE,
            ZNETCONF_CHPID, ZNETCONF_DRV, ZNETCONF_TYPE, ZNETCONF_DEV_NAME,
    :return: dictionary with new keys mapped as follows
             ZNETCONF_STATE - "state", ZNETCONF_DEV_IDS - "device_ids",
             ZNETCONF_CARDTYPE- "card_type"
             ZNETCONF_CHPID - "chpid", ZNETCONF_DRV - "driver",
             ZNETCONF_TYPE - "type", ZNETCONF_DEV_NAME - "name",
             ZNETCONF_CHPID - "chipid"
             ZNETCONF_STATE if not present then its set as Un-configured.
             As for configured device, state can be both Online and Offline
             And for un configured, state is not returned in znetconf -u
             ZNETCONF_DEV_NAME is mapped to "name" and if ZNETCONF_DEV_NAME
             is not present then "name" value is set as one of the device
             from the list of deviceIds
    """
    if device:
        try:
            device['state'] = device.pop(ZNETCONF_STATE, 'Unconfigured')
            device_ids = list(device.pop(ZNETCONF_DEV_IDS).split(','))
            device['device_ids'] = device_ids
            device['card_type'] = device.pop(ZNETCONF_CARDTYPE)
            device['chpid'] = device.pop(ZNETCONF_CHPID)
            device['driver'] = device.pop(ZNETCONF_DRV)
            device['type'] = device.pop(ZNETCONF_TYPE)
            device['name'] = device.pop(ZNETCONF_DEV_NAME, device_ids[0])
        except KeyError as e:
            wok_log.error('Issue while formatting znetconf dictionary output')
            raise e
    return device
    def lookup(self, name):
        try:
            return utils._vgdisplay_out(name)

        except OperationFailed:
            wok_log.error('failed to fetch vg info')
            raise NotFoundError("GINVG00003E", {'name': name})
Exemple #17
0
def _is_dev_extended_partition(devType, devNodePath):
    if devType != 'part':
        return False

    if devNodePath.startswith('/dev/mapper'):
        try:
            dev_maj_min = _get_dev_major_min(devNodePath.split("/")[-1])
            parent_sys_path = '/sys/dev/block/' + dev_maj_min + '/slaves'
            parent_dm_name = os.listdir(parent_sys_path)[0]
            parent_maj_min = open(
                parent_sys_path +
                '/' +
                parent_dm_name +
                '/dev').readline().rstrip()
            diskPath = _get_dev_node_path(parent_maj_min)
        except Exception as e:
            wok_log.error(
                "Error dealing with dev mapper device: " + devNodePath)
            raise OperationFailed("GGBDISK00001E", {'err': e.message})
    else:
        diskPath = devNodePath.rstrip('0123456789')

    device = PDevice(diskPath)
    try:
        extended_part = PDisk(device).getExtendedPartition()
    except NotImplementedError as e:
        wok_log.warning(
            "Error getting extended partition info for dev %s type %s: %s",
            devNodePath, devType, e.message)
        # Treate disk with unsupported partiton table as if it does not
        # contain extended partitions.
        return False
    if extended_part and extended_part.path == devNodePath:
        return True
    return False
Exemple #18
0
def get_dev_info(node_dev):
    ''' Parse the node device XML string into dict according to
    http://libvirt.org/formatnode.html.

    scsi_generic is not documented in libvirt official website. Try to
    parse scsi_generic according to the following libvirt path series.
    https://www.redhat.com/archives/libvir-list/2013-June/msg00014.html

    scsi_target is not documented in libvirt official website. Try to
    parse scsi_target according to the libvirt commit db19834a0a.
    '''
    xmlstr = node_dev.XMLDesc(0)
    info = dictize(xmlstr)['device']
    dev_type = info['capability'].pop('type')
    info['device_type'] = dev_type
    cap_dict = info.pop('capability')
    info.update(cap_dict)

    # parent device not found: set as None
    info["parent"] = info.get("parent")

    if dev_type in ('scsi', 'scsi_generic', 'scsi_target', 'system', 'usb'):
        return info

    if dev_type in ('net', 'pci', 'scsi_host', 'storage', 'usb_device'):
        return globals()['_get_%s_dev_info' % dev_type](info)

    wok_log.error("Unknown device type: %s", dev_type)
    return info
Exemple #19
0
 def disable_tcp_port(port):
     _, err, r_code = run_command(
         ['firewall-cmd', '--remove-port=%s/tcp' % port]
     )
     if r_code != 0:
         wok_log.error('Error when removing port from '
                       'firewall-cmd: %s' % err)
Exemple #20
0
    def lookup(self, name):
        try:
            return utils._pvdisplay_out(name)

        except OperationFailed:
            wok_log.error("Unable to fetch details of PV")
            raise NotFoundError("GINPV00004E", {'name': name})
Exemple #21
0
    def _generate_thumbnail(self):
        thumbnail = os.path.join(config.get_screenshot_path(), '%s-%s.png' %
                                 (self.vm_uuid, str(uuid.uuid4())))

        self._get_test_result()
        if stream_test_result is None:
            self._watch_stream_creation(thumbnail)
        elif stream_test_result:
            try:
                self._generate_scratch(thumbnail)
            except:
                wok_log.error("screenshot_creation: Unable to create "
                              "screenshot image %s." % thumbnail)
        else:
            self._create_black_image(thumbnail)

        if os.path.getsize(thumbnail) == 0:
            self._create_black_image(thumbnail)
        else:
            im = Image.open(thumbnail)
            try:
                # Prevent Image lib from lazy load,
                # work around pic truncate validation in thumbnail generation
                im.thumbnail(self.THUMBNAIL_SIZE)
            except Exception as e:
                wok_log.warning("Image load with warning: %s." % e)
            im.save(thumbnail, "PNG")

        self.info['thumbnail'] = thumbnail
Exemple #22
0
 def __exit__(self, type, value, tb):
     self._lock.release()
     if type is not None and issubclass(type, sqlite3.DatabaseError):
             # Logs the error and return False, which makes __exit__ raise
             # exception again
             wok_log.error(traceback.format_exc())
             return False
 def delete(self, name):
     try:
         utils.delete_part(name)
     except OperationFailed as e:
         wok_log.error("delete partition failed")
         raise OperationFailed("GINPART00007E",
                               {'err': e})
Exemple #24
0
        def parse_hdds(temperature_unit):
            # hddtemp will strangely convert a non-number (see error case
            #   below) to 32 deg F. So just always ask for C and convert later.
            out, error, rc = run_command(['hddtemp'])
            if rc:
                wok_log.error("Error retrieving HD temperatures: rc %s."
                              "output: %s" % (rc, error))
                return None

            hdds = OrderedDict()

            for hdd in out.splitlines():
                hdd_name = ''
                hdd_temp = 0.0
                try:
                    hdd_items = hdd.split(':')
                    hdd_name, hdd_temp = hdd_items[0], hdd_items[2]
                    hdd_temp = re.sub('°[C|F]', '', hdd_temp).strip()
                except Exception as e:
                    wok_log.error('Sensors hdd parse error: %s' % e.message)
                    continue
                try:
                    # Try to convert the number to a float. If it fails,
                    # don't add this disk to the list.
                    hdd_temp = float(hdd_temp)
                    if(temperature_unit == 'F'):
                        hdd_temp = 9.0/5.0 * hdd_temp + 32
                    hdds[hdd_name] = hdd_temp
                except ValueError:
                    # If no sensor data, parse float will fail. For example:
                    # "/dev/sda: IBM IPR-10 5D831200: S.M.A.R.T. not available"
                    wok_log.warning("Sensors hdd: %s" % hdd)
            hdds['unit'] = temperature_unit
            return hdds
def _validate_device(device):
    """
    validate the device id. Valid device Ids should have
    <single digitnumber>.<single digitnumber>.<4 digit hexadecimalnumber>
    or <4 digit hexadecimal number>
    :param device: device id
    """
    pattern_with_dot = r'^\d\.\d\.[0-9a-fA-F]{4}$'
    if isinstance(device, unicode):
        # str() on non ascii non encoded cannot be done
        device = device.encode('utf-8')
    if device and not str(device).isspace():
        device = str(device).strip()
        if "." in device:
            out = re.search(pattern_with_dot, device)
        else:
            device = '0.0.' + device
            out = re.search(pattern_with_dot, device)
        if out is None:
            wok_log.error("Invalid device id. Device: %s" % device)
            raise InvalidParameter("GS390XINVINPUT",
                                   {'reason': 'invalid device id: %s'
                                              % device})
    else:
        wok_log.error("Device id is empty. Device: %s" % device)
        raise InvalidParameter("GS390XINVINPUT",
                               {'reason': 'device id is required. Device: %s'
                                          % device})
    return device
Exemple #26
0
    def delete(self, vm_name, dev_name):
        try:
            bus_type = self.lookup(vm_name, dev_name)['bus']
            dom = VMModel.get_vm(vm_name, self.conn)
        except NotFoundError:
            raise

        if (bus_type not in HOTPLUG_TYPE and
                DOM_STATE_MAP[dom.info()[0]] != 'shutoff'):
            raise InvalidOperation('KCHVMSTOR0011E')

        try:
            disk = get_device_node(dom, dev_name)
            path = get_vm_disk_info(dom, dev_name)['path']
            if path is None or len(path) < 1:
                path = self.lookup(vm_name, dev_name)['path']
            # This has to be done before it's detached. If it wasn't
            #   in the obj store, its ref count would have been updated
            #   by get_disk_used_by()
            if path is not None:
                used_by = get_disk_used_by(self.objstore, self.conn, path)
            else:
                wok_log.error("Unable to decrement volume used_by on"
                              " delete because no path could be found.")
            dom.detachDeviceFlags(etree.tostring(disk),
                                  get_vm_config_flag(dom, 'all'))
        except Exception as e:
            raise OperationFailed("KCHVMSTOR0010E", {'error': e.message})

        if used_by is not None and vm_name in used_by:
            used_by.remove(vm_name)
            set_disk_used_by(self.objstore, path, used_by)
        else:
            wok_log.error("Unable to update %s:%s used_by on delete."
                          % (vm_name, dev_name))
def _get_deviceinfo(lscss_out, device):
    """
    :param lscss_out: out of lscss command
    :param device: device id for which we need info to be returned
    :return: device info dict for the device from lscss output
    """
    device_pattern = r'(' + re.escape(device) + r')\s+' \
        r'(\d\.\d\.[0-9a-fA-F]{4})\s+' \
        r'(\w+\/\w+)\s+' \
        r'(\w+\/\w+)\s' \
        r'(\s{3}|yes)\s+' \
        r'([0-9a-fA-F]{2})\s+' \
        r'([0-9a-fA-F]{2})\s+' \
        r'([0-9a-fA-F]{2})\s+' \
        r'(\w+\s\w+)'
    if device:
        device = utils.get_row_data(lscss_out, HEADER_PATTERN, device_pattern)
        msg = 'The device is %s' % device
        wok_log.debug(msg)
        try:
            device_info = _format_lscss(device)
            return device_info
        except KeyError as e:
            wok_log.error('lscss column key not found')
            raise e
    else:
        return device
Exemple #28
0
 def _get_resources(self, flag_filter):
     try:
         get_list = getattr(self.model, model_fn(self, 'get_list'))
         idents = get_list(*self.model_args, **flag_filter)
         res_list = []
         for ident in idents:
             # internal text, get_list changes ident to unicode for sorted
             args = self.resource_args + [ident]
             res = self.resource(self.model, *args)
             try:
                 res.lookup()
             except Exception as e:
                 # In case of errors when fetching a resource info, pass and
                 # log the error, so, other resources are returned
                 # Encoding error message as ident is also encoded value.
                 # This has to be done to avoid unicode error,
                 # as combination of encoded and unicode value results into
                 # unicode error.
                 wok_log.error("Problem in lookup of resource '%s'. "
                               "Detail: %s" % (ident,
                                               encode_value(e.message)))
                 continue
             res_list.append(res)
         return res_list
     except AttributeError:
         return []
def get_mlx5_nic_type(mlx5_iface):
    """Checks lspci output to see if mlx5_iface is a physical or
    virtual nic interface.

    This is the lspci output this function is expecting for a mlx5 virtual
    nic interface:

    'Ethernet controller: Mellanox Technologies MT27700 Family
     [ConnectX-4 Virtual Function]'

    Verification will be done by checking for the 'Virtual Function'
    string in the output. Any other lspci output format or any other
    error will make this function return the default value 'physical'.

    Args:
        mlx5_iface (str): interface loaded by the mlx5_core driver.

    Returns:
        str: 'virtual' if mlx5_iface is a virtual function/nic,
            'physical' otherwise.

    """
    bus_id = get_mlx5_nic_bus_id(mlx5_iface)

    lspci_cmd = ['lspci', '-s', bus_id]
    out, err, r_code = run_command(lspci_cmd)

    if r_code == 0 and 'Virtual Function' in out:
        return 'virtual'

    if r_code != 0:
        wok_log.error('Error while getting nic type of '
                      'interface: %s' % err)

    return 'physical'
Exemple #30
0
    def get_iommu_group(dev_info):
        # Find out the iommu group of a given device.
        # Child device belongs to the same iommu group as the parent device.
        try:
            return dev_info['iommuGroup']
        except KeyError:
            pass

        parent = dev_info['parent']
        while parent is not None:
            try:
                parent_info = dev_dict[parent]
            except KeyError:
                wok_log.error("Parent %s of device %s does not exist",
                              parent, dev_info['name'])
                break

            try:
                iommuGroup = parent_info['iommuGroup']
            except KeyError:
                pass
            else:
                return iommuGroup

            parent = parent_info['parent']

        return None
Exemple #31
0
class StoragePoolsModel(object):
    def __init__(self, **kargs):
        self.conn = kargs['conn']
        self.objstore = kargs['objstore']
        self.scanner = Scanner(self._clean_scan)
        self.scanner.delete()
        self.caps = CapabilitiesModel(**kargs)
        self.device = DeviceModel(**kargs)

        if self.conn.get() is not None:
            if self.conn.isQemuURI():
                self._check_default_pools()

    def _check_default_pools(self):
        pools = {}

        default_pool = tmpl_defaults['disks'][0]['pool']['name']
        default_pool = default_pool.split('/')[-1]

        pools[default_pool] = {}
        if default_pool == 'default':
            pools[default_pool] = {'path': '/var/lib/libvirt/images'}

        if config.get('kimchi', {}).get('create_iso_pool', False):
            pools['ISO'] = {'path': '/var/lib/kimchi/isos'}

        error_msg = ("Please, check the configuration in %s/template.conf to "
                     "ensure it has a valid storage pool." %
                     kimchiPaths.sysconf_dir)

        conn = self.conn.get()
        for pool_name in pools:
            try:
                pool = conn.storagePoolLookupByName(pool_name)
            except libvirt.libvirtError, e:
                pool_path = pools[pool_name].get('path')
                if pool_path is None:
                    msg = "Fatal: Unable to find storage pool %s. " + error_msg
                    wok_log.error(msg % pool_name)
                    wok_log.error("Details: %s", e.message)
                    sys.exit(1)

                # Try to create the pool
                pool = E.pool(E.name(pool_name), type='dir')
                pool.append(E.target(E.path(pool_path)))
                xml = ET.tostring(pool)
                try:
                    pool = conn.storagePoolDefineXML(xml, 0)
                except libvirt.libvirtError, e:
                    msg = "Fatal: Unable to create storage pool %s. "
                    msg += error_msg
                    wok_log.error(msg % pool_name)
                    wok_log.error("Details: %s", e.message)
                    sys.exit(1)

                # Build and set autostart value to pool
                # Ignore error as the pool was already successfully created
                try:
                    # Add build step to make sure target directory created
                    # The build process may fail when the pool directory
                    # already exists on system
                    pool.build(libvirt.VIR_STORAGE_POOL_BUILD_NEW)
                    pool.setAutostart(1)
                except:
                    pass

            if pool.isActive() == 0:
                try:
                    pool.create(0)
                except libvirt.libvirtError, e:
                    msg = "Fatal: Unable to craete storage pool %s. "
                    msg += error_msg
                    wok_log.error(msg % pool_name)
                    wok_log.error("Details: %s", e.message)
                    sys.exit(1)
Exemple #32
0
    def sosreport_generate(cb, name):
        def log_error(e):
            log = logging.getLogger('Model')
            log.warning('Exception in generating debug file: %s', e)

        try:
            command = ['sosreport', '--batch', '--name=%s' % name]
            output, error, retcode = run_command(command)

            if retcode != 0:
                raise OperationFailed("KCHDR0003E", {
                    'name': name,
                    'err': retcode
                })

            # SOSREPORT might create file in /tmp or /var/tmp
            # FIXME: The right way should be passing the tar.xz file directory
            # though the parameter '--tmp-dir', but it is failing in Fedora 20
            patterns = ['/tmp/sosreport-%s-*', '/var/tmp/sosreport-%s-*']
            reports = []
            reportFile = None
            for p in patterns:
                reports = reports + [f for f in glob.glob(p % name)]
            for f in reports:
                if not fnmatch.fnmatch(f, '*.md5'):
                    reportFile = f
                    break
            # Some error in sosreport happened
            if reportFile is None:
                wok_log.error(
                    'Debug report file not found. See sosreport '
                    'output for detail:\n%s', output)
                fname = (patterns[0] % name).split('/')[-1]
                raise OperationFailed('KCHDR0004E', {'name': fname})

            md5_report_file = reportFile + '.md5'
            report_file_extension = '.' + reportFile.split('.', 1)[1]
            path = config.get_debugreports_path()
            target = os.path.join(path, name + report_file_extension)
            # Moving report
            msg = 'Moving debug report file "%s" to "%s"' % (reportFile,
                                                             target)
            wok_log.info(msg)
            shutil.move(reportFile, target)
            # Deleting md5
            msg = 'Deleting report md5 file: "%s"' % (md5_report_file)
            wok_log.info(msg)
            with open(md5_report_file) as f:
                md5 = f.read().strip()
                wok_log.info('Md5 file content: "%s"', md5)
            os.remove(md5_report_file)
            cb('OK', True)
            return

        except WokException as e:
            log_error(e)
            raise

        except OSError as e:
            log_error(e)
            raise

        except Exception, e:
            # No need to call cb to update the task status here.
            # The task object will catch the exception raised here
            # and update the task status there
            log_error(e)
            raise OperationFailed("KCHDR0005E", {'name': name, 'err': e})
Exemple #33
0
                'item': str(item),
                'name': name
            })

        if name in self.get_list():
            raise InvalidOperation("KCHPOOL0001E", {'name': name})

        try:
            if task_id:
                # Create transient pool for deep scan
                conn.storagePoolCreateXML(xml, 0)
                return name

            pool = conn.storagePoolDefineXML(xml, 0)
        except libvirt.libvirtError as e:
            wok_log.error("Problem creating Storage Pool: %s", e)
            raise OperationFailed("KCHPOOL0007E", {
                'name': name,
                'err': e.get_error_message()
            })

        # Build and set autostart value to pool
        # Ignore error as the pool was already successfully created
        # The build process fails when the pool directory already exists
        try:
            if params['type'] in ['logical', 'dir', 'netfs', 'scsi']:
                pool.build(libvirt.VIR_STORAGE_POOL_BUILD_NEW)
                pool.setAutostart(1)
            else:
                pool.setAutostart(0)
        except:
Exemple #34
0
    def _create_volume_with_url(self, cb, params):
        pool_name = params['pool']
        name = params['name']
        url = params['url']

        pool_model = StoragePoolModel(conn=self.conn, objstore=self.objstore)
        pool = pool_model.lookup(pool_name)

        if pool['type'] in ['dir', 'netfs']:
            file_path = os.path.join(pool['path'], name)
        else:
            file_path = tempfile.mkstemp(prefix=name)[1]

        with contextlib.closing(urllib2.urlopen(url)) as response:
            with open(file_path, 'w') as volume_file:
                remote_size = response.info().getheader('Content-Length', '-')
                downloaded_size = 0

                try:
                    while True:
                        chunk_data = response.read(READ_CHUNK_SIZE)
                        if not chunk_data:
                            break

                        volume_file.write(chunk_data)
                        downloaded_size += len(chunk_data)
                        cb('%s/%s' % (downloaded_size, remote_size))
                except (IOError, libvirt.libvirtError) as e:
                    if os.path.isfile(file_path):
                        os.remove(file_path)

                    raise OperationFailed('KCHVOL0007E', {
                        'name': name,
                        'pool': pool_name,
                        'err': e.message
                    })

        if pool['type'] in ['dir', 'netfs']:
            virt_pool = StoragePoolModel.get_storagepool(pool_name, self.conn)
            virt_pool.refresh(0)
        else:

            def _stream_handler(stream, nbytes, fd):
                return fd.read(nbytes)

            virt_stream = virt_vol = None

            try:
                task = self.create(
                    pool_name, {
                        'name': name,
                        'format': 'raw',
                        'capacity': downloaded_size,
                        'allocation': downloaded_size
                    })
                self.task.wait(task['id'])
                virt_vol = StorageVolumeModel.get_storagevolume(
                    pool_name, name, self.conn)

                virt_stream = self.conn.get().newStream(0)
                virt_vol.upload(virt_stream, 0, downloaded_size, 0)

                with open(file_path) as fd:
                    virt_stream.sendAll(_stream_handler, fd)

                virt_stream.finish()
            except (IOError, libvirt.libvirtError) as e:
                try:
                    if virt_stream:
                        virt_stream.abort()
                    if virt_vol:
                        virt_vol.delete(0)
                except libvirt.libvirtError, virt_e:
                    wok_log.error(virt_e.message)
                finally:
                    raise OperationFailed('KCHVOL0007E', {
                        'name': name,
                        'pool': pool_name,
                        'err': e.message
                    })
            finally: