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 commit(self, name): command = ['update_flash', '-c'] output, error, rc = run_command(command) if rc: raise OperationFailed('GINFW0005E', {'rc': rc}) # update_flash returns a message on success, so log it. wok_log.info(output)
def upgrade_objectstore_data(item, old_uri, new_uri): """ Upgrade the value of a given JSON's item of all Template and VM entries of the objectstore from old_uri to new_uri. """ total = 0 try: conn = sqlite3.connect(config.get_object_store(), timeout=10) cursor = conn.cursor() sql = "SELECT id, json FROM objects WHERE type='template' OR type='vm'" cursor.execute(sql) for row in cursor.fetchall(): # execute update here template = json.loads(row[1]) path = template[item] if item in template else 'none' if path.startswith(old_uri): template[item] = new_uri + path sql = 'UPDATE objects SET json=?, version=? WHERE id=?' cursor.execute(sql, (json.dumps(template), config.get_kimchi_version(), row[0])) conn.commit() total += 1 except sqlite3.Error as e: if conn: conn.rollback() wok_log.error('Error while upgrading objectstore data: %s', e.args[0]) raise OperationFailed('KCHUTILS0006E') finally: if conn: conn.close() wok_log.info("%d '%s' entries upgraded in objectstore.", total, item)
def sosreport_generate(cb, name): def log_error(e): wok_log = logging.getLogger('Model') wok_log.warning('Exception in generating debug file: %s', e) try: # Sosreport collection sosreport_file = sosreport_collection(name) md5_report_file = sosreport_file + '.md5' report_file_extension = '.' + sosreport_file.split('.', 1)[1] path = config.get_debugreports_path() sosreport_target = os.path.join(path, name + report_file_extension) msg = 'Moving debug report file "%s" to "%s"' \ % (sosreport_file, sosreport_target) wok_log.info(msg) shutil.move(sosreport_file, sosreport_target) delete_the_sosreport_md5_file(md5_report_file) cb('OK', True) return except WokException as e: log_error(e) raise except OSError as e: log_error(e) raise except Exception as e: # No need to call cb to update the task status here. # The task object will catch the exception raised here # and update the task status there log_error(e) raise OperationFailed('GGBDR0005E', {'name': name, 'err': e})
def create_group(groupname): """ method to create user group :param groupname: non-empty string :return: group id(gid) """ wok_log.info('in create_group() method. group name: %s' % groupname) if not isinstance(groupname, str) or not groupname.strip(): wok_log.error('group name is not non-empty string. ' 'group name %s' % groupname) raise InvalidParameter('GINUSER0014E', {'group': groupname, 'err': 'see log for details'}) adm = libuser.admin() if adm.lookupGroupByName(groupname): raise OperationFailed('GINUSER0018E', {'group': groupname}) try: new_group = adm.initGroup(groupname) if new_group[libuser.GIDNUMBER][0] < 1000: new_group.set(libuser.GIDNUMBER, adm.getFirstUnusedGid(1000)) adm.addGroup(new_group) wok_log.info('successfully created group. group name: %s.' % groupname) return new_group[libuser.GIDNUMBER][0] except Exception as e: raise OperationFailed('GINUSER0014E', {'group': groupname, 'err': e})
def delete_group(groupname): wok_log.info('in delete_group(). group name: %s' % groupname) if not isinstance(groupname, str) or not groupname.strip(): wok_log.error('group name is not non-empty string. ' 'group name %s' % groupname) raise InvalidParameter('GINUSER0012E', {'group': groupname, 'err': 'see log for details'}) adm = libuser.admin() group_id = int(get_group_gid(groupname)) if group_id <= 1000: wok_log.error('Ignoring deletion of system group "%s" with gid %s' % (groupname, group_id)) return group_obj = adm.lookupGroupById(group_id) if not group_obj: wok_log.error('Could not locate group "%s" with gid %s' % (groupname, group_id)) return if not adm.enumerateUsersByGroup(groupname): # groups prepend with '%' if '%' + groupname in get_sudoers(admin_check=False): raise OperationFailed('GINUSER0017E', {'group': groupname}) try: adm.deleteGroup(group_obj) except Exception as e: raise OperationFailed('GINUSER0012E', {'group': groupname, 'err': e.__str__()}) wok_log.info('end of delete_group(). group name: %s' % groupname)
def _form_cfg_options_attr(portno, options): """ method to form OPTIONS attribute of ifcfg file Example: OPTIONS="layer2=1 portno=0 buffer_count=128" valid OPTIONS attribute includes options like layer2, portno, buffercount etc this method focus on replacing only portno with given port """ wok_log.info('In _form_cfg_options_attr(%s, %s) method' % (portno, options)) # use 0 port by default if portno is not provided portno = portno if isinstance(portno, int) else 0 if options and not options.isspace(): if re.match(r'^[\"\'][^\"\']*[\"\']$', options): # valid OPTIONS value will be enclosed by # either single or double quotes if re.search(r'portno=\d', options): return re.sub(r'portno=\d', 'portno=%s' % portno, options) else: return options.rstrip(options[-1]) \ + 'portno=%s' % portno + options[0] wok_log.info('End of _form_cfg_options_attr(%s, %s) method' % (portno, options)) return '"layer2=1 portno=%s"' % portno
def remove_user_from_group(user, group): """ method to remove user from group :param user: user name :param group: group name """ wok_log.info('in remove_user_from_group() method') if not isinstance(user, str) or not user.strip(): wok_log.error('user name is not non-empty string. name: %s' % user) raise InvalidParameter('GINUSER0010E', {'user': user, 'err': 'see log for details'}) if not isinstance(group, str) or not group.strip(): wok_log.error('group name is not non-empty string. ' 'group name %s' % group) raise InvalidParameter('GINUSER0010E', {'user': user, 'err': 'see log for details'}) try: adm = libuser.admin() grpobj = adm.lookupGroupByName(group) # Remove all ocurrences members = set(grpobj.get('gr_mem')) if user in members: members = set(grpobj.get('gr_mem')) - set([user]) grpobj.set('gr_mem', list(members)) adm.modifyGroup(grpobj) except Exception as e: raise OperationFailed('GINUSER0021E', {'user': user, 'group': group, 'err': e.__str__()}) wok_log.info('end of remove_user_from_group() method')
def _unpersist_interface(interface): """ method to unpersist network device by removing ifcfg file of corresponding network device from /etc/sysconfig/network-scripts/ directory :param interface: network device id :return: None """ wok_log.info('un persisting network device %s' % interface) ifcfg_file_path = '/' + ifcfg_path.replace('<deviceid>', interface) if isinstance(ifcfg_file_path, unicode): ifcfg_file_path = ifcfg_file_path.encode('utf-8') try: if os.path.isfile(ifcfg_file_path): os.remove(ifcfg_file_path) except Exception as e: wok_log.error('Failed to remove file %s. Error: %s' % (ifcfg_file_path, e.message)) raise OperationFailed('GS390XIONW004E', {'ifcfg_file_path': ifcfg_file_path, 'device': interface, 'error': e.message}) wok_log.info('successfully removed ifcfg file %s to unpersist ' 'network device %s' % (ifcfg_file_path, interface))
def _bring_online(interface, osa_portno=None): """ method to configure network device :param interface: network device id :return: None """ wok_log.info('Configuring network device %s with port number %s' % (interface, osa_portno)) # form command as per osa_port command = [ZNETCONF_CMD, '-a', interface, '-o', 'portno=%s' % osa_portno]\ if isinstance(osa_portno, int) else [ZNETCONF_CMD, '-a', interface] out, err, rc = run_command(command) # znetconf command gives non zero rc if the osa port is not available # for the adapter, but configures the triplet with default port(port 0) if rc: if 'Failed to configure portno' in err: # if failed to configure port, port 0 is used by default osa_portno = '0' else: # raise exception for errors excluding port configuration err = ','.join(line.strip() for line in err.splitlines()) wok_log.error('failed to configure network device %s. ' 'Error: %s' % (interface, err)) raise OperationFailed('GS390XIONW001E', {'device': interface, 'error': err}) wok_log.info("Configured network device %s " "successfully" % interface) return osa_portno
def _event_devices(self, conn, dom, alias, opaque): """ Callback to handle add/remove devices event """ if opaque._cb is None: wok_log.error('opaque must be valid') return wok_log.info('Device %s removed successfully' % alias) # Re-attach device to host if it's not managed mode if not opaque._managed: try: dev = conn.get().nodeDeviceLookupByName(alias) dev.reAttach() except libvirt.libvirtError as e: wok_log.error( 'Unable to attach device %s back to host. Error: %s', alias, str( e) ) else: wok_log.info( "Device %s was attached in 'managed' mode. " 'Skipping re-attach().' % alias ) opaque._cb('OK', True)
def get_system_report_tool(): # Please add new possible debug report command here # and implement the report generating function # based on the new report command report_tools = ( { 'cmd': '/usr/sbin/dbginfo.sh --help', 'fn': DebugReportsModel.debugreport_generate }, { 'cmd': 'sosreport --help', 'fn': DebugReportsModel.sosreport_generate }, ) # check if the command can be found by shell one by one for helper_tool in report_tools: try: retcode = subprocess.call(helper_tool['cmd'], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) if retcode == 0: return helper_tool['fn'] except Exception as e: wok_log.info('Exception running command: %s', e) return None
def _create_ifcfg_file(interface): """ method to create ifcfg-enccw<device_id> file in /etc/sysconfig/network-scripts/ folder and change persmission of that file to 644 to be in sync with other files in directory :param interface: network device id :return: None """ wok_log.info('creating ifcfg file for %s', interface) ifcfg_file_path = '/' + ifcfg_path.replace('<deviceid>', interface) try: ifcfg_file = open(ifcfg_file_path, 'w+') ifcfg_file.close() os.system('chmod 644 ' + ifcfg_file_path) wok_log.info('created file %s for network device %s' % (ifcfg_file_path, interface)) except Exception as e: wok_log.error('failed to create file %s for network device %s. ' 'Error: %s' % (ifcfg_file_path, interface, e.__str__())) raise OperationFailed("GS390XIONW005E", {'ifcfg_file_path': ifcfg_file_path, 'device': interface, 'error': e.__str__()})
def update(self, name, params): """ Modifies the rule. :param name: the existing rule. :param params: The dict of params for the new rule. :return: the new rule. """ try: gingerAuditLock.acquire() if self.is_rule_exists(name): info = self.get_audit_rule_info(name) rule = RulesModel().construct_rules(params) if rule == name: raise OperationFailed("GINAUD0034E", {"name": name}) if info['loaded'] == 'yes': RulesModel().create(params) if info['type'] == "Control Rule": RulesModel().write_to_aucontrol_rules(rule) else: RulesModel().write_to_audit_rules(rule) wok_log.info("Deleting the existing rule %s" % name) self.delete_rule(name) wok_log.info("The rule has been modified successfully.") return rule else: raise MissingParameter("GINAUD0010E", {"name": name}) except MissingParameter: raise except OperationFailed: raise except Exception: raise OperationFailed("GINAUD0011E", {"name": name}) finally: gingerAuditLock.release()
def get_console(self): """ Opens a console to this guest and returns a reference to it. Note: If another instance (eg: virsh) has an existing console opened to this guest, this code will steal that console. """ # guest must be in a running state to get its console counter = 10 while not self.is_running(): wok_log.info('[%s] Guest %s is not running, waiting for it', self._proc_name, self._name) counter -= 1 if counter <= 0: return None time.sleep(1) # attach a stream in the guest console so we can read from/write to it if self._stream is None: wok_log.info('[%s] Opening the console for guest %s', self._proc_name, self._name) self._stream = self._libvirt.newStream(libvirt.VIR_STREAM_NONBLOCK) self._guest.openConsole(None, self._stream, libvirt.VIR_DOMAIN_CONSOLE_FORCE | libvirt.VIR_DOMAIN_CONSOLE_SAFE) return self._stream
def _unpersist_interface(interface): """ method to unpersist network device by removing ifcfg file of corresponding network device from /etc/sysconfig/network-scripts/ directory :param interface: network device id :return: None """ wok_log.info('un persisting network device %s' % interface) ifcfg_file_path = '/' + ifcfg_path.replace('<deviceid>', interface) if isinstance(ifcfg_file_path, unicode): ifcfg_file_path = ifcfg_file_path.encode('utf-8') try: if os.path.isfile(ifcfg_file_path): os.remove(ifcfg_file_path) except Exception as e: wok_log.error('Failed to remove file %s. Error: %s' % (ifcfg_file_path, e.message)) raise OperationFailed( 'GS390XIONW004E', { 'ifcfg_file_path': ifcfg_file_path, 'device': interface, 'error': e.message }) wok_log.info('successfully removed ifcfg file %s to unpersist ' 'network device %s' % (ifcfg_file_path, interface))
def _validate_device(interface): """ validate the device id. Valid device Ids should have <single digitnumber>.<single digitnumber>.<4 digit hexadecimalnumber> or <4 digit hexadecimal number> :param interface: device id """ wok_log.info('Validating network interface %s' % interface) pattern_with_dot = r'^\d\.\d\.[0-9a-fA-F]{4}$' if isinstance(interface, unicode): interface = interface.encode('utf-8') if interface and not str(interface).isspace(): interface = str(interface).strip() if ENCCW in interface: interface = interface.replace(ENCCW, '') out = re.search(pattern_with_dot, interface) if out is None: wok_log.error("Invalid interface id. interface: %s" % interface) raise InvalidParameter( "GS390XINVINPUT", {'reason': 'invalid interface id: %s' % interface}) wok_log.info('Successfully validated network interface') else: wok_log.error("interface id is empty. interface: %s" % interface) raise InvalidParameter( "GS390XINVINPUT", {'reason': 'device id is required. ' 'device id: %s' % interface})
def reject(self, name): command = ['update_flash', '-r'] output, error, rc = run_command(command) if rc: raise OperationFailed('GINFW0006E', {'rc': rc}) # update_flash returns a message on success, so log it. wok_log.info(output)
def _validate_device(interface): """ validate the device id. Valid device Ids should have <single digitnumber>.<single digitnumber>.<4 digit hexadecimalnumber> or <4 digit hexadecimal number> :param interface: device id """ wok_log.info('Validating network interface %s' % interface) pattern_with_dot = r'^\d\.\d\.[0-9a-fA-F]{4}$' if interface and not str(interface).isspace(): interface = str(interface).strip() if ENCCW in interface: interface = interface.strip(ENCCW) out = re.search(pattern_with_dot, interface) if out is None: wok_log.error("Invalid interface id. interface: %s" % interface) raise InvalidParameter("GS390XINVINPUT", {'reason': 'invalid interface id: %s' % interface}) wok_log.info('Successfully validated network interface') else: wok_log.error("interface id is empty. interface: %s" % interface) raise InvalidParameter("GS390XINVINPUT", {'reason': 'device id is required. ' 'device id: %s' % interface})
def doUpdate(self, cb, params): """ Execute the update """ swupdateLock.acquire() wok_log.info('doUpdate - swupdate lock acquired') # reset messages cb('') if params is not None: cmd = self._pkg_mnger.update_cmd['specific'] + params else: cmd = self._pkg_mnger.update_cmd['all'] proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, preexec_fn=self.preUpdate) msgs = [] while proc.poll() is None: msgs.append(proc.stdout.readline()) cb(''.join(msgs)) time.sleep(0.5) # read the final output lines msgs.extend(proc.stdout.readlines()) retcode = proc.poll() swupdateLock.release() wok_log.info('doUpdate - swupdate lock released') if retcode == 0: return cb(''.join(msgs), True) msgs.extend(proc.stderr.readlines()) return cb(''.join(msgs), False)
def lookup(self, name): """ Gets list of all configured device info(dictionary) devices with name of device as key. If the list has the device lookup is looking for then returns the device info. Otherwise gets list of all un-configured device info devices with name of device as key. If the list has the device lookup is looking for then returns the device info. Otherwise raises InvalidParameter exception. :param name: name of device to lookup. :return: OSA device info if device found otherwise InvalidParameter """ wok_log.info('Fetching attributes of network devices %s' % name) _validate_device(name) configured_devices = _get_configured_devices(key=UNIQUE_COL_NAME) device = configured_devices.get(name, None) if not device: unconfigured_devices = _get_unconfigured_devices( key=UNIQUE_COL_NAME) device = unconfigured_devices.get(name, None) if not device: wok_log.error('Given device is not of type OSA. Device: %s', name) raise InvalidParameter("GS390XINVINPUT", {'reason': 'Given device is not of type ' 'OSA. Device: %s' % name}) wok_log.info('Attributes of network devices %s: %s' % (name, device)) return device
def get_vmlist_bystate(self, state='running'): try: libvirt_mod = __import__('libvirt') except Exception as e: wok_log.info('Unable to import libvirt module. Details:', e.message) # Ignore any error and assume there is no vm running in the host return [] libvirtd_running = ['systemctl', 'is-active', 'libvirtd', '--quiet'] _, _, rcode = run_command(libvirtd_running, silent=True) if rcode != 0: return [] try: conn = libvirt_mod.open(None) return [ dom.name().decode('utf-8') for dom in conn.listAllDomains(0) if (DOM_STATE_MAP[dom.info()[0]] == state) ] except Exception as e: wok_log.info( 'Unable to get virtual machines information. ' 'Details:', e.message) raise OperationFailed('GGBHOST0003E')
def upgrade_objectstore_data(item, old_uri, new_uri): """ Upgrade the value of a given JSON's item of all Template and VM entries of the objectstore from old_uri to new_uri. """ total = 0 try: conn = sqlite3.connect(config.get_object_store(), timeout=10) cursor = conn.cursor() sql = "SELECT id, json FROM objects WHERE type='template' OR type='vm'" cursor.execute(sql) for row in cursor.fetchall(): # execute update here template = json.loads(row[1]) path = template[item] if item in template else 'none' if path.startswith(old_uri): template[item] = new_uri + path sql = 'UPDATE objects SET json=?, version=? WHERE id=?' cursor.execute( sql, (json.dumps(template), config.get_kimchi_version(), row[0]) ) conn.commit() total += 1 except sqlite3.Error as e: if conn: conn.rollback() wok_log.error('Error while upgrading objectstore data: %s', e.args[0]) raise OperationFailed('KCHUTILS0006E') finally: if conn: conn.close() wok_log.info("%d '%s' entries upgraded in objectstore.", total, item)
def commit(self, name): command = ["update_flash", "-c"] output, error, rc = run_command(command) if rc: raise OperationFailed("GINFW0005E", {"rc": rc}) # update_flash returns a message on success, so log it. wok_log.info(output)
def get_console(self): """ Opens a console to this guest and returns a reference to it. Note: If another instance (eg: virsh) has an existing console opened to this guest, this code will steal that console. """ # guest must be in a running state to get its console counter = 10 while not self.is_running(): wok_log.info('Guest %s is not running, waiting for it', self._name) counter -= 1 if counter <= 0: return None time.sleep(1) # attach a stream in the guest console so we can read from/write to it if self._stream is None: wok_log.info('Opening the console for guest %s', self._name) self._stream = self._libvirt.newStream(libvirt.VIR_STREAM_NONBLOCK) self._guest.openConsole( None, self._stream, libvirt.VIR_DOMAIN_CONSOLE_FORCE | libvirt.VIR_DOMAIN_CONSOLE_SAFE) return self._stream
def get_disk_used_by(objstore, conn, path): try: with objstore as session: try: used_by = session.get("storagevolume", path)["used_by"] except (KeyError, NotFoundError): wok_log.info("Volume %s not found in obj store." % path) used_by = [] # try to find this volume in existing vm vms_list = VMsModel.get_vms(conn) for vm in vms_list: dom = VMModel.get_vm(vm, conn) storages = get_vm_disks(dom) for disk in storages.keys(): d_info = get_vm_disk_info(dom, disk) if path == d_info["path"]: used_by.append(vm) try: session.store("storagevolume", path, {"used_by": used_by}, get_kimchi_version()) except Exception as e: # Let the exception be raised. If we allow disks' # used_by to be out of sync, data corruption could # occour if a disk is added to two guests # unknowingly. wok_log.error("Unable to store storage volume id in" " objectstore due error: %s", e.message) raise OperationFailed("KCHVOL0017E", {"err": e.message}) except Exception as e: # This exception is going to catch errors returned by 'with', # specially ones generated by 'session.store'. It is outside # to avoid conflict with the __exit__ function of 'with' raise OperationFailed("KCHVOL0017E", {"err": e.message}) return used_by
def get_list(self, _configured=None): """ :param _configured: True will list only the network devices which are configured. znetconf -c will be used False will list only network devices which are not configured yet. znetconf -u will be used If not given then it will fetch both the list of devices. :return: network OSA device info list. """ wok_log.info('Fetching network devices. _configured ' '= %s' % _configured) if _configured is None: devices = _get_configured_devices() devices.extend(_get_unconfigured_devices()) elif _configured in ['True', 'true']: devices = _get_configured_devices() elif _configured in ['False', 'false']: devices = _get_unconfigured_devices() else: wok_log.error("Invalid _configured given. _configured: %s" % _configured) raise InvalidParameter("GS390XINVTYPE", {'supported_type': 'True/False'}) wok_log.info('Successfully retrieved network devices') return devices
def sosreport_generate(cb, name): def log_error(e): wok_log = logging.getLogger('Model') wok_log.warning('Exception in generating debug file: %s', e) try: # Sosreport collection sosreport_file = sosreport_collection(name) md5_report_file = sosreport_file + '.md5' report_file_extension = '.' + sosreport_file.split('.', 1)[1] path = config.get_debugreports_path() sosreport_target = os.path.join(path, name + report_file_extension) msg = 'Moving debug report file "%s" to "%s"' \ % (sosreport_file, sosreport_target) wok_log.info(msg) shutil.move(sosreport_file, sosreport_target) delete_the_sosreport_md5_file(md5_report_file) cb('OK', True) return except WokException as e: log_error(e) raise except OSError as e: log_error(e) raise except Exception, e: # No need to call cb to update the task status here. # The task object will catch the exception raised here # and update the task status there log_error(e) raise OperationFailed("GGBDR0005E", {'name': name, 'err': e})
def get_disk_used_by(objstore, conn, path): try: with objstore as session: try: used_by = session.get('storagevolume', path)['used_by'] except (KeyError, NotFoundError): wok_log.info('Volume %s not found in obj store.' % path) used_by = [] # try to find this volume in existing vm vms_list = VMsModel.get_vms(conn) for vm in vms_list: dom = VMModel.get_vm(vm, conn) storages = get_vm_disks(dom) for disk in storages.keys(): d_info = get_vm_disk_info(dom, disk) if path == d_info['path']: used_by.append(vm) try: session.store('storagevolume', path, {'used_by': used_by}, get_kimchi_version()) except Exception as e: # Let the exception be raised. If we allow disks' # used_by to be out of sync, data corruption could # occour if a disk is added to two guests # unknowingly. wok_log.error( 'Unable to store storage volume id in' ' objectstore due error: %s', e.message) raise OperationFailed('KCHVOL0017E', {'err': e.message}) except Exception as e: # This exception is going to catch errors returned by 'with', # specially ones generated by 'session.store'. It is outside # to avoid conflict with the __exit__ function of 'with' raise OperationFailed('KCHVOL0017E', {'err': e.message}) return used_by
def _create_ifcfg_file(interface): """ method to create ifcfg-enccw<device_id> file in /etc/sysconfig/network-scripts/ folder and change persmission of that file to 644 to be in sync with other files in directory :param interface: network device id :return: None """ wok_log.info('creating ifcfg file for %s', interface) ifcfg_file_path = '/' + ifcfg_path.replace('<deviceid>', interface) try: ifcfg_file = open(ifcfg_file_path, 'w+') ifcfg_file.close() if isinstance(ifcfg_file_path, unicode): # as os.system default encoding is ascii and not utf8 ifcfg_file_path.encode('utf-8') os.system('chmod 644 ' + ifcfg_file_path) wok_log.info('created file %s for network device %s' % (ifcfg_file_path, interface)) except Exception as e: wok_log.error('failed to create file %s for network device %s. ' 'Error: %s' % (ifcfg_file_path, interface, e.message)) raise OperationFailed( "GS390XIONW005E", { 'ifcfg_file_path': ifcfg_file_path, 'device': interface, 'error': e.message })
def _bring_online(interface, osa_portno=None): """ method to configure network device :param interface: network device id :return: None """ wok_log.info('Configuring network device %s with port number %s' % (interface, osa_portno)) # form command as per osa_port command = [ZNETCONF_CMD, '-a', interface, '-o', 'portno=%s' % osa_portno]\ if isinstance(osa_portno, int) else [ZNETCONF_CMD, '-a', interface] out, err, rc = run_command(command) # znetconf command gives non zero rc if the osa port is not available # for the adapter, but configures the triplet with default port(port 0) if rc: if 'Failed to configure portno' in err: # if failed to configure port, port 0 is used by default osa_portno = '0' else: # raise exception for errors excluding port configuration err = ','.join(line.strip() for line in err.splitlines()) wok_log.error('failed to configure network device %s. ' 'Error: %s' % (interface, err)) raise OperationFailed('GS390XIONW001E', { 'device': interface, 'error': err }) wok_log.info("Configured network device %s " "successfully" % interface) return osa_portno
def lookup(self, name): """ Gets list of all configured device info(dictionary) devices with name of device as key. If the list has the device lookup is looking for then returns the device info. Otherwise gets list of all un-configured device info devices with name of device as key. If the list has the device lookup is looking for then returns the device info. Otherwise raises InvalidParameter exception. :param name: name of device to lookup. :return: OSA device info if device found otherwise InvalidParameter """ wok_log.info('Fetching attributes of network devices %s' % name) _validate_device(name) configured_devices = _get_configured_devices(key=UNIQUE_COL_NAME) device = configured_devices.get(name, None) if not device: unconfigured_devices = _get_unconfigured_devices( key=UNIQUE_COL_NAME) device = unconfigured_devices.get(name, None) if not device: wok_log.error('Given device is not of type OSA. Device: %s', name) raise NotFoundError("GS390XIONW006E", {'device': name}) wok_log.info('Attributes of network devices %s: %s' % (name, device)) return device
def listen(self): """Prepares the environment before starts to accept connections Initializes and destroy the resources needed to accept connection. """ libvirt.virEventRegisterDefaultImpl() try: guest = LibvirtGuest(self._guest_name, self._uri, self.name) except Exception as e: wok_log.error( '[%s] Cannot open the guest %s due to %s', self.name, self._guest_name, str(e), ) self._socket.close() sys.exit(1) except (KeyboardInterrupt, SystemExit): self._socket.close() sys.exit(1) console = None try: console = guest.get_console() if console is None: wok_log.error( '[%s] Cannot get the console to %s', self.name, self._guest_name ) return if not self._is_vm_listening_serial(console): sys.exit(1) self._listen(guest, console) # clear resources aquired when the process is killed except (KeyboardInterrupt, SystemExit): pass finally: wok_log.info( '[%s] Shutting down the socket server to %s console', self.name, self._guest_name, ) self._socket.close() if os.path.exists(self._server_addr): os.unlink(self._server_addr) try: console.eventRemoveCallback() except Exception as e: wok_log.info( '[%s] Callback is probably removed: %s', self.name, str(e)) guest.close()
def shutdown(self, args=None): # Check for running vms before shutdown running_vms = self.get_vmlist_bystate('running') if len(running_vms) > 0: raise OperationFailed("GGBHOST0001E") wok_log.info('Host is going to shutdown.') os.system('shutdown -h now')
def reboot(self, args=None): # Check for running vms before reboot running_vms = self.get_vmlist_bystate('running') if len(running_vms) > 0: raise OperationFailed('GGBHOST0002E') wok_log.info('Host is going to reboot.') os.system('reboot')
def create(self, params): parms = None if 'parms' in params: parms = params['parms'].split() module_name = params['name'] load_kernel_module(module_name, parms) wok_log.info('Kernel module %s loaded.' % module_name) return module_name
def reboot(self, args=None): # Find running VMs running_vms = self._get_vms_list_by_state('running') if len(running_vms) > 0: raise OperationFailed("KCHHOST0002E") wok_log.info('Host is going to reboot.') os.system('reboot')
def reboot(self, args=None): # Check for running vms before reboot running_vms = self.get_vmlist_bystate('running') if len(running_vms) > 0: raise OperationFailed("GGBHOST0002E") wok_log.info('Host is going to reboot.') os.system('reboot')
def shutdown(self, args=None): # Check for running vms before shutdown running_vms = self.get_vmlist_bystate('running') if len(running_vms) > 0: raise OperationFailed('GGBHOST0001E') wok_log.info('Host is going to shutdown.') os.system('shutdown -h now')
def get_vmlist_bystate(self, state='running'): try: libvirt_mod = __import__('libvirt') except Exception, e: wok_log.info("Unable to import libvirt module. Details:", e.message) # Ignore any error and assume there is no vm running in the host return []
def listen(self): """Prepares the environment before starts to accept connections Initializes and destroy the resources needed to accept connection. """ libvirt.virEventRegisterDefaultImpl() try: guest = LibvirtGuest(self._guest_name, self._uri, self.name) except Exception as e: wok_log.error( '[%s] Cannot open the guest %s due to %s', self.name, self._guest_name, str(e), ) self._socket.close() sys.exit(1) except (KeyboardInterrupt, SystemExit): self._socket.close() sys.exit(1) console = None try: console = guest.get_console() if console is None: wok_log.error('[%s] Cannot get the console to %s', self.name, self._guest_name) return if not self._is_vm_listening_serial(console): sys.exit(1) self._listen(guest, console) # clear resources aquired when the process is killed except (KeyboardInterrupt, SystemExit): pass finally: wok_log.info( '[%s] Shutting down the socket server to %s console', self.name, self._guest_name, ) self._socket.close() if os.path.exists(self._server_addr): os.unlink(self._server_addr) try: console.eventRemoveCallback() except Exception as e: wok_log.info('[%s] Callback is probably removed: %s', self.name, str(e)) guest.close()
def shutdown(self, args=None): # Check for running vms before shutdown # FIXME : Find alternative way to figure out if any vms running # running_vms = self._get_vms_list_by_state('running') # if len(running_vms) > 0: # raise OperationFailed("GGBHOST0001E") wok_log.info('Host is going to shutdown.') os.system('shutdown -h now')
def _set_capabilities(self): wok_log.info("*** Running feature tests ***") conn = self.conn.get() self.nfs_target_probe = FeatureTests.libvirt_support_nfs_probe(conn) self.fc_host_support = FeatureTests.libvirt_support_fc_host(conn) self.kernel_vfio = FeatureTests.kernel_support_vfio() self.nm_running = FeatureTests.is_nm_running() self.mem_hotplug_support = FeatureTests.has_mem_hotplug_support(conn) wok_log.info("*** Feature tests completed ***")
def reboot(self, args=None): # Find running VMs # FIXME : Find alternative way to figure out if any vms running # running_vms = self._get_vms_list_by_state('running') # if len(running_vms) > 0: # raise OperationFailed("GGBHOST0002E") wok_log.info('Host is going to reboot.') os.system('reboot')
def _get_lun_dict(): """ Get the dictionary of LUNs configured on the system. :return: Dictionary containing discovered LUNs and their attributes """ lun_dict = {} # Get the list of sg devices of configured LUNs (FC) sg_devices = get_sg_devices() # Iterate over all FC sg devices for sg_dev in sg_devices: wwpn = open(sg_dir + "/" + sg_dev + "/device/wwpn").readline().rstrip() fcp_lun = open( sg_dir + "/" + sg_dev + "/device/fcp_lun").readline().rstrip() hba_id = open( sg_dir + "/" + sg_dev + "/device/hba_id").readline().rstrip() if hba_id not in lun_dict: lun_dict[hba_id] = {} wwpn_lun_dict = {wwpn: {}} if wwpn not in lun_dict[hba_id]: lun_dict[hba_id].update(wwpn_lun_dict) fcp_lun_dict = {fcp_lun: sg_dev} # Lets see what other LUNs we can disocover using LUN 0 if fcp_lun == lun0 or fcp_lun == wlun: out, err, rc = run_command(['sg_luns', '/dev/' + sg_dev]) if rc == 0: luns = parse_sg_luns(out) for lun in luns: if lun == fcp_lun: continue fcp_lun_dict.update({lun: None}) else: wok_log.error( "Error getting sg_luns for sg device. %s", sg_dev) # Not raising any exception here. The code should # continue to work for other LUNs even if it fails for # this LUN. That way we could grab as much info as # possible from system. if fcp_lun not in lun_dict[hba_id][wwpn]: lun_dict[hba_id][wwpn].update(fcp_lun_dict) # Dumping the LUNs info in logs. This could be very helpful # in dealing with issues where we won't have access to live system wok_log.info("Available LUNs on the system, %s", lun_dict) return lun_dict
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 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 delete_the_sosreport_md5_file(md5_file): """ Deleting md5 file and displaying the contents of the same. """ msg = 'Deleting report md5 file: "%s"' % md5_file wok_log.info(msg) with open(md5_file) as f: md5 = f.read().strip() wok_log.info('Md5 file content: "%s"', md5) os.remove(md5_file)
def _event_devices(self, conn, dom, alias, opaque): """ Callback to handle add/remove devices event """ if opaque._cb is None: wok_log.error('opaque must be valid') return wok_log.info('Device %s added successfuly' % alias) opaque._cb('OK', True)