Source code for cobbler.actions.status

"""
Reports on automatic installation activity by examining the logs in
/var/log/cobbler.
"""

from builtins import object
from past.utils import old_div
import glob
import time
import gzip
import re

from cobbler import clogger

# ARRAY INDEXES
MOST_RECENT_START = 0
MOST_RECENT_STOP = 1
MOST_RECENT_TARGET = 2
SEEN_START = 3
SEEN_STOP = 4
STATE = 5


[docs]class CobblerStatusReport(object): def __init__(self, collection_mgr, mode, logger=None): """ Constructor """ self.collection_mgr = collection_mgr self.settings = collection_mgr.settings() self.ip_data = {} self.mode = mode if logger is None: logger = clogger.Logger() self.logger = logger # -------------------------------------------------------
[docs] def scan_logfiles(self): """ Scan the install log-files - starting with the oldest file. :return: """ unsorted_files = glob.glob("/var/log/cobbler/install.log*") files_dict = dict() log_id_re = re.compile(r'install.log.(\d+)') for fname in unsorted_files: id_match = log_id_re.search(fname) if id_match: files_dict[int(id_match.group(1))] = fname files = list() sorted_ids = sorted(files_dict, key=files_dict.get, reverse=True) for file_id in sorted_ids: files.append(files_dict[file_id]) if '/var/log/cobbler/install.log' in unsorted_files: files.append('/var/log/cobbler/install.log') for fname in files: if fname.endswith('.gz'): fd = gzip.open(fname) else: fd = open(fname) data = fd.read() for line in data.split("\n"): tokens = line.split() if len(tokens) == 0: continue (profile_or_system, name, ip, start_or_stop, ts) = tokens self.catalog(profile_or_system, name, ip, start_or_stop, ts) fd.close()
# ------------------------------------------------------
[docs] def catalog(self, profile_or_system, name, ip, start_or_stop, ts): ip_data = self.ip_data if ip not in ip_data: ip_data[ip] = [-1, -1, "?", 0, 0, "?"] elem = ip_data[ip] ts = float(ts) mrstart = elem[MOST_RECENT_START] mrstop = elem[MOST_RECENT_STOP] mrtarg = elem[MOST_RECENT_TARGET] if start_or_stop == "start": if mrstart < ts: mrstart = ts mrtarg = "%s:%s" % (profile_or_system, name) elem[SEEN_START] += 1 if start_or_stop == "stop": if mrstop < ts: mrstop = ts mrtarg = "%s:%s" % (profile_or_system, name) elem[SEEN_STOP] += 1 elem[MOST_RECENT_START] = mrstart elem[MOST_RECENT_STOP] = mrstop elem[MOST_RECENT_TARGET] = mrtarg
# -------------------------------------------------------
[docs] def process_results(self): # FIXME: this should update the times here tnow = int(time.time()) for ip in list(self.ip_data.keys()): elem = self.ip_data[ip] start = int(elem[MOST_RECENT_START]) stop = int(elem[MOST_RECENT_STOP]) if (stop > start): elem[STATE] = "finished" else: delta = tnow - start min = old_div(delta, 60) sec = delta % 60 if min > 100: elem[STATE] = "unknown/stalled" else: elem[STATE] = "installing (%sm %ss)" % (min, sec) return self.ip_data
[docs] def get_printable_results(self): format = "%-15s|%-20s|%-17s|%-17s" ip_data = self.ip_data ips = list(ip_data.keys()) ips.sort() line = ( "ip", "target", "start", "state", ) buf = format % line for ip in ips: elem = ip_data[ip] if elem[MOST_RECENT_START] > -1: start = time.ctime(elem[MOST_RECENT_START]) else: start = "Unknown" line = ( ip, elem[MOST_RECENT_TARGET], start, elem[STATE] ) buf += "\n" + format % line return buf
# -------------------------------------------------------
[docs] def run(self): """ Calculate and print a automatic installation status report. """ self.scan_logfiles() results = self.process_results() if self.mode == "text": return self.get_printable_results() else: return results