def run_command(context, command): try: cm.exec_command(context, command) except: raise Exception('Unable to run command') pass
def kernel_available_version(response): available_kernel = "" if common.check_programs_installed("yum"): data, success, retcode = common.exec_command( ["yum", "list", "updates", "kernel"]) if success: lines = data.split("\n") begin_pattern = re.compile(r"^Available Upgrades") begin_pattern2 = re.compile(r"^Updated Packages") begin_pattern3 = re.compile(r"^Upgraded Packages") is_begin = False for line in lines: if not is_begin: if begin_pattern.match(line) or begin_pattern2.match( line) or begin_pattern3.match(line): is_begin = True continue else: result = line.split() if len(result) == 3: available_kernel = result[1] break elif common.check_programs_installed("apt-cache"): data, success, retcode = common.exec_command( ["apt-cache", "search", "linux-image"]) if success: lines = data.split("\n") pattern = re.compile(r"^linux-image-([\d\.]+)-(\d*)-") kernel_versions = [] for line in lines: match = pattern.match(line.strip()) if match and len(match.groups()) == 2: kernel_versions.append(match.groups()) kernel_versions.sort(key=lambda v: "".join( x.zfill(5) for x in v[0].split(".") + [v[1]]), reverse=True) if len(kernel_versions): available_kernel = "-".join(kernel_versions[0]) response["kernel"].append({ "name": Klanguage().to_ts(1129), "value": platform.release() }) if available_kernel: response["kernel"].append({ "name": Klanguage().to_ts(1130), "value": available_kernel })
def kernel_available_version(response): available_kernel = "" if lib.check_programs_installed("yum"): data, success, retcode = common.exec_command( ["yum", "list", "updates", "kernel"]) if success: lines = data.split("\n") begin_pattern = re.compile(r"^Available Upgrades") begin_pattern2 = re.compile(r"^Updated Packages") is_begin = False for line in lines: if not is_begin: if begin_pattern.match(line): is_begin = True if begin_pattern2.match(line): is_begin = True result = line.split() if len(result) == 3: available_kernel = result[1] break elif lib.check_programs_installed("apt-cache"): data, success, retcode = common.exec_command( ["apt-cache", "search", "linux-generic"]) if success: lines = data.split("\n") pattern = re.compile(r"^linux-image-([0-9]+\S+)-generic.*") kernel_versions = [] for line in lines: match = pattern.match(line) if match and len(match.groups()): kernel_versions.append(match.groups()[0]) kernel_versions.sort( key=lambda t: int(t.replace(".", "").replace("-", "")), reverse=True) if len(kernel_versions): available_kernel = kernel_versions[0] response["kernel"].append({ "name": "Kernel current version", "value": platform.release() }) if available_kernel: response["kernel"].append({ "name": "Kernel latest stable version", "value": available_kernel })
def debian_update_packages(self): if lib.check_root(): common.exec_command(['apt-get', 'update']) else: data, success, retcode = common.exec_command(['sudo', '-n', 'ls']) if success: common.exec_command(['sudo', 'apt-get', 'update'])
def ssh_detect(self): lines = [] logfile = None if os.path.exists(macro.AUTH_LOG): logfile = macro.AUTH_LOG elif os.path.exists(macro.SECURE_LOG): logfile = macro.SECURE_LOG if logfile: lines = file_op.cat_lines(logfile, "r") else: if common.check_programs_installed("journalctl"): data, success, retcode = common.exec_command( ['journalctl', '_COMM=sshd', '-n', '50']) if success: lines = data.split("\n") else: data, success, retcode = common.exec_command( ['journalctl', '_COMM=ssh', '-n', '50']) if success: lines = data.split("\n") for line in lines: #Feb 1 16:07:41 iZj6cd9xxma2xamt72ui3qZ sshd[19864]: Failed password for root from 182.100.67.252 port 57888 ssh2 #Feb 1 16:07:41 iZj6cd9xxma2xamt72ui3qZ sshd[19864]: Accepted password for root from 100.129.58.124 port 61745 ssh2 s = re.search( "(^.*\d+:\d+:\d+).*sshd.*Accepted password for (.*) from (.*) port.*$", line, re.I | re.M) f = re.search( "(^.*\d+:\d+:\d+).*sshd.*Failed password for (.*) from (.*) port.*$", line, re.I | re.M) b = re.search("(^.*\d+:\d+:\d+).*sshguard.*Blocking (.*) for.*$", line, re.I | re.M) if s: dt = datetime.strptime(s.group(1), '%b %d %X') new_dt = datetime(datetime.now().year, dt.month, dt.day, dt.hour, dt.minute, dt.second) ts = time_op.to_timestamp(new_dt) if ts > self.ssh_lasttime_scan and not net_op.is_private_ip( s.group(3)): self.ssh_login_success(s.group(2), s.group(3), ts) if f: dt = datetime.strptime(f.group(1), '%b %d %X') new_dt = datetime(datetime.now().year, dt.month, dt.day, dt.hour, dt.minute, dt.second) ts = time_op.to_timestamp(new_dt) if ts > self.ssh_lasttime_scan and not net_op.is_private_ip( f.group(3)): self.ssh_login_failed(f.group(2), f.group(3), ts)
def single_table_backup(self, db, table, operation): '''单表备份''' if not db: logger.error("请选择需要单表备份的数据库!") return if not table: logger.error("请选择需要单表备份的数据表!") return if not operation: logger.error("请选择需要单表备份的操作!") return # 检查pgpass文件配置 if not self.check_pgpass(): logger.error("请检查pgpass文件, 确保需要备份的数据库已配置到了pgpass文件") return logger.info(f"开始进行数据库[{db}]的[{table}]表备份, 请等待完成...") if operation == "data": cmd = f"pg_dump -p {self._port} -h {self._host} -U postgres -t {table} -a {db}> {self._bk_path}/{table}_data.sql" elif operation == "struct": cmd = f"pg_dump -p {self._port} -h {self._host} -U postgres -t {table} -s {db}> {self._bk_path}/{table}_struct.sql" elif operation == "all": cmd = f"pg_dump -p {self._port} -h {self._host} -U postgres -t {table} {db}> {self._bk_path}/{table}.sql" else: logger.error(f"不支持的操作:{operation}") return result = exec_command(cmd) if not result.status: logger.error(result.msg) else: logger.info(f"备份数据库[{db}]的[{table}]成功.")
def detect_debian_like_os(): #debian data, success, retcode = common.exec_command(['ls', '/etc/debian_version']) if success: return True return False
def debian_scan_cveid_from_changelog(self): cmd = "PAGER=cat {} -q=2 changelog".format(self.changelogtool) cve_obj = re.compile(r'(CVE-\d{4}-\d{4,})') self.upgradable_packages = self.debian_get_upgradable_packages() self.upgradable_packages_count = len(self.upgradable_packages) for package_name in self.upgradable_packages: tmp_cmd = "{} {}".format(cmd, package_name) data, success, retcode = common.exec_command(tmp_cmd.split()) if success: lines = data.split("\n") pattern_ver = re.compile(r'(%s)' % re.escape( self.get_installed_package_version(package_name))) for line in lines: if pattern_ver.search(line): break else: cves = cve_obj.findall(line) cves = list(set(cves)) for cve_id in cves: self.debian_append_vulsinfo(cve_id, package_name) else: Klogger().error("{} failed:{}".format(tmp_cmd, data))
def debian_append_vulsinfo(self, cveid, package_name): installed = "" candidate = "" data, success, retcode = common.exec_command( ['apt-cache', 'policy', package_name]) if success: pattern_installed = re.compile(r'\s*Installed:\s*(.*)\n') pattern_candidate = re.compile(r'\s*Candidate:\s*(.*)\n') match = pattern_installed.search(data) if match: installed = match.groups()[0] match = pattern_candidate.search(data) if match: candidate = match.groups()[0] Klogger().info( "cveid : {} package : {} installed : {} candidate : {}".format( cveid, package_name, installed, candidate)) if installed and candidate: self.common_response(cveid, package_name, installed, candidate)
def single_db_backup(self, db_name): '''备份单个数据库''' cmd = f"pg_dump -h {self._host} -p {self._port} -U postgres -c {db_name} | gzip > {self._bk_path}/{db_name}.gz" logger.info(f"备份数据库[{db_name}]开始, 请等待完成...") result = exec_command(cmd) if not result.status: logger.error(result.msg) else: logger.info(f"备份数据库[{db_name}]成功.")
def single_db_data_backup(self, db_name): '''备份单个数据库中的数据''' cmd = f"pg_dump -h {self._host} -p {self._port} -U postgres -a {db_name} > {self._bk_path}/{db_name}_data.sql" logger.info(f"备份数据库[{db_name}]数据开始, 请等待完成...") result = exec_command(cmd) if not result.status: logger.error(result.msg) else: logger.info(f"备份数据库[{db_name}]数据成功.")
def candidate_size(self, package_name, candidate): apt = common.check_programs_installed("apt-get") size = 0 if apt: data, success, retcode = common.exec_command( ["apt-cache", "show", package_name]) if success: lines = data.split("\n") pattern_size = re.compile(r'^Size: (\d+)') for line in lines: match = pattern_size.match(line) if match: size = int(match.groups()[0]) break yum = common.check_programs_installed("yum") #Available Packages #Name : systemd #Arch : x86_64 #Version : 219 #Release : 42.el7_4.4 #Size : 5.2 M if yum: data, success, retcode = common.exec_command( ["yum", "info", "available", package_name]) if success: lines = data.split("\n") pattern = re.compile(r"^Size\s*:\s(.+)") #need to upgrade for line in lines: match = pattern.match(line) if match: size = common.sizestring2int(match.groups()[0]) break return size
def check_and_update(): os.chdir(common.get_work_dir()) data, success, retcode = common.exec_command(['git', 'pull', '-f']) if success and not 'up-to-date' in data.lower(): dprint("[Init Info] go update") return True else: dprint("[Init Info] no update " + str(data)) return False
def op_service(name, op, response): if common.is_linux(): if common.check_programs_installed("systemctl"): #data, success, retcode = common.exec_command(['systemctl', 'is-enabled', name]) if op == 0: data, success, retcode = common.exec_command(['systemctl', 'enable', name, "--no-ask-password"]) if success: response["status"] = "enabled" else: response["error"] = "{} code : {}".format(data, retcode) else: data, success, retcode = common.exec_command(['systemctl', 'disable', name, "--no-ask-password"]) if success: response["status"] = "disabled" else: response["error"] = "{} code : {}".format(data, retcode) else: response["error"] = Klanguage().to_ts(4003)
def redhat_common_checkupdate(self): #FEDORA-2017-f9b4e14129 bugfix vim-filesystem-2:8.0.983-1.fc26.x86_64 #FEDORA-2017-f9b4e14129 bugfix vim-minimal-2:8.0.983-1.fc26.x86_64 #FEDORA-2017-b8fa8e1a13 Unknown/Sec. xen-libs-4.8.1-7.fc26.x86_64 #FEDORA-2017-b8fa8e1a13 Unknown/Sec. xen-licenses-4.8.1-7.fc26.x86_64 #data, success, retcode = common.exec_command(["yum", "--security", "--bugfix", "updateinfo", "list", "updates"]) data, success, retcode = common.exec_command( ["yum", "updateinfo", "list", "updates", "sec"]) if success: lines = data.split("\n") for line in lines: result = line.split() if len(result) == 3: update_id = result[0] #update_type = result[1] update_package = result[2] result = update_package.rsplit("-", 2) if len(result) == 3: name = result[0] version = result[1] if "." in result[2]: release = result[2].rsplit(".", 1)[0] if update_id in self.upgradable_packages: self.upgradable_packages[update_id].append({ "name": name, "version": version, "release": release, "fullname": update_package }) else: self.upgradable_packages[update_id] = [{ "name": name, "version": version, "release": release, "fullname": update_package }]
def get_module_description(module): data, success, retcode = common.exec_command(["modinfo", module]) if success: lines = data.split("\n") pattern = re.compile(r"^description:\s+(.+)") for line in lines: match = pattern.match(line) if match and len(match.groups()): return match.groups()[0] return ""
def repair(self, package): yum = common.check_programs_installed("yum") apt = common.check_programs_installed("apt-get") if not any([yum, apt]): return "Vulnerability repair not support on this OS" if yum: data, success, retcode = common.exec_command( ['yum', 'update', '-y', package]) if not success: return "yum error : {} code : {}".format(data, retcode) elif apt: data, success, retcode = common.exec_command( ['apt-get', 'install', '-y', '--only-upgrade', package]) if not success: return "apt-get error : {} code : {}".format(data, retcode) self.update_record(package) return None
def redhat_centos_checkupdate(self): #wireless-tools.i686 1:29-6.el6 base #xorg-x11-drv-ati-firmware.noarch 7.6.1-2.el6 base #Obsoleting Packages #firefox.i686 52.3.0-3.el6.centos updates data, success, retcode = common.exec_command( ["yum", "--color=never", "check-update"]) #Returns exit value of 100 if there are packages available for an update if success or retcode == 100: lines = data.split("\n") start_parse = False pattern_end_parse = re.compile(r'Obsoleting Packages') for line in lines: if not start_parse: if len(line.split()) == 0: start_parse = True continue else: if pattern_end_parse.match(line): break result = line.split() #xorg-x11-xauth.x86_64 1:1.0.9-1.el6 base #Obsoleting Packages if len(result) == 3: package_name, arch = result[0].split(".") version, release = result[1].split("-") if ":" in version: version = version.split(":")[1] self.upgradable_packages[package_name] = { "name": package_name, "version": version, "release": release, "fullname": "{0}-{1}-{2}.{3}".format(package_name, version, release, arch) } self.upgradable_packages_count += 1
def redhat_common_vulscan(self): cmd = "yum updateinfo info" cve_obj = re.compile(r'(CVE-\d{4}-\d{4,})') for key, value in self.upgradable_packages.items(): tmp_cmd = "{} {}".format(cmd, key) data, success, retcode = common.exec_command(tmp_cmd.split()) if success: cves = cve_obj.findall(data) cves = list(set(cves)) for cveid in cves: for info in value: self.redhat_append_vulsinfo(cveid, info["name"], info["fullname"])
def debian_get_installed_packages(self): data, success, retcode = common.exec_command(['dpkg-query', '-W']) #snap-confine 2.25 #snapd 2.25 #snapd-login-service 1.2-0ubuntu1.1~xenial #sni-qt:amd64 0.2.7+16.04.20170217.1-0ubuntu1 if success: lines = data.split("\n") for line in lines: if line: package, ver = line.split() package = package.split(":")[0] self.installed_packages[package] = ver Klogger().info("package : {} ver : {}".format( package, ver))
def redhat_get_installed_packages(self): #atmel-firmware atmel-firmware-1.3-16.fc26.noarch #libqb libqb-1.0.2-1.fc26.x86_64 #gnutls gnutls-3.5.14-1.fc26.x86_64 data, success, retcode = common.exec_command([ "rpm", "-qa", "--queryformat", "'%{NAME}\t%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n\'" ]) if success: lines = data.split("\n") for line in lines: result = line.split() if len(result) == 2: self.installed_packages[result[0]] = result[1] Klogger().info("package : {} version : {}".format( result[0], result[1]))
def redhat_centos_vulscan(self): cmd = "yum --changelog --assumeno update" cve_obj = re.compile(r'(CVE-\d{4}-\d{4,})') pattern_begin = re.compile(r'ChangeLog for:') pattern_end = re.compile(r'Dependencies Resolved') for key, value in self.upgradable_packages.items(): tmp_cmd = "{0} {1}".format(cmd, key) data, success, retcode = common.exec_command(tmp_cmd.split()) if retcode == 1 or retcode == 0: lines = data.split("\n") begin_founded = False #Changes in packages about to be updated: # #ChangeLog for: bash-4.1.2-48.el6.x86_64 #* Wed Feb 15 04:00:00 2017 Siteshwar Vashisht <*****@*****.**> - 4.1.2-48 #- Fix signal handling in read builtin # Resolves: #1421926 #* Mon Dec 12 04:00:00 2016 Siteshwar Vashisht <*****@*****.**> - 4.1.2-47 #- CVE-2016-9401 - Fix crash when '-' is passed as second sign to popd # Resolves: #1396383 # #Dependencies Resolved for line in lines: if not begin_founded: if pattern_begin.match(line): begin_founded = True continue if pattern_end.match(line): break cves = cve_obj.findall(line) cves = list(set(cves)) if len(cves) != 0 and line.startswith("-"): for cve_id in cves: self.redhat_append_vulsinfo( cve_id, value["name"], value["fullname"])
def find_service_manager(): global service_manager data, success, retcode = common.exec_command(['cat', '/proc/1/cmdline']) if success: systemd_pattern = re.compile(r'systemd') if systemd_pattern.search(data): service_manager = "systemd" init_pattern = re.compile(r'init') if init_pattern.search(data): service_manager = "SysV Init" upstart_pattern = re.compile(r'upstart') if upstart_pattern.search(data): service_manager = "upstart"
def get_boot_time(): if common.check_programs_installed("systemd-analyze"): data, success, retcode = common.exec_command( ['systemd-analyze', 'time']) if success: pattern = re.compile( r"^Startup finished in (.+s) \(kernel\) \+ (.+s) \(initrd\) \+ (.+s) \(userspace\) \= (.+s)" ) match = pattern.match(data) if match: groups = list(match.groups()) if len(groups) == 4: for i in range(len(groups)): index = groups[i].find(".") if index >= 0 and len( groups[i][index + 1:index + 4]) == 3: groups[i] = groups[i][:index + 2] + groups[i][index + 4:] return tuple(groups) pattern = re.compile( r"^Startup finished in (.+s) \(kernel\) \+ (.+s) \(userspace\) \= (.+s)" ) match = pattern.match(data) if match: groups = list(match.groups()) if len(groups) == 3: for i in range(len(groups)): index = groups[i].find(".") if index >= 0 and len( groups[i][index + 1:index + 4]) == 3: groups[i] = groups[i][:index + 2] + groups[i][index + 4:] return tuple(groups) return None
def table_struct_backup(self): '''表结构备份''' if not self._dbs: logger.error("请选择需要进行表结构备份的数据库!") return # 检查pgpass文件配置 if not self.check_pgpass(): logger.error("请检查pgpass文件, 确保需要备份的数据库已配置到了pgpass文件") return logger.info(f"开始进行数据库[{self._dbs}]表结构备份, 请等待完成...") for loop in self._dbs: cmd = f"pg_dump -p {self._port} -h {self._host} -U postgres -s {loop} > {self._bk_path}/{loop}_struct.sql" result = exec_command(cmd) if not result.status: logger.error(result.msg) else: logger.info(f"备份数据库[{loop}]表结构成功.") logger.info("备份数据库表结构已完成")
def db_restore(self, path): '''数据库恢复(慎用, 未通过测试)''' if not self._dbs: logger.error("请选择需要进行恢复的数据库!") return # 检查pgpass文件配置 if not self.check_pgpass(): logger.error("请检查pgpass文件, 确保需要备份的数据库已配置到了pgpass文件!") return # 恢复前检查 if not self.restore_check(path): logger.error("请检查数据目录, 确保需要恢复的数据库对应的文件都存在!") return False logger.info(f"开始进行数据库{self._dbs}恢复, 请等到完成...") for loop in self._dbs: cmd = f"cat {path}/{loop}.gz | gunzip | psql -p {self._port} -h {self._host} -U postgres {loop}" result = exec_command(cmd) if not result.status: logger.error(result.msg) logger.info("数据库恢复完成.")
def debian_get_upgradable_packages(self): data, success, retcode = common.exec_command( ['LANGUAGE=en_US.UTF-8', 'apt-get', 'upgrade', '--dry-run']) packages = [] if success: lines = data.split("\n") pattern_begin = re.compile( r'The following packages will be upgraded:') pattern_end = re.compile(r'^(\d+) upgraded.*') begin_found = False for line in lines: if not begin_found: if pattern_begin.match(line): begin_found = True continue match = pattern_end.match(line) if match: num = int(match.groups()[0]) if num == len(packages): #should return here Klogger().info("packages : {}".format(packages)) return packages else: return None else: line = line.strip("\n") packages.extend(line.split()) #error return packages
def get_useradd_list(response): global uid_min global uid_max user_connect_time = {} if lib.check_programs_installed("ac"): data, success, retcode = common.exec_command(["ac", "-p"]) if success: lines = data.split("\n") for line in lines: result = line.split() if len(result) == 2: user_connect_time[result[0]] = result[1] uid_values = [["USERNAME", "UID", "GID", "HOME", "SHELL"]] if user_connect_time: uid_values[0].append("TOTAL CONNECT HOURS") gid_values = [["GID", "GROUP NAME", "MEMBERS"]] #root:x:0:0:root:/root:/bin/bash #bin:x:1:1:bin:/bin:/sbin/nologin #daemon:x:2:2:daemon:/sbin:/sbin/nologin data = file_op.cat("/etc/passwd", "r") if data: lines = data.split("\n") for line in lines: if line: username, password, uid, gid, comment, home, shell = line.split( ":") if int(uid) >= int(uid_min) and int(uid) <= int(uid_max): uid_values.append([username, uid, gid, home, shell]) if user_connect_time: uid_values[len(uid_values) - 1].append( user_connect_time[username] if username in user_connect_time else "Unknown") #root:x:0: #bin:x:1: #daemon:x:2: data = file_op.cat("/etc/group", "r") if data: lines = data.split("\n") for line in lines: if line: group_name, password, gid, members = line.split(":") gid_values.append([gid, group_name, members]) response["authentication"].append({ "name": "Users create with useradd", "value": len(uid_values) - 1, "values": uid_values }) response["authentication"].append({ "name": "User groups", "value": len(gid_values) - 1, "values": gid_values })
def get_boot_services(response): global runlevel if common.check_programs_installed("systemctl"): values = [] blame = {} #service time data, success, retcode = common.exec_command( ['systemd-analyze', 'blame']) if success: lines = data.split("\n") for line in lines: result = line.split() if len(result) == 2: index = result[0].find(".") if index >= 0 and len(result[0][index + 1:index + 4]) == 3: result[0] = result[0][:index + 2] + result[0][index + 4:] blame[result[1]] = result[0] data, success, retcode = common.exec_command( ['systemctl', 'list-unit-files', '--type=service']) if success: lines = data.split("\n") for line in lines: result = line.split() if len(result) == 2 and (result[1] == "enabled" or result[1] == "disabled"): values.append([ result[0], blame[result[0]] if result[0] in blame else "", lib.get_description_by_name(result[0], 0), result[1] ]) response["boot_services"] = {"value": len(values), "values": values} else: values = [] if runlevel: init_rcd = "/etc/rc{}.d".format(runlevel) systemv_script_pattern = re.compile(r"S\d{2}(\S+)") for file in os.listdir(init_rcd): match = systemv_script_pattern.match(file) if match and len(match.groups()): values.append([ match.groups()[0], "", lib.get_description_by_name(match.groups()[0], 2), "enabled" ]) response["boot_services"] = { "value": len(values), "values": values } ''' elif lib.check_programs_installed("initctl"): values = [["Upstart Script", "Start On", "Stop On"]] upstart_config = [] data, success, retcode = common.exec_command(['initctl', 'list']) if success: lines = data.split("\n") for line in lines: if line: upstart_config.append(line.split()[0]) starton_pattern = re.compile(r"\s*start on\s(.*)") stopon_pattern = re.compile(r"\s*stop on\s(.*)") for config in upstart_config: data, success, retcode = common.exec_command(['initctl', 'show-config', config]) if success: lines = data.split("\n") starton = "" stopon = "" for line in lines: match = starton_pattern.match(line) if match: starton = match.groups()[0] match = stopon_pattern.match(line) if match: stopon = match.groups()[0] values.append([ config, starton, stopon]) response["boot_services"].append({ "name" : "Boot Services", "value" : len(values) - 1, "values" : values }) ''' '''
def find_runlevel(): global runlevel #runlevel #N 5 #who -r # run-level 5 2017-07-08 15:12 data, success, retcode = common.exec_command(['runlevel']) if success: runlevel_pattern = re.compile(r'^N\s(\d)') match = runlevel_pattern.match(data) if match: runlevel = match.groups()[0] return #/etc/systemd/system/default.target -> /lib/systemd/system/graphical.target default_target = "/etc/systemd/system/default.target" target = lib.readlink(default_target, 1) if target != "": for i in ["runlevel5.target", "graphical.target"]: tmp, num = common.grep(target, i) if num: runlevel = 5 return for i in ["runlevel3.target", "multi-user.target"]: tmp, num = common.grep(target, i) if num: runlevel = 3 return ## Default runlevel. The runlevels used are: # 0 - halt (Do NOT set initdefault to this) # 1 - Single user mode # 2 - Multiuser, without NFS (The same as 3, if you do not have networking) # 3 - Full multiuser mode # 4 - unused # 5 - X11 # 6 - reboot (Do NOT set initdefault to this) # #id:3:initdefault: data = file_op.cat("/etc/inittab", "r") if data: lines = data.split("\n") for line in lines: tmp, num = common.grep(line, r"^id:(\d)") if num: runlevel = tmp return # run-level 5 2017-09-17 13:35 data, success, retcode = common.exec_command(['who', '-r']) if success: tmp, num = common.grep(data, r"^\s*run-level\s(\d)") if num: runlevel = tmp return