def find_logseg(self, logf, from_time, to_time): logseg_path = os.path.join(envir.HA_NOARCHBIN, 'print_logseg') if os.access(logseg_path, os.F_OK) and os.access(logsef_path, os.X_OK): utillib.do_command([logseg_path, logf, from_time, to_time]) cat = self.find_decompressor(logf).split() cat.append(logf) srcstr = utillib.do_command(cat) srcf = tempfile.mkstemp()[1] self.RM_FILES.append(srcf) srcfd = open(srcf, 'w') srcfd.write(srcstr) srcfd.close() if from_time == 0: FROM_LINE = 1 else: FROM_LINE = utillib.findln_by_time(self, srcf, from_time) if not FROM_LINE: warning("couldn't find line for time " + from_time + '; corrupt log file?') return '' TO_LINE = 0 if to_time != 0: TO_LINE = utillib.findln_by_time(self, srcf, to_time) if not TO_LINE: utillib.warning("couldn't find for time " + to_time + '; corrupt log file?') return '' utillib.debug('including log segment[' + str(FROM_LINE) + '-' + str(TO_LINE) + '] from' + logf) return '\n'.join(srcstr.split('\n')[FROM_LINE:TO_LINE])
def find_first_ts(self, message): for l in message.split('\n'): if not len(l): break ts = self.get_ts(l) if ts: return ts utillib.warning('cannot extract time: |' + l + '|; will try the next one')
def findsshuser(self): ''' If user not provide ssh users, find ssh user by itself ''' rc = 0 ssh_user = '******' if not len(envir.SSH_USER): try_user_list = '__default ' + ' '.join(envir.TRY_SSH) else: try_user_list = ' '.join(envir.SSH_USER) #debug message utillib.debug('FROM FINDSSHUSER: node name is ' + ' '.join(envir.USER_NODES)) for n in envir.USER_NODES: rc = 1 if n == self.WE: # Ahh, It' me, will break! continue for u in try_user_list.split(' '): if u != '__default': ssh_s = u + '@' + n else: ssh_s = n if self.testsshconn(ssh_s): utillib.debug('ssh ' + ssh_s + ' OK') ssh_user = u try_ssh_list = u rc = 0 break else: utillib.debug('ssh ' + ssh_s + ' failed') if rc: envir.SSH_PASSWD_NODES = envir.SSH_PASSWD_NODES + n if len(envir.SSH_PASSWD_NODES): utillib.warning('passwordless ssh to node(s) ' + envir.SSH_PASSWD_NODES + ' does not work') if ssh_user == '__undef': return 1 if ssh_user != '__default': envir.SSH_USER = ssh_user #ssh user is default return 0
def collect_journal(self, workdir): ''' Collect Journal from Systemd, then write the result to file journal.log ''' global outf from_time = str(int(envir.FROM_TIME)) to_time = str(int(envir.TO_TIME)) outf = os.path.join(workdir, envir.JOURNAL_F) if utillib.do_which('journalctl'): if from_time.isdigit() and from_time != '0': from_t = datetime.datetime.fromtimestamp( int(from_time)).strftime("+%Y-%m-%d %H:%M") #do not know from_time in which cases elif from_time.isdigit(): from_t = datetime.datetime.fromtimestamp( int(from_time)).strftime("+%Y-%m-%d %H:%M") #to_time if to_time.isdigit() and to_time != '0': to_t = datetime.datetime.fromtimestamp( int(to_time)).strftime("+%Y-%m-%d %H:%M") #do not know from_time in which cases elif to_time.isdigit(): to_t = datetime.datetime.fromtimestamp( int(to_time)).strftime("+%Y-%m-%d %H:%M") if os.path.isfile(outf): utillib.warning(outf + ' already exists') fd = open(outf, "w") fd.write('journalctl from: ' + from_time + ' until: ' + to_time + ' from_time ' + from_t + ' to_time: ' + to_time + '\n') #use journalctl to get log messages cmd1 = [ 'journalctl', '-o', 'short-iso', '--since', from_t[1:], '--until', to_t[1:], '--no-pager' ] cmd2 = ['tail', '-n', '+2'] jnl_process = subprocess.Popen(cmd1, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) grep_process = subprocess.Popen(cmd2, stdin=jnl_process.stdout, stdout=subprocess.PIPE) output = grep_process.communicate()[0] fd.write(output) fd.close()
def get_result(self): # for p in self.PIDS: # pid, status = os.waitpid(p.pid,0) global LOG_NODES LOG_NODES = [] for n in envir.USER_NODES: if n + '.tar' not in os.listdir(self.WORKDIR): utillib.warning('NOTICE: ' + n + ' not return logs!') else: LOG_NODES.append(n) tar = tarfile.open(os.path.join(self.WORKDIR, n + '.tar'), 'r:') tar.extractall(path=self.WORKDIR) tar.close() self.RM_FILES.append(os.path.join(self.WORKDIR, n + '.tar'))
def getlog(self): ''' Get Specify Logs ''' global getstampproc outf = os.path.join(self.WORKDIR, envir.HALOG_F) outfd = open(outf, 'w') #collect journal from systemd self.collect_journal(self.WORKDIR) if len(envir.HA_LOG): if not os.path.isfile(envir.HA_LOG): utillib.warning( envir.HA_LOG + ' not found; We will try to find log ourselves') envir.HA_LOG = '' if not len(envir.HA_LOG): envir.HA_LOG = self.findlog() if not len(envir.HA_LOG) or not os.path.isfile(envir.HA_LOG): if len(envir.CTS): #argvment is envir.CTS msg = self.cts_findlogseg() outfd.write(msg) else: utillib.warning('no log at' + self.WE) return if not envir.FROM_TIME: utillib.warning("a log found; but we cannot slice it") utillib.warning("please check the from time you input") elif len(envir.CTS): #argvment is envir.CTS and envir.HA_LOG msg = self.cts_findlogseg() outfd.write(msg) else: getstampproc = utillib.find_getstampproc(self) if len(getstampproc): msg = self.dumplogset() outfd.write(msg) else: utillib.warning('could not figure out the log format of ' + envir.HA_LOG)
def sanitize(self): ''' Replace sensitive info with **** ''' need_replace_files = [] for b in envir.B_CONF.split(): print b for f in os.path.join(self.WORKDIR, b).split(): if os.path.isfile(f): utillib.sanitize_one(f) rc = 0 try: dirs = os.path.join(self.WORKDIR, envir.CIB_F).split() except OSError: pass else: need_replace_files.extend(dirs) try: dirs = os.listdir(os.path.join(self.WORKDIR, 'pengine')) except OSError: pass else: need_replace_files.extend(dirs) for n in need_replace_files: if os.path.isfile(n): if envir.DO_SANITIZE: utillib.sanitize_one(n) else: if utillib.test_sensitive_one(n): utillib.warning( 'some PE or CIB file contain possibly sensitive data' ) utillib.warning( 'you may not want to send this report to a public mailing list' )
def run(): ''' This method do most of the job that master node should do ''' utillib.check_user() utillib.setvarsanddefaults() utillib.get_ocf_directories() mtr = master() mtr.analyzed_argvment(sys.argv) #who am i mtr.WE = socket.gethostname() envir.MASTER = mtr.WE #get WORKDIR mtr.WORKDIR = mtr.mktemp(envir.DEST) mtr.WORKDIR = os.path.join(mtr.WORKDIR, envir.DEST) envir.MASTER_WORKDIR = mtr.WORKDIR mtr.compabitility_pcmk() mtr.cluster_type() support = __import__(mtr.import_support()) if len(envir.CTS): support.get_log_var() utillib.debug('log setting :facility = ' + envir.HA_LOGFACILITY + ' logfile = ' + envir.HA_LOGFILE + ' debug file = ' + envir.HA_DEBUGFILE) else: mtr.get_cts_log() # #part 1:get nodes # utillib.get_nodes() utillib.debug('nodes: ' + ' '.join(envir.USER_NODES)) mtr.is_member() #this is node for n in envir.USER_NODES: if n == mtr.WE: mtr.THIS_IS_NODE = 1 if not mtr.is_node and envir.NODE_SOUECE != 'user': utillib.warning( 'this is not a node and you didn\'t specify a list of nodes using -n' ) # #part 2: ssh business # #find out id ssh works if not envir.NO_SSH: mtr.findsshuser() if len(envir.SSH_USER): envir.SSH_OPTS = envir.SSH_OPTS.append('-o User='******'' euid = os.geteuid() if not len(envir.SSH_USER) and euid != 0: utillib.debug('ssh user other than root, use sudo') SUDO = 'sudo -u root' LOCAL_SUDO = '' if not euid: utillib.debug('local user ither than root, use sudo') LOCAL_SUDO = 'sudo -u root' # #part 4: find the logs and cut out the segment for the period # if mtr.THIS_IS_NODE: mtr.getlog() #create xml before collect utillib.creat_xml() #then scp the file to collector for n in envir.USER_NODES: p = Process(target=mtr.send_env, args=(n, )) p.start() if not envir.NO_SSH: mtr.collect_for_nodes(envir.USER_NODES) elif is_node: mtr.collecct_for_nodes([mtr.WE]) # #part 5: # slaves tar their result to stdout, send it to master, # then master analyses result, asks the user to edit the # problem description template, and print final words # mtr.get_result() Process(target=mtr.analyze).start() Process(target=mtr.events).start() # #part 6: endgame: # remove tmpfiles and logs we do not need utillib.remove_files(mtr)