From dd05c92699e657990c77af311b85fbef30472c11 Mon Sep 17 00:00:00 2001 From: Michael DeHaan Date: Fri, 27 Jul 2007 13:34:01 -0400 Subject: Added a SNIPPET::foo feature which can do the equivalent of %include in kickstart without the need for a wget and http hosting. Snippets live in /var/lib/cobbler/snippets -- Cobbler ships with only one snippet now (as a demo), though users can create as many as they want. --- cobbler/action_check.py | 2 +- cobbler/action_import.py | 2 +- cobbler/action_status.py | 2 +- cobbler/action_sync.py | 41 ++++++++++++++++++++++++++++++++--------- cobbler/api.py | 3 ++- cobbler/settings.py | 1 + 6 files changed, 38 insertions(+), 13 deletions(-) (limited to 'cobbler') diff --git a/cobbler/action_check.py b/cobbler/action_check.py index 9f258cc..d369527 100644 --- a/cobbler/action_check.py +++ b/cobbler/action_check.py @@ -68,7 +68,7 @@ class BootCheck: if os.path.exists("/etc/rc.d/init.d/iptables"): rc = sub_process.call("/sbin/service iptables status >/dev/null 2>/dev/null", shell=True) if rc == 0: - status.append(_("since iptables may be running, ensure 69, 80, %s, and %s are unblocked") % (self.settings.syslog_port, self.settings.xmlrpc_port)) + status.append(_("since iptables may be running, ensure 69, 80, %(syslog)s, and %(xmlrpc)s are unblocked") % { "syslog" : self.settings.syslog_port, "xmlrpc" : self.settings.xmlrpc_port }) def check_name(self,status): """ diff --git a/cobbler/action_import.py b/cobbler/action_import.py index c906bdc..c3e7b1a 100644 --- a/cobbler/action_import.py +++ b/cobbler/action_import.py @@ -345,7 +345,7 @@ class Importer: p1 = os.path.join(comps_path, "repodata", "comps.xml") p2 = os.path.join(comps_path, "base", "comps.xml") if os.path.exists(p1) and os.path.exists(p2): - print _("- cp %s %s") % (p1, p2) + print _("- cp %(p1)s %(p2)s") % { "p1" : p1, "p2" : p2 } shutil.copyfile(p1,p2) except: diff --git a/cobbler/action_status.py b/cobbler/action_status.py index b1bca72..158ee30 100644 --- a/cobbler/action_status.py +++ b/cobbler/action_status.py @@ -113,7 +113,7 @@ class BootStatusReport: time_collisions = 0 #header = ("Address", "State", "Started", "Last Request", "Seconds", "Log Entries") - print _("%-20s | %-15s | %-25s | %-25s | %-10s | %-6s") % ( + print "%-20s | %-15s | %-25s | %-25s | %-10s | %-6s" % ( _("Address"), _("State"), _("Last Request"), diff --git a/cobbler/action_sync.py b/cobbler/action_sync.py index 9346f28..d668895 100644 --- a/cobbler/action_sync.py +++ b/cobbler/action_sync.py @@ -60,8 +60,7 @@ class BootSync: """ if not os.path.exists(self.settings.tftpboot): raise CX(_("cannot find directory: %s") % self.settings.tftpboot) - # not having a /var/www/cobbler is ok, the app will create it since - # no other package has to own it. + self.load_snippet_cache() self.clean_trees() self.copy_koan() self.copy_bootloaders() @@ -279,9 +278,9 @@ class BootSync: kernel = utils.find_kernel(d.kernel) # full path initrd = utils.find_initrd(d.initrd) # full path if kernel is None or not os.path.isfile(kernel): - raise CX(_("kernel not found: %s, distro: %s"), d.kernel, d.name) + raise CX(_("kernel not found: %(file)s, distro: %(distro)s") % { "file" : d.kernel, "distro" : d.name }) if initrd is None or not os.path.isfile(initrd): - raise CX(_("initrd not found: %s, distro: %s"), d.initrd, d.name) + raise CX(_("initrd not found: %(file)s, distro: %(distro)s") % { "file" : d.initrd, "distro" : d.name }) b_kernel = os.path.basename(kernel) b_initrd = os.path.basename(initrd) self.copyfile(kernel, os.path.join(distro_dir, b_kernel)) @@ -448,7 +447,23 @@ class BootSync: self.apply_template(kfile, meta, dest) kfile.close() except: - raise CX(_("Error templating file %s to %s") % { "src" : meta["kickstart"], "dest" : dest }) + raise CX(_("Error templating file %(src)s to %(dest)s") % { "src" : meta["kickstart"], "dest" : dest }) + + def load_snippet_cache(self): + + # first load all of the files in /var/lib/cobbler/snippets and load them, for use + # in adding long bits to kickstart templates without having to have them hard coded + # inside the sync code. + + snippet_cache = {} + snippets = glob.glob("%s/*" % self.settings.snippetsdir) + for snip in snippets: + snip_file = open(snip) + data = snip_file.read() + snip_file.close() + snippet_cache[os.path.basename(snip)] = data + self.snippet_cache = snippet_cache + def apply_template(self, data_input, metadata, out_path): """ @@ -456,7 +471,6 @@ class BootSync: Cheetah and save as out_path. """ - if type(data_input) != str: data = data_input.read() else: @@ -466,10 +480,19 @@ class BootSync: # template syntax. data = data.replace("TEMPLATE::","$") + # replace contents of the data stream with items from the snippet cache + # do not use Cheetah yet, Cheetah can't really be run twice on the same + # stream and be expected to do the right thing + for x in self.snippet_cache: + data = data.replace("SNIPPET::%s" % x, self.snippet_cache[x]) + + # tell Cheetah not to blow up if it can't find a symbol for something data = "#errorCatcher Echo\n" + data - + + # now do full templating scan, where we will also templatify the snippet insertions t = Template(source=data, searchList=[metadata]) data_out = str(t) + if out_path is not None: self.mkdir(os.path.dirname(out_path)) fd = open(out_path, "w+") @@ -506,10 +529,10 @@ class BootSync: profile = system.get_conceptual_parent() if profile is None: - raise CX(_("system %s references a missing profile %s") % { "system" : system.name, "profile" : system.profile}) + raise CX(_("system %(system)s references a missing profile %(profile)s") % { "system" : system.name, "profile" : system.profile}) distro = profile.get_conceptual_parent() if distro is None: - raise CX(_("profile %s references a missing distro %s") % { "profile" : system.profile, "distro" : profile.distro}) + raise CX(_("profile %(profile)s references a missing distro %(distro)s") % { "profile" : system.profile, "distro" : profile.distro}) f1 = utils.get_config_filename(system) # tftp only diff --git a/cobbler/api.py b/cobbler/api.py index d520cc9..bd597b2 100644 --- a/cobbler/api.py +++ b/cobbler/api.py @@ -53,7 +53,8 @@ class BootAPI: result = cmd.communicate()[0].replace("cobbler-","") if result.find("not installed") != -1: return "?" - return result[:result.rfind(".")] + tokens = result[:result.rfind("-")].split(".") + return int(tokens[0]) + 0.1 * int(tokens[1]) + 0.001 * int(tokens[2]) def clear(self): diff --git a/cobbler/settings.py b/cobbler/settings.py index 19a07a2..ac89715 100644 --- a/cobbler/settings.py +++ b/cobbler/settings.py @@ -35,6 +35,7 @@ DEFAULTS = { "tftpd_conf" : "/etc/xinetd.d/tftp", "tftpboot" : "/tftpboot", "webdir" : "/var/www/cobbler", + "snippetsdir" : "/var/lib/cobbler/snippets", "default_kickstart" : "/etc/cobbler/default.ks", "manage_dhcp" : 0, "manage_dhcp_mode" : "isc", -- cgit