Example #1
0
    def diskpool_get_info(self, pool):
        dp_info = self._smutclient.get_diskpool_info(pool)
        with zvmutils.expect_invalid_resp_data(dp_info):
            for k in list(dp_info.keys()):
                s = dp_info[k].strip().upper()
                if s.endswith('G'):
                    sl = s[:-1].split('.')
                    n1, n2 = int(sl[0]), int(sl[1])
                    if n2 >= 5:
                        n1 += 1
                    dp_info[k] = n1
                elif s.endswith('M'):
                    n_mb = int(s[:-3])
                    n_gb, n_ad = n_mb // 1024, n_mb % 1024
                    if n_ad >= 512:
                        n_gb += 1
                    dp_info[k] = n_gb
                else:
                    exp = "ending with a 'G' or 'M'"
                    errmsg = ("Invalid diskpool size format: %(invalid)s; "
                        "Expected: %(exp)s") % {'invalid': s, 'exp': exp}
                    LOG.error(errmsg)
                    raise exception.SDKInternalError(msg=errmsg)

        return dp_info
Example #2
0
    def get_info(self, userid):
        power_stat = self.get_power_state(userid)
        perf_info = self._smutclient.get_image_performance_info(userid)

        if perf_info:
            try:
                max_mem_kb = int(perf_info['max_memory'].split()[0])
                mem_kb = int(perf_info['used_memory'].split()[0])
                num_cpu = int(perf_info['guest_cpus'])
                cpu_time_us = int(perf_info['used_cpu_time'].split()[0])
            except (ValueError, TypeError, IndexError, AttributeError,
                    KeyError) as err:
                LOG.error('Parse performance_info encounter error: %s',
                          str(perf_info))
                raise exception.SDKInternalError(msg=str(err),
                                                    modID='guest')

            return {'power_state': power_stat,
                    'max_mem_kb': max_mem_kb,
                    'mem_kb': mem_kb,
                    'num_cpu': num_cpu,
                    'cpu_time_us': cpu_time_us}
        else:
            # virtual machine in shutdown state or not exists
            dict_info = self._smutclient.get_user_direct(userid)
            return {
                'power_state': power_stat,
                'max_mem_kb': self._get_max_memory_from_user_dict(dict_info),
                'mem_kb': 0,
                'num_cpu': self._get_cpu_num_from_user_dict(dict_info),
                'cpu_time_us': 0}
Example #3
0
 def get_adapters_info(self, userid):
     adapters_info = self._smtclient.get_adapters_info(userid)
     if not adapters_info:
         msg = 'Get network information failed on: %s' % userid
         LOG.error(msg)
         raise exception.SDKInternalError(msg=msg, modID='guest')
     return {'adapters': adapters_info}
Example #4
0
    def get_console_output(self, userid):
        def append_to_log(log_data, log_path):
            LOG.debug('log_data: %(log_data)r, log_path: %(log_path)r',
                         {'log_data': log_data, 'log_path': log_path})
            with open(log_path, 'a+') as fp:
                fp.write(log_data)

            return log_path

        LOG.info("Begin to capture console log on vm %s", userid)
        log_size = CONF.guest.console_log_size * 1024
        console_log = self._smutclient.get_user_console_output(userid)

        log_path = self._pathutils.get_console_log_path(userid)
        # TODO: need consider shrink log file size
        append_to_log(console_log, log_path)

        log_fp = file(log_path, 'rb')
        try:
            log_data, remaining = zvmutils.last_bytes(log_fp, log_size)
        except Exception as err:
            msg = ("Failed to truncate console log, error: %s" %
                   six.text_type(err))
            LOG.error(msg)
            raise exception.SDKInternalError(msg)

        if remaining > 0:
            LOG.info('Truncated console log returned, %d bytes ignored' %
                     remaining)

        LOG.info("Complete get console output on vm %s", userid)
        return log_data
