summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael DeHaan <mdehaan@redhat.com>2009-02-24 15:17:30 -0500
committerMichael DeHaan <mdehaan@redhat.com>2009-02-24 15:17:30 -0500
commitbed7e41ecf6d8fe27b3230bdd69f52714612e51b (patch)
treea376f8e3575d4bd0364fa38672d76bb7d657228d
parent3e86f2b24df1f8eff70c3d8773e5616c90ad5e3d (diff)
parent83e78b67973be5f3c5d1d175e4884537dd783f87 (diff)
downloadcobbler-bed7e41ecf6d8fe27b3230bdd69f52714612e51b.tar.gz
cobbler-bed7e41ecf6d8fe27b3230bdd69f52714612e51b.tar.xz
cobbler-bed7e41ecf6d8fe27b3230bdd69f52714612e51b.zip
Merge commit 'jamesc/standalone' into devel
-rw-r--r--cobbler/action_buildiso.py209
-rw-r--r--cobbler/api.py4
-rw-r--r--cobbler/modules/cli_misc.py8
3 files changed, 165 insertions, 56 deletions
diff --git a/cobbler/action_buildiso.py b/cobbler/action_buildiso.py
index 20364dfd..67546d5f 100644
--- a/cobbler/action_buildiso.py
+++ b/cobbler/action_buildiso.py
@@ -29,6 +29,7 @@ import sys
import traceback
import shutil
import sub_process
+import re
import utils
from cexceptions import *
@@ -68,8 +69,10 @@ class BuildIso:
self.distros = config.distros()
self.profiles = config.profiles()
self.systems = config.systems()
+ self.distros = config.distros()
self.distmap = {}
self.distctr = 0
+ self.source = ""
def make_shorter(self,distname):
if self.distmap.has_key(distname):
@@ -79,44 +82,8 @@ class BuildIso:
self.distmap[distname] = str(self.distctr)
return str(self.distctr)
- def run(self,iso=None,tempdir=None,profiles=None,systems=None):
-
- # if iso is none, create it in . as "kickstart.iso"
- if iso is None:
- iso = "kickstart.iso"
-
- if tempdir is None:
- tempdir = os.path.join(os.getcwd(), "buildiso")
- print _("- using/creating tempdir: %s") % tempdir
- if not os.path.exists(tempdir):
- os.makedirs(tempdir)
- else:
- shutil.rmtree(tempdir)
- os.makedirs(tempdir)
-
- # if base of tempdir does not exist, fail
- # create all profiles unless filtered by "profiles"
-
- imagesdir = os.path.join(tempdir, "images")
- isolinuxdir = os.path.join(tempdir, "isolinux")
-
- print _("- building tree for isolinux")
- if not os.path.exists(imagesdir):
- os.makedirs(imagesdir)
- if not os.path.exists(isolinuxdir):
- os.makedirs(isolinuxdir)
-
- print _("- copying miscellaneous files")
- isolinuxbin = "/usr/lib/syslinux/isolinux.bin"
- menu = "/var/lib/cobbler/menu.c32"
- chain = "/usr/lib/syslinux/chain.c32"
- files = [ isolinuxbin, menu, chain ]
- for f in files:
- if not os.path.exists(f):
- raise CX(_("Required file not found: %s") % f)
- else:
- utils.copyfile(f, os.path.join(isolinuxdir, os.path.basename(f)), self.api)
-
+
+ def generate_netboot_iso(self,imagesdir,isolinuxdir,profiles=None,systems=None):
print _("- copying kernels and initrds - for profiles")
# copy all images in included profiles to images dir
for profile in self.api.profiles():
@@ -162,7 +129,7 @@ class BuildIso:
isolinuxcfg = os.path.join(isolinuxdir, "isolinux.cfg")
cfg = open(isolinuxcfg, "w+")
cfg.write(HEADER) # fixme, use template
-
+
print _("- generating profile list...")
#sort the profiles
profile_list = [profile for profile in self.profiles]
@@ -201,10 +168,10 @@ class BuildIso:
length=len(append_line)
if length>254:
- print _("WARNING - append line length is greater than 254 chars: (%s chars)") % length
-
+ print _("WARNING - append line length is greater than 254 chars: (%s chars)") % length
+
cfg.write(append_line)
-
+
if systems is not None:
print _("- generating system list...")
@@ -267,26 +234,162 @@ class BuildIso:
length=len(append_line)
if length > 254:
- print _("WARNING - append line length is greater than 254 chars: (%s chars)") % length
-
+ print _("WARNING - append line length is greater than 254 chars: (%s chars)") % length
+
cfg.write(append_line)
- print _("- done writing config")
+ print _("- done writing config")
cfg.write("\n")
cfg.write("MENU END\n")
cfg.close()
-
- cmd = "mkisofs -o %s -r -b isolinux/isolinux.bin -c isolinux/boot.cat" % iso
- cmd = cmd + " -no-emul-boot -boot-load-size 4 "
- cmd = cmd + " -boot-info-table -V Cobbler\ Install -R -J -T %s" % tempdir
+
+
+ def generate_standalone_iso(self,imagesdir,isolinuxdir,distname,filesource):
+
+ # Get the distro object for the requested distro
+ # and then get all of its descendants (profiles/sub-profiles/systems)
+ distro = self.api.find_distro(distname)
+ if distro is None:
+ raise CX("distro %s was not found, aborting" % distname)
+ descendants = distro.get_descendants()
+
+ print _("- copying kernels and initrds - for standalone distro")
+ # tempdir/isolinux/$distro/vmlinuz, initrd.img
+ # FIXME: this will likely crash on non-Linux breeds
+ f1 = os.path.join(isolinuxdir, "vmlinuz")
+ f2 = os.path.join(isolinuxdir, "initrd.img")
+ if not os.path.exists(distro.kernel):
+ raise CX("path does not exist: %s" % distro.kernel)
+ if not os.path.exists(distro.initrd):
+ raise CX("path does not exist: %s" % distro.initrd)
+ shutil.copyfile(distro.kernel, f1)
+ shutil.copyfile(distro.initrd, f2)
+
+ cmd = "rsync -rlptgu --exclude=boot.cat --exclude=TRANS.TBL --exclude=isolinux/ %s/ %s/../" % (filesource, isolinuxdir)
+ print _("- copying distro %s files (%s)" % (distname,cmd))
+ rc = sub_process.call(cmd, shell=True, close_fds=True)
+ if rc:
+ raise CX(_("rsync of files failed"))
+
+ print _("- generating a isolinux.cfg")
+ isolinuxcfg = os.path.join(isolinuxdir, "isolinux.cfg")
+ cfg = open(isolinuxcfg, "w+")
+ cfg.write(HEADER) # fixme, use template
+
+ for descendant in descendants:
+ data = utils.blender(self.api, True, descendant)
+
+ cfg.write("\n")
+ cfg.write("LABEL %s\n" % descendant.name)
+ cfg.write(" MENU LABEL %s\n" % descendant.name)
+ cfg.write(" kernel vmlinuz\n")
+
+ data["kickstart"] = "cdrom:/isolinux/ks-%s.cfg" % descendant.name
+
+ append_line = " append initrd=initrd.img"
+ append_line = append_line + " ks=%s " % data["kickstart"]
+ append_line = append_line + " %s\n" % data["kernel_options"]
+
+ cfg.write(append_line)
+
+ if descendant.COLLECTION_TYPE == 'profile':
+ kickstart_data = self.api.kickgen.generate_kickstart_for_profile(descendant.name)
+ elif descendant.COLLECTION_TYPE == 'system':
+ kickstart_data = self.api.kickgen.generate_kickstart_for_system(descendant.name)
+
+ cdregex = re.compile("url .*\n", re.IGNORECASE)
+ kickstart_data = cdregex.sub("cdrom\n", kickstart_data)
+
+ ks_name = os.path.join(isolinuxdir, "ks-%s.cfg" % descendant.name)
+ ks_file = open(ks_name, "w+")
+ ks_file.write(kickstart_data)
+ ks_file.close()
+
+ print _("- done writing config")
+ cfg.write("\n")
+ cfg.write("MENU END\n")
+ cfg.close()
+
+ return
+
+
+ def run(self,iso=None,tempdir=None,profiles=None,systems=None,distro=None,standalone=None,source=None):
+
+ # the distro option is for stand-alone builds only
+ if not standalone and distro is not None:
+ raise CX(_("The --distro option should only be used when creating a standalone ISO"))
+ # if building standalone, we only want --distro,
+ # profiles/systems are disallowed
+ if standalone:
+ if profiles is not None or systems is not None:
+ raise CX(_("When building a standalone ISO, use --distro only instead of --profiles/--systems"))
+ elif distro is None:
+ raise CX(_("When building a standalone ISO, you must specify a --distro"))
+ elif source is None:
+ raise CX(_("When building a standalone ISO, you must specify a --source"))
+ elif not os.path.exists(source):
+ raise CX(_("The source specified (%s) does not exist" % source))
+
+ # if iso is none, create it in . as "kickstart.iso"
+ if iso is None:
+ iso = "kickstart.iso"
+
+ if tempdir is None:
+ tempdir = os.path.join(os.getcwd(), "buildiso")
+ else:
+ if not os.path.isdir(tempdir):
+ raise CX(_("The --tempdir specified is not a directory"))
+
+ (tempdir_head,tempdir_tail) = os.path.split(os.path.normpath(tempdir))
+ if tempdir_tail != "buildiso":
+ tempdir = os.path.join(tempdir, "buildiso")
+
+ print _("- using/creating tempdir: %s") % tempdir
+ if not os.path.exists(tempdir):
+ os.makedirs(tempdir)
+ else:
+ shutil.rmtree(tempdir)
+ os.makedirs(tempdir)
+
+ # if base of tempdir does not exist, fail
+ # create all profiles unless filtered by "profiles"
+
+ imagesdir = os.path.join(tempdir, "images")
+ isolinuxdir = os.path.join(tempdir, "isolinux")
+
+ print _("- building tree for isolinux")
+ if not os.path.exists(imagesdir):
+ os.makedirs(imagesdir)
+ if not os.path.exists(isolinuxdir):
+ os.makedirs(isolinuxdir)
+
+ print _("- copying miscellaneous files")
+ isolinuxbin = "/usr/lib/syslinux/isolinux.bin"
+ menu = "/var/lib/cobbler/menu.c32"
+ chain = "/usr/lib/syslinux/chain.c32"
+ files = [ isolinuxbin, menu, chain ]
+ for f in files:
+ if not os.path.exists(f):
+ raise CX(_("Required file not found: %s") % f)
+ else:
+ utils.copyfile(f, os.path.join(isolinuxdir, os.path.basename(f)), self.api)
+
+ if standalone:
+ self.generate_standalone_iso(imagesdir,isolinuxdir,distro,source)
+ else:
+ self.generate_netboot_iso(imagesdir,isolinuxdir,profiles,systems)
+
+ cmd = "mkisofs -quiet -o %s -r -b isolinux/isolinux.bin -c isolinux/boot.cat" % iso
+ cmd = cmd + " -no-emul-boot -boot-load-size 4"
+ cmd = cmd + " -boot-info-table -V Cobbler\ Install -R -J -T %s" % tempdir
print _("- running: %s") % cmd
rc = sub_process.call(cmd, shell=True, close_fds=True)
if rc:
raise CX(_("mkisofs failed"))
-
+
print _("ISO build complete")
print _("You may wish to delete: %s") % tempdir
- print _("The output file is: %s") % iso
-
-
+ print _("The output file is: %s") % iso
+
+
diff --git a/cobbler/api.py b/cobbler/api.py
index 3980e1c6..fd7a09ce 100644
--- a/cobbler/api.py
+++ b/cobbler/api.py
@@ -673,10 +673,10 @@ class BootAPI:
self.log("authorize",[user,resource,arg1,arg2,rc],debug=True)
return rc
- def build_iso(self,iso=None,profiles=None,systems=None,tempdir=None):
+ def build_iso(self,iso=None,profiles=None,systems=None,tempdir=None,distro=None,standalone=None,source=None):
builder = action_buildiso.BuildIso(self._config)
return builder.run(
- iso=iso, profiles=profiles, systems=systems, tempdir=tempdir
+ iso=iso, profiles=profiles, systems=systems, tempdir=tempdir, distro=distro, standalone=standalone, source=source
)
def replicate(self, cobbler_master = None, sync_all=False, sync_kickstarts=False, sync_trees=False, sync_repos=False, sync_triggers=False, systems=False):
diff --git a/cobbler/modules/cli_misc.py b/cobbler/modules/cli_misc.py
index 71967002..f83b5c8c 100644
--- a/cobbler/modules/cli_misc.py
+++ b/cobbler/modules/cli_misc.py
@@ -225,6 +225,9 @@ class BuildIsoFunction(commands.CobblerFunction):
p.add_option("--profiles", dest="profiles", help="(OPTIONAL) use these profiles only")
p.add_option("--systems", dest="systems", help="(OPTIONAL) use these systems only")
p.add_option("--tempdir", dest="tempdir", help="(OPTIONAL) working directory")
+ p.add_option("--distro", dest="distro", help="(OPTIONAL) used with --standalone to create a distro-based ISO including all associated profiles/systems")
+ p.add_option("--standalone", dest="standalone", action="store_true", help="(OPTIONAL) creates a standalone ISO with all required distro files on it")
+ p.add_option("--source", dest="source", help="(OPTIONAL) used with --standalone to specify a source for the distribution files")
def help_me(self):
return HELP_FORMAT % ("cobbler buildiso","[ARGS]")
@@ -237,7 +240,10 @@ class BuildIsoFunction(commands.CobblerFunction):
iso=self.options.isoname,
profiles=self.options.profiles,
systems=self.options.systems,
- tempdir=self.options.tempdir
+ tempdir=self.options.tempdir,
+ distro=self.options.distro,
+ standalone=self.options.standalone,
+ source=self.options.source
)
########################################################