def get_sels(server): sels = [] serverData = get_config(server) if serverData: password = serverData['password'] ipaddr = serverData['ipaddr'] salt = serverData['salt'] if serverData.get('username'): out, err, rc = run_command( ['ipmitool', '-H', ipaddr, '-I', 'lanplus', '-U', serverData['username'], '-P', decrypt(password, salt), 'sel', 'list']) else: out, err, rc = run_command( ['ipmitool', '-H', ipaddr, '-I', 'lanplus', '-P', decrypt(password, salt), 'sel', 'list']) if rc == 0: output = out.rstrip().split('\n') for each in output: sels.append(get_each_sel(each)) else: raise OperationFailed( 'GINSEL00001E', {'name': server, 'err': err, 'rc': rc}) else: raise OperationFailed('GINSEL00002E', {'name': server}) return sels
def activate(self, ifacename): wok_log.info('Bring up an interface ' + ifacename) iface_type = netinfo.get_interface_type(ifacename) if iface_type == "Ethernet": cmd_ipup = ['ip', 'link', 'set', '%s' % ifacename, 'up'] out, error, returncode = run_command(cmd_ipup) if returncode != 0: wok_log.error( 'Unable to bring up the interface on ' + ifacename + ', ' + error) raise OperationFailed('GINNET0059E', {'name': ifacename, 'error': error}) # Some times based on system load, it takes few seconds to # reflect the /sys/class/net files upon execution of 'ip link # set' command. Following snippet is to wait util files get # reflect. timeout = self.wait_time(ifacename) if timeout == 5: wok_log.warn("Time-out has happened upon execution of 'ip " "link set <interface> up', hence behavior of " "activating an interface may not as expected.") else: wok_log.info( 'Successfully brought up the interface ' + ifacename) wok_log.info('Activating an interface ' + ifacename) cmd_ifup = ['ifup', '%s' % ifacename] out, error, returncode = run_command(cmd_ifup) if returncode != 0: wok_log.error( 'Unable to activate the interface on ' + ifacename + ', ' + error) raise OperationFailed('GINNET0016E', {'name': ifacename, 'error': error}) wok_log.info( 'Connection successfully activated for the interface ' + ifacename)
def change_dasdpart_type(part, type): """ Change the type of the dasd partition :param part: name of the dasd partition e.g. dasd1 :param type: partition type to be changed to e.g 4 (Linux LVM type) :return: """ part_details = re.search(r'(dasd[a-zA-Z]+)(\d+)', part) if not part_details: raise OperationFailed('GINDASDPAR0011E', {'name': part}) devname, partnum = part_details.groups() devname = '/dev/' + devname typ_str = '\nt\n' + partnum + '\n' + type + '\n' + 'w\n' p1_out = subprocess.Popen(["echo", "-e", "\'", typ_str, "\'"], stdout=subprocess.PIPE) p2_out = subprocess.Popen(["fdasd", devname], stdin=p1_out.stdout, stderr=subprocess.PIPE, stdout=subprocess.PIPE) p1_out.stdout.close() out, err = p2_out.communicate() if p2_out.returncode != 0: if 'error while rereading partition table' in err.lower(): run_command(["partprobe", devname, "-s"]) else: raise OperationFailed("GINDASDPAR0014E", {'err': err}) return
def delete_sel(server, sel_id): serverData = get_config(server) sel_id_int = int(sel_id, 16) if serverData: password = serverData['password'] ipaddr = serverData['ipaddr'] salt = serverData['salt'] if serverData.get('username'): out, err, rc = run_command( ['ipmitool', '-H', ipaddr, '-I', 'lanplus', '-U', serverData['username'], '-P', decrypt(password, salt), 'sel', 'delete', str(sel_id_int)]) else: out, err, rc = run_command( ['ipmitool', '-H', ipaddr, '-I', 'lanplus', '-P', decrypt(password, salt), 'sel', 'delete', str(sel_id_int)]) if rc != 0: raise OperationFailed( 'GINSEL00004E', {'name': server, 'sel_id': sel_id, 'err': err, 'rc': rc}) else: raise OperationFailed('GINSEL00002E', {'name': server})
def _has_sudo(self, result): result.value = False _master, slave = pty.openpty() os.setsid() fcntl.ioctl(slave, termios.TIOCSCTTY, 0) out, err, exit = run_command(['sudo', '-l', '-U', self.user[USER_NAME], 'sudo']) if exit == 0: debug("User %s is allowed to run sudo" % self.user[USER_NAME]) # sudo allows a wide range of configurations, such as controlling # which binaries the user can execute with sudo. # For now, we will just check whether the user is allowed to run # any command with sudo. out, err, exit = run_command(['sudo', '-l', '-U', self.user[USER_NAME]]) for line in out.split('\n'): if line and re.search("(ALL)", line): result.value = True debug("User %s can run any command with sudo" % result.value) return debug("User %s can only run some commands with sudo" % self.user[USER_NAME]) else: debug("User %s is not allowed to run sudo" % self.user[USER_NAME])
def server_power_cycle(serverData, cmd): count = 0 if 'username' in serverData.keys() and serverData['username']: out, err, rc = run_command( ['ipmitool', '-H', serverData['ipaddr'], '-I', 'lanplus', '-U', serverData['username'], '-P', decrypt(serverData['password'], serverData['salt']), 'chassis', 'power', cmd]) else: out, err, rc = run_command( ['ipmitool', '-H', serverData['ipaddr'], '-I', 'lanplus', '-P', decrypt(serverData['password'], serverData['salt']), 'chassis', 'power', cmd]) if rc == 0: while True: serverData = get_server_status(serverData) if 'on' in cmd and 'on' in serverData['status']: return True elif 'off' in cmd and 'off' in serverData['status']: return True else: if count == 15: return False count += 1 time.sleep(20) else: return False # raising exception is handled by the caller
def prepare(self, conn): mnt_point = tempfile.mkdtemp(dir='/tmp') export_path = "%s:%s" % ( self.poolArgs['source']['host'], self.poolArgs['source']['path']) mount_cmd = ["mount", "-o", 'soft,timeo=100,retrans=3,retry=0', export_path, mnt_point] umount_cmd = ["umount", "-f", export_path] mounted = False # Due to an NFS bug (See Red Hat BZ 1023059), NFSv4 exports may take # 10-15 seconds to mount the first time. cmd_timeout = 15 with RollbackContext() as rollback: rollback.prependDefer(os.rmdir, mnt_point) try: run_command(mount_cmd, cmd_timeout) rollback.prependDefer(run_command, umount_cmd, cmd_timeout) except TimeoutExpired: raise InvalidParameter("KCHPOOL0012E", {'path': export_path}) with open("/proc/mounts", "rb") as f: rawMounts = f.read() output_items = ['dev_path', 'mnt_point', 'type'] mounts = parse_cmd_output(rawMounts, output_items) for item in mounts: if 'dev_path' in item and item['dev_path'] == export_path: mounted = True if not mounted: raise InvalidParameter("KCHPOOL0013E", {'path': export_path})
def _update_lvm_disks(self, pool_name, disks): # check if all the disks/partitions exists in the host for disk in disks: lsblk_cmd = ['lsblk', disk] output, error, returncode = run_command(lsblk_cmd) if returncode != 0: wok_log.error( '%s is not a valid disk/partition. Could not ' 'add it to the pool %s.', disk, pool_name, ) raise OperationFailed( 'KCHPOOL0027E', {'disk': disk, 'pool': pool_name}) # add disks to the lvm pool using vgextend + virsh refresh vgextend_cmd = ['vgextend', pool_name] vgextend_cmd += disks output, error, returncode = run_command(vgextend_cmd) if returncode != 0: msg = 'Could not add disks to pool %s, error: %s' wok_log.error(msg, pool_name, error) raise OperationFailed( 'KCHPOOL0028E', {'pool': pool_name, 'err': error}) # refreshing pool state pool = self.get_storagepool(pool_name, self.conn) if pool.isActive(): pool.refresh(0)
def add_lun(adapter, port, lun_id): """ Add a LUN to system :param adapter: HBA adapter id :param port: Remote port wwpn :param lun_id: Id of the given LUN """ port_dir = '/sys/bus/ccw/drivers/zfcp/' + adapter + '/' + port + '/' lun_dir = port_dir + lun_id wok_log.info("Adding LUN, %s", lun_dir) if os.path.exists(lun_dir): # LUN already present on the system, nothing to add. return else: try: with open(port_dir + 'unit_add', "w") as txt_file: txt_file.write(lun_id) for _ in range(4): # Don't wait for udev queue to completely flush. # Wait for the relavant entry for this LUN is created in sysfs run_command([udevadm, "settle", "--exit-if-exists=" + lun_dir]) if os.path.exists(lun_dir): break except Exception as e: wok_log.error("Unable to add LUN, %s", lun_dir) raise OperationFailed("GS390XSTG00003", {'err': e.message})
def _create_dasd_part(dev, size): """ This method creates a DASD partition :param dev: name of DASD device for creation of partition :param size: block size :return: """ devname = '/dev/' + dev device = PDevice(devname) disk = PDisk(device) num_parts = len(disk.partitions) if num_parts == 3: raise OperationFailed("GINDASDPAR0016E") def kill_proc(proc, timeout_flag): try: parent = psutil.Process(proc.pid) for child in parent.get_children(recursive=True): child.kill() # kill the process after no children is left proc.kill() except OSError: pass else: timeout_flag[0] = True dasd_devs = _get_dasd_names() if dev not in dasd_devs: raise NotFoundError("GINDASDPAR0012E", {'name': dev}) p_str = _form_part_str(size) try: p1_out = subprocess.Popen(["echo", "-e", "\'", p_str, "\'"], stdout=subprocess.PIPE) p2_out = subprocess.Popen(["fdasd", devname], stdin=p1_out.stdout, stderr=subprocess.PIPE, stdout=subprocess.PIPE) p1_out.stdout.close() timeout = 2.0 timeout_flag = [False] timer = Timer(timeout, kill_proc, [p2_out, timeout_flag]) timer.setDaemon(True) timer.start() out, err = p2_out.communicate() if timeout_flag[0]: msg_args = {'cmd': "fdasd " + devname, 'seconds': str(timeout)} raise TimeoutExpired("WOKUTILS0002E", msg_args) if p2_out.returncode != 0: if 'error while rereading partition table' in err.lower(): run_command(["partprobe", devname, "-s"]) else: raise OperationFailed("GINDASDPAR0007E", {'name': devname, 'err': err}) except TimeoutExpired: raise finally: if timer and not timeout_flag[0]: timer.cancel()
def __init__(self, **kargs): self.guest_threads_enabled = False self.sockets = 0 self.cores_present = 0 self.cores_available = 0 self.cores_per_socket = 0 self.threads_per_core = 0 self.max_threads = 0 self.conn = kargs['conn'] libvirt_topology = None try: connect = self.conn.get() libvirt_topology = get_topo_capabilities(connect) except Exception as e: wok_log.info("Unable to get CPU topology capabilities: %s" % e.message) return if libvirt_topology is None: wok_log.info("cpu_info topology not supported.") return if ARCH == 'power': # IBM PowerPC self.guest_threads_enabled = True out, error, rc = run_command(['ppc64_cpu', '--smt']) if rc or 'on' in out: # SMT has to be disabled for guest to use threads as CPUs. # rc is always zero, whether SMT is off or on. self.guest_threads_enabled = False out, error, rc = run_command(['ppc64_cpu', '--cores-present']) if not rc: self.cores_present = int(out.split()[-1]) out, error, rc = run_command(['ppc64_cpu', '--cores-on']) if not rc: self.cores_available = int(out.split()[-1]) out, error, rc = run_command(['ppc64_cpu', '--threads-per-core']) if not rc: self.threads_per_core = int(out.split()[-1]) self.sockets = self.cores_present/self.threads_per_core if self.sockets == 0: self.sockets = 1 self.cores_per_socket = self.cores_present/self.sockets else: # Intel or AMD self.guest_threads_enabled = True self.sockets = int(libvirt_topology.get('sockets')) self.cores_per_socket = int(libvirt_topology.get('cores')) self.cores_present = self.cores_per_socket * self.sockets self.cores_available = self.cores_present self.threads_per_core = int(libvirt_topology.get('threads'))
def create_file(self): fcmd = ["dd", "if=/dev/zero", "of=%s" % TESTFILE, "bs=10M", "count=1"] fout, err, rc = run_command(fcmd) if rc: self.assertRaises(OperationFailed) fscmd = ["mkfs.ext4", TESTFILE, "-F"] fsout, err, rc = run_command(fscmd) if rc: self.assertRaises(OperationFailed) if not os.path.exists(TESTDIR): os.makedirs(TESTDIR)
def activate_iface(self, ifacename): wok_log.info('Bring up an interface ' + ifacename) iface_type = netinfo.get_interface_type(ifacename) if iface_type == "nic": cmd_ipup = ['ip', 'link', 'set', '%s' % ifacename, 'up'] out, error, returncode = run_command(cmd_ipup) if returncode != 0: # non-ascii encoded value and unicode value # cannot be concatenated, so convert both variable # to one format. raise OperationFailed('GINNET0059E', {'name': encode_value(ifacename), 'error': encode_value(error)}) # Some times based on system load, it takes few seconds to # reflect the /sys/class/net files upon execution of 'ip link # set' command. Following snippet is to wait util files get # reflect. timeout = self.wait_time(ifacename) if timeout == 5: wok_log.warn("Time-out has happened upon execution of 'ip " "link set <interface> up', hence behavior of " "activating an interface may not as expected.") else: wok_log.info('Successfully brought up the interface ' + ifacename) wok_log.info('Activating an interface ' + ifacename) cmd_ifup = ['ifup', ifacename] out, error, returncode = run_command(cmd_ifup) # Timeout is used for carrier file # since the carrier file needs few seconds approx 5 sec # to update the carrier value of an iface from 0 to 1. self.wait_time_carrier(ifacename) # Check for the carrier value after the device is activated if os.path.isfile(carrier_path % ifacename): with open(carrier_path % ifacename) as car_file: carrier_val = car_file.readline().strip() if (carrier_val == '0'): if iface_type != "nic": raise OperationFailed('GINNET0094E', {'name': ifacename}) else: raise OperationFailed('GINNET0090E', {'name': ifacename}) else: raise OperationFailed('GINNET0091E', {'name': ifacename}) if returncode != 0: raise OperationFailed('GINNET0016E', {'name': encode_value(ifacename), 'error': encode_value(error)}) wok_log.info( 'Connection successfully activated for the interface ' + ifacename)
def activate_iface(self, ifacename): wok_log.info('Bring up an interface ' + ifacename) iface_type = netinfo.get_interface_type(ifacename) filename = ifcfg_filename_format % ifacename filepath = os.sep + network_configpath + filename if os.path.exists(filepath): if not (os.stat(filepath).st_size == 0): wok_log.info('Activating an interface ' + ifacename) cmd_ifup = ['ifup', ifacename] out, error, returncode = run_command(cmd_ifup) if (returncode == 4): raise OperationFailed('GINNET0095E', {'name': ifacename}) # Timeout is used for carrier file # since the carrier file needs few seconds approx 5 sec # to update the carrier value of an iface from 0 to 1. self.wait_time_carrier(ifacename) # Check for the carrier value after the device is activated if os.path.isfile(carrier_path % ifacename): with open(carrier_path % ifacename) as car_file: carrier_val = car_file.readline().strip() if (carrier_val == '0'): if iface_type != "nic": raise OperationFailed('GINNET0094E', {'name': ifacename}) else: raise OperationFailed('GINNET0090E', {'name': ifacename}) else: raise OperationFailed('GINNET0091E', {'name': ifacename}) if returncode != 0: raise OperationFailed('GINNET0016E', {'name': encode_value(ifacename), 'error': encode_value(error)}) wok_log.info('Connection successfully activated for the ' 'interface ' + ifacename) else: cmd_ipup = ['ip', 'link', 'set', '%s' % ifacename, 'up'] out, error, returncode = run_command(cmd_ipup) if returncode != 0: raise OperationFailed('GINNET0059E', {'name': ifacename}) wok_log.info('Connection successfully activated for the ' 'interface ' + ifacename) else: cmd_ipup = ['ip', 'link', 'set', '%s' % ifacename, 'up'] out, error, returncode = run_command(cmd_ipup) if returncode != 0: raise OperationFailed('GINNET0059E', {'name': ifacename}) wok_log.info('Connection successfully activated for the ' 'interface ' + ifacename)
def _validate_pci_passthrough_env(): # Linux kernel < 3.5 doesn't provide /sys/kernel/iommu_groups if os.path.isdir('/sys/kernel/iommu_groups'): if not glob.glob('/sys/kernel/iommu_groups/*'): raise InvalidOperation("KCHVMHDEV0003E") # Enable virt_use_sysfs on RHEL6 and older distributions # In recent Fedora, there is no virt_use_sysfs. out, err, rc = run_command(['getsebool', 'virt_use_sysfs'], silent=True) if rc == 0 and out.rstrip('\n') != "virt_use_sysfs --> on": out, err, rc = run_command(['setsebool', '-P', 'virt_use_sysfs=on']) if rc != 0: wok_log.warning("Unable to turn on sebool virt_use_sysfs")
def create_file(self): fcmd = ["dd", "if=/dev/zero", "of=/testfile", "bs=10M", "count=1"] fout, err, rc = run_command(fcmd) if rc: self.assertRaises(OperationFailed) fscmd = ["mkfs.ext4", "/testfile", "-F"] fsout, err, rc = run_command(fscmd) if rc: self.assertRaises(OperationFailed) mntpt = '/test' if not os.path.exists(mntpt): os.makedirs(mntpt)
def deactivate_iface(self, ifacename): wok_log.info('Deactivating an interface ' + ifacename) cmd_ifdown = ['ifdown', '%s' % ifacename] out, error, returncode = run_command(cmd_ifdown) if returncode != 0: wok_log.error( 'Unable to deactivate the interface on ' + ifacename + ', ' + error) raise OperationFailed('GINNET0017E', {'name': ifacename, 'error': error}) wok_log.info( 'Connection successfully deactivated for the interface ' + ifacename) wok_log.info('Bringing down an interface ' + ifacename) iface_type = netinfo.get_interface_type(ifacename) if iface_type == "Ethernet": cmd_ipdown = ['ip', 'link', 'set', '%s' % ifacename, 'down'] out, error, returncode = run_command(cmd_ipdown) if returncode != 0: wok_log.error( 'Unable to bring down the interface on ' + ifacename + ', ' + error) raise OperationFailed('GINNET0060E', {'name': ifacename, 'error': error}) # Some times based on system load, it takes few seconds to # reflect the /sys/class/net files upon execution of 'ip link # set' command. Following snippet is to wait util files get # reflect. timeout = self.wait_time(ifacename) if timeout == 5: wok_log.warn("Time-out has happened upon execution of 'ip " "link set <interface> down', hence behavior of " "activating an interface may not as expected.") else: wok_log.info('Successfully brought down the interface ' + ifacename) vlan_or_bond = [nw_cfginterfaces_utils.IFACE_BOND, nw_cfginterfaces_utils.IFACE_VLAN] if iface_type in vlan_or_bond: if ifacename in ethtool.get_devices(): cmd_ip_link_del = ['ip', 'link', 'delete', '%s' % ifacename] out, error, returncode = run_command(cmd_ip_link_del) if returncode != 0 and ifacename in ethtool.get_devices(): wok_log.error('Unable to delete the interface ' + ifacename + ', ' + error) raise OperationFailed('GINNET0017E', {'name': ifacename, 'error': error})
def __init__(self): # This stores all packages to be updated for Ginger Base perspective. # It's a dictionary of dictionaries, in the format # {'package_name': package}, # where: # package = {'package_name': <string>, 'version': <string>, # 'arch': <string>, 'repository': <string> # } self._packages = {} # This stores the number of packages to update self._num2update = 0 # Get the distro of host machine and creates an object related to # correct package management system try: __import__('yum') wok_log.info("Loading YumUpdate features.") self._pkg_mnger = YumUpdate() except ImportError: try: __import__('apt') wok_log.info("Loading AptUpdate features.") self._pkg_mnger = AptUpdate() except ImportError: zypper_help = ["zypper", "--help"] (stdout, stderr, returncode) = run_command(zypper_help) if returncode == 0: wok_log.info("Loading ZypperUpdate features.") self._pkg_mnger = ZypperUpdate() else: raise Exception("There is no compatible package manager " "for this system.")
def ovs_bridge_ports(ovsbr): """Get the ports of a OVS bridge. In some distributions, like Fedora, the files bridge and brif are not created under /sys/class/net/<ovsbridge> for OVS bridges. These specific functions allows one to differentiate OVS bridges from other types of bridges. Args: ovsbr (str): name of the OVS bridge Returns: List[str]: a list with the ports of this bridge. """ if not is_openvswitch_running(): return [] ovs_cmd = find_executable("ovs-vsctl") # openvswitch not installed: there is no OVS bridge configured if ovs_cmd is None: return [] out, _, r_code = run_command([ovs_cmd, 'list-ports', ovsbr], silent=True) if r_code != 0: return [] return [x.strip() for x in out.rstrip('\n').split('\n') if x.strip()]
def _pvdisplay_out(name): """ This method fetches the details of particular PV :param name: path of the PV :return: """ pv_version = get_lvm_version() # Disabled unsupported options to vgs command below # a threshold version if LooseVersion(pv_version) < LooseVersion(LVM_THR_VERSION): below_threshold_version = True cmd = ['pvs', '-o', 'pv_name,vg_name,' 'pv_size,' 'pv_pe_count,pv_pe_alloc_count,' 'pv_uuid,vg_extent_size,' 'vg_free_count', "--separator", ":", name, "--units", "K"] else: below_threshold_version = False cmd = ['pvs', '-o', 'pv_name,vg_name,' 'pv_size,pv_allocatable,' 'pv_pe_count,pv_pe_alloc_count,' 'pv_uuid,vg_extent_size,' 'vg_free_count', "--separator", ":", name, "--units", "K"] out, err, rc = run_command(cmd) if rc == 5 and 'Failed to find device' in err: raise NotFoundError("GINPV00011E", {'dev': name}) elif rc != 0: raise OperationFailed("GINPV00007E", {'dev': name, 'err': err}) return parse_pvdisplay_output(out, below_threshold_version)
def parse_hdds(temperature_unit): # hddtemp will strangely convert a non-number (see error case # below) to 32 deg F. So just always ask for C and convert later. out, error, rc = run_command(['hddtemp']) if rc: wok_log.error("Error retrieving HD temperatures: rc %s." "output: %s" % (rc, error)) return None hdds = OrderedDict() for hdd in out.splitlines(): hdd_name = '' hdd_temp = 0.0 try: hdd_items = hdd.split(':') hdd_name, hdd_temp = hdd_items[0], hdd_items[2] hdd_temp = re.sub('°[C|F]', '', hdd_temp).strip() except Exception as e: wok_log.error('Sensors hdd parse error: %s' % e.message) continue try: # Try to convert the number to a float. If it fails, # don't add this disk to the list. hdd_temp = float(hdd_temp) if(temperature_unit == 'F'): hdd_temp = 9.0/5.0 * hdd_temp + 32 hdds[hdd_name] = hdd_temp except ValueError: # If no sensor data, parse float will fail. For example: # "/dev/sda: IBM IPR-10 5D831200: S.M.A.R.T. not available" wok_log.warning("Sensors hdd: %s" % hdd) hdds['unit'] = temperature_unit return hdds
def get_mlx5_nic_type(mlx5_iface): """Checks lspci output to see if mlx5_iface is a physical or virtual nic interface. This is the lspci output this function is expecting for a mlx5 virtual nic interface: 'Ethernet controller: Mellanox Technologies MT27700 Family [ConnectX-4 Virtual Function]' Verification will be done by checking for the 'Virtual Function' string in the output. Any other lspci output format or any other error will make this function return the default value 'physical'. Args: mlx5_iface (str): interface loaded by the mlx5_core driver. Returns: str: 'virtual' if mlx5_iface is a virtual function/nic, 'physical' otherwise. """ bus_id = get_mlx5_nic_bus_id(mlx5_iface) lspci_cmd = ['lspci', '-s', bus_id] out, err, r_code = run_command(lspci_cmd) if r_code == 0 and 'Virtual Function' in out: return 'virtual' if r_code != 0: wok_log.error('Error while getting nic type of ' 'interface: %s' % err) return 'physical'
def vgs(): """ lists all volume groups in the system. All size units are in bytes. [{'vgname': 'vgtest', 'size': 999653638144L, 'free': 0}] """ cmd = ['vgs', '--units', 'b', '--nosuffix', '--noheading', '--unbuffered', '--options', 'vg_name,vg_size,vg_free'] out, err, rc = run_command(cmd) if rc != 0: raise OperationFailed("KCHLVM0001E", {'err': err}) if not out: return [] # remove blank spaces and create a list of VGs vgs = map(lambda v: v.strip(), out.strip('\n').split('\n')) # create a dict based on data retrieved from vgs return map(lambda l: {'vgname': l[0], 'size': long(l[1]), 'free': long(l[2])}, [fields.split() for fields in vgs])
def _erase_remote_file(self, path): username_host = "root@%s" % KIMCHI_LIVE_MIGRATION_TEST cmd = ['ssh', '-oStrictHostKeyChecking=no', username_host, 'rm', '-f', path] _, _, returncode = run_command(cmd, silent=True) if returncode != 0: print 'cannot erase remote file ', path
def disable_tcp_port(port): _, err, r_code = run_command( ['firewall-cmd', '--remove-port=%s/tcp' % port] ) if r_code != 0: wok_log.error('Error when removing port from ' 'firewall-cmd: %s' % err)
def lvs(vgname=None): """ lists all logical volumes found in the system. It can be filtered by the volume group. All size units are in bytes. [{'lvname': 'lva', 'path': '/dev/vgtest/lva', 'size': 12345L}, {'lvname': 'lvb', 'path': '/dev/vgtest/lvb', 'size': 12345L}] """ cmd = ['lvs', '--units', 'b', '--nosuffix', '--noheading', '--unbuffered', '--options', 'lv_name,lv_path,lv_size,vg_name'] out, err, rc = run_command(cmd) if rc != 0: raise OperationFailed("KCHLVM0001E", {'err': err}) if not out: return [] # remove blank spaces and create a list of LVs filtered by vgname, if # provided lvs = filter(lambda f: vgname is None or vgname in f, map(lambda v: v.strip(), out.strip('\n').split('\n'))) # create a dict based on data retrieved from lvs return map(lambda l: {'lvname': l[0], 'path': l[1], 'size': long(l[2])}, [fields.split() for fields in lvs])
def is_libvirtd_up(): """ Checks if libvirtd.service is up. """ cmd = ['systemctl', 'is-active', 'libvirtd.service'] output, error, rc = run_command(cmd, silent=True) return True if output == 'active\n' else False
def create_disk_image(format_type, path, capacity): """ Create a disk image for the Guest Args: format: Format of the storage. e.g. qcow2 path: Path where the virtual disk will be created capacity: Capacity of the virtual disk in GBs Returns: """ out, err, rc = run_command( [ '/usr/bin/qemu-img', 'create', '-f', format_type, '-o', 'preallocation=metadata', path, encode_value(capacity) + 'G', ] ) if rc != 0: raise OperationFailed('KCHTMPL0041E', {'err': err}) return
def _vgdisplay_out(name): """ This method gets the details of particular volume group :param name: Name of the volume group :return: """ vg_version = get_lvm_version() # Disabled unsupported options to vgs command below # a threshold version if LooseVersion(vg_version) < LooseVersion(LVM_THR_VERSION): below_threshold_version = True cmd = ["vgs", "-o", "vg_name,vg_sysid," "vg_fmt,vg_mda_count,vg_seqno," "max_lv,lv_count,max_pv,pv_count," "vg_size,vg_extent_size,pv_pe_count," "pv_pe_alloc_count,pv_used,vg_free_count,pv_free," "vg_uuid,pv_name", "--separator", ":", name, "--units", "K"] else: below_threshold_version = False cmd = ["vgs", "-o", "vg_name,vg_sysid," "vg_fmt,vg_mda_count,vg_seqno,vg_permissions," "vg_extendable,max_lv,lv_count,max_pv,pv_count," "vg_size,vg_extent_size,pv_pe_count," "pv_pe_alloc_count,pv_used,vg_free_count,pv_free," "vg_uuid,pv_name", "--separator", ":", name, "--units", "K"] out, err, rc = run_command(cmd) if rc != 0: raise OperationFailed("GINVG00008E") return parse_vgdisplay_output(out, below_threshold_version)
def is_feature_available(self): _, _, returncode = run_command(['lsdasd', '-l']) ptfm = platform.machine() if ptfm != 's390x' or returncode != 0: return False else: return True
def _erase_remote_file(self, path): username_host = "root@%s" % KIMCHI_LIVE_MIGRATION_TEST cmd = [ 'ssh', '-oStrictHostKeyChecking=no', username_host, 'rm', '-f', path ] _, _, returncode = run_command(cmd, silent=True) if returncode != 0: print 'cannot erase remote file ', path
def reload_rules(self, name): rules_list = get_list_of_loaded_rules() unload_all_rules = ['auditctl', '-D'] out, err, returncode = run_command(unload_all_rules) if returncode != 0: raise OperationFailed('GINAUD0002E', {'name': unload_all_rules}) for each_rule in rules_list: if each_rule != str(name): self.load(each_rule)
def lookup(self, params): cmd = ['systemctl', 'status', "sepctl"] output, error, rc = run_command(cmd) # workarround to get the correct output from this command if rc == 0: return {"status": "running"} return {"status": "not running"}
def update(self, powerprofile, params): if params['active'] and self.active_powerprofile != powerprofile: self.active_powerprofile = powerprofile tuned_cmd = ["tuned-adm", "profile", powerprofile] output, error, returncode = run_command(tuned_cmd) if returncode != 0: raise OperationFailed("GINPOWER004E", {'profile': powerprofile, 'err': error}) return powerprofile
def clear_multipath(dm_long_name): """ Clear a multipath device entry @param dm_long_name : name of multipath device """ out, err, rc = run_command(['multipath', '-f', dm_long_name]) if rc != 0: wok_log.error("Unable to remove multipath device, %s", dm_long_name) raise OperationFailed("GS390XSTG0018E", {'err': err})
def _remove_devices(cb, devices): """ Remove one or more device IDs from blacklist. :param devices: List of devices IDs. It can have range of device IDs Ex: ['0.0.0120', '0.0.1230-0.0.1300', '0.0.001'] device ID format: "<CSSID>.<SSID>.<DEVNO>". Ex: "0.0.0190" Devices for which CSSID and SSID are 0 can alternatively be specified by using only the device number, either with or without leading "0x" and zeros. Ex: "190", "0x190" or "0190" """ cb('') # reset messages try: wok_log.info('Removing devices %s from ignore list' % devices) failed_devices = {} devices = [ x.encode('utf-8') if isinstance(x, unicode) else str(x) for x in devices ] for device in devices: if device and not device.isspace(): if '-' in device: # if range, remove space if any before or after '-' device = device.replace(' ', '') command = [CIO_IGNORE, '-r', device] out, err, rc = run_command(command) if rc: wok_log.error('failed to remove device(s): %s, from' ' ignore list. Error: %s' % (device, err.strip())) err = err.strip().split(':')[-1].strip() failed_devices[device] = err else: failed_devices[device] = 'device ID is required' wok_log.error('failed to remove device since' ' device id is empty') if failed_devices: # to handle unicode charater str_failed_devices = ', '.join('%s: %s' % (device, err) for (device, err) in failed_devices.items()) wok_log.error( 'failed to remove devices \"%s\" from' ' ignore list', str_failed_devices) raise OperationFailed('GS390XIOIG002E', {'failed_devices': str_failed_devices}) str_devices = ', '.join(devices) wok_log.info('Successfully removed devices \"%s\" from' ' ignore list' % str_devices) cb( 'Successfully removed devices \"%s\" from ignore' ' list' % str_devices, True) except Exception as e: cb(e.message, False)
def _get_vg_list(): """ This method gets a list of volume group names :return: """ cmd = ["vgs", "-o", "vg_name"] out, err, rc = run_command(cmd) if rc != 0: raise OperationFailed("GINVG00007E") return parse_pvlist_output(out)
def unload_kernel_module(module_name): out, err, returncode = run_command(['modprobe', '-r', module_name]) if returncode != 0: if 'not found' in err: raise NotFoundError('GINSYSMOD00002E', {'module': module_name}) else: raise OperationFailed('GINSYSMOD00005E', { 'err': err, 'module': module_name })
def get_disks_by_id_out(): """ Execute 'ls -l /dev/disk/by-id' :return: Output of 'ls -l /dev/disk/by-id' """ cmd = ['ls', '-l', '/dev/disk/by-id'] out, err, rc = run_command(cmd) if rc != 0: raise OperationFailed('GINSD00001E', {'err': err}) return out
def _rollback_on_failure(self, gateway): _, err, rc = run_command(['ip', 'route', 'del', 'default']) if rc and not ('No such process' in err): raise OperationFailed('GINNET0010E', {'reason': err}) if gateway: _, err, rc = run_command( ['ip', 'route', 'add', 'default', 'via', gateway]) if rc: raise OperationFailed('GINNET0011E', {'reason': err}) conn = self._conn try: conn.changeRollback() except libvirt.libvirtError as e: # In case the timeout thread is preempted, and confirm_change() is # called before our changeRollback(), we can just ignore the # VIR_ERR_OPERATION_INVALID error. if e.get_error_code() != libvirt.VIR_ERR_OPERATION_INVALID: raise
def is_openvswitch_running(): """Checks if the openvswitch service is running in the host. Returns: bool: True if openvswitch service is running, False otherwise. """ cmd = ['systemctl', 'is-active', 'openvswitch', '--quiet'] _, _, r_code = run_command(cmd, silent=True) return r_code == 0
def run_zipl_cmd(): """ Run zipl command to update the bootloader """ wok_log.info('Running zipl command to update bootloader') out, err, rc = run_command(['zipl']) if rc: wok_log.error('failed to execute zipl, %s', err) raise OperationFailed("GS390XSTG00015", {'err': err})
def create_local_sdr_cache( username, password, ipaddr, salt, localSdrCache, server): out, err, rc = run_command( ['ipmitool', '-H', ipaddr, '-I', 'lanplus', '-U', username, '-P', decrypt(password, salt), 'sdr', 'dump', localSdrCache]) if rc == 0: return True else: return False
def _get_dasd_dev_details(bus_id): """ Executes 'lsdasd -l bus_id' command and returns :return: details of device with given bus_id """ command = ['lsdasd', '-l', bus_id] dasdout, err, rc = run_command(command) if rc: raise OperationFailed("GINDASD0002E", {'err': err}) return _parse_lsdasd_output(dasdout)
def _get_lsdasd_devs(): """ Executes 'lsdasd -l' command and returns :return: output of 'lsdasd -l' command """ command = ['lsdasd', '-l'] dasdout, err, rc = run_command(command) if rc: raise OperationFailed('GINDASD0001E', {'err': err}) return _parse_lsdasd_output(dasdout)
def get_active_tuned_profile(): tuned_cmd = ["tuned-adm", "active"] output, error, returncode = run_command(tuned_cmd) # This is a possible scenario where tuned is running # but there is no active profile yet. No need to # report/issue an error. if returncode != 0: return None output = output.split() return output[-1].rstrip()
def _swapoff_device(device_name): """ Remove a swap device :param device_name: file or device path :return: """ out, err, rc = run_command(["swapoff", device_name]) if rc != 0: raise OperationFailed("GINSP00016E", {'err': err})
def _activate_swap(file_loc): """ Activate a swap device :param file_loc: file location or a device path :return: """ out, err, rc = run_command(["swapon", file_loc]) if rc != 0: raise OperationFailed("GINSP00013E", {'err': err}) return
def _get_lv_list(): """ This method fetches the list of existing logical volumes :return: """ cmd = ["lvs", "-o", "lv_path"] out, err, rc = run_command(cmd) if rc != 0: raise OperationFailed("GINLV00008E") return parse_pvlist_output(out)
def _get_pv_devices(): """ This method fetches the list of PV names :return: """ cmd = ["pvs", "-o", "pv_name"] pvout, err, rc = run_command(cmd) if rc != 0: raise OperationFailed("GINPV00006E", {'err': err}) return parse_pvlist_output(pvout)
def _create_pv(name): """ This method creates the PV :param name: path of the partition to be used as PV :return: """ out, err, rc = run_command(["pvcreate", "-f", name]) if rc != 0: raise OperationFailed("GINPV00008E", {'err': err}) return
def _qemu_support_spice(self): qemu_path = find_qemu_binary(find_emulator=True) out, err, rc = run_command(['ldd', qemu_path]) if rc != 0: wok_log.error('Failed to find qemu binary dependencies: %s', err) return False for line in out.split('\n'): if line.lstrip().startswith('libspice-server.so'): return True return False
def add_lun(adapter, port, lun_id): """ Add a LUN to system :param adapter: HBA adapter id :param port: Remote port wwpn :param lun_id: Id of the given LUN """ port_dir = '/sys/bus/ccw/drivers/zfcp/' + adapter + '/' + port + '/' lun_dir = port_dir + lun_id wok_log.info("Adding LUN, %s", lun_dir) if os.path.exists(lun_dir): # LUN already present on the system, nothing to add. return else: try: with open(port_dir + 'unit_add', "w") as txt_file: txt_file.write(lun_id) for _ in range(4): # Don't wait for udev queue to completely flush. # Wait for the relavant entry for this LUN is created in sysfs run_command([udevadm, "settle", "--exit-if-exists=" + lun_dir]) if os.path.exists(lun_dir): entry_exists = False fo = open("/etc/zfcp.conf", "r") lines = fo.readlines() for line in lines: if [adapter, port, lun_id] == line.split(): entry_exists = True fo.close() if not entry_exists: with open("/etc/zfcp.conf", "a") as zfcp: zfcp.write(adapter + " " + port + " " + lun_id + "\n") break except Exception as e: wok_log.error("Unable to add LUN, %s", lun_dir) raise OperationFailed("GS390XSTG00003", {'err': e.message})
def _lvdisplay_out(path): """ This method fetches the details of the logical volume :param path: Path of the particular logical volume :return: """ cmd = ["lvdisplay", path] out, err, rc = run_command(cmd) if rc != 0: raise OperationFailed("GINLV00009E") return parse_lvdisplay_output(out)
def load_smt_s390x(self, backup): """ Method to execute the changes done in zipl file for s390x architecture. """ command = ['zipl'] output, error, retcode = run_command(command) if retcode != 0: self.recover_ziplfile(ZIPL, backup) raise OperationFailed('GINSMT0008E', {'error': error}) wok_log.info('Successfully applied SMT settings.')
def _get_df_output(): """ Executes 'df -kT' command and returns :return: output of 'df -kT' command """ command = ['df', '-kT'] dfout, err, rc = run_command(command) if rc: wok_log.error("df -kT failed") raise OperationFailed("GINFS00006E", {'err': err}) return _parse_df_output(dfout)
def _remove_lv(name): """ This method removes the logical volume :param name: Path of the logical volume :return: """ cmd = ["lvremove", "-f", name] out, err, rc = run_command(cmd) if rc != 0: raise OperationFailed("GINLV00010E") return
def _restore_tar(self, archive_id): backup_dir = os.path.join( PluginPaths('ginger').state_dir, 'ginger_backups') backup_file = os.path.join(backup_dir, archive_id + '.tar.gz') cmd = ['tar', '-xzf', backup_file, '-C', '/'] out, err, rc = run_command(cmd) if rc != 0: raise OperationFailed('GINHBK0001E', { 'name': backup_file, 'cmd': ' '.join(cmd) })
def nfsmount(server, share, mount_point, mnt_opts): """ This method mounts the remote nfs share on local system :param server: ip address of the nfs server :param share: remote share location :param mount_point: mount point on local system :return: """ if not os.path.exists(mount_point): d_cmd = ['mkdir', mount_point] d_out, err, rc = run_command(d_cmd) if rc: wok_log.error("mkdir failed") if mnt_opts: nfs_cmd = ['mount', server + ':' + share, mount_point, "-o", mnt_opts] else: nfs_cmd = ['mount', server + ':' + share, mount_point] nfs_out, err, rc = run_command(nfs_cmd) if rc: raise OperationFailed("GINFS00018E", err)
def get_list_of_loaded_rules(): cmd_sc = ['auditctl', '-l'] out, err, returncode = run_command(cmd_sc) if returncode == 0: audit_rules = out.split('\n') audit_rules.pop() if audit_rules[0] == "No rules": audit_rules.pop() return audit_rules + get_list_of_loaded_control_rules() else: raise OperationFailed('GINAUD0002E', {'name': ' '.join(cmd_sc)})