def start(self, test): """ Start ftrace profiler :param test: Autotest test in which the profiler will operate on. """ # Make sure debugfs is mounted and tracing disabled. utils.system('%s reset' % self.trace_cmd) output_dir = os.path.join(test.profdir, 'ftrace') if not os.path.isdir(output_dir): os.makedirs(output_dir) self.output = os.path.join(output_dir, 'trace.dat') cmd = [self.trace_cmd, 'record', '-o', self.output] cmd += self.trace_cmd_args self.record_job = utils.BgJob(self.join_command(cmd), stderr_tee=utils.TEE_TO_LOGS) # Wait for tracing to be enabled. If trace-cmd dies before enabling # tracing, then there was a problem. tracing_on = os.path.join(self.tracing_dir, 'tracing_on') while (self.record_job.sp.poll() is None and utils.read_file(tracing_on).strip() != '1'): time.sleep(0.1) if self.record_job.sp.poll() is not None: utils.join_bg_jobs([self.record_job]) raise error.CmdError(self.record_job.command, self.record_job.sp.returncode, 'trace-cmd exited early.')
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 = utils.CmdResult(command=command, exit_status=status, stdout=output, stderr=errput) if (status and (not ignore_status)): raise error.CmdError(command, cmd_result) return cmd_result
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 error.CmdError(cmdResult.command, cmdResult) # store service name and status. _service2status_dict = {} lines = cmdResult.stdout.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 fetch_pkg_file(self, filename, dest_path): logging.info('Fetching %s from %s to %s', filename, self.url, dest_path) # do a quick test to verify the repo is reachable self._quick_http_test() # try to retrieve the package via http package_url = os.path.join(self.url, filename) try: cmd = self.wget_cmd_pattern % (package_url, dest_path) result = self.run_command(cmd) file_exists = self.run_command( 'ls %s' % dest_path, _run_command_dargs={'ignore_status': True}).exit_status == 0 if not file_exists: logging.error('wget failed: %s', result) raise error.CmdError(cmd, result) logging.debug('Successfully fetched %s from %s', filename, package_url) except error.CmdError: # remove whatever junk was retrieved when the get failed self.run_command('rm -f %s' % dest_path) raise error.PackageFetchError('%s not found in %s' % (filename, package_url))
def method(cmdResult): """ Parse method for systemctl list XXX.service. Return a dict from service name to status. e.g: {"sshd": "enabled", "vsftpd": "disabled", "systemd-sysctl": "static", ... } """ if cmdResult.exit_status: raise error.CmdError(cmdResult.command, cmdResult) # Dict to store service name to status. _service2status_dict = {} lines = cmdResult.stdout.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 fetch_pkg_file(self, filename, dest_path): """ Fetch a package file and save it to the given destination path git is an SCM, you can download the test directly. No need to fetch a bz2'd tarball file. However 'filename' is <type>-<name>.tar.bz2 break this up and only fetch <name>. :type filename: string :param filename: The filename of the package file to fetch. :type dest_path: string :param dest_path: Destination path to download the file to. """ logging.info('Fetching %s from %s to %s', filename, self.url, dest_path) name, _ = self.pkgmgr.parse_tarball_name(filename) package_path = self.branch + " " + name try: cmd = self.git_archive_cmd_pattern % (self.url, dest_path, package_path) result = self.run_command(cmd) file_exists = self.run_command('ls %s' % dest_path, _run_command_dargs={ 'ignore_status': True }).exit_status == 0 if not file_exists: logging.error('git archive failed: %s', result) raise error.CmdError(cmd, result) logging.debug('Successfully fetched %s from %s', package_path, self.url) except error.CmdError: raise error.PackageFetchError('%s not found in %s' % (name, package_path))
def _dumpxml(name, to_file="", **dargs): """ Get a xml from name. """ if not name: cmd = "virsh dumpxml %s" % name stdout = "error: command 'dumpxml' requires <domain> option" stderr = stdout exit_status = 1 result = utils.CmdResult(cmd, stdout, stderr, exit_status) raise error.CmdError(cmd, result, "Virsh Command returned non-zero exit status") file_path = os.path.join(LibvirtXMLTestBase.__doms_dir__, '%s.xml' % name) if os.path.exists(file_path): xml_file = open(file_path, 'r') domain_xml = xml_file.read() else: xml_file = open(file_path, 'w') domain_xml = LibvirtXMLTestBase.__domain_xml__ % (name, LibvirtXMLTestBase._domuuid(None)) xml_file.write(domain_xml) xml_file.close() cmd = "virsh dumpxml %s" % name stdout = domain_xml stderr = "" exit_status = 0 return utils.CmdResult(cmd, stdout, stderr, exit_status)
def snapshot_info(name, snapshot, **dargs): """ Check snapshot information. @param name: name of domain @param snapshot: name os snapshot to verify @param: dargs: standardized virsh function API keywords @return: snapshot information dictionary """ # CmdResult is handled here, force ignore_status dargs['ignore_status'] = True ret = {} values = [ "Name", "Domain", "Current", "State", "Parent", "Children", "Descendants", "Metadata" ] cmd = "snapshot-info %s %s" % (name, snapshot) sc_output = command(cmd, **dargs) if sc_output.exit_status != 0: raise error.CmdError(cmd, sc_output, "Failed to get snapshot info") for val in values: data = re.search("(?<=%s:) *\w*" % val, sc_output.stdout) if data is None: continue ret[val] = data.group(0).strip() if ret["Parent"] == "-": ret["Parent"] = None return ret
def cmd_result(self, cmd, ignore_status=False): """Mimic utils.run()""" exit_status, stdout = self.cmd_status_output(cmd) stderr = '' # no way to retrieve this separately result = utils.CmdResult(cmd, stdout, stderr, exit_status) if not ignore_status and exit_status: raise error.CmdError( cmd, result, "Guestfish Command returned non-zero exit status") return result
def snapshot_current(name, **dargs): """ Create snapshot of domain. @param name: name of domain @param: dargs: standardized virsh function API keywords @return: name of snapshot """ # CmdResult is handled here, force ignore_status dargs['ignore_status'] = True cmd = "snapshot-current %s --name" % name sc_output = command(cmd, **dargs) if sc_output.exit_status != 0: raise error.CmdError(cmd, sc_output, "Failed to get current snapshot") return sc_output.stdout.strip()
def sysvinit_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": {0: 'off', 1: 'off', 2: 'off', ..., 6: 'off'}, "vsftpd": {0: 'off', 1: 'off', 2: 'off', ..., 6: 'off'}, "xinetd": {'discard-dgram:': 'off', 'rsync:': 'on',...}, ... } """ if cmdResult.exit_status: raise error.CmdError(cmdResult.command, cmdResult) # The final dict to return. _service2statusOnTarget_dict = {} # Dict to store status on every target for each service. _status_on_target = {} # Dict to store the status for service based on xinetd. _service2statusOnXinet_dict = {} lines = cmdResult.stdout.strip().splitlines() for line in lines: sublines = line.strip().split() if len(sublines) == 8: # Service and status on each target. service_name = sublines[0] # Store the status of each target in _status_on_target. for target in range(7): status = sublines[target + 1].split(":")[-1] _status_on_target[target] = status _service2statusOnTarget_dict[ service_name] = _status_on_target.copy() elif len(sublines) == 2: # Service based on xinetd. service_name = sublines[0].strip(":") status = sublines[-1] _service2statusOnXinet_dict[service_name] = status else: # Header or some lines useless. continue # Add xinetd based service in the main dict. _service2statusOnTarget_dict["xinetd"] = _service2statusOnXinet_dict return _service2statusOnTarget_dict
def method(cmdResult): """ Parse method for service XXX list. Return dict from service name to status. e.g: {"sshd": {0: 'off', 1: 'off', 2: 'off', 3: 'off', 4: 'off', 5: 'off', 6: 'off'}, "vsftpd": {0: 'off', 1: 'off', 2: 'off', 3: 'off', 4: 'off', 5: 'off', 6: 'off'}, "xinetd": {'discard-dgram:': 'off', 'rsync:': 'off'...'chargen-stream:': 'off'}, ... } """ if cmdResult.exit_status: raise error.CmdError(cmdResult.command, cmdResult) # The final dict to return. _service2statusOnTarget_dict = {} # Dict to store status on every target for each service. _status_on_target = {} # Dict to store the status for service based on xinetd. _service2statusOnXinet_dict = {} lines = cmdResult.stdout.strip().splitlines() for line in lines: sublines = line.strip().split() if len(sublines) == 8: # Service and status on each target. service_name = sublines[0] # Store the status of each target in _status_on_target. for target in range(7): status = sublines[target + 1].split(":")[-1] _status_on_target[target] = status _service2statusOnTarget_dict[ service_name] = _status_on_target.copy() elif len(sublines) == 2: # Service based on xinetd. service_name = sublines[0].strip(":") status = sublines[-1] _service2statusOnXinet_dict[service_name] = status else: # Header or some lines useless. continue # Add xinetd based service in the main dict. _service2statusOnTarget_dict[ "xinetd"] = _service2statusOnXinet_dict return _service2statusOnTarget_dict
def snapshot_create(name, **dargs): """ Create snapshot of domain. @param name: name of domain @param: dargs: standardized virsh function API keywords @return: name of snapshot """ # CmdResult is handled here, force ignore_status dargs['ignore_status'] = True cmd = "snapshot-create %s" % name sc_output = command(cmd, **dargs) if sc_output.exit_status != 0: raise error.CmdError(cmd, sc_output, "Failed to create snapshot") snapshot_number = re.search("\d+", sc_output.stdout.strip()).group(0) return snapshot_number
def dumpxml(name, to_file="", **dargs): """ Return the domain information as an XML dump. @param: name: VM name @param: to_file: optional file to write XML output to @param: dargs: standardized virsh function API keywords @return: standard output from command """ dargs['ignore_status'] = True if to_file: cmd = "dumpxml %s > %s" % (name, to_file) else: cmd = "dumpxml %s" % name result = command(cmd, **dargs) if result.exit_status: raise error.CmdError(cmd, result, "Virsh dumpxml returned non-zero exit status") return result.stdout.strip()
def snapshot_list(name, **dargs): """ Get list of snapshots of domain. @param name: name of domain @param: dargs: standardized virsh function API keywords @return: list of snapshot names """ # CmdResult is handled here, force ignore_status dargs['ignore_status'] = True ret = [] cmd = "snapshot-list %s" % name sc_output = command(cmd, **dargs) if sc_output.exit_status != 0: raise error.CmdError(cmd, sc_output, "Failed to get list of snapshots") data = re.findall("\w* *\d*-\d*-\d* \d*:\d*:\d* [+-]\d* \w*", sc_output.stdout) for rec in data: if not rec: continue ret.append(re.match("\w*", rec).group()) return ret
path, size="1M", disk_format="qcow2") os.chmod(path, 0666) if attach_type == "qemu_monitor": if usb_type == "storage": attach_cmd = "drive_add" attach_cmd += (" 0 id=drive-usb-%s,if=none,file=%s" % (i, path)) result = virsh.qemu_monitor_command(vm_name, attach_cmd, options=opt) if result.exit_status or (result.stdout.find("OK") == -1): raise error.CmdError(result.command, result) attach_cmd = "device_add usb-storage," attach_cmd += ( "id=drive-usb-%s,bus=usb1.0,drive=drive-usb-%s" % (i, i)) else: attach_cmd = "device_add" attach_cmd += " usb-%s,bus=usb1.0,id=%s%s" % (usb_type, usb_type, i) result = virsh.qemu_monitor_command(vm_name, attach_cmd, options=opt) if result.exit_status: raise error.CmdError(result.command, result)
def run(test, params, env): """ Stress test for the hotplug feature of usb device. """ # get the params from params vm_name = params.get("main_vm", "virt-tests-vm1") vm = env.get_vm(vm_name) keyboard = "yes" == params.get("usb_hotplug_keyboard", "no") mouse = "yes" == params.get("usb_hotplug_mouse", "no") tablet = "yes" == params.get("usb_hotplug_tablet", "no") disk = "yes" == params.get("usb_hotplug_disk", "no") attach_count = int(params.get("attach_count", "1")) attach_type = params.get("attach_type", "attach_device") bench_type = params.get("guest_bench", None) control_file = params.get("control_file", None) status_error = ("yes" == params.get("status_error", "no")) vm_xml = VMXML.new_from_inactive_dumpxml(vm_name) vm_xml_backup = vm_xml.copy() tmp_dir = os.path.join(data_dir.get_tmp_dir(), "usb_hotplug_files") if control_file is not None: params["test_control_file"] = control_file params["main_vm"] = vm_name control_path = os.path.join(test.virtdir, "control", control_file) session = vm.wait_for_login() command = utils_test.run_autotest(vm, session, control_path, None, None, params, copy_only=True) session.cmd("%s &" % command) def _is_iozone_running(): session_tmp = vm.wait_for_login() return ( not session_tmp.cmd_status("ps -ef|grep iozone|grep -v grep")) def _is_stress_running(): session_tmp = vm.wait_for_login() return ( not session_tmp.cmd_status("ps -ef|grep stress|grep -v grep")) if bench_type == "stress": if not utils_misc.wait_for(_is_stress_running, timeout=160): raise error.TestNAError( "Failed to run stress in guest.\n" "Since we need to run a autotest of iozone " "in guest, so please make sure there are " "some necessary packages in guest," "such as gcc, tar, bzip2") elif bench_type == "iozone": if not utils_misc.wait_for(_is_iozone_running, timeout=160): raise error.TestNAError( "Failed to run iozone in guest.\n" "Since we need to run a autotest of iozone " "in guest, so please make sure there are " "some necessary packages in guest," "such as gcc, tar, bzip2") logging.debug("bench is already running in guest.") try: try: result = None disk_xml = None tablet_xml = None mouse_xml = None if not os.path.isdir(tmp_dir): os.mkdir(tmp_dir) for i in range(attach_count): path = os.path.join(tmp_dir, "%s.img" % i) if attach_type == "qemu_monitor": options = "--hmp" if disk: utils_test.libvirt.create_local_disk("file", path, size="1M") attach_cmd = "drive_add" attach_cmd += ( " 0 id=drive-usb-disk%s,if=none,file=%s" % (i, path)) result = virsh.qemu_monitor_command(vm_name, attach_cmd, options=options) if result.exit_status: raise error.CmdError(result.command, result) if keyboard: attach_cmd = "device_add" attach_cmd += " usb-kdb,bus=usb1.0,id=kdb" result = virsh.qemu_monitor_command(vm_name, attach_cmd, options=options) if result.exit_status: raise error.CmdError(result.command, result) if mouse: attach_cmd = "device_add" attach_cmd += " usb-mouse,bus=usb1.0,id=mouse" result = virsh.qemu_monitor_command(vm_name, attach_cmd, options=options) if result.exit_status: raise error.CmdError(result.command, result) if tablet: attach_cmd = "device_add" attach_cmd += " usb-tablet,bus=usb1.0,id=tablet" result = virsh.qemu_monitor_command(vm_name, attach_cmd, options=options) if result.exit_status: raise error.CmdError(result.command, result) else: if disk: utils_test.libvirt.create_local_disk("file", path, size="1M") os.chmod(path, 0666) disk_xml = Disk(type_name="file") disk_xml.device = "disk" disk_xml.source = disk_xml.new_disk_source( **{"attrs": { 'file': path }}) disk_xml.driver = { "name": "qemu", "type": 'raw', "cache": "none" } disk_xml.target = {"dev": 'sdb', "bus": "usb"} attributes = { 'type_name': "usb", 'bus': "1", 'port': "0" } disk_xml.address = disk_xml.new_disk_address( **{"attrs": attributes}) result = virsh.attach_device(vm_name, disk_xml.xml) if result.exit_status: raise error.CmdError(result.command, result) if mouse: mouse_xml = Input("mouse") mouse_xml.input_bus = "usb" attributes = { 'type_name': "usb", 'bus': "1", 'port': "0" } mouse_xml.address = mouse_xml.new_input_address( **{"attrs": attributes}) result = virsh.attach_device(vm_name, mouse_xml.xml) if result.exit_status: raise error.CmdError(result.command, result) if tablet: tablet_xml = Input("tablet") tablet_xml.input_bus = "usb" attributes = { 'type_name': "usb", 'bus': "1", 'port': "0" } tablet_xml.address = tablet_xml.new_input_address( **{"attrs": attributes}) result = virsh.attach_device(vm_name, tablet_xml.xml) if result.exit_status: raise error.CmdError(result.command, result) if keyboard: kbd_xml = Input("keyboard") kbd_xml.input_bus = "usb" attributes = { 'type_name': "usb", 'bus': "1", 'port': "0" } kbd_xml.address = kbd_xml.new_input_address( **{"attrs": attributes}) result = virsh.attach_device(vm_name, kbd_xml.xml) if result.exit_status: raise error.CmdError(result.command, result) if attach_type == "qemu_monitor": options = "--hmp" if disk: attach_cmd = "drive_del" attach_cmd += (" drive-usb-disk") result = virsh.qemu_monitor_command(vm_name, attach_cmd, options=options) if result.exit_status: raise error.CmdError(result.command, result) if mouse: attach_cmd = "device_del" attach_cmd += (" mouse") result = virsh.qemu_monitor_command(vm_name, attach_cmd, options=options) if result.exit_status: raise error.CmdError(result.command, result) if keyboard: attach_cmd = "device_del" attach_cmd += (" keyboard") result = virsh.qemu_monitor_command(vm_name, attach_cmd, options=options) if result.exit_status: raise error.CmdError(result.command, result) if tablet: attach_cmd = "device_del" attach_cmd += (" tablet") result = virsh.qemu_monitor_command(vm_name, attach_cmd, options=options) if result.exit_status: raise error.CmdError(result.command, result) else: if disk: result = virsh.detach_device(vm_name, disk_xml.xml) if result.exit_status: raise error.CmdError(result.command, result) if mouse: result = virsh.detach_device(vm_name, mouse_xml.xml) if result.exit_status: raise error.CmdError(result.command, result) if keyboard: result = virsh.detach_device(vm_name, kbd_xml.xml) if result.exit_status: raise error.CmdError(result.command, result) if tablet: result = virsh.detach_device(vm_name, tablet_xml.xml) if result.exit_status: raise error.CmdError(result.command, result) except error.CmdError, e: if not status_error: raise error.TestFail("failed to attach device.\n" "Detail: %s." % result) finally: if os.path.isdir(tmp_dir): shutil.rmtree(tmp_dir) vm_xml_backup.sync()