diff options
-rw-r--r-- | cobbler/action_status.py | 113 | ||||
-rw-r--r-- | cobbler/action_sync.py | 17 | ||||
-rw-r--r-- | cobbler/api.py | 1 | ||||
-rwxr-xr-x | cobbler/cobbler.py | 13 | ||||
-rw-r--r-- | kickstart_fc5.ks | 3 | ||||
-rw-r--r-- | kickstart_fc6.ks | 3 |
6 files changed, 125 insertions, 25 deletions
diff --git a/cobbler/action_status.py b/cobbler/action_status.py index de3da43..2c0fba1 100644 --- a/cobbler/action_status.py +++ b/cobbler/action_status.py @@ -19,20 +19,103 @@ import cobbler_msg class BootStatusReport: - def __init__(self,config): - """ - Constructor - """ - self.config = config - self.settings = config.settings() - - def run(self): - """ - Returns None if there are no errors, otherwise returns a list - of things to correct prior to running application 'for real'. - (The CLI usage is "cobbler check" before "cobbler sync") - """ - print "..." - return True + def __init__(self,config,mode): + """ + Constructor + """ + self.config = config + self.settings = config.settings() + self.mode = mode + + # ------------------------------------------------------- + + def run(self): + """ + Calculate and print a kickstart-status report. + For kickstart trees not in /var/lib/cobbler (or a symlink off of there) + tracking will be incomplete. This should be noted in the docs. + """ + + done = {} # keep track of finish times by IP addr + files = {} # keep up with xfer'd files by IP addr + + # gather stats from logfiles, allowing for rotations in the log file ... + for i in range(0,6): + + # figure out what logfile to open + j = "" + if i != 0: + j = "%s" % (i-1) + fname = "/var/log/cobbler/cobbler%s.log" % j + + # open it if it's there + if not os.path.exists(fname): + print "no such file: %s" % fname + break + logfile = open(fname, "r") + + # each line in the file corresponds to an accessed file + while(True): + data = logfile.readline() + if data is None or data == "": + break + + # fields are tab delimited + # (1) seconds since 1970, in decimal + # (2) ASCII date for humans + # (3) IP address of requester + # (4) HTTP request line + + (epoch, strdate, ip, request) = data.split("\t") + + # HTTP request line is essentially space delimited + # (1) method, which should always be GET + # (2) filename, which is relative from server root + # (3) protocol, such as HTTP/1.1 + + (method, filepath, protocol) = request.split(" ") + + # make room in the nested datastructures for report info + + if not done.has_key(ip): + done[ip] = [] # list of kickstart finish times + if not files.has_key(ip): + files[ip] = {} # hash of access times and filenames + + # keep track of when IP addresses's finish. Right now, we don't + # care much about profile or system name but can get this later. + + if filepath.find("?system_done") != -1: + done[ip].append(epoch) + elif filepath.find("?profile_done") != -1: + done[ip].append(epoch) + else: + files[ip][epoch] = filepath + + # FIXME: what's a good way to see when systems START? For FC6+ + # it will install via yum, so xml and xml.gz files come first. + # elsewhere, that's not true. + + logfile.close() + + + # report on the data found in all of the files, aggregated. + + self.generate_report(files,done) + return True + + #----------------------------------------- + + def generate_report(self,files,done): + """ + Given the information about transferred files and kickstart finish times, attempt + to produce a report that most describes the state of the system. + + FIXME: just text for now, but should pay attention to self.mode and possibly offer + a HTML or XML or YAML version for other apps. Not all, just some alternatives. + """ + print "%s" % files + print "%s" % done + diff --git a/cobbler/action_sync.py b/cobbler/action_sync.py index 694425f..10fe3df 100644 --- a/cobbler/action_sync.py +++ b/cobbler/action_sync.py @@ -320,19 +320,23 @@ class BootSync: )) meta["yum_repo_stanza"] = self.generate_repo_stanza(g) meta["yum_config_stanza"] = self.generate_config_stanza(g) - meta["kickstart_done"] = self.generate_kickstart_done(g, is_system=False) + meta["kickstart_done"] = self.generate_kickstart_signal(g, is_system=False, is_done=True) + meta["kickstart_start"] = self.generate_kickstart_signal(g, is_system=False, is_done=False) self.apply_template(kickstart_path, meta, dest) except: traceback.print_exc() # leave this in, for now... msg = "err_kickstart2" raise cexceptions.CobblerException(msg,kickstart_path,dest) - def generate_kickstart_done(self, obj, is_system=False): - pattern = "wget http://%s/cobbler/watcher.py?%s_done=%s --output-document=kickstart_done" + def generate_kickstart_signal(self, obj, is_system=False, is_done=True): + doneness = "done" + if not is_done: + doneness = "start" + pattern = "wget http://%s/cobbler/watcher.py?%s_%s=%s -b" if is_system: - return pattern % (self.settings.server, "system", obj.name) + return pattern % (self.settings.server, "system", doneness, obj.name) else: - return pattern % (self.settings.server, "profile", obj.name) + return pattern % (self.settings.server, "profile", doneness, obj.name) def generate_repo_stanza(self, profile): # returns the line of repo additions (Anaconda supports in FC-6 and later) that adds @@ -394,7 +398,8 @@ class BootSync: )) meta["yum_repo_stanza"] = self.generate_repo_stanza(profile) meta["yum_config_stanza"] = self.generate_config_stanza(profile) - meta["kickstart_done"] = self.generate_kickstart_done(profile, is_system=True) + meta["kickstart_done"] = self.generate_kickstart_signal(profile, is_system=True, is_done=True) + meta["kickstart_start"] = self.generate_kickstart_signal(profile, is_system=True, is_done=False) self.apply_template(kickstart_path, meta, dest) except: msg = "err_kickstart2" diff --git a/cobbler/api.py b/cobbler/api.py index ed2f66c..dda4052 100644 --- a/cobbler/api.py +++ b/cobbler/api.py @@ -21,6 +21,7 @@ import action_check import action_enchant import action_import import action_reposync +import action_status import cexceptions class BootAPI: diff --git a/cobbler/cobbler.py b/cobbler/cobbler.py index 62a0e4a..b2abfcd 100755 --- a/cobbler/cobbler.py +++ b/cobbler/cobbler.py @@ -18,6 +18,7 @@ import sys import api import os import os.path +import traceback import cobbler_msg import cexceptions @@ -230,6 +231,8 @@ class BootCLI: 'cobbler status [--mode=text|somethingelse]' """ self.mode = "text" + if args is None or len(args) == 0: + return self.api.status(self.mode) def set_mode(a): if a.lower in [ "text" ]: self.mode = a @@ -237,12 +240,11 @@ class BootCLI: else: return False commands = { - '--mode' : lambda(a): set_mode(a) + '--mode' : set_mode } def go_status(): - return self.api.show_status(self.mode) - on_ok = lambda: go_status() - return self.apply_args(args, commands, on_ok) + return self.api.status(self.mode) + return self.apply_args(args, commands, go_status) def enchant(self,args): """ @@ -499,6 +501,9 @@ def main(): except cexceptions.CobblerException, exc: print str(exc)[1:-1] # remove framing air quotes exitcode = 1 + except Exception, other: + traceback.print_exc() + exitcode = 1 if LOCKING_ENABLED and not lock_hit: try: os.remove(LOCKFILE) diff --git a/kickstart_fc5.ks b/kickstart_fc5.ks index adaff5e..754e5a6 100644 --- a/kickstart_fc5.ks +++ b/kickstart_fc5.ks @@ -37,6 +37,9 @@ zerombr %packages +%pre +TEMPLATE::kickstart_start + %post TEMPLATE::yum_config_stanza TEMPLATE::kickstart_done diff --git a/kickstart_fc6.ks b/kickstart_fc6.ks index 6a55cbc..9c516e4 100644 --- a/kickstart_fc6.ks +++ b/kickstart_fc6.ks @@ -39,6 +39,9 @@ zerombr %packages +%pre +TEMPLATE::kickstart_start + %post TEMPLATE::yum_config_stanza TEMPLATE::kickstart_done |