diff options
author | Michael DeHaan <mdehaan@redhat.com> | 2006-10-13 16:09:31 -0400 |
---|---|---|
committer | Jim Meyering <jim@meyering.net> | 2006-10-13 16:09:31 -0400 |
commit | 47590f79742b9cb91f876ad4507208a875ea2880 (patch) | |
tree | 81b346bd0ae6bb48fb0b2108b68b1580be40a5e9 /cobbler | |
parent | cd9b923b946c45c5a732fa6e053a59c0f9fcb40e (diff) | |
download | third_party-cobbler-47590f79742b9cb91f876ad4507208a875ea2880.tar.gz third_party-cobbler-47590f79742b9cb91f876ad4507208a875ea2880.tar.xz third_party-cobbler-47590f79742b9cb91f876ad4507208a875ea2880.zip |
Lots of work on importing rsync mirrors, including preliminary code to guess
kickstart files and assign them for distributions that we know how to minimally kickstart.
Diffstat (limited to 'cobbler')
-rw-r--r-- | cobbler/action_import.py | 127 | ||||
-rw-r--r-- | cobbler/api.py | 4 | ||||
-rwxr-xr-x | cobbler/cobbler.py | 7 |
3 files changed, 117 insertions, 21 deletions
diff --git a/cobbler/action_import.py b/cobbler/action_import.py index e50ffd8..3a28e6c 100644 --- a/cobbler/action_import.py +++ b/cobbler/action_import.py @@ -21,13 +21,26 @@ import traceback import api +# MATCH_LIST uses path segments of mirror URLs to assign kickstart +# files. It's not all that intelligent. + +# FIXME: add common FC, RHEL, and Centos path segments +MATCH_LIST = ( + ( "FC-5/" , "/etc/cobbler/kickstart_fc56.ks" ), + ( "FC-6/" , "/etc/cobbler/kickstart_fc56.ks" ), + ( "RHEL-4/", "/etc/cobbler/kickstart_fc56.ks" ), + ( "6/" , "/etc/cobbler/kickstart_fc56.ks" ), + ( "5/" , "/etc/cobbler/kickstart_fc56.ks" ) +) + class Importer: - def __init__(self,config,path,mirror): + def __init__(self,config,path,mirror,mirror_name): # FIXME: consider a basename for the import self.config = config self.path = path self.mirror = mirror + self.mirror_name = mirror_name if path is None: raise cexceptions.CobblerException("import_failed","no path specified") self.distros = config.distros() @@ -39,12 +52,93 @@ class Importer: raise cexceptions.CobblerException("import_failed","no path specified") if not os.path.isdir(self.path): raise cexceptions.CobblerException("import_failed","bad path") + if self.mirror is not None: + if not self.mirror.startswith("rsync://"): + raise cexceptions.CobblerException("import_failed","expecting rsync:// url") + if self.mirror_name is None: + raise cexceptions.CobblerException("import_failed","must specify --mirror-name") + # FIXME: --delete is a little harsh and should be a command + # line option and not the default (?) + print "This will take a while..." + self.path = "/var/www/cobbler/localmirror/%s" % self.mirror_name + cmd = "rsync -az %s /var/www/cobbler/localmirror/%s --progress" % self.mirror_name + sub_process.call(cmd,shell=True) + update_file = os.path.open(os.path.join(self.path,"update.sh")) + update.file.write("#!/bin/sh") + update_file.write(cmd) + update_file.close() if self.path is not None: arg = None os.path.walk(self.path, self.walker, arg) + self.scrub_orphans() + self.guess_kickstarts() return True return False + def scrub_orphans(self): + """ + This has nothing to do with parentless children that need baths. + first: remove any distros with missing kernel or initrd files + second: remove any profiles that depend on distros that don't exist + systems will be left as orphans as the MAC info may be useful + to the sysadmin and may not be recorded elsewhere. We will report + the orphaned systems. + FIXME: this should also be a seperate API command! + """ + print "*** SCRUBBING ORPHANS" + # FIXME + for distro in self.distros: + if not os.path.exists(distro.kernel): + print "*** ORPHANED DISTRO: %s" % distro.name + self.distros.remove(distro.name) + continue + if not os.path.exists(distro.initrd): + print "*** ORPHANED DISTRO: %s" % distro.name + self.distros.remove(distro.initrd) + continue + print "*** KEEPING: %s" % distro.name + for profile in self.profiles: + if not self.distros.find(profile.distro): + print "*** ORPHANED PROFILE: %s" % profile.name + self.profiles.remove(profile.name) + continue + print "*** KEEPING: %s" % profile.name + for system in self.systems: + if not self.profiles.find(system.profile): + print "*** ORPHANED SYSTEM (NOT DELETED): %s" % system.name + continue + + def guess_kickstarts(self): + """ + For all of the profiles in the config w/o a kickstart, look + at the kernel path, from that, see if we can guess the distro, + and if we can, assign a kickstart if one is available for it. + """ + print "*** GUESSING KICKSTARTS" + for profile in self.profiles: + distro = self.distros.find(profile.name) + kpath = distro.kernel + if not kpath.startswith("/var/www/cobbler"): + print "*** CAN'T GUESS (kpath): %s" % kpath + continue + for entry in MATCH_LIST: + (part, kickstart) = entry + if kpath.find(part) != -1: + print "*** CONSIDERING: %s" % kickstart + if os.path.exists(kickstart): + print "*** ASSIGNING kickstart: %s" % kickstart + profile.set_kickstart(kickstart) + # from the kernel path, the tree path is always two up. + # FIXME: that's probably not always true + base = os.path.basename(kpath) + base = os.path.basename(base) + base = base.replace("/var/www/cobbler/","") + print "%s" % base + tree = "tree=http://%s/localmirror/%s/" % (self.settings,server, self.mirror_name, base) + print "%s" % tree + print "*** ASSIGNING KS META = %s" % tree + profile.set_ksmeta(tree) + def walker(self,arg,dirname,fnames): # FIXME: requires getting an arch out of the path # FIXME: requires making sure the path contains "pxe" somewhere @@ -85,26 +179,23 @@ class Importer: def get_proposed_name(self,dirname): # FIXME: how can this name be nicer? - str = "_".join(dirname.split("/")) - if str.startswith("_"): - return str[1:] - return str + temp = "_".join(dirname.split("/")) + if temp.startswith("_"): + temp = temp[1:] + return temp def get_pxe_arch(self,dirname): - tokens = os.path.split(dirname) - tokens = [x.lower() for x in tokens] - for t in tokens: - if t == "i386" or t == "386" or t == "x86": - return "x86" - if t == "x86_64": - return "x86_64" - if t == "ia64": - return "ia64" + t = dirname + if t.find("x86_64") != -1: + return "x86_64" + if t.find("ia64") != -1: + return "ia64" + if t.find("i386") != -1 or t.find("386") != -1 or t.find("x86") != -1: + return "x86" return "x86" def is_pxe_or_xen_dir(self,dirname): - tokens = os.path.split(dirname) - for x in tokens: - if x.lower() == "pxe" or x.lower() == "pxeboot" or x.lower() == "xen": - return True + if dirname.find("pxe") != -1 or dirname.find("xen") != -1: + return True return False + diff --git a/cobbler/api.py b/cobbler/api.py index 18ed9e0..fae5d64 100644 --- a/cobbler/api.py +++ b/cobbler/api.py @@ -116,13 +116,13 @@ class BootAPI: enchant = action_enchant.Enchant(self._config,sysname,password) return enchant.run() - def import_tree(self,tree_path,mirror_url): + def import_tree(self,tree_path,mirror_url,mirror_name): """ Automatically import a directory tree full of distribution files. Imports either a tree (path) or mirror (ftp/http). Mirror support really doesn't exist yet... TBA. """ - importer = action_import.Importer(self._config, tree_path, mirror_url) + importer = action_import.Importer(self._config, tree_path, mirror_url, mirror_name) return importer.run() def serialize(self): diff --git a/cobbler/cobbler.py b/cobbler/cobbler.py index e7a512c..d31924c 100755 --- a/cobbler/cobbler.py +++ b/cobbler/cobbler.py @@ -152,6 +152,9 @@ class BootCLI: """ self.temp_path = None self.temp_mirror = None + self.temp_mirror_name = None + def set_mirror_name(a): + self.temp_mirror_name = a def set_mirror(a): self.temp_mirror = a def set_path(a): @@ -160,7 +163,9 @@ class BootCLI: return True return False def go_import(): - return self.api.import_tree(self.temp_path,self.temp_mirror) + return self.api.import_tree(self.temp_path, + self.temp_mirror, + self.temp_mirror_name) commands = { '--path' : lambda(a): set_path(a), '--mirror' : lambda(a): set_mirror(a) |