Example #5
0
def execute(cmd):
    """ execute command, return rc and output string.
    The cmd argument can be a string or a list composed of
    the command name and each of its argument.
    eg, ['/usr/bin/cp', '-r', 'src', 'dst'] """

    # Parse cmd string to a list
    if not isinstance(cmd, list):
        cmd = shlex.split(cmd)
    # Execute command
    rc = 0
    output = ""
    try:
        output = subprocess.check_output(cmd,
                                         close_fds=True,
                                         stderr=subprocess.STDOUT)
    except subprocess.CalledProcessError as err:
        rc = err.returncode
        output = err.output
    except Exception as err:
        err_msg = ('Command "%s" Error: %s' % (' '.join(cmd), str(err)))
        raise exception.SDKInternalError(msg=err_msg)

    output = bytes.decode(output)
    return (rc, output)
Example #6
0
def translate_response_to_dict(rawdata, dirt):
    """Translate SMUT response to a python dictionary.

    SMUT response example:
    keyword1: value1\n
    keyword2: value2\n
    ...
    keywordn: valuen\n

    Will return a python dictionary:
    {keyword1: value1,
     keyword2: value2,
     ...
     keywordn: valuen,}

    """
    data_list = rawdata.split("\n")
    data = {}

    for ls in data_list:
        for k in list(dirt.keys()):
            if ls.__contains__(dirt[k]):
                data[k] = ls[(ls.find(dirt[k]) + len(dirt[k])):].strip()
                break

    if data == {}:
        msg = ("Invalid smut response data. Error: No value matched with "
               "keywords. Raw Data: %(raw)s; Keywords: %(kws)s" %
               {'raw': rawdata, 'kws': str(dirt)})
        raise exception.SDKInternalError(msg=msg)

    return data
Example #7
0
    def update_guest_by_userid(self,
                               userid,
                               meta=None,
                               net_set=None,
                               comments=None):
        userid = userid
        if (meta is None) and (net_set is None) and (comments is None):
            msg = ("Update guest with userid: %s failed, no field "
                   "specified to be updated." % userid)
            LOG.error(msg)
            raise exception.SDKInternalError(msg=msg, modID=self._module_id)

        # First check whether the guest exist in db table
        self._check_existence_by_userid(userid)
        # Start update
        sql_cmd = "UPDATE guests SET"
        sql_var = []
        if meta is not None:
            sql_cmd += " metadata=?,"
            sql_var.append(meta)
        if net_set is not None:
            sql_cmd += " net_set=?,"
            sql_var.append(net_set)
        if comments is not None:
            sql_cmd += " comments=?,"
            sql_var.append(comments)

        # remove the tailing comma
        sql_cmd = sql_cmd.strip(',')
        # Add the id filter
        sql_cmd += " WHERE userid=?"
        sql_var.append(userid)

        with get_guest_conn() as conn:
            conn.execute(sql_cmd, sql_var)
Example #8
0
 def decorated_function(*arg, **kwargs):
     try:
         return function(*arg, **kwargs)
     except (ValueError, TypeError, IndexError, AttributeError,
             KeyError) as err:
         msg = ('Invalid smt response data. Error: %s' % six.text_type(err))
         LOG.error(msg)
         raise exception.SDKInternalError(msg=msg)
Example #9
0
def expect_and_reraise_internal_error(modID='SDK'):
    """Catch all kinds of zvm client request failure and reraise.

    modID: the moduleID that the internal error happens in.
    """
    try:
        yield
    except exception.SDKInternalError as err:
        msg = err.format_message()
        raise exception.SDKInternalError(msg, modID=modID)
Example #10
0
def expect_invalid_resp_data(data=''):
    """Catch exceptions when using zvm client response data."""
    try:
        yield
    except (ValueError, TypeError, IndexError, AttributeError,
            KeyError) as err:
        msg = ('Invalid smut response data: %s. Error: %s' %
               (data, six.text_type(err)))
        LOG.error(msg)
        raise exception.SDKInternalError(msg=msg)
Example #11
0
def get_smut_userid():
    """Get the userid of smut server"""
    cmd = ["sudo", "/sbin/vmcp", "query userid"]
    try:
        userid = subprocess.check_output(cmd,
                                         close_fds=True,
                                         stderr=subprocess.STDOUT).split()[0]
        return userid
    except Exception as err:
        msg = ("Could not find the userid of the smut server: %s") % err
        raise exception.SDKInternalError(msg=msg)
