diff options
-rw-r--r-- | CHANGELOG | 10 | ||||
-rw-r--r-- | MANIFEST.in | 28 | ||||
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | cobbler.spec | 6 | ||||
-rw-r--r-- | cobbler/action_import.py | 178 | ||||
-rw-r--r-- | cobbler/action_sync.py | 147 | ||||
-rw-r--r-- | cobbler/api.py | 7 | ||||
-rwxr-xr-x | cobbler/cobbler.py | 10 | ||||
-rw-r--r-- | cobbler/settings.py | 3 | ||||
-rw-r--r-- | loaders/COPYING_ELILO (renamed from COPYING_ELILO) | 0 | ||||
-rw-r--r-- | loaders/elilo-3.6-ia64.efi (renamed from elilo-3.6-ia64.efi) | bin | 374146 -> 374146 bytes | |||
-rw-r--r-- | loaders/menu.c32 (renamed from menu.c32) | bin | 26496 -> 26496 bytes | |||
-rwxr-xr-x | scripts/cobbler (renamed from cobbler/cobbler) | 0 | ||||
-rwxr-xr-x | scripts/cobbler_syslogd (renamed from cobbler/cobbler_syslogd) | 0 | ||||
-rwxr-xr-x | scripts/cobblersyslogd (renamed from cobblersyslogd) | 0 | ||||
-rwxr-xr-x | scripts/watcher.py (renamed from watcher.py) | 2 | ||||
-rw-r--r-- | setup.py | 31 | ||||
-rw-r--r-- | templates/dhcp.template | 27 | ||||
-rw-r--r-- | templates/pxedefault.template | 13 | ||||
-rw-r--r-- | templates/pxeprofile.template | 4 | ||||
-rw-r--r-- | templates/pxesystem.template | 7 | ||||
-rw-r--r-- | templates/pxesystem_ia64.template | 6 | ||||
-rw-r--r-- | templates/rsync.exclude (renamed from rsync.exclude) | 0 |
23 files changed, 268 insertions, 215 deletions
@@ -1,12 +1,14 @@ Cobbler CHANGELOG (all entries mdehaan@redhat.com unless noted otherwise) -* Fri Mar 02 2007 - 0.4.4 +* Fri Mar 16 2007 - 0.4.4 +- Generate PXE configuration files from templates in /etc/cobbler - Fix bug with wrong kickstart metadata being used for import - Fix bug with argument parsing for --repos -- Generate PXE configuration files from editable files: - /etc/cobbler/pxe.template, pxemenuitem.template, pxemenu.template -- Generate PXE menus from /etc/cobbler/pxemenuitem.template +- Much cleaner distro/profile names with --import +- For import, the "tree" parameter is now attached to the distro, not the profile +- Add "links" directory in webdir for symlinking to full kickstart tree paths. +- Misc tweaks to shorten kernel parameter length * Wed Feb 28 2007 - 0.4.3 - Added netboot_enabled option for systems to control install loops in programmatic context. diff --git a/MANIFEST.in b/MANIFEST.in index dda3c0e..0f03e0e 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,14 +1,16 @@ -include COPYING_ELILO -include elilo-3.6-ia64.efi -include dhcp.template -include kickstart_fc5.ks -include kickstart_fc6.ks -include kickstart_fc6_domU.ks -include default.ks -include default.pxe -include cobbler.1.gz +include loaders/COPYING_ELILO +include loaders/elilo-3.6-ia64.efi +include loaders/menu.c32 +include templates/dhcp.template +include templates/pxeprofile.template +include templates/pxedefault.template +include templates/pxesystem.template +include kickstarts/kickstart_fc5.ks +include kickstarts/kickstart_fc6.ks +include kickstarts/kickstart_fc6_domU.ks +include kickstarts/default.ks +include docs/cobbler.1.gz include COPYING AUTHORS README CHANGELOG NEWS -include rsync.exclude -include watcher.py -include cobblersyslogd -include menu.c32 +include templates/rsync.exclude +include scripts/watcher.py +include scripts/cobblersyslogd @@ -5,8 +5,8 @@ clean: -rm -rf cobbler-* dist build manpage: - pod2man --center="cobbler" --release="" cobbler.pod | gzip -c > cobbler.1.gz - pod2html cobbler.pod > cobbler.html + pod2man --center="cobbler" --release="" ./docs/cobbler.pod | gzip -c > ./docs/cobbler.1.gz + pod2html ./docs/cobbler.pod > ./docs/cobbler.html test: python tests/tests.py diff --git a/cobbler.spec b/cobbler.spec index 8b35889..56eb1b2 100644 --- a/cobbler.spec +++ b/cobbler.spec @@ -88,7 +88,9 @@ test "x$RPM_BUILD_ROOT" != "x" && rm -rf $RPM_BUILD_ROOT %config(noreplace) /etc/cobbler/kickstart_fc6.ks %config(noreplace) /etc/cobbler/kickstart_fc6_domU.ks %config(noreplace) /etc/cobbler/dhcp.template -%config(noreplace) /etc/cobbler/pxe.template +%config(noreplace) /etc/cobbler/pxedefault.template +%config(noreplace) /etc/cobbler/pxeprofile.template +%config(noreplace) /etc/cobbler/pxesystem.template %config(noreplace) /etc/cobbler/rsync.exclude %dir %{python_sitelib}/cobbler %dir %{python_sitelib}/cobbler/yaml @@ -106,7 +108,7 @@ test "x$RPM_BUILD_ROOT" != "x" && rm -rf $RPM_BUILD_ROOT %changelog -* Fri Mar 02 2007 Michael DeHaan <mdehaan@redhat.com> - 0.4.4-0 +* Fri Mar 16 2007 Michael DeHaan <mdehaan@redhat.com> - 0.4.4-0 - Upstream changes (see CHANGELOG) * Wed Feb 28 2007 Michael DeHaan <mdehaan@redhat.com> - 0.4.3-0 diff --git a/cobbler/action_import.py b/cobbler/action_import.py index ff777d4..47e68e3 100644 --- a/cobbler/action_import.py +++ b/cobbler/action_import.py @@ -1,9 +1,9 @@ """ -Enables the "cobbler distro import" command to seed cobbler -information with available distributions. A minimal (kickstartless) -profile will also be created with the same name as the distro. +Enables the "cobbler import" command to seed cobbler +information with available distribution from rsync mirrors +and mounted DVDs. -Copyright 2006, Red Hat, Inc +Copyright 2006-2007, Red Hat, Inc Michael DeHaan <mdehaan@redhat.com> This software may be freely redistributed under the terms of the GNU @@ -22,33 +22,34 @@ import sub_process import api +WGET_CMD = "wget --mirror --no-parent --no-host-directories --directory-prefix %s/%s %s" +RSYNC_CMD = "rsync -a %s %s %s/ks_mirror/%s --exclude-from=/etc/cobbler/rsync.exclude --delete --delete-excluded --progress" + # MATCH_LIST uses path segments of mirror URLs to assign kickstart # files. It's not all that intelligent. +# patches welcome! -# FIXME: add common FC, RHEL, and Centos path segments -# it's exceedingly wrong right now and the kickstart file -# for FC5 is sent everywhere. That probably WON'T work in most -# places even though it's a minimalistic kickstart. This will -# get patched over time. MATCH_LIST = ( + ( "FC-5/" , "/etc/cobbler/kickstart_fc5.ks" ), + ( "FC-6/" , "/etc/cobbler/kickstart_fc6.ks" ), + ( "RHEL-4/" , "/etc/cobbler/kickstart_fc5.ks" ), + ( "RHEL-5/" , "/etc/cobbler/kickstart_fc6.ks" ), + ( "Centos/4" , "/etc/cobbler/kickstart_fc5.ks" ), + ( "Centos/5" , "/etc/cobbler/kickstart_fc6.ks" ), ( "1/" , "/etc/cobbler/kickstart_fc5.ks" ), ( "2/" , "/etc/cobbler/kickstart_fc5.ks" ), ( "3/" , "/etc/cobbler/kickstart_fc5.ks" ), ( "4/" , "/etc/cobbler/kickstart_fc5.ks" ), ( "5/" , "/etc/cobbler/kickstart_fc5.ks" ), - ( "FC-5/" , "/etc/cobbler/kickstart_fc5.ks" ), - ( "FC-6/" , "/etc/cobbler/kickstart_fc6.ks" ), - ( "RHEL-4/" , "/etc/cobbler/kickstart_fc5.ks" ), - ( "6/" , "/etc/cobbler/kickstart_fc5.ks" ), - ( "5/" , "/etc/cobbler/kickstart_fc5.ks" ), - ( "Centos/4" , "/etc/cobbler/kickstart_fc5.ks" ) + ( "6/" , "/etc/cobbler/kickstart_fc6.ks" ), ) # the following is a filter to reduce import scan times, # particularly over NFS. these indicate directory segments # that we do not need to recurse into. In the case where # these path segments are important to a certain distro import, -# it's a bug, and this list needs to be edited. +# it's a bug, and this list needs to be edited. please submit +# patches or reports in this case. DIRECTORY_SIEVE = [ "debuginfo", "ppc", "s390x", "s390", "variant-src", @@ -61,16 +62,11 @@ DIRECTORY_SIEVE = [ "src-isos", "dvd-isos", "docs", "misc" ] -# to keep serialization to a good level, serialize every -# so many iterations, but not every time. - - class Importer: - def __init__(self,api,config,path,mirror,mirror_name): + def __init__(self,api,config,mirror,mirror_name): self.api = api self.config = config - self.path = path self.mirror = mirror self.mirror_name = mirror_name self.distros = config.distros() @@ -80,91 +76,61 @@ class Importer: self.serialize_counter = 0 def run(self): - if self.path is None and self.mirror is None: - raise cexceptions.CobblerException("import_failed","no path specified") - if self.path and not os.path.isdir(self.path): - raise cexceptions.CobblerException("import_failed","bad path") - if self.mirror is not None: - if self.mirror_name is None: - raise cexceptions.CobblerException("import_failed","must specify --mirror-name") - print "This will take a while..." - self.path = "%s/ks_mirror/%s" % (self.settings.webdir, self.mirror_name) - try: - os.makedirs(self.path) - except: - if not os.path.exists(self.path): - raise cexceptions.CobblerException("couldn't create: %s" % (self.path)) + if self.mirror is None: + raise cexceptions.CobblerException("import_failed","no mirror specified") + if self.mirror_name is None: + raise cexceptions.CobblerException("import_failed","no mirror-name specified") + if self.mirror_name is None: + raise cexceptions.CobblerException("import_failed","must specify --mirror-name") + + # make the output path + self.path = "%s/ks_mirror/%s" % (self.settings.webdir, self.mirror_name) + self.mkdir(self.path) + # prevent rsync from creating the directory name twice + if not self.mirror.endswith("/"): + self.mirror = "%s/" % self.mirror - if self.mirror.startswith("http://"): - # http mirrors are kind of primative. rsync is better. - try: - os.makedirs("%s/ks_mirror/%s" % (self.settings.webdir, self.mirror_name)) - except: - print "- didn't create %s" % self.mirror_name - cmd = "wget --mirror --no-parent --no-host-directories --directory-prefix %s/%s %s" % (self.settings.webdir, self.mirror_name, self.mirror) - print "- %s" % cmd - sub_process.call(cmd,shell=True) - else: - # use rsync... + if self.mirror.startswith("http://"): + # http mirrors are kind of primative. rsync is better. + self.run_this(WGET_CMD, (self.settings.webdir, self.mirror_name, self.mirror)) + else: + # use rsync.. no SSH for public mirrors and local files. + # presence of user@host syntax means use SSH + spacer = "" + if not self.mirror.startswith("rsync://") and not self.mirror.startswith("/"): + spacer = ' -e "ssh" ' + self.run_this(RSYNC_CMD, (spacer, self.mirror, self.settings.webdir, self.mirror_name)) - spacer = "" - if not self.mirror.startswith("rsync://"): - spacer = ' -e "ssh" ' - cmd = "rsync -a %s %s %s/ks_mirror/%s --exclude-from=/etc/cobbler/rsync.exclude --delete --delete-excluded --progress" % (spacer, self.mirror, self.settings.webdir, self.mirror_name) - print "- %s" % cmd - sub_process.call(cmd,shell=True) + processed_repos = {} + os.path.walk(self.path, self.walker, processed_repos) + self.guess_kickstarts() + return True - if self.path is not None: - processed_repos = {} - os.path.walk(self.path, self.walker, processed_repos) - self.scrub_orphans() - self.guess_kickstarts() - return True - raise cexceptions.CobblerException("path not specified") - 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 as it's useful elsewhere - """ - print "- Removing orphaned distributions" - for distro in self.distros: - remove = False - if not os.path.exists(distro.kernel): - print "- Orphaned distro (no kernel): %s" % distro.name - remove = True - if not os.path.exists(distro.initrd): - print "- Orphaned distro (no initrd): %s" % distro.name - remove = True - if not remove: - continue - # cascade removal - for profile in self.profiles: - if profile.distro == distro.name: - # cascade removal of systems - for system in self.systems: - if system.profile == profile.name: - print "- System removed: %s" % system.name - self.systems.remove(system.name) - print "- Profile removed: %s" % profile.name - self.profiles.remove(profile.name) - print "- Distro removed: %s" % distro.name - self.distros.remove(distro.name) + def mkdir(self, dir): + try: + os.makedirs(dir) + except: + print "- didn't create %s" % dir + + def run_this(self, cmd, args): + my_cmd = cmd % args + print "- %s" % my_cmd + sub_process.call(my_cmd,shell=True) 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. """ + # FIXME: refactor this and make it more intelligent + # FIXME: if no distro can be found from the path, find through alternative means. + for profile in self.profiles: distro = self.distros.find(profile.distro) if distro is None: @@ -183,11 +149,15 @@ class Importer: print "dirname = %s" % dirname tokens = dirname.split("/") tokens = tokens[:-2] - base = "/".join(tokens) + base = "/".join(tokens) + dest_link = os.path.join(self.settings.webdir, "links", distro.name) + print "base=%s -> %s to %s" % (base, dest_link) + if not os.path.exists(dest_link): + os.symlink(base, dest_link) base = base.replace(self.settings.webdir,"") - tree = "tree=http://%s/cobbler_track/%s" % (self.settings.server, base) + tree = "tree=http://%s/cblr/links/%s" % distro.name print "*** KICKSTART TREE = %s" % tree - profile.set_ksmeta(tree) + distro.set_ksmeta(tree) self.serialize_counter = self.serialize_counter + 1 if (self.serialize_counter % 5) == 0: self.api.serialize() @@ -254,9 +224,21 @@ class Importer: self.api.serialize() def get_proposed_name(self,dirname): - name = "_".join(dirname.split("/")) - if name.startswith("_"): + name = "-".join(dirname.split("/")) + if name.startswith("-"): name = name[1:] + # some of this filtering is a bit excessive though we want to compensate for + # finding "tree" vs "image" in the path and so on, and being a little more + # aggressive in filtering will reduce path name lengths in all circumstances. + # long paths are bad because they are hard to type, look weird, and run up + # against the 255 char kernel options limit too quickly. + name = name.replace("var-www-cobbler-", "") + name = name.replace("ks-mirror-","") + name = name.replace("os-images-","") + name = name.replace("tree-images-","") + name = name.replace("images-","") + name = name.replace("tree-","") + name = name.replace("--","-") return name def get_pxe_arch(self,dirname): diff --git a/cobbler/action_sync.py b/cobbler/action_sync.py index 24b7d0d..cee56e6 100644 --- a/cobbler/action_sync.py +++ b/cobbler/action_sync.py @@ -191,7 +191,7 @@ class BootSync: data = fh.read() if data.find(self.settings.webdir) != -1: found_webdir = True - if data.find("cobbler_track") != -1: + if data.find("cblr") != -1: found_track_support = True fh.close() @@ -236,6 +236,7 @@ class BootSync: # to be accessed over HTTP in addition to PXE. AliasMatch ^/cobbler(/.*)?$ "/cobbler_webdir$1" AliasMatch ^/cobbler_track(/.*)?$ "/cobbler_webdir$1" + AliasMatch ^/cblr(/.*)?$ "/cobbler_webdir$1" <Directory "/cobbler_webdir"> Options Indexes FollowSymLinks AllowOverride None @@ -370,7 +371,7 @@ class BootSync: raise cexceptions.CobblerException(msg,kickstart_path,dest) def generate_kickstart_signal(self, obj, is_system=False): - pattern = "wget http://%s/cobbler_track/watcher.py?%s_%s=%s -b" + pattern = "wget http://%s/cblr/watcher.py?%s_%s=%s -b" if is_system: return pattern % (self.settings.server, "system", "done", obj.name) else: @@ -386,7 +387,7 @@ class BootSync: repo = self.repos.find(r) if repo is None: continue - http_url = "http://%s/cobbler_track/repo_mirror/%s" % (self.settings.server, repo.name) + http_url = "http://%s/cblr/repo_mirror/%s" % (self.settings.server, repo.name) buf = buf + "repo --name=%s --baseurl=%s\n" % (repo.name, http_url) return buf @@ -399,7 +400,7 @@ class BootSync: if repo is None: continue if not (repo.local_filename is None) or (repo.local_filename == ""): - buf = buf + "wget http://%s/cobbler_track/repo_mirror/%s/config.repo --output-document=/etc/yum.repos.d/%s.repo\n" % (self.settings.server, repo.name, repo.local_filename) + buf = buf + "wget http://%s/cblr/repo_mirror/%s/config.repo --output-document=/etc/yum.repos.d/%s.repo\n" % (self.settings.server, repo.name, repo.local_filename) return buf def validate_kickstarts_per_system(self): @@ -451,9 +452,14 @@ class BootSync: Take filesystem file kickstart_input, apply metadata using Cheetah and save as out_path. """ + + print "DEBUG: AT: ... ", out_path + if type(data_input) != str: + print "DEBUG: from file" data = data_input.read() else: + print "DEBUG: from string" data = data_input # backward support for Cobbler's legacy (and slightly more readable) @@ -462,12 +468,19 @@ class BootSync: data = "#errorCatcher Echo\n" + data + print "DEBUG: data in = %s" % data t = Template(source=data, searchList=[metadata]) data_out = str(t) - self.mkdir(os.path.dirname(out_path)) - fd = open(out_path, "w+") - fd.write(data_out) - fd.close() + print "DEBUG: data out = %s" % data_out + if out_path is not None: + print "DEBUG: making: %s" % os.path.dirname(out_path) + self.mkdir(os.path.dirname(out_path)) + fd = open(out_path, "w+") + fd.write(data_out) + fd.close() + else: + print "DEBUG: out_path: %s" % out_path + return data_out def build_trees(self): """ @@ -558,41 +571,37 @@ class BootSync: default = self.systems.find("default") if default is not None: return - # generate the defaults file: + fname = os.path.join(self.settings.tftpboot, "pxelinux.cfg", "default") - defaults = open(fname, "w") - defaults.write("DEFAULT local\n") - defaults.write("PROMPT 1\n") - defaults.write("MENU TITLE Cobbler | http://cobbler.et.redhat.com\n") - defaults.write("TIMEOUT 200\n") - defaults.write("TOTALTIMEOUT 6000\n") - defaults.write("ONTIMEOUT local\n") - defaults.write("\n") - defaults.write("LABEL local\n") - defaults.write("\tMENU LABEL (local)\n") - defaults.write("\tMENU DEFAULT\n") - defaults.write("\tLOCALBOOT 0\n") - defaults.write("\n") + # read the default template file + template_src = open("/etc/cobbler/pxedefault.template") + template_data = template_src.read() + # sort the profiles profile_list = [profile for profile in self.profiles] def sort_name(a,b): return cmp(a.name,b.name) profile_list.sort(sort_name) + # build out the menu entries + pxe_menu_items = "" for profile in profile_list: - - defaults.write("LABEL %s\n" % profile.name) - # a evil invocation of the pxe file creation tool that only generates bits and pieces - # without a filename to write to, and without system interpolation, so it's basically just - # bits and pieces relevant to the profile. distro = self.distros.find(profile.distro) contents = self.write_pxe_file(None,None,profile,distro,False,include_header=False) if contents is not None: - defaults.write(contents + "\n") - defaults.write("\n") + pxe_menu_items = pxe_menu_items + contents + + # save the template. + print "DEBUG: src = %s" % template_data + metadata = { "pxe_menu_items" : pxe_menu_items } + print "DEBUG: metadata = %s" % metadata + outfile = os.path.join(self.settings.tftpboot, "pxelinux.cfg", "default") + print "DEBUG: outfile = %s" % outfile + self.apply_template(template_data, metadata, outfile) + print "** DEBUG: APPLIED **" + template_src.close() - defaults.close() def write_pxe_file(self,filename,system,profile,distro,is_ia64, include_header=True): """ @@ -603,34 +612,32 @@ class BootSync: NOTE: relevant to tftp only """ + # --- # system might have netboot_enabled set to False (see item_system.py), if so, # don't do anything else and flag the error condition. if system is not None and not system.netboot_enabled: return None + # --- + # just some random variables + template = None + metadata = {} buffer = "" + # --- + # find kernel and initrd kernel_path = os.path.join("/images",distro.name,os.path.basename(distro.kernel)) initrd_path = os.path.join("/images",distro.name,os.path.basename(distro.initrd)) kickstart_path = profile.kickstart - #fd = self.open_file(filename,"w+") - if not is_ia64: - # pxelinux tree - if include_header: - buffer = buffer + "default linux\n" - buffer = buffer + "prompt 0\n" - buffer = buffer + "timeout 1\n" - buffer = buffer + "label linux\n" - buffer = buffer + "ipappend 2\n" - buffer = buffer + "\tkernel %s\n" % kernel_path + # --- + # choose a template + if system is None: + template = "/etc/cobbler/pxeprofile.template" + elif not is_ia64: + template = "/etc/cobbler/pxesystem.template" else: - # elilo thrown in root - buffer = buffer + "image=%s\n" % kernel_path - buffer = buffer + "\tlabel=netinstall\n" - buffer = buffer + "\tinitrd=%s\n" % initrd_path - buffer = buffer + "\tread-only\n" - buffer = buffer + "\troot=/dev/ram\n" + template = "/etc/cobbler/pxesystem_ia64.template" # now build the kernel command line if system is not None: @@ -647,23 +654,19 @@ class BootSync: distro.kernel_options )) - - # the kernel options line is common to elilo and pxelinux - append_line = "%s" % self.hash_to_string(kopts) - - # if not ia64, include initrd on this line - # for ia64, it's already done + # --- + # generate the append line + append_line = "append %s" % self.hash_to_string(kopts) if not is_ia64: - append_line = "%s initrd=%s" % (append_line,initrd_path) + append_line = "%s initrd=%s" % (append_line, initrd_path) - # kickstart path (if kickstart is used) + # --- + # kickstart path rewriting (get URLs for local files) if kickstart_path is not None and kickstart_path != "": - # if kickstart path is on disk, we've already copied it into - # the HTTP mirror, so make it something anaconda can get at. if system is not None and kickstart_path.startswith("/") or kickstart_path.find("/cobbler/kickstarts/") != -1: pxe_fn = self.get_pxe_filename(system.name) - kickstart_path = "http://%s/cobbler_track/kickstarts_sys/%s/ks.cfg" % (self.settings.server, pxe_fn) + kickstart_path = "http://%s/cblr/kickstarts_sys/%s/ks.cfg" % (self.settings.server, pxe_fn) elif kickstart_path.startswith("/") or kickstart_path.find("/cobbler/kickstarts/") != -1: kickstart_path = "http://%s/cobbler_track/kickstarts/%s/ks.cfg" % (self.settings.server, profile.name) @@ -672,21 +675,29 @@ class BootSync: elif distro.breed == "suse": append_line = "%s autoyast=%s" % (append_line, kickstart_path) - # now to add the append line to the file - if not is_ia64: - if system is None: - buffer = buffer + "\tMENU LABEL %s\n" % profile.name - # pxelinux.cfg syntax - buffer = buffer + "\tappend %s" % append_line - else: - # elilo.conf syntax - buffer = buffer + "\tappend=\"%s\"" % append_line - + # --- + # store variables for templating + metadata["menu_label"] = "" + if not is_ia64 and system is None: + metadata["menu_label"] = "MENU LABEL %s\n" % profile.name + metadata["profile_name"] = profile.name + metadata["kernel_path"] = kernel_path + metadata["initrd_path"] = initrd_path + metadata["append_line"] = append_line + + # --- + # get the template + template_fh = open(template) + template_data = template_fh.read() + template_fh.close() + + # --- + # save file and/or return results, depending on how called. + buffer = self.apply_template(template_data, metadata, None) if filename is not None: fd = self.open_file(filename, "w") self.tee(fd, buffer) self.close_file(fd) - return buffer diff --git a/cobbler/api.py b/cobbler/api.py index 165c3f1..8881d83 100644 --- a/cobbler/api.py +++ b/cobbler/api.py @@ -143,13 +143,12 @@ class BootAPI: statusifier = action_status.BootStatusReport(self._config, mode) return statusifier.run() - def import_tree(self,tree_path,mirror_url,mirror_name): + def import_tree(self,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. + mirror_url can be a string that represents a path, a user@host syntax for SSH, or an rsync:// address """ - importer = action_import.Importer(self, self._config, tree_path, mirror_url, mirror_name) + importer = action_import.Importer(self, self._config, mirror_url, mirror_name) return importer.run() def serialize(self): diff --git a/cobbler/cobbler.py b/cobbler/cobbler.py index 14a8f56..bdf892f 100755 --- a/cobbler/cobbler.py +++ b/cobbler/cobbler.py @@ -285,24 +285,18 @@ class BootCLI: Import a directory tree and auto-create distros & profiles. 'cobbler """ - 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): - if os.path.isdir(a): - self.temp_path = a - return True - return False def go_import(): - return self.api.import_tree(self.temp_path, + return self.api.import_tree( self.temp_mirror, self.temp_mirror_name) commands = { - '--path' : lambda(a): set_path(a), + '--path' : lambda(a): set_mirror(a), '--mirror' : lambda(a): set_mirror(a), '--mirror-name' : lambda(a): set_mirror_name(a), '--name' : lambda(a): set_mirror_name(a) diff --git a/cobbler/settings.py b/cobbler/settings.py index d7fcd8c..68ea9b4 100644 --- a/cobbler/settings.py +++ b/cobbler/settings.py @@ -25,10 +25,9 @@ DEFAULTS = { "next_server" : "127.0.0.1", "dhcpd_bin" : "/usr/sbin/dhcpd", "kernel_options" : { - "append" : None, "devfs" : "nomount", "ramdisk_size" : 16438, - "lang=" : " ", + "lang" : " ", "text" : None, "ksdevice" : "eth0", }, diff --git a/COPYING_ELILO b/loaders/COPYING_ELILO index ed08493..ed08493 100644 --- a/COPYING_ELILO +++ b/loaders/COPYING_ELILO diff --git a/elilo-3.6-ia64.efi b/loaders/elilo-3.6-ia64.efi Binary files differindex de0df83..de0df83 100644 --- a/elilo-3.6-ia64.efi +++ b/loaders/elilo-3.6-ia64.efi diff --git a/menu.c32 b/loaders/menu.c32 Binary files differindex 7912a08..7912a08 100644 --- a/menu.c32 +++ b/loaders/menu.c32 diff --git a/cobbler/cobbler b/scripts/cobbler index 4aef615..4aef615 100755 --- a/cobbler/cobbler +++ b/scripts/cobbler diff --git a/cobbler/cobbler_syslogd b/scripts/cobbler_syslogd index 86e77e1..86e77e1 100755 --- a/cobbler/cobbler_syslogd +++ b/scripts/cobbler_syslogd diff --git a/cobblersyslogd b/scripts/cobblersyslogd index b8bc3f7..b8bc3f7 100755 --- a/cobblersyslogd +++ b/scripts/cobblersyslogd diff --git a/watcher.py b/scripts/watcher.py index b002146..1074458 100755 --- a/watcher.py +++ b/scripts/watcher.py @@ -25,7 +25,7 @@ def outputfilter(filter): logfile = open("/var/log/cobbler/kicklog/%s" % address,"a+") log_it = True - if request.the_request.find("cobbler_track") == -1: + if request.the_request.find("cobbler_track") == -1 and request.the_request.find("ctr/") == -1": log_it = False if log_it: @@ -29,6 +29,7 @@ if __name__ == "__main__": vw_distros = "/var/www/cobbler/distros" vw_systems = "/var/www/cobbler/systems" vw_profiles = "/var/www/cobbler/profiles" + vw_links = "/var/www/cobbler/links" tftp_cfg = "/tftpboot/pxelinux.cfg" tftp_images = "/tftpboot/images" setup( @@ -42,21 +43,24 @@ if __name__ == "__main__": "cobbler", "cobbler/yaml" ], - scripts = ["cobbler/cobbler", "cobbler/cobbler_syslogd"], + scripts = ["scripts/cobbler", "scripts/cobbler_syslogd"], data_files = [ # (docspath, ['README']), - (wwwpath, ['watcher.py']), - (cobpath, ['elilo-3.6-ia64.efi']), - (cobpath, ['menu.c32']), - (etcpath, ['kickstart_fc5.ks']), - (etcpath, ['kickstart_fc6.ks']), - (etcpath, ['kickstart_fc6_domU.ks']), - (etcpath, ['default.ks']), - (etcpath, ['dhcp.template']), - (etcpath, ['pxe.template']), - (manpath, ['cobbler.1.gz']), - (etcpath, ['rsync.exclude']), - (initpath, ['cobblersyslogd']), + (wwwpath, ['scripts/watcher.py']), + (cobpath, ['loaders/elilo-3.6-ia64.efi']), + (cobpath, ['loaders/menu.c32']), + (etcpath, ['kickstarts/kickstart_fc5.ks']), + (etcpath, ['kickstarts/kickstart_fc6.ks']), + (etcpath, ['kickstarts/kickstart_fc6_domU.ks']), + (etcpath, ['kickstarts/default.ks']), + (etcpath, ['templates/dhcp.template']), + (etcpath, ['templates/pxedefault.template']), + (etcpath, ['templates/pxesystem.template']), + (etcpath, ['templates/pxesystem_ia64.template']), + (etcpath, ['templates/pxeprofile.template']), + (manpath, ['docs/cobbler.1.gz']), + (etcpath, ['templates/rsync.exclude']), + (initpath, ['scripts/cobblersyslogd']), (logpath, []), (logpath2, []), (logpath3, []), @@ -69,6 +73,7 @@ if __name__ == "__main__": (vw_images, []), (vw_systems, []), (vw_profiles, []), + (vw_links, []), (tftp_cfg, []), (tftp_images, []), ], diff --git a/templates/dhcp.template b/templates/dhcp.template new file mode 100644 index 0000000..705cc77 --- /dev/null +++ b/templates/dhcp.template @@ -0,0 +1,27 @@ +# ****************************************************************** +# Cobbler managed dhcpd.conf file +# +# generated from cobbler dhcp.conf template ($date) +# +# ****************************************************************** + +ddns-update-style interim; + +allow booting; +allow bootp; + +ignore client-updates; +set vendorclass = option vendor-class-identifier; + +subnet 192.168.1.0 netmask 255.255.255.0 { + option routers 192.168.1.5; + option subnet-mask 255.255.255.0; + range dynamic-bootp 192.168.1.100 192.168.1.254; + filename "/pxelinux.0"; + default-lease-time 21600; + max-lease-time 43200; + next-server $next_server; +} + +$insert_cobbler_system_definitions + diff --git a/templates/pxedefault.template b/templates/pxedefault.template new file mode 100644 index 0000000..d731892 --- /dev/null +++ b/templates/pxedefault.template @@ -0,0 +1,13 @@ +DEFAULT local +PROMPT 1 +MENU TITLE Cobbler | http://cobbler.et.redhat.com +TIMEOUT 200 +TOTALTIMEOUT 6000 +ONTIMEOUT local + +LABEL local + MENU LABEL (local) + MENU DEFAULT + LOCALBOOT 0 + +$pxe_menu_items diff --git a/templates/pxeprofile.template b/templates/pxeprofile.template new file mode 100644 index 0000000..e1a6e2e --- /dev/null +++ b/templates/pxeprofile.template @@ -0,0 +1,4 @@ +LABEL $profile_name + kernel $kernel_path + $menu_label + $append_line diff --git a/templates/pxesystem.template b/templates/pxesystem.template new file mode 100644 index 0000000..1564d7e --- /dev/null +++ b/templates/pxesystem.template @@ -0,0 +1,7 @@ +default linux +prompt 0 +timeout 1 +label linux + kernel $kernel_path + append $append_line + diff --git a/templates/pxesystem_ia64.template b/templates/pxesystem_ia64.template new file mode 100644 index 0000000..dd06d4e --- /dev/null +++ b/templates/pxesystem_ia64.template @@ -0,0 +1,6 @@ +image=$kernel_path + label=netinstall + append=$append_line + initrd=$initrd_path + read-only + root=/dev/ram diff --git a/rsync.exclude b/templates/rsync.exclude index 15ed695..15ed695 100644 --- a/rsync.exclude +++ b/templates/rsync.exclude |