def start(self): cmd = [ _IPERF3_BINARY.cmd, '--client', self._server_ip, '--version4', # only IPv4 '--time', str(self._test_time), '--parallel', str(self._threads), '--bind', self._bind_to, '--zerocopy', # use less cpu '--json' ] rc, self._raw_output, err = execCmd(cmd) if rc == 1 and 'No route to host' in self.out['error']: # it seems that it takes some time for the routes to get updated # on the os so that we don't get this error, hence the horrific # sleep here. # TODO: Investigate, understand, and remove this sleep. time.sleep(3) rc, self._raw_output, err = execCmd(cmd) if rc: raise Exception('iperf3 client failed: cmd=%s, rc=%s, out=%s, ' 'err=%s' % (' '.join(cmd), rc, self._raw_output, err))
def _parted_dev_test(self): cmd = ['parted', '-s', self.devPath, 'mktable', 'gpt'] rc, out, err = utils.execCmd(cmd) self.assertEquals(rc, 0) cmd = [ 'parted', '-s', self.devPath, 'mkpart', 'primary', '0', '%sMB' % PART_SIZE_MB ] rc, out, err = utils.execCmd(cmd) self.assertEquals(rc, 0) cmd = ['parted', '-s', self.devPath, 'set', '1', 'boot', 'on'] rc, out, err = utils.execCmd(cmd) self.assertEquals(rc, 0) time.sleep(1) # wait for syncing info = putils.getDevicePartedInfo(self.devPath) self.assertTrue(info['sectorSize'] >= 0) self.assertEquals(info['type'], 'gpt') self.assertTrue(info['freeSpaceRegions'][0][3] >= FREE_SIZE) partName = '%sp1' % self.devPath partInfo = info['partitions'].get(partName) self.assertTrue(partInfo) self.assertIn(partInfo[0], (['boot'], ['boot', 'esp'])) self.assertTrue(partInfo[1] >= 0) self.assertTrue((partInfo[2] * info['sectorSize']) >= PART_END_SIZE)
def chown(vendorid, productid): # remove the 0x from the vendor and product id devid = vendorid[2:] + ':' + productid[2:] command = ['lsusb', '-d', devid] retcode, out, err = utils.execCmd(command, sudo=False, raw=True) if retcode != 0: sys.stderr.write('hostusb: cannot find usb device: %s\n' % devid) sys.exit(2) # find the device path: # /dev/bus/usb/xxx/xxx devpath = '/dev/bus/usb/' + out[4:7] + '/' + out[15:18] stat = os.stat(devpath) group = grp.getgrnam('qemu') gid = group.gr_gid user = pwd.getpwnam('qemu') uid = user.pw_uid # we don't use os.chown because we need sudo owner = str(uid) + ':' + str(gid) command = ['/bin/chown', owner, devpath] retcode, out, err = utils.execCmd(command, sudo=True, raw=True) if retcode != 0: sys.stderr.write('hostusb: error chown %s to %s, err = %s\n' % (devpath, owner, err)) sys.exit(2) log_dev_owner(devpath, stat.st_uid, stat.st_gid)
def _removeFile(filename): """Remove file, umounting ovirt config files if needed.""" mounts = open('/proc/mounts').read() if ' /config ext3' in mounts and ' %s ext3' % filename in mounts: utils.execCmd([constants.EXT_UMOUNT, '-n', filename]) utils.rmFile(filename) logging.debug("Removed file %s", filename)
def check_brctl(): try: execCmd([EXT_BRCTL, "show"]) except OSError as e: if e.errno == errno.ENOENT: raise SkipTest("Cannot run %r: %s\nDo you have bridge-utils " "installed?" % (EXT_BRCTL, e)) raise
def removeBridge(self, bridge): DynamicSourceRoute.addInterfaceTracking(bridge) ifdown(bridge.name) self._removeSourceRoute(bridge, StaticSourceRoute) utils.execCmd([constants.EXT_BRCTL, 'delbr', bridge.name]) self.configApplier.removeBridge(bridge.name) if bridge.port: bridge.port.remove()
def configureNic(self, nic, **opts): self.configApplier.setIfaceConfigAndUp(nic) ethtool_opts = getEthtoolOpts(nic.name) if ethtool_opts: # We ignore ethtool's return code to maintain initscripts' # behaviour. execCmd( [_ETHTOOL_BINARY.cmd, '-K', nic.name] + ethtool_opts.split())
def configureNic(self, nic, **opts): DynamicSourceRoute.addInterfaceTracking(nic) self.configApplier.setIfaceConfigAndUp(nic) self._addSourceRoute(nic) ethtool_opts = getEthtoolOpts(nic.name) if ethtool_opts: # We ignore ethtool's return code to maintain initscripts' # behaviour. execCmd([_ETHTOOL_BINARY.cmd, "-K", nic.name] + ethtool_opts.split())
def configureNic(self, nic, **opts): DynamicSourceRoute.addInterfaceTracking(nic) self.configApplier.setIfaceConfigAndUp(nic) self._addSourceRoute(nic) ethtool_opts = getEthtoolOpts(nic.name) if ethtool_opts: # We ignore ethtool's return code to maintain initscripts' # behaviour. execCmd([_ETHTOOL_BINARY.cmd, '-K', nic.name] + ethtool_opts.split())
def adjust(self): """Adjust ksm's vigor Recalculate how hard should ksm work, according to configuration and current memory stress. Return whether ksm is running""" with self._lock: utils.execCmd([constants.EXT_SERVICE, 'ksmtuned', 'retune'], sudo=True) return running()
def adjust(self): """adjust ksm state according to configuration and current memory stress return whether ksm is running""" self._lock.acquire() try: utils.execCmd([constants.EXT_SERVICE, 'ksmtuned', 'retune'], sudo=True) self.state, self.pages = self.readState() finally: self._lock.release() return self.state
def _createThinPool(poolName, vg, alignment=0, poolMetaDataSize=0, poolDataSize=0): if not alignment: # bz#1180228: blivet doesn't handle percentage-based sizes properly # Workaround: Till the bz gets fixed, we take only 99% size from vg pool = LVMThinPoolDevice(poolName, parents=[vg], size=(vg.size * 99 / 100), grow=True) blivetEnv.createDevice(pool) return pool else: metaName = "meta-%s" % poolName vgPoolName = "%s/%s" % (vg.name, poolName) metaLv = LVMLogicalVolumeDevice(metaName, parents=[vg], size=blivet.size.Size( '%d KiB' % poolMetaDataSize)) poolLv = LVMLogicalVolumeDevice(poolName, parents=[vg], size=blivet.size.Size( '%d KiB' % poolDataSize)) blivetEnv.createDevice(metaLv) blivetEnv.createDevice(poolLv) blivetEnv.doIt() # bz#1100514: LVM2 currently only supports physical extent sizes # that are a power of 2. Till that support is available we need # to use lvconvert to achive that. # bz#1179826: blivet doesn't support lvconvert functionality. # Workaround: Till the bz gets fixed, lvconvert command is used rc, out, err = utils.execCmd([ _lvconvertCommandPath.cmd, '--chunksize', '%sK' % alignment, '--thinpool', vgPoolName, '--poolmetadata', "%s/%s" % (vg.name, metaName), '--poolmetadataspar', 'n', '-y' ]) if rc: raise ge.GlusterHostStorageDeviceLVConvertFailedException( vg.path, alignment, rc, out, err) rc, out, err = utils.execCmd( [_lvchangeCommandPath.cmd, '--zero', 'n', vgPoolName]) if rc: raise ge.GlusterHostStorageDeviceLVChangeFailedException( vgPoolName, rc, out, err) blivetEnv.reset() return blivetEnv.devicetree.getDeviceByName(poolLv.name)
def adjust(self): """Adjust ksm's vigor Recalculate how hard should ksm work, according to configuration and current memory stress. Return whether ksm is running""" self._lock.acquire() try: utils.execCmd([constants.EXT_SERVICE, "ksmtuned", "retune"], sudo=True) finally: self._lock.release() return running()
def setUp(self): self.assertFalse(self.tempFilePath and self.devPath) tempFd, self.tempFilePath = tempfile.mkstemp() os.close(tempFd) cmd = ['dd', 'if=/dev/zero', 'of=%s' % self.tempFilePath, 'bs=%sM' % FILE_SIZE_MB, 'count=1'] rc, out, err = utils.execCmd(cmd) self.assertEquals(rc, 0) cmd = ['losetup', '-f', '--show', self.tempFilePath] rc, out, err = utils.execCmd(cmd) self.assertEquals(rc, 0) self.devPath = out[0].strip()
def start(self): cmd = [_IPERF3_BINARY.cmd, '--server', '--bind', self._bind_to] if self._net_ns is not None: p = netns_exec(self._net_ns, cmd) else: p = execCmd(cmd, sync=False) self._pid = p.pid
def _import(self): # TODO: use the process handling http://gerrit.ovirt.org/#/c/33909/ self._prepare_volumes() cmd = self._create_command() logging.info('Job %r starting import', self._id) # This is the way we run qemu-img convert jobs. virt-v2v is invoking # qemu-img convert to perform the migration. self._proc = execCmd(cmd, sync=False, deathSignal=signal.SIGTERM, nice=NICENESS.HIGH, ioclass=IOCLASS.IDLE, env=self._execution_environments()) self._proc.blocking = True self._watch_process_output() self._wait_for_process() if self._proc.returncode != 0: raise V2VProcessError('Job %r process failed exit-code: %r' ', stderr: %s' % (self._id, self._proc.returncode, self._proc.stderr.read(1024))) if self._status != STATUS.ABORTED: self._status = STATUS.DONE logging.info('Job %r finished import successfully', self._id)
def testExec(self): """ Tests that execCmd execs and returns the correct ret code """ ret, out, err = utils.execCmd([EXT_ECHO]) self.assertEquals(ret, 0)
def start(self, interface, dhcp_range_from, dhcp_range_to, dhcpv6_range_from=None, dhcpv6_range_to=None, router=None, bind_dynamic=True): # -p 0 don't act as a DNS server # --dhcp-option=3,<router> advertise a specific gateway (or None) # --dhcp-option=6 don't reply with any DNS servers # -d don't daemonize and log to stderr # --bind-dynamic bind only the testing veth iface # (a better, and quiet, version of --bind-interfaces, but not on EL6) command = [ _DNSMASQ_BINARY.cmd, '--dhcp-authoritative', '-p', '0', '--dhcp-range={0},{1},2m'.format(dhcp_range_from, dhcp_range_to), '--dhcp-option=3' + (',{0}'.format(router) if router else ''), '--dhcp-option=6', '-i', interface, '-I', 'lo', '-d', '--bind-dynamic' if bind_dynamic else '--bind-interfaces' ] if dhcpv6_range_from and dhcpv6_range_to: command += [ '--dhcp-range={0},{1},2m'.format(dhcpv6_range_from, dhcpv6_range_to) ] self.proc = execCmd(command, sync=False) sleep(_START_CHECK_TIMEOUT) if self.proc.returncode: raise DhcpError('Failed to start dnsmasq DHCP server.\n%s\n%s' % (''.join(self.proc.stderr), ' '.join(command)))
def snapshotScheduleDisable(): command = [_snapSchedulerPath.cmd, "disable_force"] rc, out, err = utils.execCmd(command) if rc not in [0, SNAP_SCHEDULER_ALREADY_DISABLED_RC]: raise ge.GlusterDisableSnapshotScheduleFailedException( rc) return True
def start(self, interface, dhcp_range_from, dhcp_range_to, dhcpv6_range_from=None, dhcpv6_range_to=None, router=None, bind_dynamic=True): # -p 0 don't act as a DNS server # --dhcp-option=3,<router> advertise a specific gateway (or None) # --dhcp-option=6 don't reply with any DNS servers # -d don't daemonize and log to stderr # --bind-dynamic bind only the testing veth iface # (a better, and quiet, version of --bind-interfaces, but not on EL6) command = [ _DNSMASQ_BINARY.cmd, '--dhcp-authoritative', '-p', '0', '--dhcp-range={0},{1},2m'.format(dhcp_range_from, dhcp_range_to), '--dhcp-option=3' + (',{0}'.format(router) if router else ''), '--dhcp-option=6', '-i', interface, '-I', 'lo', '-d', '--bind-dynamic' if bind_dynamic else '--bind-interfaces'] if dhcpv6_range_from and dhcpv6_range_to: command += ['--dhcp-range={0},{1},2m'.format(dhcpv6_range_from, dhcpv6_range_to)] self.proc = execCmd(command, sync=False) sleep(_START_CHECK_TIMEOUT) if self.proc.returncode: raise DhcpError('Failed to start dnsmasq DHCP server.\n%s\n%s' % (''.join(self.proc.stderr), ' '.join(command)))
def writeLargeData(self): data = """The Doctor: Davros, if you had created a virus in your laboratory, something contagious and infectious that killed on contact, a virus that would destroy all other forms of life; would you allow its use? Davros: It is an interesting conjecture. The Doctor: Would you do it? Davros: The only living thing... The microscopic organism... reigning supreme... A fascinating idea. The Doctor: But would you do it? Davros: Yes; yes. To hold in my hand, a capsule that contained such power. To know that life and death on such a scale was my choice. To know that the tiny pressure on my thumb, enough to break the glass, would end everything. Yes! I would do it! That power would set me up above the gods! And through the Daleks, I shall have that power! """ # (C) BBC - Doctor Who data = data * ((4096 / len(data)) * 2) self.assertTrue(data > 4096) p = utils.execCmd([EXT_CAT], sync=False) self.log.info("Writing data to std out") p.stdin.write(data) p.stdin.flush() self.log.info("Written data reading") self.assertEquals(p.stdout.read(len(data)), data)
def _echo(self, text): proc = utils.execCmd(["echo", "-n", "test"], sync=False) def parse(rc, out, err): return out return utils.AsyncProcessOperation(proc, parse)
def getCpuTopology(capabilities): topology = {} if capabilities is None: retcode, out, err = utils.execCmd(['lscpu'], raw=True) capabilities = out corePS = None threadsPC = None sockets = None for line in capabilities.splitlines(): if line.strip() == '': continue key, value = map(str.strip, line.split(':', 1)) if key == 'Socket(s)': sockets = int(value) elif key == 'Thread(s) per core': threadsPC = int(value) elif key == 'Core(s) per socket': corePS = int(value) if corePS and threadsPC and sockets: topology['sockets'] = sockets topology['cores'] = corePS * sockets topology['threads'] = threadsPC * corePS * sockets else: raise RuntimeError('Undefined topology') return topology
def _fail(self, t): proc = utils.execCmd(["sleep", str(t)], sync=False) def parse(rc, out, err): raise Exception("TEST!!!") return utils.AsyncProcessOperation(proc, parse)
def testWriteLargeData(self): data = """The Doctor: Davros, if you had created a virus in your laboratory, something contagious and infectious that killed on contact, a virus that would destroy all other forms of life; would you allow its use? Davros: It is an interesting conjecture. The Doctor: Would you do it? Davros: The only living thing... The microscopic organism... reigning supreme... A fascinating idea. The Doctor: But would you do it? Davros: Yes; yes. To hold in my hand, a capsule that contained such power. To know that life and death on such a scale was my choice. To know that the tiny pressure on my thumb, enough to break the glass, would end everything. Yes! I would do it! That power would set me up above the gods! And through the Daleks, I shall have that power! """ # (C) BBC - Doctor Who data = data * 100 p = utils.execCmd([EXT_CAT], sync=False) self.log.info("Writing data to std out") p.stdin.write(data) p.stdin.flush() self.log.info("Written data reading") self.assertEquals(p.stdout.read(len(data)), data)
def volumeStatvfs(volumeName, host=GLUSTER_VOL_HOST, port=GLUSTER_VOL_PORT, protocol=GLUSTER_VOL_PROTOCOL): module = "gluster.gfapi" command = [constants.EXT_PYTHON, '-m', module, '-v', volumeName, '-p', str(port), '-H', host, '-t', protocol, '-c', 'statvfs'] # to include /usr/share/vdsm in python path env = os.environ.copy() env['PYTHONPATH'] = "%s:%s" % ( env.get("PYTHONPATH", ""), constants.P_VDSM) env['PYTHONPATH'] = ":".join(map(os.path.abspath, env['PYTHONPATH'].split(":"))) rc, out, err = utils.execCmd(command, raw=True, env=env) if rc != 0: raise ge.GlfsStatvfsException(rc, [out], [err]) res = json.loads(out) return os.statvfs_result((res['f_bsize'], res['f_frsize'], res['f_blocks'], res['f_bfree'], res['f_bavail'], res['f_files'], res['f_ffree'], res['f_favail'], res['f_flag'], res['f_namemax']))
def testResetAffinityByDefault(self): try: proc = utils.execCmd((EXT_SLEEP, '30s'), sync=False) self.assertEquals(taskset.get(proc.pid), taskset.get(os.getpid())) finally: proc.kill()
def cleanup_transient_repository(*args): """ Cleanup the unused transient disks present in the repository. (NOTE: it is recommended to NOT execute this command when the vdsm daemon is running) """ transient_images = set(glob.glob(os.path.join(TRANSIENT_DISKS_REPO, "*"))) if len(transient_images) == 0: return # Nothing to do cmd_ret, cmd_out, cmd_err = execCmd([_fuser.cmd] + list(transient_images)) # According to: "fuser returns a non-zero return code if none of the # specified files is accessed or in case of a fatal error. If at least # one access has been found, fuser returns zero." we can discard the # return code. # NOTE: the list of open files is printed to cmd_err with an extra ":" # character appended (removed by [:-1]). open_transient_images = set(x[:-1] for x in cmd_err) for image_path in transient_images - open_transient_images: # NOTE: This could cause a race with the creation of a virtual # machine with a transient disk (if vdsm is running). try: os.unlink(image_path) except OSError as e: if e.errno != os.errno.ENOENT: raise
def _persistentBackup(cls, filename): """ Persistently backup ifcfg-* config files """ if os.path.exists('/usr/libexec/ovirt-functions'): utils.execCmd([constants.EXT_SH, '/usr/libexec/ovirt-functions', 'unmount_config', filename]) logging.debug("unmounted %s using ovirt", filename) (dummy, basename) = os.path.split(filename) if os.path.exists(filename): content = open(filename).read() else: # For non-exists ifcfg-* file use predefined header content = cls.DELETED_HEADER + '\n' logging.debug("backing up %s: %s", basename, content) cls.writeBackupFile(netinfo.NET_CONF_BACK_DIR, basename, content)
def _createThinPool(poolName, vg, alignment=0, poolMetaDataSize=0, poolDataSize=0): if not alignment: # bz#1180228: blivet doesn't handle percentage-based sizes properly # Workaround: Till the bz gets fixed, we take only 99% size from vg pool = LVMThinPoolDevice(poolName, parents=[vg], size=(vg.size * 99 / 100), grow=True) blivetEnv.createDevice(pool) return pool else: metaName = "meta-%s" % poolName vgPoolName = "%s/%s" % (vg.name, poolName) metaLv = LVMLogicalVolumeDevice( metaName, parents=[vg], size=blivet.size.Size('%d KiB' % poolMetaDataSize)) poolLv = LVMLogicalVolumeDevice( poolName, parents=[vg], size=blivet.size.Size('%d KiB' % poolDataSize)) blivetEnv.createDevice(metaLv) blivetEnv.createDevice(poolLv) blivetEnv.doIt() # bz#1100514: LVM2 currently only supports physical extent sizes # that are a power of 2. Till that support is available we need # to use lvconvert to achive that. # bz#1179826: blivet doesn't support lvconvert functionality. # Workaround: Till the bz gets fixed, lvconvert command is used rc, out, err = utils.execCmd([_lvconvertCommandPath.cmd, '--chunksize', '%sK' % alignment, '--thinpool', vgPoolName, '--poolmetadata', "%s/%s" % (vg.name, metaName), '--poolmetadataspar', 'n', '-y']) if rc: raise ge.GlusterHostStorageDeviceLVConvertFailedException( vg.path, alignment, rc, out, err) rc, out, err = utils.execCmd([_lvchangeCommandPath.cmd, '--zero', 'n', vgPoolName]) if rc: raise ge.GlusterHostStorageDeviceLVChangeFailedException( vgPoolName, rc, out, err) blivetEnv.reset() return blivetEnv.devicetree.getDeviceByName(poolLv.name)
def getLsBlk(): rc, out, err = utils.execCmd([ constants.EXT_LSBLK, '--all', '--bytes', '--pairs', '--output', 'KNAME,FSTYPE,UUID' ]) if rc: raise LsBlkException(rc) return _parseLsBlk(out)
def _dhclient(self): # Ask dhclient to stop any dhclient running for the device if os.path.exists(os.path.join(netinfo.NET_PATH, self.iface)): kill_dhclient(self.iface) rc, out, err = execCmd([self.DHCLIENT.cmd, '-1', '-pf', self.pidFile, '-lf', self.leaseFile, self.iface]) return rc, out, err
def test(self): args = [EXT_SLEEP, "4"] sproc = utils.execCmd(args, sync=False) try: self.assertEquals(utils.getCmdArgs(sproc.pid), tuple(args)) finally: sproc.kill() sproc.wait()
def _read_ovf_from_ova(ova_path): # FIXME: change to tarfile package when support --to-stdout cmd = ['/usr/bin/tar', 'xf', ova_path, '*.ovf', '--to-stdout'] rc, output, error = execCmd(cmd) if rc: raise V2VError(error) return ''.join(output)
def upload(url, path, headers={}): cmd = [constants.EXT_CURL_IMG_WRAP, "--upload"] cmd.extend(_headersToOptions(headers) + [path, url]) rc, out, err = utils.execCmd(cmd, deathSignal=signal.SIGKILL) if rc != 0: raise CurlError(rc, out, err)
def _exec_ifup(iface_name): """Bring up an interface""" rc, out, err = utils.execCmd([constants.EXT_IFUP, iface_name], raw=False) if rc != 0: # In /etc/sysconfig/network-scripts/ifup* the last line usually # contains the error reason. raise ConfigNetworkError(ERR_FAILED_IFUP, out[-1] if out else '')
def _ifup(netIf): rc, out, err = utils.execCmd([constants.EXT_IFUP, netIf], raw=False) if rc != 0: # In /etc/sysconfig/network-scripts/ifup* the last line usually # contains the error reason. raise ConfigNetworkError(ERR_FAILED_IFUP, out[-1] if out else '') return rc, out, err
def _validate_module(name): if not os.path.exists('/sys/module/' + name): cmd_modprobe = [modprobe.cmd, name] rc, out, err = utils.execCmd(cmd_modprobe, sudo=True) if rc != 0: raise SkipTest("This test requires %s module " "(failed to load module: rc=%s, out=%s, err=%s)" % (name, rc, out, err))
def addBridge(self, bridge): rc, _, err = execCmd([EXT_BRCTL, 'addbr', bridge.name]) if rc != 0: raise ConfigNetworkError(ERR_FAILED_IFUP, err) if bridge.stp: with open(netinfo.BRIDGING_OPT % (bridge.name, 'stp_state'), 'w') as bridge_stp: bridge_stp.write('1')
def download(url, path, headers={}): cmd = [constants.EXT_CURL_IMG_WRAP, "--download"] cmd.extend(_headersToOptions(headers) + [path, url]) rc, out, err = utils.execCmd(cmd) if rc != 0: raise CurlError(rc, out, err)
def _dhclient(self): # Ask dhclient to stop any dhclient running for the device if os.path.exists(os.path.join(netinfo.NET_PATH, self.iface)): kill_dhclient(self.iface, self.family) rc, out, err = execCmd([self.DHCLIENT.cmd, '-%s' % self.family, '-1', '-pf', self.pidFile, '-lf', self.leaseFile, self.iface]) return rc, out, err
def _read_ovf_from_tar_ova(ova_path): # FIXME: change to tarfile package when support --to-stdout cmd = ['/usr/bin/tar', 'xf', ova_path, '*.ovf', '--to-stdout'] rc, output, error = execCmd(cmd) if rc: raise V2VError(error) return ''.join(output)
def _persistentBackup(cls, filename): """ Persistently backup ifcfg-* config files """ if os.path.exists('/usr/libexec/ovirt-functions'): utils.execCmd([ constants.EXT_SH, '/usr/libexec/ovirt-functions', 'unmount_config', filename ]) logging.debug("unmounted %s using ovirt", filename) (dummy, basename) = os.path.split(filename) if os.path.exists(filename): content = open(filename).read() else: # For non-exists ifcfg-* file use predefined header content = cls.DELETED_HEADER + '\n' logging.debug("backing up %s: %s", basename, content) cls.writeBackupFile(netinfo.NET_CONF_BACK_DIR, basename, content)