Example #12
0
def check_userid_on_others(userid):
    try:
        check_userid_exist(userid)
        cmd = 'sudo vmcp q %s' % userid
        rc, output = execute(cmd)
        if re.search(' - SSI', output):
            return True
        return False
    except Exception as err:
        msg = ("Could not find the userid: %s") % err
        raise exception.SDKInternalError(msg=msg)
Example #13
0
    def _expand_fcp_list(fcp_list):
        """Expand fcp list string into a python list object which contains
        each fcp devices in the list string. A fcp list is composed of fcp
        device addresses, range indicator '-', and split indicator ';'.

        For example, if fcp_list is
        "0011-0013;0015;0017-0018", expand_fcp_list(fcp_list) will return
        [0011, 0012, 0013, 0015, 0017, 0018].

        ATTENTION: To support multipath, we expect fcp_list should be like
        "0011-0014;0021-0024", "0011-0014" should have been on same physical
        WWPN which we called path0, "0021-0024" should be on another physical
        WWPN we called path1 which is different from "0011-0014".
        path0 and path1 should have same count of FCP devices in their group.
        When attach, we will choose one WWPN from path0 group, and choose
        another one from path1 group. Then we will attach this pair of WWPNs
        together to the guest as a way to implement multipath.

        """
        LOG.debug("Expand FCP list %s" % fcp_list)

        if not fcp_list:
            return set()
        fcp_list = fcp_list.strip()
        fcp_list = fcp_list.replace(' ', '')
        range_pattern = '[0-9a-fA-F]{1,4}(-[0-9a-fA-F]{1,4})?'
        match_pattern = "^(%(range)s)(;%(range)s;?)*$" % \
                        {'range': range_pattern}
        if not re.match(match_pattern, fcp_list):
            errmsg = ("Invalid FCP address %s") % fcp_list
            raise exception.SDKInternalError(msg=errmsg)

        fcp_devices = {}
        path_no = 0
        for _range in fcp_list.split(';'):
            # remove duplicate entries
            devices = set()
            if _range != '':
                if '-' not in _range:
                    # single device
                    fcp_addr = int(_range, 16)
                    devices.add("%04x" % fcp_addr)
                else:
                    # a range of address
                    (_min, _max) = _range.split('-')
                    _min = int(_min, 16)
                    _max = int(_max, 16)
                    for fcp_addr in range(_min, _max + 1):
                        devices.add("%04x" % fcp_addr)
                fcp_devices[path_no] = devices
            path_no = path_no + 1

        return fcp_devices
Example #14
0
def convert_to_mb(s):
    """Convert memory size from GB to MB."""
    s = s.upper()
    try:
        if s.endswith('G'):
            return float(s[:-1].strip()) * 1024
        elif s.endswith('T'):
            return float(s[:-1].strip()) * 1024 * 1024
        else:
            return float(s[:-1].strip())
    except (IndexError, ValueError, KeyError, TypeError):
        errmsg = ("Invalid memory format: %s") % s
        raise exception.SDKInternalError(msg=errmsg)
Example #15
0
def get_lpar_name():
    """Get the name of the LPAR that this vm is on."""
    cmd = ["sudo", "/sbin/vmcp", "query userid"]
    try:
        userid = subprocess.check_output(cmd,
                                         close_fds=True,
                                         stderr=subprocess.STDOUT)
        userid = bytes.decode(userid)
        userid = userid.split()[-1]
        return userid
    except Exception as err:
        msg = ("Failed to get the LPAR name for the smt server: %s") % err
        raise exception.SDKInternalError(msg=msg)
Example #16
0
    def get_metadata_by_userid(self, userid):
        """get metadata record.
        output should be like: "a=1,b=2,c=3"
        """
        userid = userid
        with get_guest_conn() as conn:
            res = conn.execute("SELECT * FROM guests "
                               "WHERE userid=?", (userid, ))
            guest = res.fetchall()

        if len(guest) == 1:
            return guest[0][2]
        elif len(guest) == 0:
            LOG.debug("Guest with userid: %s not found from DB!" % userid)
            return ''
        else:
            msg = "Guest with userid: %s have multiple records!" % userid
            LOG.error(msg)
            raise exception.SDKInternalError(msg=msg, modID=self._module_id)
