def lv_take_snapshot(vg_name, lv_name, lv_snapshot_name, lv_snapshot_size): """ Take a snapshot of the original logical volume. """ error_context.context("Taking snapshot from original logical volume", logging.info) if not vg_check(vg_name): raise exceptions.TestError("Volume group could not be found") if lv_check(vg_name, lv_snapshot_name): raise exceptions.TestError("Snapshot already exists") if not lv_check(vg_name, lv_name): raise exceptions.TestError("Snapshot's origin could not be found") cmd = ("lvcreate --size " + lv_snapshot_size + " --snapshot " + " --name " + lv_snapshot_name + " /dev/" + vg_name + "/" + lv_name) try: result = process.run(cmd) except process.CmdError as ex: if ('Logical volume "%s" already exists in volume group "%s"' % (lv_snapshot_name, vg_name) in results_stderr_52lts(ex.result) and re.search(re.escape(lv_snapshot_name + " [active]"), results_stdout_52lts(process.run("lvdisplay")))): # the above conditions detect if merge of snapshot was postponed logging.warning(("Logical volume %s is still active! " + "Attempting to deactivate..."), lv_name) lv_reactivate(vg_name, lv_name) result = process.run(cmd) else: raise ex logging.info(results_stdout_52lts(result).rstrip())
def get_status(selinux_force=False): """ Get the status of selinux. :param selinux_force: True to force selinux configuration on Ubuntu :return: string of status in STATUS_LIST. :raise SeCmdError: if execute 'getenforce' failed. :raise SelinuxError: if 'getenforce' command exit 0, but the output is not expected. """ if ubuntu and not selinux_force: logging.warning("Ubuntu doesn't support selinux by default") return 'disabled' cmd = 'getenforce' try: result = process.run(cmd, ignore_status=True) except OSError: raise SeCmdError(cmd, "Command not available") if result.exit_status: raise SeCmdError(cmd, results_stderr_52lts(result)) for status in STATUS_LIST: if results_stdout_52lts(result).lower().count(status): return status else: continue raise SelinuxError("result of 'getenforce' (%s)is not expected." % results_stdout_52lts(result))
def find_hbas(hba_type="hba", status="online"): """ Find online hba/vhba cards. :params hba_type: "vhba" or "hba" :params status: "online" or "offline" :return: A list contains the online/offline vhba/hba list """ # TODO: add status=offline/online judgement, we don't test offline vhba now # so leave it here as a placeholder. result = virsh.nodedev_list(cap="scsi_host") if result.exit_status: raise exceptions.TestFail(results_stderr_52lts(result)) scsi_hosts = results_stdout_52lts(result).strip().splitlines() online_hbas_list = [] online_vhbas_list = [] # go through all scsi hosts, and split hbas/vhbas into lists for scsi_host in scsi_hosts: result = virsh.nodedev_dumpxml(scsi_host) stdout = results_stdout_52lts(result).strip() if result.exit_status: raise exceptions.TestFail(results_stderr_52lts(result)) if (re.search('vport_ops', stdout) and not re.search('<fabric_wwn>ffffffffffffffff</fabric_wwn>', stdout) and not re.search('<fabric_wwn>0</fabric_wwn>', stdout)): online_hbas_list.append(scsi_host) if re.search('fc_host', stdout) and not re.search('vport_ops', stdout): online_vhbas_list.append(scsi_host) if hba_type == "hba": return online_hbas_list if hba_type == "vhba": return online_vhbas_list
def get_cpustats(vm, cpu=None): """ Get the cpustats output of a given domain :param vm: VM domain :param cpu: Host cpu index, default all cpus :return: dict of cpu stats values result format: {0:[vcputime,emulatortime,cputime] .. 'total':[cputime]} """ host_cpu_online = utils.cpu_online_list() cpustats = {} if cpu: cpustats[cpu] = [] option = "--start %s --count 1" % cpu result = virsh.cpu_stats(vm.name, option) if result.exit_status != 0: logging.error("cpu stats command failed: %s", results_stderr_52lts(result)) return None output = results_stdout_52lts(result).strip().split() if re.match("CPU%s" % cpu, output[0]): cpustats[cpu] = [ float(output[5]), # vcputime float(output[2]) - float(output[5]), # emulator float(output[2]) ] # cputime else: for i in range(len(host_cpu_online)): cpustats[host_cpu_online[i]] = [] option = "--start %s --count 1" % host_cpu_online[i] result = virsh.cpu_stats(vm.name, option) if result.exit_status != 0: logging.error("cpu stats command failed: %s", results_stderr_52lts(result)) return None output = results_stdout_52lts(result).strip().split() if re.match("CPU%s" % host_cpu_online[i], output[0]): cpustats[host_cpu_online[i]] = [ float(output[5]), float(output[2]) - float(output[5]), float(output[2]) ] result = virsh.cpu_stats(vm.name, "--total") cpustats["total"] = [] if result.exit_status != 0: logging.error("cpu stats command failed: %s", results_stderr_52lts(result)) return None output = results_stdout_52lts(result).strip().split() cpustats["total"] = [float(output[2])] # cputime return cpustats
def get_vcpucount_details(vm, options): """ To get vcpucount output :param vm: VM object :param options: options to passed to vcpucount :return: tuple of result and dict of vcpucount output values """ vcpucount_details = { 'max_config': None, 'max_live': None, 'cur_config': None, 'cur_live': None, 'guest_live': None } result = virsh.vcpucount(vm.name, options, ignore_status=True, debug=True) if results_stderr_52lts(result): logging.debug("vcpu count command failed") return (result, vcpucount_details) if options: stdout = results_stdout_52lts(result).strip() if 'guest' in options: vcpucount_details['guest_live'] = int(stdout) elif 'config' in options: if 'maximum' in options: vcpucount_details['max_config'] = int(stdout) else: vcpucount_details['cur_config'] = int(stdout) elif 'live' in options: if 'maximum' in options: vcpucount_details['max_live'] = int(stdout) else: vcpucount_details['cur_live'] = int(stdout) else: output = results_stdout_52lts(result).strip().split('\n') for item in output: if ('maximum' in item) and ('config' in item): vcpucount_details['max_config'] = int(item.split()[2].strip()) elif ('maximum' in item) and ('live' in item): vcpucount_details['max_live'] = int(item.split()[2].strip()) elif ('current' in item) and ('config' in item): vcpucount_details['cur_config'] = int(item.split()[2].strip()) elif ('current' in item) and ('live' in item): vcpucount_details['cur_live'] = int(item.split()[2].strip()) else: pass return (result, vcpucount_details)
def vg_ramdisk(vg_name, ramdisk_vg_size, ramdisk_basedir, ramdisk_sparse_filename): """ Create vg on top of ram memory to speed up lv performance. """ error_context.context("Creating virtual group on top of ram memory", logging.info) vg_size = ramdisk_vg_size vg_ramdisk_dir = os.path.join(ramdisk_basedir, vg_name) ramdisk_filename = os.path.join(vg_ramdisk_dir, ramdisk_sparse_filename) vg_ramdisk_cleanup(ramdisk_filename, vg_ramdisk_dir, vg_name, "") result = "" if not os.path.exists(vg_ramdisk_dir): os.mkdir(vg_ramdisk_dir) try: logging.info("Mounting tmpfs") result = process.run("mount -t tmpfs tmpfs " + vg_ramdisk_dir) logging.info("Converting and copying /dev/zero") cmd = ("dd if=/dev/zero of=" + ramdisk_filename + " bs=1M count=1 seek=" + vg_size) result = process.run(cmd, verbose=True) logging.info("Finding free loop device") result = process.run("losetup --find", verbose=True) except process.CmdError as ex: logging.error(ex) vg_ramdisk_cleanup(ramdisk_filename, vg_ramdisk_dir, vg_name, "") raise ex loop_device = results_stdout_52lts(result).rstrip() try: logging.info("Creating loop device") result = process.run("losetup " + loop_device + " " + ramdisk_filename) logging.info("Creating physical volume %s", loop_device) result = process.run("pvcreate " + loop_device) logging.info("Creating volume group %s", vg_name) result = process.run("vgcreate " + vg_name + " " + loop_device) except process.CmdError as ex: logging.error(ex) vg_ramdisk_cleanup(ramdisk_filename, vg_ramdisk_dir, vg_name, loop_device) raise ex logging.info(results_stdout_52lts(result).rstrip())
def get_cpustats(vm, cpu=None): """ Get the cpustats output of a given domain :param vm: VM domain :param cpu: Host cpu index, default all cpus :return: dict of cpu stats values result format: {0:[vcputime,emulatortime,cputime] .. 'total':[cputime]} """ host_cpu_online = utils.cpu_online_list() cpustats = {} if cpu: cpustats[cpu] = [] option = "--start %s --count 1" % cpu result = virsh.cpu_stats(vm.name, option) if result.exit_status != 0: logging.error("cpu stats command failed: %s", results_stderr_52lts(result)) return None output = results_stdout_52lts(result).strip().split() if re.match("CPU%s" % cpu, output[0]): cpustats[cpu] = [float(output[5]), # vcputime float(output[2]) - float(output[5]), # emulator float(output[2])] # cputime else: for i in range(len(host_cpu_online)): cpustats[host_cpu_online[i]] = [] option = "--start %s --count 1" % host_cpu_online[i] result = virsh.cpu_stats(vm.name, option) if result.exit_status != 0: logging.error("cpu stats command failed: %s", results_stderr_52lts(result)) return None output = results_stdout_52lts(result).strip().split() if re.match("CPU%s" % host_cpu_online[i], output[0]): cpustats[host_cpu_online[i]] = [float(output[5]), float(output[2]) - float(output[5]), float(output[2])] result = virsh.cpu_stats(vm.name, "--total") cpustats["total"] = [] if result.exit_status != 0: logging.error("cpu stats command failed: %s", results_stderr_52lts(result)) return None output = results_stdout_52lts(result).strip().split() cpustats["total"] = [float(output[2])] # cputime return cpustats
def compare_images(self, image1, image2, strict_mode=False, verbose=True, force_share=False): """ Compare 2 images using the appropriate tools for each virt backend. :param image1: image path of first image :param image2: image path of second image :param strict_mode: Boolean value, True for strict mode, False for default mode. :param verbose: Record output in debug file or not :return: process.CmdResult object containing the result of the command """ compare_images = self.support_cmd("compare") force_share &= self.cap_force_share if not compare_images: logging.warn("sub-command compare not supported by qemu-img") return None else: logging.info("Comparing images %s and %s", image1, image2) compare_cmd = "%s compare" % self.image_cmd if force_share: compare_cmd += " -U" if strict_mode: compare_cmd += " -s" compare_cmd += " %s %s" % (image1, image2) cmd_result = process.run(compare_cmd, ignore_status=True, shell=True) if verbose: logging.debug("Output from command: %s", results_stdout_52lts(cmd_result)) if cmd_result.exit_status == 0: logging.info("Compared images are equal") elif cmd_result.exit_status == 1: raise exceptions.TestFail("Compared images differ") else: raise exceptions.TestError("Error in image comparison") cmd_result.stdout = results_stdout_52lts(cmd_result) cmd_result.stderr = results_stderr_52lts(cmd_result) return cmd_result
def get_qemu_cpu_models(qemu_binary): """Get listing of CPU models supported by QEMU Get list of CPU models by parsing the output of <qemu> -cpu '?' """ cmd = qemu_binary + " -cpu '?'" result = process.run(cmd, verbose=False) return extract_qemu_cpu_models(results_stdout_52lts(result))
def run(self, command, timeout=60, ignore_status=False): """ Method to provide a utils.run-like interface to execute command on remote host or guest. :param timeout: Total time duration to wait for command return. :param ignore_status: If ignore_status=True, do not raise an exception, no matter what the exit code of the command is. Else, raise CmdError if exit code of command is not zero. """ # Redirect the stdout and stderr to file, Deviding error message # from output, and taking off the color of output. To return the same # result with utils.run() function. command = "%s 1>%s 2>%s" % ( command, self.stdout_pipe, self.stderr_pipe) status, _ = self.session.cmd_status_output(command, timeout=timeout) output = self.session.cmd_output("cat %s;rm -f %s" % (self.stdout_pipe, self.stdout_pipe)) errput = self.session.cmd_output("cat %s;rm -f %s" % (self.stderr_pipe, self.stderr_pipe)) cmd_result = process.CmdResult(command=command, exit_status=status, stdout=output, stderr=errput) cmd_result.stdout = results_stdout_52lts(cmd_result) cmd_result.stderr = results_stderr_52lts(cmd_result) if status and (not ignore_status): raise process.CmdError(command, cmd_result) return cmd_result
def prepare_scheduler(params, test, vm): """ 1. Save old scheduler for test tear down 2. Set scheduler for test or cancel test if not supported 3. Return test parameter dictionary :param params: test parameters :param test: test instance :param vm: test vm instance :return: dictionary of test parameters enriched with scheduler dynamic parameters """ update_schedulerfd(params) test_dict = dict(params) test_dict['vm'] = vm cmd = "cat " + schedulerfd iosche = results_stdout_52lts(process.run(cmd, shell=True)) logging.debug("iosche value is:%s", iosche) test_dict['oldmode'] = re.findall(r"\[(.*?)\]", iosche)[0] iosche_for_test = "" with open(schedulerfd, 'w') as scf: if 'cfq' in iosche: iosche_for_test = 'cfq' elif 'bfq' in iosche: iosche_for_test = 'bfq' else: test.fail('Unknown scheduler in %s' % schedulerfd) scf.write(iosche_for_test) test_dict['iosche_for_test'] = iosche_for_test return test_dict
def vg_list(): """ List available volume groups. """ cmd = "vgs --all" vgroups = {} result = process.run(cmd) lines = results_stdout_52lts(result).strip().splitlines() if len(lines) > 1: columns = lines[0].split() lines = lines[1:] else: return vgroups for line in lines: details = line.split() details_dict = {} index = 0 for column in columns: if re.search("VG", column): vg_name = details[index] else: details_dict[column] = details[index] index += 1 vgroups[vg_name] = details_dict return vgroups
def _run_restorecon(pathname, dirdesc, readonly=True, force=False, selinux_force=False): """ Use restorecon to restore selinux context for file :param pathname: Absolute path to file, directory, or symlink :param dirdesc: True to descend into sub-directories :param readonly: True to passive check and don't change any file labels :param force: True to force reset of context to match file_context :param selinux_force: True to force selinux configuration on Ubuntu """ if ubuntu and not selinux_force: logging.warning("Ubuntu doesn't support selinux by default") return 0 cmd = 'restorecon -v' if dirdesc: cmd += 'R' if readonly: cmd += 'n' if force: cmd += 'F' cmd += ' "%s"' % pathname # Always returns 0, even if contexts wrong return results_stdout_52lts(process.run(cmd)).strip()
def get_virsh_output_dict(self, vm_name=None, virsh_cmd=None): """ Get the virsh cmd output as a dict :param vm_name: Name of the vm :param virsh_cmd: Name of the virsh cmd :return: The virsh cmd output, as a dict """ if virsh_cmd == "memtune": func = virsh.memtune_list elif virsh_cmd == "blkiotune": func = virsh.blkiotune elif virsh_cmd == "schedinfo": func = virsh.schedinfo else: logging.error("There is no virsh cmd '%s'", virsh_cmd) return None result = func(vm_name, ignore_status=True) output = results_stdout_52lts(result).strip() output_list = output.splitlines() output_dict = {} for output_line in output_list: output_info = output_line.split(":") output_param = output_info[0].strip() if len(output_info) == 1: output_value = "" else: output_value = output_info[1].strip() output_dict[output_param] = output_value return output_dict
def systemd_list_parser(cmdResult=None): """ Parse method for service sub-command list. :return in form of dict-like, including service name, status and so on For example:: {"sshd": "enabled", "vsftpd": "disabled", "systemd-sysctl": "static", ... } """ if cmdResult.exit_status: raise process.CmdError(cmdResult.command, cmdResult) # store service name and status. _service2status_dict = {} lines = results_stdout_52lts(cmdResult).strip().splitlines() for line in lines: sublines = line.strip().split() if (not len(sublines) == 2) or (not sublines[0].endswith("service")): # Some lines useless. continue service_name = sublines[0].rstrip(".service") status = sublines[-1] _service2status_dict[service_name] = status return _service2status_dict
def set_context_of_file(filename, context, selinux_force=False): """ Set context of file. :param filename: filename for the context to be set :param context: new value of the extended context attribute :param selinux_force: True to force selinux configuration on Ubuntu :raise SeCmdError: if failed to execute chcon. :raise SelinuxError: if command chcon execute normally, but the context of file is not setted to context. """ if ubuntu and not selinux_force: logging.warning("Ubuntu doesn't support selinux by default") return context = context.strip() # setfattr used for consistency with getfattr use above cmd = ("setfattr --name security.selinux --value \"%s\" %s" % (context, filename)) result = process.run(cmd, ignore_status=True) if result.exit_status: raise SeCmdError(cmd, results_stdout_52lts(result)) context_result = get_context_of_file(filename) if not context == context_result: raise SelinuxError("Context of %s after chcon is %s, " "but not expected %s." % (filename, context_result, context)) logging.debug("Set context of %s success.", filename)
def check_migration_res(result): """ Check if the migration result is as expected :param result: the output of migration :raise: test.fail if test is failed """ logging.info("Migration out: %s", results_stdout_52lts(result).strip()) logging.info("Migration error: %s", results_stderr_52lts(result).strip()) if status_error: # Migration should fail if err_msg: # Special error messages are expected if not re.search(err_msg, results_stderr_52lts(result).strip()): test.fail("Can not find the expected patterns '%s' in " "output '%s'" % (err_msg, results_stderr_52lts(result).strip())) else: logging.debug("It is the expected error message") else: if int(result.exit_status) != 0: logging.debug("Migration failure is expected result") else: test.fail("Migration success is unexpected result") else: if int(result.exit_status) != 0: test.fail(results_stderr_52lts(result).strip())
def hotplug_supported(vm_name, mtype): """ hotplug support check for ppc64le :param vm_name: VM name :param mtype: machine type :return: True if supported and False in all other cases """ supported = False if "ppc64" in platform.machine(): cmd = '{\"execute\":\"query-machines\"}' json_result = virsh.qemu_monitor_command(vm_name, cmd, "--pretty", debug=False) try: result = json.loads(results_stdout_52lts(json_result)) except Exception: # Failure to parse json output and default support to False # TODO: Handle for failure cases return supported for item in result['return']: try: if item['name'] == mtype: try: if item['hotpluggable-cpus'] == 'True': supported = True except KeyError: pass except KeyError: pass else: # For now returning for other arch by default true supported = True return supported
def run(self, args): # Enable root logger as some Avocado-vt libraries use that handler = logging.StreamHandler() handler.setLevel(logging.DEBUG) logging.getLogger("").addHandler(handler) try: bootstrap.bootstrap(options=args, interactive=True) sys.exit(0) except process.CmdError as ce: if ce.result.interrupted: logging.info('Bootstrap command interrupted by user') logging.info('Command: %s', ce.command) else: logging.error('Bootstrap command failed') logging.error('Command: %s', ce.command) stderr = results_stderr_52lts(ce.result) if stderr: logging.error('stderr output:') logging.error(stderr) stdout = results_stdout_52lts(ce.result) if stdout: logging.error('stdout output:') logging.error(stdout) sys.exit(1) except KeyboardInterrupt: logging.info('Bootstrap interrupted by user') sys.exit(1)
def find_scsi_luns(scsi_host): """ Find available luns of specified scsi_host. :param scsi_host: The scsi host name in format of "scsi_host#" :return: A dictionary contains all available fc luns """ lun_dicts = [] tmp_list = [] scsi_number = scsi_host.replace("scsi_host", "") cmd = "multipath -ll | grep '\- %s:' | grep 'ready running' |\ awk '{FS=\" \"}{for (f=1; f<=NF; f+=1) {if ($f ~ /%s:/)\ {print $f}}}'" % (scsi_number, scsi_number) try: result = process.run(cmd, shell=True) except Exception as e: raise exceptions.TestError("run 'multipath' failed: %s" % str(e)) tmp_list = results_stdout_52lts(result).strip().splitlines() for lun in tmp_list: lun = lun.split(":") lun_dicts_item = {} lun_dicts_item["scsi"] = lun[0] lun_dicts_item["bus"] = lun[1] lun_dicts_item["target"] = lun[2] lun_dicts_item["unit"] = lun[3] lun_dicts.append(lun_dicts_item) return lun_dicts
def list_pools(self): """ Return a dict include pools' information with structure: pool_name ==> pool_details(a dict: feature ==> value) """ # Allow it raise exception if command has executed failed. result = self.virsh_instance.pool_list("--all", ignore_status=False) pools = {} lines = results_stdout_52lts(result).strip().splitlines() if len(lines) > 2: head = lines[0] lines = lines[2:] else: return pools for line in lines: details = line.split() details_dict = {} head_iter = enumerate(head.split()) while True: try: (index, column) = next(head_iter) except StopIteration: break if re.match("[N|n]ame", column): pool_name = details[index] else: details_dict[column] = details[index] pools[pool_name] = details_dict return pools
def list_volumes(self): """ Return a dict include volumes' name(key) and path(value). """ volumes = {} try: result = self.virsh_instance.vol_list(self.pool_name, ignore_status=False) except process.CmdError as detail: logging.error('List volume failed: %s', detail) return volumes lines = results_stdout_52lts(result).strip().splitlines() if len(lines) > 2: head = lines[0] lines = lines[2:] else: return volumes for line in lines: # Path may be not standard unix path try: path = re.findall("\s+\S*/.*", line)[0] except IndexError: # Do not find a path path = "" name = line.split(path)[0].lstrip() volumes[name] = path.strip() return volumes
def do_migration(vm, dest_uri, options, extra): """ Execute the migration with given parameters :param vm: the guest to be migrated :param dest_uri: the destination uri for migration :param options: options next to 'migrate' command :param extra: options in the end of the migrate command line :return: CmdResult object """ logging.info("Sleeping 10 seconds before migration") time.sleep(10) # Migrate the guest. migration_res = vm.migrate(dest_uri, options, extra, **virsh_args) logging.info("Migration out: %s", results_stdout_52lts(migration_res).strip()) logging.info("Migration error: %s", results_stderr_52lts(migration_res).strip()) if int(migration_res.exit_status) != 0: logging.error("Migration failed for %s.", vm_name) return migration_res if vm.is_alive(): # vm.connect_uri was updated logging.info("VM is alive on destination %s.", dest_uri) else: test.fail("VM is not alive on destination %s" % dest_uri) # Throws exception if console shows panic message vm.verify_kernel_crash() return migration_res
def get_version(abbrev=4): global _GIT_VERSION_CACHE release_version = _read_release_version() if _GIT_VERSION_CACHE is not None: version = _GIT_VERSION_CACHE else: _GIT_VERSION_CACHE = get_git_version(abbrev) version = _GIT_VERSION_CACHE if version is None: version = release_version if version is None: try: cmd_result = process.run("rpm -q avocado-plugins-vt " "--queryformat '%{VERSION}'", shell=True, verbose=False) return '%s (RPM install)' % results_stdout_52lts(cmd_result) except process.CmdError: return 'unknown' if version != release_version: _write_release_version(version) return version
def get_secret_list(): """ Get secret list. :return secret list """ logging.info("Get secret list ...") secret_list_result = virsh.secret_list() secret_list = results_stdout_52lts( secret_list_result).strip().splitlines() # First two lines contain table header followed by entries # for each secret, such as: # # UUID Usage # -------------------------------------------------------------------------------- # b4e8f6d3-100c-4e71-9f91-069f89742273 ceph client.libvirt secret secret_list = secret_list[2:] result = [] # If secret list is empty. if secret_list: for line in secret_list: # Split on whitespace, assume 1 column linesplit = line.split(None, 1) result.append(linesplit[0]) return result
def get_vcpucount_details(vm, options): """ To get vcpucount output :param vm: VM object :param options: options to passed to vcpucount :return: tuple of result and dict of vcpucount output values """ vcpucount_details = {'max_config': None, 'max_live': None, 'cur_config': None, 'cur_live': None, 'guest_live': None} result = virsh.vcpucount(vm.name, options, ignore_status=True, debug=True) if results_stderr_52lts(result): logging.debug("vcpu count command failed") return (result, vcpucount_details) if options: stdout = results_stdout_52lts(result).strip() if 'guest' in options: vcpucount_details['guest_live'] = int(stdout) elif 'config' in options: if 'maximum' in options: vcpucount_details['max_config'] = int(stdout) else: vcpucount_details['cur_config'] = int(stdout) elif 'live' in options: if 'maximum' in options: vcpucount_details['max_live'] = int(stdout) else: vcpucount_details['cur_live'] = int(stdout) else: output = results_stdout_52lts(result).strip().split('\n') for item in output: if ('maximum' in item) and ('config' in item): vcpucount_details['max_config'] = int(item.split()[2].strip()) elif ('maximum' in item) and ('live' in item): vcpucount_details['max_live'] = int(item.split()[2].strip()) elif ('current' in item) and ('config' in item): vcpucount_details['cur_config'] = int(item.split()[2].strip()) elif ('current' in item) and ('live' in item): vcpucount_details['cur_live'] = int(item.split()[2].strip()) else: pass return (result, vcpucount_details)
def get_name_of_init(self): """ Internal function to determine what executable is PID 1, :return: executable name for PID 1, aka init :rtype: str """ output = results_stdout_52lts(self.run("ps -o comm 1")) return output.splitlines()[-1].strip()
def read_from_numastat(pid, key): """ Get the process numastat from numastat output. """ cmd = "numastat %s" % pid numa_mem = results_stdout_52lts(process.run(cmd)).strip() mem_line = re.findall(r"^%s.*" % key, numa_mem, re.M)[0] return re.findall(r"(\d+.\d+)", mem_line)
def amend(self, params, cache_mode=None, ignore_status=False): """ Amend the image format specific options for the image :param params: dictionary containing the test parameters :param cache_mode: the cache mode used to write the output disk image, the valid options are: 'none', 'writeback' (default), 'writethrough', 'directsync' and 'unsafe'. :param ignore_status: Whether to raise an exception when command returns =! 0 (False), or not (True). :note: params may contain amend options: amend_size virtual disk size of the image (a string qemu-img can understand, such as '10G') amend_compat compatibility level (0.10 or 1.1) amend_backing_file file name of a base image amend_backing_fmt image format of the base image amend_encryption encrypt the image, allowed values: on and off. Default is "off" amend_cluster_size cluster size for the image amend_preallocation preallocation mode when create image, allowed values: off, metadata. Default is "off" amend_lazy_refcounts postpone refcount updates, allowed values: on and off. Default is "off" amend_refcount_bits width of a reference count entry in bits amend_extra_params additional options, used for extending amend :return: process.CmdResult object containing the result of the command """ cmd_list = [self.image_cmd, 'amend'] options = [ "%s=%s" % (key[6:], val) for key, val in six.iteritems(params) if key.startswith('amend_') ] if cache_mode: cmd_list.append("-t %s" % cache_mode) if options: cmd_list.append("-o %s" % ",".join(options).replace("extra_params=", "")) cmd_list.append("-f %s %s" % (self.image_format, self.image_filename)) logging.info("Amend image %s" % self.image_filename) cmd_result = process.run(" ".join(cmd_list), ignore_status=False) cmd_result.stdout = results_stdout_52lts(cmd_result) cmd_result.stderr = results_stderr_52lts(cmd_result) return cmd_result
def kill_blockcopy_process(): """ Kill running blockcopy process """ kill_cmd = "ps aux|grep -i 'blockcopy'|grep -v grep|grep -v transient_job|awk '{print $2}'" pid_list = results_stdout_52lts(process.run( kill_cmd, shell=True)).strip().split('\n') for pid in pid_list: utils_misc.safe_kill(pid, signal.SIGKILL)
def vg_ramdisk_cleanup(ramdisk_filename, vg_ramdisk_dir, vg_name, loop_device): """ Inline cleanup function in case of test error. """ result = process.run("vgremove " + vg_name, ignore_status=True) if result.exit_status == 0: logging.info(results_stdout_52lts(result).rstrip()) else: logging.debug("%s -> %s", result.command, results_stderr_52lts(result)) result = process.run("pvremove " + loop_device, ignore_status=True) if result.exit_status == 0: logging.info(results_stdout_52lts(result).rstrip()) else: logging.debug("%s -> %s", result.command, results_stderr_52lts(result)) for _ in range(10): time.sleep(0.1) result = process.run("losetup -d " + loop_device, ignore_status=True) if b"resource busy" not in result.stderr: if result.exit_status != 0: logging.debug("%s -> %s", result.command, results_stderr_52lts(result)) else: logging.info("Loop device %s deleted", loop_device) break if os.path.exists(ramdisk_filename): os.unlink(ramdisk_filename) logging.info("Ramdisk filename %s deleted", ramdisk_filename) process.run("umount " + vg_ramdisk_dir, ignore_status=True) if result.exit_status == 0: if loop_device != "": logging.info("Loop device %s unmounted", loop_device) else: logging.debug("%s -> %s", result.command, results_stderr_52lts(result)) if os.path.exists(vg_ramdisk_dir): try: shutil.rmtree(vg_ramdisk_dir) logging.info("Ramdisk directory %s deleted", vg_ramdisk_dir) except OSError: pass
def lv_revert(vg_name, lv_name, lv_snapshot_name): """ Revert the origin to a snapshot. """ error_context.context("Reverting original logical volume to snapshot", logging.info) try: if not vg_check(vg_name): raise exceptions.TestError("Volume group could not be found") if not lv_check(vg_name, lv_snapshot_name): raise exceptions.TestError("Snapshot could not be found") if (not lv_check(vg_name, lv_snapshot_name) and not lv_check(vg_name, lv_name)): raise exceptions.TestError( "Snapshot and its origin could not be found") if (lv_check(vg_name, lv_snapshot_name) and not lv_check(vg_name, lv_name)): raise exceptions.TestError("Snapshot origin could not be found") cmd = ("lvconvert --merge /dev/%s/%s" % (vg_name, lv_snapshot_name)) result = process.run(cmd) if ("Merging of snapshot %s will start next activation." % lv_snapshot_name) in results_stdout_52lts(result): raise exceptions.TestError("The logical volume %s is still " "active" % lv_name) result = results_stdout_52lts(result).rstrip() except exceptions.TestError as ex: # detect if merge of snapshot was postponed # and attempt to reactivate the volume. if (('Snapshot could not be found' in ex and re.search(re.escape(lv_snapshot_name + " [active]"), results_stdout_52lts(process.run("lvdisplay")))) or ("The logical volume %s is still active" % lv_name) in ex): logging.warning(("Logical volume %s is still active! " + "Attempting to deactivate..."), lv_name) lv_reactivate(vg_name, lv_name) result = "Continuing after reactivation" elif 'Snapshot could not be found' in ex: logging.error(ex) result = "Could not revert to snapshot" else: raise ex logging.info(result)
def amend(self, params, cache_mode=None, ignore_status=False): """ Amend the image format specific options for the image :param params: dictionary containing the test parameters :param cache_mode: the cache mode used to write the output disk image, the valid options are: 'none', 'writeback' (default), 'writethrough', 'directsync' and 'unsafe'. :param ignore_status: Whether to raise an exception when command returns =! 0 (False), or not (True). :note: params may contain amend options: amend_size virtual disk size of the image (a string qemu-img can understand, such as '10G') amend_compat compatibility level (0.10 or 1.1) amend_backing_file file name of a base image amend_backing_fmt image format of the base image amend_encryption encrypt the image, allowed values: on and off. Default is "off" amend_cluster_size cluster size for the image amend_preallocation preallocation mode when create image, allowed values: off, metadata. Default is "off" amend_lazy_refcounts postpone refcount updates, allowed values: on and off. Default is "off" amend_refcount_bits width of a reference count entry in bits amend_extra_params additional options, used for extending amend :return: process.CmdResult object containing the result of the command """ cmd_list = [self.image_cmd, 'amend'] options = ["%s=%s" % (key[6:], val) for key, val in six.iteritems(params) if key.startswith('amend_')] if cache_mode: cmd_list.append("-t %s" % cache_mode) if options: cmd_list.append("-o %s" % ",".join(options).replace("extra_params=", "")) cmd_list.append("-f %s %s" % (self.image_format, self.image_filename)) logging.info("Amend image %s" % self.image_filename) cmd_result = process.run(" ".join(cmd_list), ignore_status=False) cmd_result.stdout = results_stdout_52lts(cmd_result) cmd_result.stderr = results_stderr_52lts(cmd_result) return cmd_result
def dmesg(self): cmd = "dmesg -c" g_output = self.session.cmd_output(cmd) output = process.run(cmd, timeout=30, ignore_status=True, verbose=False, shell=True) h_output = results_stdout_52lts(output) if "Call Trace" in g_output: self.test.fail("Hit Call Trace in guest") if "Call Trace" in h_output: self.test.fail("Hit Call Trace in host")
def dmesg(self): cmd = "dmesg" error_context.context("Check exception", logging.info) g_output = self.session.cmd_output(cmd) output = process.run(cmd, timeout=30, ignore_status=True, verbose=False, shell=True) h_output = results_stdout_52lts(output) if "Call Trace" in g_output: self.test.fail("Hit Call Trace in guest") if "Call Trace" in h_output: self.test.fail("Hit Call Trace in host")
def run(test, params, env): """ Logs the host name and exits :param test: QEMU test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment. """ result = process.run("hostname") logging.info("Output of 'hostname' cmd is '%s'", results_stdout_52lts(result))
def get_domstats(vm, key): """ Get VM's domstats output value for given keyword :param vm: VM object :param key: keyword for which value is needed :return: value string """ domstats_output = virsh.domstats(vm.name) for item in results_stdout_52lts(domstats_output).strip().split(): if key in item: return item.split("=")[1]
def find_mpath_devs(): """ Find all mpath devices in /dev/mapper which is start with "mpath" and not ending with a digit (which means it's a partition) """ mpath_devs = [] cmd = "ls -l /dev/mapper/ | grep mpath | awk -F ' ' '{print $9}' \ | grep -Ev [0-9]$ |sort -d" cmd_result = process.run(cmd, shell=True) mpath_devs = results_stdout_52lts(cmd_result).split("\n") return mpath_devs
def cmd_output(cmd, res="[\w/]+"): result = process.run(cmd, ignore_status=True) if result.exit_status != 0: logging.warn(result) return None output = results_stdout_52lts(result) for line in output.splitlines(): val = re.findall(res, line) if val: return val[0] return None
def virt_xml_validate(filename, schema_name=None): """ Return CmdResult from running virt-xml-validate on backing XML """ command = 'virt-xml-validate %s' % filename if schema_name: command += ' %s' % schema_name cmdresult = process.run(command, ignore_status=True) cmdresult.stdout = results_stdout_52lts(cmdresult) cmdresult.stderr = results_stderr_52lts(cmdresult) return cmdresult