Example #17
0
    def _expand_fcp_list(fcp_list):
        """Expand fcp list string into a python list object which contains
        each fcp devices in the list string. A fcp list is composed of fcp
        device addresses, range indicator '-', and split indicator ';'.

        For example, if fcp_list is
        "0011-0013;0015;0017-0018", expand_fcp_list(fcp_list) will return
        [0011, 0012, 0013, 0015, 0017, 0018].

        """

        LOG.debug("Expand FCP list %s" % fcp_list)

        if not fcp_list:
            return set()

        range_pattern = '[0-9a-fA-F]{1,4}(-[0-9a-fA-F]{1,4})?'
        match_pattern = "^(%(range)s)(;%(range)s)*$" % {'range': range_pattern}
        if not re.match(match_pattern, fcp_list):
            errmsg = ("Invalid FCP address %s") % fcp_list
            raise exception.SDKInternalError(msg=errmsg)

        fcp_devices = set()
        for _range in fcp_list.split(';'):
            if '-' not in _range:
                # single device
                fcp_addr = int(_range, 16)
                fcp_devices.add("%04x" % fcp_addr)
            else:
                # a range of address
                (_min, _max) = _range.split('-')
                _min = int(_min, 16)
                _max = int(_max, 16)
                for fcp_addr in range(_min, _max + 1):
                    fcp_devices.add("%04x" % fcp_addr)

        # remove duplicate entries
        return fcp_devices
Example #18
0
    def get_info(self, userid):
        power_stat = self.get_power_state(userid)
        perf_info = self._smtclient.get_image_performance_info(userid)

        # Get the online CPU number, OS distro and kernel version
        try:
            act_cpus = self._smtclient.get_active_cpu_addrs(userid)
            act_cpus_num = len(act_cpus)
            LOG.debug('Online cpu info: %s, %d' % (act_cpus, act_cpus_num))
        except exception.SDKSMTRequestFailed as err:
            msg = ('Failed to execute command on capture source vm %(vm)s '
                   'to get online cpu number with error %(err)s'
                   % {'vm': userid, 'err': err.results['response'][0]})
            LOG.error(msg)
            act_cpus_num = 0

        try:
            os_distro = self._smtclient.guest_get_os_version(userid)
            kernel_info = self._smtclient.guest_get_kernel_info(userid)
            LOG.debug('OS and kernel info: %s, %s' % (os_distro, kernel_info))
        except exception.SDKSMTRequestFailed as err:
            msg = ('Failed to execute command on capture source vm %(vm)s '
                   'to get OS distro with error %(err)s'
                   % {'vm': userid, 'err': err.results['response'][0]})
            LOG.error(msg)
            os_distro = ''
            kernel_info = ''

        if perf_info:
            try:
                max_mem_kb = int(perf_info['max_memory'].split()[0])
                mem_kb = int(perf_info['used_memory'].split()[0])
                num_cpu = int(perf_info['guest_cpus'])
                cpu_time_us = int(perf_info['used_cpu_time'].split()[0])
            except (ValueError, TypeError, IndexError, AttributeError,
                    KeyError) as err:
                LOG.error('Parse performance_info encounter error: %s',
                          str(perf_info))
                raise exception.SDKInternalError(msg=str(err),
                                                    modID='guest')

            return {'power_state': power_stat,
                    'max_mem_kb': max_mem_kb,
                    'mem_kb': mem_kb,
                    'num_cpu': num_cpu,
                    'cpu_time_us': cpu_time_us,
                    'online_cpu_num': act_cpus_num,
                    'os_distro': os_distro,
                    'kernel_info': kernel_info}
        else:
            # virtual machine in shutdown state or not exists
            dict_info = self._smtclient.get_user_direct(userid)
            return {
                'power_state': power_stat,
                'max_mem_kb': self._get_max_memory_from_user_dict(dict_info),
                'mem_kb': 0,
                'num_cpu': self._get_cpu_num_from_user_dict(dict_info),
                'cpu_time_us': 0,
                'online_cpu_num': act_cpus_num,
                'os_distro': os_distro,
                'kernel_info': kernel_info}