From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) by finch.gentoo.org (Postfix) with ESMTP id EEAEF13827E for ; Sat, 14 Dec 2013 03:21:04 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 0959EE0BBA; Sat, 14 Dec 2013 03:20:38 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183]) (using TLSv1 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id 1DE80E0BB3 for ; Sat, 14 Dec 2013 03:20:37 +0000 (UTC) Received: from big_daddy.dol-sen.ca (S010600222de111ff.vc.shawcable.net [96.49.5.156]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: dolsen) by smtp.gentoo.org (Postfix) with ESMTPSA id 299A633F228; Sat, 14 Dec 2013 03:20:36 +0000 (UTC) From: Brian Dolbec To: gentoo-catalyst@lists.gentoo.org Cc: Brian Dolbec Subject: [gentoo-catalyst] [PATCH 3/4] rename the modules subpkg to targets, it better reflects what it contains Date: Fri, 13 Dec 2013 19:20:10 -0800 Message-Id: <1386991211-9296-4-git-send-email-dolsen@gentoo.org> X-Mailer: git-send-email 1.8.3.2 In-Reply-To: <1386991211-9296-1-git-send-email-dolsen@gentoo.org> References: <1386991211-9296-1-git-send-email-dolsen@gentoo.org> Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-catalyst@lists.gentoo.org Reply-to: gentoo-catalyst@lists.gentoo.org X-Archives-Salt: 30225f57-4aac-4c54-b4df-b6a6838ad9e3 X-Archives-Hash: 62806d89ad8b3bde7a7ceff5dd41f591 --- catalyst/main.py | 6 +- catalyst/modules/__init__.py | 1 - catalyst/modules/embedded_target.py | 51 - catalyst/modules/generic_stage_target.py | 1691 ------------------------------ catalyst/modules/generic_target.py | 11 - catalyst/modules/grp_target.py | 118 --- catalyst/modules/livecd_stage1_target.py | 75 -- catalyst/modules/livecd_stage2_target.py | 146 --- catalyst/modules/netboot2_target.py | 166 --- catalyst/modules/netboot_target.py | 128 --- catalyst/modules/snapshot_target.py | 91 -- catalyst/modules/stage1_target.py | 96 -- catalyst/modules/stage2_target.py | 62 -- catalyst/modules/stage3_target.py | 31 - catalyst/modules/stage4_target.py | 43 - catalyst/modules/tinderbox_target.py | 44 - catalyst/targets/__init__.py | 1 + catalyst/targets/embedded_target.py | 51 + catalyst/targets/generic_stage_target.py | 1691 ++++++++++++++++++++++++++++++ catalyst/targets/generic_target.py | 11 + catalyst/targets/grp_target.py | 118 +++ catalyst/targets/livecd_stage1_target.py | 75 ++ catalyst/targets/livecd_stage2_target.py | 146 +++ catalyst/targets/netboot2_target.py | 166 +++ catalyst/targets/netboot_target.py | 128 +++ catalyst/targets/snapshot_target.py | 91 ++ catalyst/targets/stage1_target.py | 96 ++ catalyst/targets/stage2_target.py | 62 ++ catalyst/targets/stage3_target.py | 31 + catalyst/targets/stage4_target.py | 43 + catalyst/targets/tinderbox_target.py | 44 + 31 files changed, 2757 insertions(+), 2757 deletions(-) delete mode 100644 catalyst/modules/__init__.py delete mode 100644 catalyst/modules/embedded_target.py delete mode 100644 catalyst/modules/generic_stage_target.py delete mode 100644 catalyst/modules/generic_target.py delete mode 100644 catalyst/modules/grp_target.py delete mode 100644 catalyst/modules/livecd_stage1_target.py delete mode 100644 catalyst/modules/livecd_stage2_target.py delete mode 100644 catalyst/modules/netboot2_target.py delete mode 100644 catalyst/modules/netboot_target.py delete mode 100644 catalyst/modules/snapshot_target.py delete mode 100644 catalyst/modules/stage1_target.py delete mode 100644 catalyst/modules/stage2_target.py delete mode 100644 catalyst/modules/stage3_target.py delete mode 100644 catalyst/modules/stage4_target.py delete mode 100644 catalyst/modules/tinderbox_target.py create mode 100644 catalyst/targets/__init__.py create mode 100644 catalyst/targets/embedded_target.py create mode 100644 catalyst/targets/generic_stage_target.py create mode 100644 catalyst/targets/generic_target.py create mode 100644 catalyst/targets/grp_target.py create mode 100644 catalyst/targets/livecd_stage1_target.py create mode 100644 catalyst/targets/livecd_stage2_target.py create mode 100644 catalyst/targets/netboot2_target.py create mode 100644 catalyst/targets/netboot_target.py create mode 100644 catalyst/targets/snapshot_target.py create mode 100644 catalyst/targets/stage1_target.py create mode 100644 catalyst/targets/stage2_target.py create mode 100644 catalyst/targets/stage3_target.py create mode 100644 catalyst/targets/stage4_target.py create mode 100644 catalyst/targets/tinderbox_target.py diff --git a/catalyst/main.py b/catalyst/main.py index 90ee722..28afc59 100644 --- a/catalyst/main.py +++ b/catalyst/main.py @@ -201,11 +201,11 @@ def import_modules(): targetmap={} try: - module_dir = __selfpath__ + "/modules/" + module_dir = __selfpath__ + "/targets/" for x in required_build_targets: try: fh=open(module_dir + x + ".py") - module=imp.load_module(x, fh,"modules/" + x + ".py", + module=imp.load_module(x, fh,"targets/" + x + ".py", (".py", "r", imp.PY_SOURCE)) fh.close() @@ -215,7 +215,7 @@ def import_modules(): for x in valid_build_targets: try: fh=open(module_dir + x + ".py") - module=imp.load_module(x, fh, "modules/" + x + ".py", + module=imp.load_module(x, fh, "targets/" + x + ".py", (".py", "r", imp.PY_SOURCE)) module.register(targetmap) fh.close() diff --git a/catalyst/modules/__init__.py b/catalyst/modules/__init__.py deleted file mode 100644 index 8b13789..0000000 --- a/catalyst/modules/__init__.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/catalyst/modules/embedded_target.py b/catalyst/modules/embedded_target.py deleted file mode 100644 index 7cee7a6..0000000 --- a/catalyst/modules/embedded_target.py +++ /dev/null @@ -1,51 +0,0 @@ -""" -Enbedded target, similar to the stage2 target, builds upon a stage2 tarball. - -A stage2 tarball is unpacked, but instead -of building a stage3, it emerges @system into another directory -inside the stage2 system. This way, we do not have to emerge GCC/portage -into the staged system. -It may sound complicated but basically it runs -ROOT=/tmp/submerge emerge --something foo bar . -""" -# NOTE: That^^ docstring has influence catalyst-spec(5) man page generation. - -import os,string,imp,types,shutil -from catalyst.support import * -from generic_stage_target import * -from stat import * - -class embedded_target(generic_stage_target): - """ - Builder class for embedded target - """ - def __init__(self,spec,addlargs): - self.required_values=[] - self.valid_values=[] - self.valid_values.extend(["embedded/empty","embedded/rm","embedded/unmerge","embedded/fs-prepare","embedded/fs-finish","embedded/mergeroot","embedded/packages","embedded/fs-type","embedded/runscript","boot/kernel","embedded/linuxrc"]) - self.valid_values.extend(["embedded/use"]) - if "embedded/fs-type" in addlargs: - self.valid_values.append("embedded/fs-ops") - - generic_stage_target.__init__(self,spec,addlargs) - self.set_build_kernel_vars(addlargs) - - def set_action_sequence(self): - self.settings["action_sequence"]=["dir_setup","unpack","unpack_snapshot",\ - "config_profile_link","setup_confdir",\ - "portage_overlay","bind","chroot_setup",\ - "setup_environment","build_kernel","build_packages",\ - "bootloader","root_overlay","fsscript","unmerge",\ - "unbind","remove","empty","clean","capture","clear_autoresume"] - - def set_stage_path(self): - self.settings["stage_path"]=normpath(self.settings["chroot_path"]+"/tmp/mergeroot") - print "embedded stage path is "+self.settings["stage_path"] - - def set_root_path(self): - self.settings["root_path"]=normpath("/tmp/mergeroot") - print "embedded root path is "+self.settings["root_path"] - -def register(foo): - foo.update({"embedded":embedded_target}) - return foo diff --git a/catalyst/modules/generic_stage_target.py b/catalyst/modules/generic_stage_target.py deleted file mode 100644 index 5200d8a..0000000 --- a/catalyst/modules/generic_stage_target.py +++ /dev/null @@ -1,1691 +0,0 @@ -import os,string,imp,types,shutil -from catalyst.support import * -from generic_target import * -from stat import * -from catalyst.lock import LockDir - -class generic_stage_target(generic_target): - """ - This class does all of the chroot setup, copying of files, etc. It is - the driver class for pretty much everything that Catalyst does. - """ - def __init__(self,myspec,addlargs): - self.required_values.extend(["version_stamp","target","subarch",\ - "rel_type","profile","snapshot","source_subpath"]) - - self.valid_values.extend(["version_stamp","target","subarch",\ - "rel_type","profile","snapshot","source_subpath","portage_confdir",\ - "cflags","cxxflags","ldflags","cbuild","hostuse","portage_overlay",\ - "distcc_hosts","makeopts","pkgcache_path","kerncache_path"]) - - self.set_valid_build_kernel_vars(addlargs) - generic_target.__init__(self,myspec,addlargs) - - """ - The semantics of subarchmap and machinemap changed a bit in 2.0.3 to - work better with vapier's CBUILD stuff. I've removed the "monolithic" - machinemap from this file and split up its contents amongst the - various arch/foo.py files. - - When register() is called on each module in the arch/ dir, it now - returns a tuple instead of acting on the subarchmap dict that is - passed to it. The tuple contains the values that were previously - added to subarchmap as well as a new list of CHOSTs that go along - with that arch. This allows us to build machinemap on the fly based - on the keys in subarchmap and the values of the 2nd list returned - (tmpmachinemap). - - Also, after talking with vapier. I have a slightly better idea of what - certain variables are used for and what they should be set to. Neither - 'buildarch' or 'hostarch' are used directly, so their value doesn't - really matter. They are just compared to determine if we are - cross-compiling. Because of this, they are just set to the name of the - module in arch/ that the subarch is part of to make things simpler. - The entire build process is still based off of 'subarch' like it was - previously. -agaffney - """ - - self.archmap = {} - self.subarchmap = {} - machinemap = {} - arch_dir = self.settings["PythonDir"] + "/arch/" - for x in [x[:-3] for x in os.listdir(arch_dir) if x.endswith(".py")]: - try: - fh=open(arch_dir + x + ".py") - """ - This next line loads the plugin as a module and assigns it to - archmap[x] - """ - self.archmap[x]=imp.load_module(x,fh,"../arch/" + x + ".py", - (".py", "r", imp.PY_SOURCE)) - """ - This next line registers all the subarches supported in the - plugin - """ - tmpsubarchmap, tmpmachinemap = self.archmap[x].register() - self.subarchmap.update(tmpsubarchmap) - for machine in tmpmachinemap: - machinemap[machine] = x - for subarch in tmpsubarchmap: - machinemap[subarch] = x - fh.close() - except IOError: - """ - This message should probably change a bit, since everything in - the dir should load just fine. If it doesn't, it's probably a - syntax error in the module - """ - msg("Can't find/load " + x + ".py plugin in " + arch_dir) - - if "chost" in self.settings: - hostmachine = self.settings["chost"].split("-")[0] - if hostmachine not in machinemap: - raise CatalystError, "Unknown host machine type "+hostmachine - self.settings["hostarch"]=machinemap[hostmachine] - else: - hostmachine = self.settings["subarch"] - if hostmachine in machinemap: - hostmachine = machinemap[hostmachine] - self.settings["hostarch"]=hostmachine - if "cbuild" in self.settings: - buildmachine = self.settings["cbuild"].split("-")[0] - else: - buildmachine = os.uname()[4] - if buildmachine not in machinemap: - raise CatalystError, "Unknown build machine type "+buildmachine - self.settings["buildarch"]=machinemap[buildmachine] - self.settings["crosscompile"]=(self.settings["hostarch"]!=\ - self.settings["buildarch"]) - - """ Call arch constructor, pass our settings """ - try: - self.arch=self.subarchmap[self.settings["subarch"]](self.settings) - except KeyError: - print "Invalid subarch: "+self.settings["subarch"] - print "Choose one of the following:", - for x in self.subarchmap: - print x, - print - sys.exit(2) - - print "Using target:",self.settings["target"] - """ Print a nice informational message """ - if self.settings["buildarch"]==self.settings["hostarch"]: - print "Building natively for",self.settings["hostarch"] - elif self.settings["crosscompile"]: - print "Cross-compiling on",self.settings["buildarch"],\ - "for different machine type",self.settings["hostarch"] - else: - print "Building on",self.settings["buildarch"],\ - "for alternate personality type",self.settings["hostarch"] - - """ This must be set first as other set_ options depend on this """ - self.set_spec_prefix() - - """ Define all of our core variables """ - self.set_target_profile() - self.set_target_subpath() - self.set_source_subpath() - - """ Set paths """ - self.set_snapshot_path() - self.set_root_path() - self.set_source_path() - self.set_snapcache_path() - self.set_chroot_path() - self.set_autoresume_path() - self.set_dest_path() - self.set_stage_path() - self.set_target_path() - - self.set_controller_file() - self.set_action_sequence() - self.set_use() - self.set_cleanables() - self.set_iso_volume_id() - self.set_build_kernel_vars() - self.set_fsscript() - self.set_install_mask() - self.set_rcadd() - self.set_rcdel() - self.set_cdtar() - self.set_fstype() - self.set_fsops() - self.set_iso() - self.set_packages() - self.set_rm() - self.set_linuxrc() - self.set_busybox_config() - self.set_overlay() - self.set_portage_overlay() - self.set_root_overlay() - - """ - This next line checks to make sure that the specified variables exist - on disk. - """ - #pdb.set_trace() - file_locate(self.settings,["source_path","snapshot_path","distdir"],\ - expand=0) - """ If we are using portage_confdir, check that as well. """ - if "portage_confdir" in self.settings: - file_locate(self.settings,["portage_confdir"],expand=0) - - """ Setup our mount points """ - if "SNAPCACHE" in self.settings: - self.mounts=["/proc","/dev","/usr/portage","/usr/portage/distfiles","/var/tmp/portage"] - self.mountmap={"/proc":"/proc","/dev":"/dev","/dev/pts":"/dev/pts",\ - "/usr/portage":self.settings["snapshot_cache_path"]+"/portage",\ - "/usr/portage/distfiles":self.settings["distdir"],"/var/tmp/portage":"tmpfs"} - else: - self.mounts=["proc","dev", "distdir", "port_tmpdir"] - self.mountmap={"proc":"/proc", "dev":"/dev", "pts":"/dev/pts", - "distdir":self.settings["distdir"], "port_tmpdir":"tmpfs"} - if os.uname()[0] == "Linux": - self.mounts.append("pts") - - self.set_mounts() - - """ - Configure any user specified options (either in catalyst.conf or on - the command line). - """ - if "PKGCACHE" in self.settings: - self.set_pkgcache_path() - print "Location of the package cache is "+\ - self.settings["pkgcache_path"] - self.mounts.append("packagedir") - self.mountmap["packagedir"] = self.settings["pkgcache_path"] - - if "KERNCACHE" in self.settings: - self.set_kerncache_path() - print "Location of the kerncache is "+\ - self.settings["kerncache_path"] - self.mounts.append("kerncache") - self.mountmap["kerncache"]=self.settings["kerncache_path"] - - if "CCACHE" in self.settings: - if "CCACHE_DIR" in os.environ: - ccdir=os.environ["CCACHE_DIR"] - del os.environ["CCACHE_DIR"] - else: - ccdir="/root/.ccache" - if not os.path.isdir(ccdir): - raise CatalystError,\ - "Compiler cache support can't be enabled (can't find "+\ - ccdir+")" - self.mounts.append("ccache") - self.mountmap["ccache"]=ccdir - """ for the chroot: """ - self.env["CCACHE_DIR"]="/var/tmp/ccache" - - if "ICECREAM" in self.settings: - self.mounts.append("/var/cache/icecream") - self.mountmap["/var/cache/icecream"]="/var/cache/icecream" - self.env["PATH"]="/usr/lib/icecc/bin:"+self.env["PATH"] - - if "port_logdir" in self.settings: - self.mounts.append("/var/log/portage") - self.mountmap["/var/log/portage"]=self.settings["port_logdir"] - self.env["PORT_LOGDIR"]="/var/log/portage" - self.env["PORT_LOGDIR_CLEAN"]='find "${PORT_LOGDIR}" -type f ! -name "summary.log*" -mtime +30 -delete' - - def override_cbuild(self): - if "CBUILD" in self.makeconf: - self.settings["CBUILD"]=self.makeconf["CBUILD"] - - def override_chost(self): - if "CHOST" in self.makeconf: - self.settings["CHOST"]=self.makeconf["CHOST"] - - def override_cflags(self): - if "CFLAGS" in self.makeconf: - self.settings["CFLAGS"]=self.makeconf["CFLAGS"] - - def override_cxxflags(self): - if "CXXFLAGS" in self.makeconf: - self.settings["CXXFLAGS"]=self.makeconf["CXXFLAGS"] - - def override_ldflags(self): - if "LDFLAGS" in self.makeconf: - self.settings["LDFLAGS"]=self.makeconf["LDFLAGS"] - - def set_install_mask(self): - if "install_mask" in self.settings: - if type(self.settings["install_mask"])!=types.StringType: - self.settings["install_mask"]=\ - string.join(self.settings["install_mask"]) - - def set_spec_prefix(self): - self.settings["spec_prefix"]=self.settings["target"] - - def set_target_profile(self): - self.settings["target_profile"]=self.settings["profile"] - - def set_target_subpath(self): - self.settings["target_subpath"]=self.settings["rel_type"]+"/"+\ - self.settings["target"]+"-"+self.settings["subarch"]+"-"+\ - self.settings["version_stamp"] - - def set_source_subpath(self): - if type(self.settings["source_subpath"])!=types.StringType: - raise CatalystError,\ - "source_subpath should have been a string. Perhaps you have something wrong in your spec file?" - - def set_pkgcache_path(self): - if "pkgcache_path" in self.settings: - if type(self.settings["pkgcache_path"])!=types.StringType: - self.settings["pkgcache_path"]=\ - normpath(string.join(self.settings["pkgcache_path"])) - else: - self.settings["pkgcache_path"]=\ - normpath(self.settings["storedir"]+"/packages/"+\ - self.settings["target_subpath"]+"/") - - def set_kerncache_path(self): - if "kerncache_path" in self.settings: - if type(self.settings["kerncache_path"])!=types.StringType: - self.settings["kerncache_path"]=\ - normpath(string.join(self.settings["kerncache_path"])) - else: - self.settings["kerncache_path"]=normpath(self.settings["storedir"]+\ - "/kerncache/"+self.settings["target_subpath"]+"/") - - def set_target_path(self): - self.settings["target_path"]=normpath(self.settings["storedir"]+\ - "/builds/"+self.settings["target_subpath"]+".tar.bz2") - if "AUTORESUME" in self.settings\ - and os.path.exists(self.settings["autoresume_path"]+\ - "setup_target_path"): - print \ - "Resume point detected, skipping target path setup operation..." - else: - """ First clean up any existing target stuff """ - # XXX WTF are we removing the old tarball before we start building the - # XXX new one? If the build fails, you don't want to be left with - # XXX nothing at all -# if os.path.isfile(self.settings["target_path"]): -# cmd("rm -f "+self.settings["target_path"],\ -# "Could not remove existing file: "\ -# +self.settings["target_path"],env=self.env) - touch(self.settings["autoresume_path"]+"setup_target_path") - - if not os.path.exists(self.settings["storedir"]+"/builds/"): - os.makedirs(self.settings["storedir"]+"/builds/") - - def set_fsscript(self): - if self.settings["spec_prefix"]+"/fsscript" in self.settings: - self.settings["fsscript"]=\ - self.settings[self.settings["spec_prefix"]+"/fsscript"] - del self.settings[self.settings["spec_prefix"]+"/fsscript"] - - def set_rcadd(self): - if self.settings["spec_prefix"]+"/rcadd" in self.settings: - self.settings["rcadd"]=\ - self.settings[self.settings["spec_prefix"]+"/rcadd"] - del self.settings[self.settings["spec_prefix"]+"/rcadd"] - - def set_rcdel(self): - if self.settings["spec_prefix"]+"/rcdel" in self.settings: - self.settings["rcdel"]=\ - self.settings[self.settings["spec_prefix"]+"/rcdel"] - del self.settings[self.settings["spec_prefix"]+"/rcdel"] - - def set_cdtar(self): - if self.settings["spec_prefix"]+"/cdtar" in self.settings: - self.settings["cdtar"]=\ - normpath(self.settings[self.settings["spec_prefix"]+"/cdtar"]) - del self.settings[self.settings["spec_prefix"]+"/cdtar"] - - def set_iso(self): - if self.settings["spec_prefix"]+"/iso" in self.settings: - if self.settings[self.settings["spec_prefix"]+"/iso"].startswith('/'): - self.settings["iso"]=\ - normpath(self.settings[self.settings["spec_prefix"]+"/iso"]) - else: - # This automatically prepends the build dir to the ISO output path - # if it doesn't start with a / - self.settings["iso"] = normpath(self.settings["storedir"] + \ - "/builds/" + self.settings["rel_type"] + "/" + \ - self.settings[self.settings["spec_prefix"]+"/iso"]) - del self.settings[self.settings["spec_prefix"]+"/iso"] - - def set_fstype(self): - if self.settings["spec_prefix"]+"/fstype" in self.settings: - self.settings["fstype"]=\ - self.settings[self.settings["spec_prefix"]+"/fstype"] - del self.settings[self.settings["spec_prefix"]+"/fstype"] - - if "fstype" not in self.settings: - self.settings["fstype"]="normal" - for x in self.valid_values: - if x == self.settings["spec_prefix"]+"/fstype": - print "\n"+self.settings["spec_prefix"]+\ - "/fstype is being set to the default of \"normal\"\n" - - def set_fsops(self): - if "fstype" in self.settings: - self.valid_values.append("fsops") - if self.settings["spec_prefix"]+"/fsops" in self.settings: - self.settings["fsops"]=\ - self.settings[self.settings["spec_prefix"]+"/fsops"] - del self.settings[self.settings["spec_prefix"]+"/fsops"] - - def set_source_path(self): - if "SEEDCACHE" in self.settings\ - and os.path.isdir(normpath(self.settings["storedir"]+"/tmp/"+\ - self.settings["source_subpath"]+"/")): - self.settings["source_path"]=normpath(self.settings["storedir"]+\ - "/tmp/"+self.settings["source_subpath"]+"/") - else: - self.settings["source_path"]=normpath(self.settings["storedir"]+\ - "/builds/"+self.settings["source_subpath"]+".tar.bz2") - if os.path.isfile(self.settings["source_path"]): - # XXX: Is this even necessary if the previous check passes? - if os.path.exists(self.settings["source_path"]): - self.settings["source_path_hash"]=\ - generate_hash(self.settings["source_path"],\ - hash_function=self.settings["hash_function"],\ - verbose=False) - print "Source path set to "+self.settings["source_path"] - if os.path.isdir(self.settings["source_path"]): - print "\tIf this is not desired, remove this directory or turn off" - print "\tseedcache in the options of catalyst.conf the source path" - print "\twill then be "+\ - normpath(self.settings["storedir"]+"/builds/"+\ - self.settings["source_subpath"]+".tar.bz2\n") - - def set_dest_path(self): - if "root_path" in self.settings: - self.settings["destpath"]=normpath(self.settings["chroot_path"]+\ - self.settings["root_path"]) - else: - self.settings["destpath"]=normpath(self.settings["chroot_path"]) - - def set_cleanables(self): - self.settings["cleanables"]=["/etc/resolv.conf","/var/tmp/*","/tmp/*",\ - "/root/*", self.settings["portdir"]] - - def set_snapshot_path(self): - self.settings["snapshot_path"]=normpath(self.settings["storedir"]+\ - "/snapshots/" + self.settings["snapshot_name"] + - self.settings["snapshot"]+".tar.xz") - - if os.path.exists(self.settings["snapshot_path"]): - self.settings["snapshot_path_hash"]=\ - generate_hash(self.settings["snapshot_path"],\ - hash_function=self.settings["hash_function"],verbose=False) - else: - self.settings["snapshot_path"]=normpath(self.settings["storedir"]+\ - "/snapshots/" + self.settings["snapshot_name"] + - self.settings["snapshot"]+".tar.bz2") - - if os.path.exists(self.settings["snapshot_path"]): - self.settings["snapshot_path_hash"]=\ - generate_hash(self.settings["snapshot_path"],\ - hash_function=self.settings["hash_function"],verbose=False) - - def set_snapcache_path(self): - if "SNAPCACHE" in self.settings: - self.settings["snapshot_cache_path"]=\ - normpath(self.settings["snapshot_cache"]+"/"+\ - self.settings["snapshot"]+"/") - self.snapcache_lock=\ - LockDir(self.settings["snapshot_cache_path"]) - print "Caching snapshot to "+self.settings["snapshot_cache_path"] - - def set_chroot_path(self): - """ - NOTE: the trailing slash is very important! - Things *will* break without it! - """ - self.settings["chroot_path"]=normpath(self.settings["storedir"]+\ - "/tmp/"+self.settings["target_subpath"]+"/") - self.chroot_lock=LockDir(self.settings["chroot_path"]) - - def set_autoresume_path(self): - self.settings["autoresume_path"]=normpath(self.settings["storedir"]+\ - "/tmp/"+self.settings["rel_type"]+"/"+".autoresume-"+\ - self.settings["target"]+"-"+self.settings["subarch"]+"-"+\ - self.settings["version_stamp"]+"/") - if "AUTORESUME" in self.settings: - print "The autoresume path is " + self.settings["autoresume_path"] - if not os.path.exists(self.settings["autoresume_path"]): - os.makedirs(self.settings["autoresume_path"],0755) - - def set_controller_file(self): - self.settings["controller_file"]=normpath(self.settings["sharedir"]+\ - "/targets/"+self.settings["target"]+"/"+self.settings["target"]+\ - "-controller.sh") - - def set_iso_volume_id(self): - if self.settings["spec_prefix"]+"/volid" in self.settings: - self.settings["iso_volume_id"]=\ - self.settings[self.settings["spec_prefix"]+"/volid"] - if len(self.settings["iso_volume_id"])>32: - raise CatalystError,\ - "ISO volume ID must not exceed 32 characters." - else: - self.settings["iso_volume_id"]="catalyst "+self.settings["snapshot"] - - def set_action_sequence(self): - """ Default action sequence for run method """ - self.settings["action_sequence"]=["unpack","unpack_snapshot",\ - "setup_confdir","portage_overlay",\ - "base_dirs","bind","chroot_setup","setup_environment",\ - "run_local","preclean","unbind","clean"] -# if "TARBALL" in self.settings or \ -# "FETCH" not in self.settings: - if "FETCH" not in self.settings: - self.settings["action_sequence"].append("capture") - self.settings["action_sequence"].append("clear_autoresume") - - def set_use(self): - if self.settings["spec_prefix"]+"/use" in self.settings: - self.settings["use"]=\ - self.settings[self.settings["spec_prefix"]+"/use"] - del self.settings[self.settings["spec_prefix"]+"/use"] - if "use" not in self.settings: - self.settings["use"]="" - if type(self.settings["use"])==types.StringType: - self.settings["use"]=self.settings["use"].split() - - # Force bindist when options ask for it - if "BINDIST" in self.settings: - self.settings["use"].append("bindist") - - def set_stage_path(self): - self.settings["stage_path"]=normpath(self.settings["chroot_path"]) - - def set_mounts(self): - pass - - def set_packages(self): - pass - - def set_rm(self): - if self.settings["spec_prefix"]+"/rm" in self.settings: - if type(self.settings[self.settings["spec_prefix"]+\ - "/rm"])==types.StringType: - self.settings[self.settings["spec_prefix"]+"/rm"]=\ - self.settings[self.settings["spec_prefix"]+"/rm"].split() - - def set_linuxrc(self): - if self.settings["spec_prefix"]+"/linuxrc" in self.settings: - if type(self.settings[self.settings["spec_prefix"]+\ - "/linuxrc"])==types.StringType: - self.settings["linuxrc"]=\ - self.settings[self.settings["spec_prefix"]+"/linuxrc"] - del self.settings[self.settings["spec_prefix"]+"/linuxrc"] - - def set_busybox_config(self): - if self.settings["spec_prefix"]+"/busybox_config" in self.settings: - if type(self.settings[self.settings["spec_prefix"]+\ - "/busybox_config"])==types.StringType: - self.settings["busybox_config"]=\ - self.settings[self.settings["spec_prefix"]+"/busybox_config"] - del self.settings[self.settings["spec_prefix"]+"/busybox_config"] - - def set_portage_overlay(self): - if "portage_overlay" in self.settings: - if type(self.settings["portage_overlay"])==types.StringType: - self.settings["portage_overlay"]=\ - self.settings["portage_overlay"].split() - print "portage_overlay directories are set to: \""+\ - string.join(self.settings["portage_overlay"])+"\"" - - def set_overlay(self): - if self.settings["spec_prefix"]+"/overlay" in self.settings: - if type(self.settings[self.settings["spec_prefix"]+\ - "/overlay"])==types.StringType: - self.settings[self.settings["spec_prefix"]+"/overlay"]=\ - self.settings[self.settings["spec_prefix"]+\ - "/overlay"].split() - - def set_root_overlay(self): - if self.settings["spec_prefix"]+"/root_overlay" in self.settings: - if type(self.settings[self.settings["spec_prefix"]+\ - "/root_overlay"])==types.StringType: - self.settings[self.settings["spec_prefix"]+"/root_overlay"]=\ - self.settings[self.settings["spec_prefix"]+\ - "/root_overlay"].split() - - def set_root_path(self): - """ ROOT= variable for emerges """ - self.settings["root_path"]="/" - - def set_valid_build_kernel_vars(self,addlargs): - if "boot/kernel" in addlargs: - if type(addlargs["boot/kernel"])==types.StringType: - loopy=[addlargs["boot/kernel"]] - else: - loopy=addlargs["boot/kernel"] - - for x in loopy: - self.valid_values.append("boot/kernel/"+x+"/aliases") - self.valid_values.append("boot/kernel/"+x+"/config") - self.valid_values.append("boot/kernel/"+x+"/console") - self.valid_values.append("boot/kernel/"+x+"/extraversion") - self.valid_values.append("boot/kernel/"+x+"/gk_action") - self.valid_values.append("boot/kernel/"+x+"/gk_kernargs") - self.valid_values.append("boot/kernel/"+x+"/initramfs_overlay") - self.valid_values.append("boot/kernel/"+x+"/machine_type") - self.valid_values.append("boot/kernel/"+x+"/sources") - self.valid_values.append("boot/kernel/"+x+"/softlevel") - self.valid_values.append("boot/kernel/"+x+"/use") - self.valid_values.append("boot/kernel/"+x+"/packages") - if "boot/kernel/"+x+"/packages" in addlargs: - if type(addlargs["boot/kernel/"+x+\ - "/packages"])==types.StringType: - addlargs["boot/kernel/"+x+"/packages"]=\ - [addlargs["boot/kernel/"+x+"/packages"]] - - def set_build_kernel_vars(self): - if self.settings["spec_prefix"]+"/gk_mainargs" in self.settings: - self.settings["gk_mainargs"]=\ - self.settings[self.settings["spec_prefix"]+"/gk_mainargs"] - del self.settings[self.settings["spec_prefix"]+"/gk_mainargs"] - - def kill_chroot_pids(self): - print "Checking for processes running in chroot and killing them." - - """ - Force environment variables to be exported so script can see them - """ - self.setup_environment() - - if os.path.exists(self.settings["sharedir"]+\ - "/targets/support/kill-chroot-pids.sh"): - cmd("/bin/bash "+self.settings["sharedir"]+\ - "/targets/support/kill-chroot-pids.sh",\ - "kill-chroot-pids script failed.",env=self.env) - - def mount_safety_check(self): - mypath=self.settings["chroot_path"] - - """ - Check and verify that none of our paths in mypath are mounted. We don't - want to clean up with things still mounted, and this allows us to check. - Returns 1 on ok, 0 on "something is still mounted" case. - """ - - if not os.path.exists(mypath): - return - - for x in self.mounts: - if not os.path.exists(mypath + self.mountmap[x]): - continue - - if ismount(mypath +self.mountmap[x]): - """ Something is still mounted "" """ - try: - print self.mountmap[x] + " is still mounted; performing auto-bind-umount...", - """ Try to umount stuff ourselves """ - self.unbind() - if ismount(mypath + self.mountmap[x]): - raise CatalystError, "Auto-unbind failed for " + self.mountmap[x] - else: - print "Auto-unbind successful..." - except CatalystError: - raise CatalystError, "Unable to auto-unbind " + self.mountmap[x] - - def unpack(self): - unpack=True - - clst_unpack_hash=read_from_clst(self.settings["autoresume_path"]+\ - "unpack") - - if "SEEDCACHE" in self.settings: - if os.path.isdir(self.settings["source_path"]): - """ SEEDCACHE Is a directory, use rsync """ - unpack_cmd="rsync -a --delete "+self.settings["source_path"]+\ - " "+self.settings["chroot_path"] - display_msg="\nStarting rsync from "+\ - self.settings["source_path"]+"\nto "+\ - self.settings["chroot_path"]+\ - " (This may take some time) ...\n" - error_msg="Rsync of "+self.settings["source_path"]+" to "+\ - self.settings["chroot_path"]+" failed." - else: - """ SEEDCACHE is a not a directory, try untar'ing """ - print "Referenced SEEDCACHE does not appear to be a directory, trying to untar..." - display_msg="\nStarting tar extract from "+\ - self.settings["source_path"]+"\nto "+\ - self.settings["chroot_path"]+\ - " (This may take some time) ...\n" - if "bz2" == self.settings["chroot_path"][-3:]: - unpack_cmd="tar -I lbzip2 -xpf "+self.settings["source_path"]+" -C "+\ - self.settings["chroot_path"] - else: - unpack_cmd="tar -I lbzip2 -xpf "+self.settings["source_path"]+" -C "+\ - self.settings["chroot_path"] - error_msg="Tarball extraction of "+\ - self.settings["source_path"]+" to "+\ - self.settings["chroot_path"]+" failed." - else: - """ No SEEDCACHE, use tar """ - display_msg="\nStarting tar extract from "+\ - self.settings["source_path"]+"\nto "+\ - self.settings["chroot_path"]+\ - " (This may take some time) ...\n" - if "bz2" == self.settings["chroot_path"][-3:]: - unpack_cmd="tar -I lbzip2 -xpf "+self.settings["source_path"]+" -C "+\ - self.settings["chroot_path"] - else: - unpack_cmd="tar -I lbzip2 -xpf "+self.settings["source_path"]+" -C "+\ - self.settings["chroot_path"] - error_msg="Tarball extraction of "+self.settings["source_path"]+\ - " to "+self.settings["chroot_path"]+" failed." - - if "AUTORESUME" in self.settings: - if os.path.isdir(self.settings["source_path"]) \ - and os.path.exists(self.settings["autoresume_path"]+"unpack"): - """ Autoresume is valid, SEEDCACHE is valid """ - unpack=False - invalid_snapshot=False - - elif os.path.isfile(self.settings["source_path"]) \ - and self.settings["source_path_hash"]==clst_unpack_hash: - """ Autoresume is valid, tarball is valid """ - unpack=False - invalid_snapshot=True - - elif os.path.isdir(self.settings["source_path"]) \ - and not os.path.exists(self.settings["autoresume_path"]+\ - "unpack"): - """ Autoresume is invalid, SEEDCACHE """ - unpack=True - invalid_snapshot=False - - elif os.path.isfile(self.settings["source_path"]) \ - and self.settings["source_path_hash"]!=clst_unpack_hash: - """ Autoresume is invalid, tarball """ - unpack=True - invalid_snapshot=True - else: - """ No autoresume, SEEDCACHE """ - if "SEEDCACHE" in self.settings: - """ SEEDCACHE so let's run rsync and let it clean up """ - if os.path.isdir(self.settings["source_path"]): - unpack=True - invalid_snapshot=False - elif os.path.isfile(self.settings["source_path"]): - """ Tarball so unpack and remove anything already there """ - unpack=True - invalid_snapshot=True - """ No autoresume, no SEEDCACHE """ - else: - """ Tarball so unpack and remove anything already there """ - if os.path.isfile(self.settings["source_path"]): - unpack=True - invalid_snapshot=True - elif os.path.isdir(self.settings["source_path"]): - """ We should never reach this, so something is very wrong """ - raise CatalystError,\ - "source path is a dir but seedcache is not enabled" - - if unpack: - self.mount_safety_check() - - if invalid_snapshot: - if "AUTORESUME" in self.settings: - print "No Valid Resume point detected, cleaning up..." - - self.clear_autoresume() - self.clear_chroot() - - if not os.path.exists(self.settings["chroot_path"]): - os.makedirs(self.settings["chroot_path"]) - - if not os.path.exists(self.settings["chroot_path"]+"/tmp"): - os.makedirs(self.settings["chroot_path"]+"/tmp",1777) - - if "PKGCACHE" in self.settings: - if not os.path.exists(self.settings["pkgcache_path"]): - os.makedirs(self.settings["pkgcache_path"],0755) - - if "KERNCACHE" in self.settings: - if not os.path.exists(self.settings["kerncache_path"]): - os.makedirs(self.settings["kerncache_path"],0755) - - print display_msg - cmd(unpack_cmd,error_msg,env=self.env) - - if "source_path_hash" in self.settings: - myf=open(self.settings["autoresume_path"]+"unpack","w") - myf.write(self.settings["source_path_hash"]) - myf.close() - else: - touch(self.settings["autoresume_path"]+"unpack") - else: - print "Resume point detected, skipping unpack operation..." - - def unpack_snapshot(self): - unpack=True - snapshot_hash=read_from_clst(self.settings["autoresume_path"]+\ - "unpack_portage") - - if "SNAPCACHE" in self.settings: - snapshot_cache_hash=\ - read_from_clst(self.settings["snapshot_cache_path"]+\ - "catalyst-hash") - destdir=self.settings["snapshot_cache_path"] - if "bz2" == self.settings["chroot_path"][-3:]: - unpack_cmd="tar -I lbzip2 -xpf "+self.settings["snapshot_path"]+" -C "+destdir - else: - unpack_cmd="tar xpf "+self.settings["snapshot_path"]+" -C "+destdir - unpack_errmsg="Error unpacking snapshot" - cleanup_msg="Cleaning up invalid snapshot cache at \n\t"+\ - self.settings["snapshot_cache_path"]+\ - " (This can take a long time)..." - cleanup_errmsg="Error removing existing snapshot cache directory." - self.snapshot_lock_object=self.snapcache_lock - - if self.settings["snapshot_path_hash"]==snapshot_cache_hash: - print "Valid snapshot cache, skipping unpack of portage tree..." - unpack=False - else: - destdir=normpath(self.settings["chroot_path"] + self.settings["portdir"]) - cleanup_errmsg="Error removing existing snapshot directory." - cleanup_msg=\ - "Cleaning up existing portage tree (This can take a long time)..." - if "bz2" == self.settings["chroot_path"][-3:]: - unpack_cmd="tar -I lbzip2 -xpf "+self.settings["snapshot_path"]+" -C "+\ - self.settings["chroot_path"]+"/usr" - else: - unpack_cmd="tar xpf "+self.settings["snapshot_path"]+" -C "+\ - self.settings["chroot_path"]+"/usr" - unpack_errmsg="Error unpacking snapshot" - - if "AUTORESUME" in self.settings \ - and os.path.exists(self.settings["chroot_path"]+\ - self.settings["portdir"]) \ - and os.path.exists(self.settings["autoresume_path"]\ - +"unpack_portage") \ - and self.settings["snapshot_path_hash"] == snapshot_hash: - print \ - "Valid Resume point detected, skipping unpack of portage tree..." - unpack=False - - if unpack: - if "SNAPCACHE" in self.settings: - self.snapshot_lock_object.write_lock() - if os.path.exists(destdir): - print cleanup_msg - cleanup_cmd="rm -rf "+destdir - cmd(cleanup_cmd,cleanup_errmsg,env=self.env) - if not os.path.exists(destdir): - os.makedirs(destdir,0755) - - print "Unpacking portage tree (This can take a long time) ..." - cmd(unpack_cmd,unpack_errmsg,env=self.env) - - if "SNAPCACHE" in self.settings: - myf=open(self.settings["snapshot_cache_path"]+"catalyst-hash","w") - myf.write(self.settings["snapshot_path_hash"]) - myf.close() - else: - print "Setting snapshot autoresume point" - myf=open(self.settings["autoresume_path"]+"unpack_portage","w") - myf.write(self.settings["snapshot_path_hash"]) - myf.close() - - if "SNAPCACHE" in self.settings: - self.snapshot_lock_object.unlock() - - def config_profile_link(self): - if "AUTORESUME" in self.settings \ - and os.path.exists(self.settings["autoresume_path"]+\ - "config_profile_link"): - print \ - "Resume point detected, skipping config_profile_link operation..." - else: - # TODO: zmedico and I discussed making this a directory and pushing - # in a parent file, as well as other user-specified configuration. - print "Configuring profile link..." - cmd("rm -f "+self.settings["chroot_path"]+"/etc/portage/make.profile",\ - "Error zapping profile link",env=self.env) - cmd("mkdir -p "+self.settings["chroot_path"]+"/etc/portage/") - cmd("ln -sf ../.." + self.settings["portdir"] + "/profiles/"+\ - self.settings["target_profile"]+" "+\ - self.settings["chroot_path"]+"/etc/portage/make.profile",\ - "Error creating profile link",env=self.env) - touch(self.settings["autoresume_path"]+"config_profile_link") - - def setup_confdir(self): - if "AUTORESUME" in self.settings \ - and os.path.exists(self.settings["autoresume_path"]+\ - "setup_confdir"): - print "Resume point detected, skipping setup_confdir operation..." - else: - if "portage_confdir" in self.settings: - print "Configuring /etc/portage..." - cmd("rsync -a "+self.settings["portage_confdir"]+"/ "+\ - self.settings["chroot_path"]+"/etc/portage/",\ - "Error copying /etc/portage",env=self.env) - touch(self.settings["autoresume_path"]+"setup_confdir") - - def portage_overlay(self): - """ We copy the contents of our overlays to /usr/local/portage """ - if "portage_overlay" in self.settings: - for x in self.settings["portage_overlay"]: - if os.path.exists(x): - print "Copying overlay dir " +x - cmd("mkdir -p "+self.settings["chroot_path"]+\ - self.settings["local_overlay"],\ - "Could not make portage_overlay dir",env=self.env) - cmd("cp -R "+x+"/* "+self.settings["chroot_path"]+\ - self.settings["local_overlay"],\ - "Could not copy portage_overlay",env=self.env) - - def root_overlay(self): - """ Copy over the root_overlay """ - if self.settings["spec_prefix"]+"/root_overlay" in self.settings: - for x in self.settings[self.settings["spec_prefix"]+\ - "/root_overlay"]: - if os.path.exists(x): - print "Copying root_overlay: "+x - cmd("rsync -a "+x+"/ "+\ - self.settings["chroot_path"],\ - self.settings["spec_prefix"]+"/root_overlay: "+x+\ - " copy failed.",env=self.env) - - def base_dirs(self): - pass - - def bind(self): - for x in self.mounts: - if not os.path.exists(self.settings["chroot_path"] + self.mountmap[x]): - os.makedirs(self.settings["chroot_path"]+x,0755) - - if not os.path.exists(self.mountmap[x]): - if not self.mountmap[x] == "tmpfs": - os.makedirs(self.mountmap[x],0755) - - src=self.mountmap[x] - if "SNAPCACHE" in self.settings and x == "/usr/portage": - self.snapshot_lock_object.read_lock() - if os.uname()[0] == "FreeBSD": - if src == "/dev": - retval=os.system("mount -t devfs none " + - self.settings["chroot_path"] + src) - else: - retval=os.system("mount_nullfs " + src + " " + - self.settings["chroot_path"] + src) - else: - if src == "tmpfs": - if "var_tmpfs_portage" in self.settings: - retval=os.system("mount -t tmpfs -o size="+\ - self.settings["var_tmpfs_portage"]+"G "+src+" "+\ - self.settings["chroot_path"]+x) - else: - retval=os.system("mount --bind " + src + " " + - self.settings["chroot_path"] + src) - if retval!=0: - self.unbind() - raise CatalystError,"Couldn't bind mount " + src - - def unbind(self): - ouch=0 - mypath=self.settings["chroot_path"] - myrevmounts=self.mounts[:] - myrevmounts.reverse() - """ Unmount in reverse order for nested bind-mounts """ - for x in myrevmounts: - if not os.path.exists(mypath + self.mountmap[x]): - continue - - if not ismount(mypath + self.mountmap[x]): - continue - - retval=os.system("umount "+\ - os.path.join(mypath, self.mountmap[x].lstrip(os.path.sep))) - - if retval!=0: - warn("First attempt to unmount: " + mypath + - self.mountmap[x] +" failed.") - warn("Killing any pids still running in the chroot") - - self.kill_chroot_pids() - - retval2=os.system("umount " + mypath + self.mountmap[x]) - if retval2!=0: - ouch=1 - warn("Couldn't umount bind mount: " + mypath + self.mountmap[x]) - - if "SNAPCACHE" in self.settings and x == "/usr/portage": - try: - """ - It's possible the snapshot lock object isn't created yet. - This is because mount safety check calls unbind before the - target is fully initialized - """ - self.snapshot_lock_object.unlock() - except: - pass - if ouch: - """ - if any bind mounts really failed, then we need to raise - this to potentially prevent an upcoming bash stage cleanup script - from wiping our bind mounts. - """ - raise CatalystError,\ - "Couldn't umount one or more bind-mounts; aborting for safety." - - def chroot_setup(self): - self.makeconf=read_makeconf(self.settings["chroot_path"]+\ - "/etc/portage/make.conf") - self.override_cbuild() - self.override_chost() - self.override_cflags() - self.override_cxxflags() - self.override_ldflags() - if "AUTORESUME" in self.settings \ - and os.path.exists(self.settings["autoresume_path"]+"chroot_setup"): - print "Resume point detected, skipping chroot_setup operation..." - else: - print "Setting up chroot..." - - #self.makeconf=read_makeconf(self.settings["chroot_path"]+"/etc/portage/make.conf") - - cmd("cp /etc/resolv.conf "+self.settings["chroot_path"]+"/etc",\ - "Could not copy resolv.conf into place.",env=self.env) - - """ Copy over the envscript, if applicable """ - if "ENVSCRIPT" in self.settings: - if not os.path.exists(self.settings["ENVSCRIPT"]): - raise CatalystError,\ - "Can't find envscript "+self.settings["ENVSCRIPT"] - - print "\nWarning!!!!" - print "\tOverriding certain env variables may cause catastrophic failure." - print "\tIf your build fails look here first as the possible problem." - print "\tCatalyst assumes you know what you are doing when setting" - print "\t\tthese variables." - print "\tCatalyst Maintainers use VERY minimal envscripts if used at all" - print "\tYou have been warned\n" - - cmd("cp "+self.settings["ENVSCRIPT"]+" "+\ - self.settings["chroot_path"]+"/tmp/envscript",\ - "Could not copy envscript into place.",env=self.env) - - """ - Copy over /etc/hosts from the host in case there are any - specialties in there - """ - if os.path.exists(self.settings["chroot_path"]+"/etc/hosts"): - cmd("mv "+self.settings["chroot_path"]+"/etc/hosts "+\ - self.settings["chroot_path"]+"/etc/hosts.catalyst",\ - "Could not backup /etc/hosts",env=self.env) - cmd("cp /etc/hosts "+self.settings["chroot_path"]+"/etc/hosts",\ - "Could not copy /etc/hosts",env=self.env) - - """ Modify and write out make.conf (for the chroot) """ - cmd("rm -f "+self.settings["chroot_path"]+"/etc/portage/make.conf",\ - "Could not remove "+self.settings["chroot_path"]+\ - "/etc/portage/make.conf",env=self.env) - myf=open(self.settings["chroot_path"]+"/etc/portage/make.conf","w") - myf.write("# These settings were set by the catalyst build script that automatically\n# built this stage.\n") - myf.write("# Please consult /usr/share/portage/config/make.conf.example for a more\n# detailed example.\n") - if "CFLAGS" in self.settings: - myf.write('CFLAGS="'+self.settings["CFLAGS"]+'"\n') - if "CXXFLAGS" in self.settings: - if self.settings["CXXFLAGS"]!=self.settings["CFLAGS"]: - myf.write('CXXFLAGS="'+self.settings["CXXFLAGS"]+'"\n') - else: - myf.write('CXXFLAGS="${CFLAGS}"\n') - else: - myf.write('CXXFLAGS="${CFLAGS}"\n') - - if "LDFLAGS" in self.settings: - myf.write("# LDFLAGS is unsupported. USE AT YOUR OWN RISK!\n") - myf.write('LDFLAGS="'+self.settings["LDFLAGS"]+'"\n') - if "CBUILD" in self.settings: - myf.write("# This should not be changed unless you know exactly what you are doing. You\n# should probably be using a different stage, instead.\n") - myf.write('CBUILD="'+self.settings["CBUILD"]+'"\n') - - myf.write("# WARNING: Changing your CHOST is not something that should be done lightly.\n# Please consult http://www.gentoo.org/doc/en/change-chost.xml before changing.\n") - myf.write('CHOST="'+self.settings["CHOST"]+'"\n') - - """ Figure out what our USE vars are for building """ - myusevars=[] - if "HOSTUSE" in self.settings: - myusevars.extend(self.settings["HOSTUSE"]) - - if "use" in self.settings: - myusevars.extend(self.settings["use"]) - - if myusevars: - myf.write("# These are the USE flags that were used in addition to what is provided by the\n# profile used for building.\n") - myusevars = sorted(set(myusevars)) - myf.write('USE="'+string.join(myusevars)+'"\n') - if '-*' in myusevars: - print "\nWarning!!! " - print "\tThe use of -* in "+self.settings["spec_prefix"]+\ - "/use will cause portage to ignore" - print "\tpackage.use in the profile and portage_confdir. You've been warned!" - - myf.write('PORTDIR="%s"\n' % self.settings['portdir']) - myf.write('DISTDIR="%s"\n' % self.settings['distdir']) - myf.write('PKGDIR="%s"\n' % self.settings['packagedir']) - - """ Setup the portage overlay """ - if "portage_overlay" in self.settings: - myf.write('PORTDIR_OVERLAY="/usr/local/portage"\n') - - myf.close() - cmd("cp "+self.settings["chroot_path"]+"/etc/portage/make.conf "+\ - self.settings["chroot_path"]+"/etc/portage/make.conf.catalyst",\ - "Could not backup /etc/portage/make.conf",env=self.env) - touch(self.settings["autoresume_path"]+"chroot_setup") - - def fsscript(self): - if "AUTORESUME" in self.settings \ - and os.path.exists(self.settings["autoresume_path"]+"fsscript"): - print "Resume point detected, skipping fsscript operation..." - else: - if "fsscript" in self.settings: - if os.path.exists(self.settings["controller_file"]): - cmd("/bin/bash "+self.settings["controller_file"]+\ - " fsscript","fsscript script failed.",env=self.env) - touch(self.settings["autoresume_path"]+"fsscript") - - def rcupdate(self): - if "AUTORESUME" in self.settings \ - and os.path.exists(self.settings["autoresume_path"]+"rcupdate"): - print "Resume point detected, skipping rcupdate operation..." - else: - if os.path.exists(self.settings["controller_file"]): - cmd("/bin/bash "+self.settings["controller_file"]+" rc-update",\ - "rc-update script failed.",env=self.env) - touch(self.settings["autoresume_path"]+"rcupdate") - - def clean(self): - if "AUTORESUME" in self.settings \ - and os.path.exists(self.settings["autoresume_path"]+"clean"): - print "Resume point detected, skipping clean operation..." - else: - for x in self.settings["cleanables"]: - print "Cleaning chroot: "+x+"... " - cmd("rm -rf "+self.settings["destpath"]+x,"Couldn't clean "+\ - x,env=self.env) - - """ Put /etc/hosts back into place """ - if os.path.exists(self.settings["chroot_path"]+"/etc/hosts.catalyst"): - cmd("mv -f "+self.settings["chroot_path"]+"/etc/hosts.catalyst "+\ - self.settings["chroot_path"]+"/etc/hosts",\ - "Could not replace /etc/hosts",env=self.env) - - """ Remove our overlay """ - if os.path.exists(self.settings["chroot_path"] + self.settings["local_overlay"]): - cmd("rm -rf " + self.settings["chroot_path"] + self.settings["local_overlay"], - "Could not remove " + self.settings["local_overlay"], env=self.env) - cmd("sed -i '/^PORTDIR_OVERLAY/d' "+self.settings["chroot_path"]+\ - "/etc/portage/make.conf",\ - "Could not remove PORTDIR_OVERLAY from make.conf",env=self.env) - - """ Clean up old and obsoleted files in /etc """ - if os.path.exists(self.settings["stage_path"]+"/etc"): - cmd("find "+self.settings["stage_path"]+\ - "/etc -maxdepth 1 -name \"*-\" | xargs rm -f",\ - "Could not remove stray files in /etc",env=self.env) - - if os.path.exists(self.settings["controller_file"]): - cmd("/bin/bash "+self.settings["controller_file"]+" clean",\ - "clean script failed.",env=self.env) - touch(self.settings["autoresume_path"]+"clean") - - def empty(self): - if "AUTORESUME" in self.settings \ - and os.path.exists(self.settings["autoresume_path"]+"empty"): - print "Resume point detected, skipping empty operation..." - else: - if self.settings["spec_prefix"]+"/empty" in self.settings: - if type(self.settings[self.settings["spec_prefix"]+\ - "/empty"])==types.StringType: - self.settings[self.settings["spec_prefix"]+"/empty"]=\ - self.settings[self.settings["spec_prefix"]+\ - "/empty"].split() - for x in self.settings[self.settings["spec_prefix"]+"/empty"]: - myemp=self.settings["destpath"]+x - if not os.path.isdir(myemp) or os.path.islink(myemp): - print x,"not a directory or does not exist, skipping 'empty' operation." - continue - print "Emptying directory",x - """ - stat the dir, delete the dir, recreate the dir and set - the proper perms and ownership - """ - mystat=os.stat(myemp) - shutil.rmtree(myemp) - os.makedirs(myemp,0755) - os.chown(myemp,mystat[ST_UID],mystat[ST_GID]) - os.chmod(myemp,mystat[ST_MODE]) - touch(self.settings["autoresume_path"]+"empty") - - def remove(self): - if "AUTORESUME" in self.settings \ - and os.path.exists(self.settings["autoresume_path"]+"remove"): - print "Resume point detected, skipping remove operation..." - else: - if self.settings["spec_prefix"]+"/rm" in self.settings: - for x in self.settings[self.settings["spec_prefix"]+"/rm"]: - """ - We're going to shell out for all these cleaning - operations, so we get easy glob handling. - """ - print "livecd: removing "+x - os.system("rm -rf "+self.settings["chroot_path"]+x) - try: - if os.path.exists(self.settings["controller_file"]): - cmd("/bin/bash "+self.settings["controller_file"]+\ - " clean","Clean failed.",env=self.env) - touch(self.settings["autoresume_path"]+"remove") - except: - self.unbind() - raise - - def preclean(self): - if "AUTORESUME" in self.settings \ - and os.path.exists(self.settings["autoresume_path"]+"preclean"): - print "Resume point detected, skipping preclean operation..." - else: - try: - if os.path.exists(self.settings["controller_file"]): - cmd("/bin/bash "+self.settings["controller_file"]+\ - " preclean","preclean script failed.",env=self.env) - touch(self.settings["autoresume_path"]+"preclean") - - except: - self.unbind() - raise CatalystError, "Build failed, could not execute preclean" - - def capture(self): - if "AUTORESUME" in self.settings \ - and os.path.exists(self.settings["autoresume_path"]+"capture"): - print "Resume point detected, skipping capture operation..." - else: - """ Capture target in a tarball """ - mypath=self.settings["target_path"].split("/") - """ Remove filename from path """ - mypath=string.join(mypath[:-1],"/") - - """ Now make sure path exists """ - if not os.path.exists(mypath): - os.makedirs(mypath) - - print "Creating stage tarball..." - - cmd("tar -I lbzip2 -cpf "+self.settings["target_path"]+" -C "+\ - self.settings["stage_path"]+" .",\ - "Couldn't create stage tarball",env=self.env) - - self.gen_contents_file(self.settings["target_path"]) - self.gen_digest_file(self.settings["target_path"]) - - touch(self.settings["autoresume_path"]+"capture") - - def run_local(self): - if "AUTORESUME" in self.settings \ - and os.path.exists(self.settings["autoresume_path"]+"run_local"): - print "Resume point detected, skipping run_local operation..." - else: - try: - if os.path.exists(self.settings["controller_file"]): - cmd("/bin/bash "+self.settings["controller_file"]+" run",\ - "run script failed.",env=self.env) - touch(self.settings["autoresume_path"]+"run_local") - - except CatalystError: - self.unbind() - raise CatalystError,"Stage build aborting due to error." - - def setup_environment(self): - """ - Modify the current environment. This is an ugly hack that should be - fixed. We need this to use the os.system() call since we can't - specify our own environ - """ - for x in self.settings.keys(): - """ Sanitize var names by doing "s|/-.|_|g" """ - varname="clst_"+string.replace(x,"/","_") - varname=string.replace(varname,"-","_") - varname=string.replace(varname,".","_") - if type(self.settings[x])==types.StringType: - """ Prefix to prevent namespace clashes """ - #os.environ[varname]=self.settings[x] - self.env[varname]=self.settings[x] - elif type(self.settings[x])==types.ListType: - #os.environ[varname]=string.join(self.settings[x]) - self.env[varname]=string.join(self.settings[x]) - elif type(self.settings[x])==types.BooleanType: - if self.settings[x]: - self.env[varname]="true" - else: - self.env[varname]="false" - if "makeopts" in self.settings: - self.env["MAKEOPTS"]=self.settings["makeopts"] - - def run(self): - self.chroot_lock.write_lock() - - """ Kill any pids in the chroot "" """ - self.kill_chroot_pids() - - """ Check for mounts right away and abort if we cannot unmount them """ - self.mount_safety_check() - - if "CLEAR_AUTORESUME" in self.settings: - self.clear_autoresume() - - if "PURGETMPONLY" in self.settings: - self.purge() - return - - if "PURGEONLY" in self.settings: - self.purge() - return - - if "PURGE" in self.settings: - self.purge() - - for x in self.settings["action_sequence"]: - print "--- Running action sequence: "+x - sys.stdout.flush() - try: - apply(getattr(self,x)) - except: - self.mount_safety_check() - raise - - self.chroot_lock.unlock() - - def unmerge(self): - if "AUTORESUME" in self.settings \ - and os.path.exists(self.settings["autoresume_path"]+"unmerge"): - print "Resume point detected, skipping unmerge operation..." - else: - if self.settings["spec_prefix"]+"/unmerge" in self.settings: - if type(self.settings[self.settings["spec_prefix"]+\ - "/unmerge"])==types.StringType: - self.settings[self.settings["spec_prefix"]+"/unmerge"]=\ - [self.settings[self.settings["spec_prefix"]+"/unmerge"]] - myunmerge=\ - self.settings[self.settings["spec_prefix"]+"/unmerge"][:] - - for x in range(0,len(myunmerge)): - """ - Surround args with quotes for passing to bash, allows - things like "<" to remain intact - """ - myunmerge[x]="'"+myunmerge[x]+"'" - myunmerge=string.join(myunmerge) - - """ Before cleaning, unmerge stuff """ - try: - cmd("/bin/bash "+self.settings["controller_file"]+\ - " unmerge "+ myunmerge,"Unmerge script failed.",\ - env=self.env) - print "unmerge shell script" - except CatalystError: - self.unbind() - raise - touch(self.settings["autoresume_path"]+"unmerge") - - def target_setup(self): - if "AUTORESUME" in self.settings \ - and os.path.exists(self.settings["autoresume_path"]+"target_setup"): - print "Resume point detected, skipping target_setup operation..." - else: - print "Setting up filesystems per filesystem type" - cmd("/bin/bash "+self.settings["controller_file"]+\ - " target_image_setup "+ self.settings["target_path"],\ - "target_image_setup script failed.",env=self.env) - touch(self.settings["autoresume_path"]+"target_setup") - - def setup_overlay(self): - if "AUTORESUME" in self.settings \ - and os.path.exists(self.settings["autoresume_path"]+"setup_overlay"): - print "Resume point detected, skipping setup_overlay operation..." - else: - if self.settings["spec_prefix"]+"/overlay" in self.settings: - for x in self.settings[self.settings["spec_prefix"]+"/overlay"]: - if os.path.exists(x): - cmd("rsync -a "+x+"/ "+\ - self.settings["target_path"],\ - self.settings["spec_prefix"]+"overlay: "+x+\ - " copy failed.",env=self.env) - touch(self.settings["autoresume_path"]+"setup_overlay") - - def create_iso(self): - if "AUTORESUME" in self.settings \ - and os.path.exists(self.settings["autoresume_path"]+"create_iso"): - print "Resume point detected, skipping create_iso operation..." - else: - """ Create the ISO """ - if "iso" in self.settings: - cmd("/bin/bash "+self.settings["controller_file"]+" iso "+\ - self.settings["iso"],"ISO creation script failed.",\ - env=self.env) - self.gen_contents_file(self.settings["iso"]) - self.gen_digest_file(self.settings["iso"]) - touch(self.settings["autoresume_path"]+"create_iso") - else: - print "WARNING: livecd/iso was not defined." - print "An ISO Image will not be created." - - def build_packages(self): - if "AUTORESUME" in self.settings \ - and os.path.exists(self.settings["autoresume_path"]+\ - "build_packages"): - print "Resume point detected, skipping build_packages operation..." - else: - if self.settings["spec_prefix"]+"/packages" in self.settings: - if "AUTORESUME" in self.settings \ - and os.path.exists(self.settings["autoresume_path"]+\ - "build_packages"): - print "Resume point detected, skipping build_packages operation..." - else: - mypack=\ - list_bashify(self.settings[self.settings["spec_prefix"]\ - +"/packages"]) - try: - cmd("/bin/bash "+self.settings["controller_file"]+\ - " build_packages "+mypack,\ - "Error in attempt to build packages",env=self.env) - touch(self.settings["autoresume_path"]+"build_packages") - except CatalystError: - self.unbind() - raise CatalystError,self.settings["spec_prefix"]+\ - "build aborting due to error." - - def build_kernel(self): - "Build all configured kernels" - if "AUTORESUME" in self.settings \ - and os.path.exists(self.settings["autoresume_path"]+"build_kernel"): - print "Resume point detected, skipping build_kernel operation..." - else: - if "boot/kernel" in self.settings: - try: - mynames=self.settings["boot/kernel"] - if type(mynames)==types.StringType: - mynames=[mynames] - """ - Execute the script that sets up the kernel build environment - """ - cmd("/bin/bash "+self.settings["controller_file"]+\ - " pre-kmerge ","Runscript pre-kmerge failed",\ - env=self.env) - for kname in mynames: - self._build_kernel(kname=kname) - touch(self.settings["autoresume_path"]+"build_kernel") - except CatalystError: - self.unbind() - raise CatalystError,\ - "build aborting due to kernel build error." - - def _build_kernel(self, kname): - "Build a single configured kernel by name" - if "AUTORESUME" in self.settings \ - and os.path.exists(self.settings["autoresume_path"]\ - +"build_kernel_"+kname): - print "Resume point detected, skipping build_kernel for "+kname+" operation..." - return - self._copy_kernel_config(kname=kname) - - """ - If we need to pass special options to the bootloader - for this kernel put them into the environment - """ - if "boot/kernel/"+kname+"/kernelopts" in self.settings: - myopts=self.settings["boot/kernel/"+kname+\ - "/kernelopts"] - - if type(myopts) != types.StringType: - myopts = string.join(myopts) - self.env[kname+"_kernelopts"]=myopts - - else: - self.env[kname+"_kernelopts"]="" - - if "boot/kernel/"+kname+"/extraversion" not in self.settings: - self.settings["boot/kernel/"+kname+\ - "/extraversion"]="" - - self.env["clst_kextraversion"]=\ - self.settings["boot/kernel/"+kname+\ - "/extraversion"] - - self._copy_initramfs_overlay(kname=kname) - - """ Execute the script that builds the kernel """ - cmd("/bin/bash "+self.settings["controller_file"]+\ - " kernel "+kname,\ - "Runscript kernel build failed",env=self.env) - - if "boot/kernel/"+kname+"/initramfs_overlay" in self.settings: - if os.path.exists(self.settings["chroot_path"]+\ - "/tmp/initramfs_overlay/"): - print "Cleaning up temporary overlay dir" - cmd("rm -R "+self.settings["chroot_path"]+\ - "/tmp/initramfs_overlay/",env=self.env) - - touch(self.settings["autoresume_path"]+\ - "build_kernel_"+kname) - - """ - Execute the script that cleans up the kernel build - environment - """ - cmd("/bin/bash "+self.settings["controller_file"]+\ - " post-kmerge ", - "Runscript post-kmerge failed",env=self.env) - - def _copy_kernel_config(self, kname): - if "boot/kernel/"+kname+"/config" in self.settings: - if not os.path.exists(self.settings["boot/kernel/"+kname+"/config"]): - self.unbind() - raise CatalystError,\ - "Can't find kernel config: "+\ - self.settings["boot/kernel/"+kname+\ - "/config"] - - try: - cmd("cp "+self.settings["boot/kernel/"+kname+\ - "/config"]+" "+\ - self.settings["chroot_path"]+"/var/tmp/"+\ - kname+".config",\ - "Couldn't copy kernel config: "+\ - self.settings["boot/kernel/"+kname+\ - "/config"],env=self.env) - - except CatalystError: - self.unbind() - - def _copy_initramfs_overlay(self, kname): - if "boot/kernel/"+kname+"/initramfs_overlay" in self.settings: - if os.path.exists(self.settings["boot/kernel/"+\ - kname+"/initramfs_overlay"]): - print "Copying initramfs_overlay dir "+\ - self.settings["boot/kernel/"+kname+\ - "/initramfs_overlay"] - - cmd("mkdir -p "+\ - self.settings["chroot_path"]+\ - "/tmp/initramfs_overlay/"+\ - self.settings["boot/kernel/"+kname+\ - "/initramfs_overlay"],env=self.env) - - cmd("cp -R "+self.settings["boot/kernel/"+\ - kname+"/initramfs_overlay"]+"/* "+\ - self.settings["chroot_path"]+\ - "/tmp/initramfs_overlay/"+\ - self.settings["boot/kernel/"+kname+\ - "/initramfs_overlay"],env=self.env) - - def bootloader(self): - if "AUTORESUME" in self.settings \ - and os.path.exists(self.settings["autoresume_path"]+"bootloader"): - print "Resume point detected, skipping bootloader operation..." - else: - try: - cmd("/bin/bash "+self.settings["controller_file"]+\ - " bootloader " + self.settings["target_path"],\ - "Bootloader script failed.",env=self.env) - touch(self.settings["autoresume_path"]+"bootloader") - except CatalystError: - self.unbind() - raise CatalystError,"Script aborting due to error." - - def livecd_update(self): - if "AUTORESUME" in self.settings \ - and os.path.exists(self.settings["autoresume_path"]+\ - "livecd_update"): - print "Resume point detected, skipping build_packages operation..." - else: - try: - cmd("/bin/bash "+self.settings["controller_file"]+\ - " livecd-update","livecd-update failed.",env=self.env) - touch(self.settings["autoresume_path"]+"livecd_update") - - except CatalystError: - self.unbind() - raise CatalystError,"build aborting due to livecd_update error." - - def clear_chroot(self): - myemp=self.settings["chroot_path"] - if os.path.isdir(myemp): - print "Emptying directory",myemp - """ - stat the dir, delete the dir, recreate the dir and set - the proper perms and ownership - """ - mystat=os.stat(myemp) - #cmd("rm -rf "+myemp, "Could not remove existing file: "+myemp,env=self.env) - """ There's no easy way to change flags recursively in python """ - if os.uname()[0] == "FreeBSD": - os.system("chflags -R noschg "+myemp) - shutil.rmtree(myemp) - os.makedirs(myemp,0755) - os.chown(myemp,mystat[ST_UID],mystat[ST_GID]) - os.chmod(myemp,mystat[ST_MODE]) - - def clear_packages(self): - if "PKGCACHE" in self.settings: - print "purging the pkgcache ..." - - myemp=self.settings["pkgcache_path"] - if os.path.isdir(myemp): - print "Emptying directory",myemp - """ - stat the dir, delete the dir, recreate the dir and set - the proper perms and ownership - """ - mystat=os.stat(myemp) - #cmd("rm -rf "+myemp, "Could not remove existing file: "+myemp,env=self.env) - shutil.rmtree(myemp) - os.makedirs(myemp,0755) - os.chown(myemp,mystat[ST_UID],mystat[ST_GID]) - os.chmod(myemp,mystat[ST_MODE]) - - def clear_kerncache(self): - if "KERNCACHE" in self.settings: - print "purging the kerncache ..." - - myemp=self.settings["kerncache_path"] - if os.path.isdir(myemp): - print "Emptying directory",myemp - """ - stat the dir, delete the dir, recreate the dir and set - the proper perms and ownership - """ - mystat=os.stat(myemp) - #cmd("rm -rf "+myemp, "Could not remove existing file: "+myemp,env=self.env) - shutil.rmtree(myemp) - os.makedirs(myemp,0755) - os.chown(myemp,mystat[ST_UID],mystat[ST_GID]) - os.chmod(myemp,mystat[ST_MODE]) - - def clear_autoresume(self): - """ Clean resume points since they are no longer needed """ - if "AUTORESUME" in self.settings: - print "Removing AutoResume Points: ..." - myemp=self.settings["autoresume_path"] - if os.path.isdir(myemp): - if "AUTORESUME" in self.settings: - print "Emptying directory",myemp - """ - stat the dir, delete the dir, recreate the dir and set - the proper perms and ownership - """ - mystat=os.stat(myemp) - if os.uname()[0] == "FreeBSD": - cmd("chflags -R noschg "+myemp,\ - "Could not remove immutable flag for file "\ - +myemp) - #cmd("rm -rf "+myemp, "Could not remove existing file: "+myemp,env-self.env) - shutil.rmtree(myemp) - os.makedirs(myemp,0755) - os.chown(myemp,mystat[ST_UID],mystat[ST_GID]) - os.chmod(myemp,mystat[ST_MODE]) - - def gen_contents_file(self,file): - if os.path.exists(file+".CONTENTS"): - os.remove(file+".CONTENTS") - if "contents" in self.settings: - if os.path.exists(file): - myf=open(file+".CONTENTS","w") - keys={} - for i in self.settings["contents"].split(): - keys[i]=1 - array=keys.keys() - array.sort() - for j in array: - contents=generate_contents(file,contents_function=j,\ - verbose="VERBOSE" in self.settings) - if contents: - myf.write(contents) - myf.close() - - def gen_digest_file(self,file): - if os.path.exists(file+".DIGESTS"): - os.remove(file+".DIGESTS") - if "digests" in self.settings: - if os.path.exists(file): - myf=open(file+".DIGESTS","w") - keys={} - for i in self.settings["digests"].split(): - keys[i]=1 - array=keys.keys() - array.sort() - for f in [file, file+'.CONTENTS']: - if os.path.exists(f): - if "all" in array: - for k in hash_map.keys(): - hash=generate_hash(f,hash_function=k,verbose=\ - "VERBOSE" in self.settings) - myf.write(hash) - else: - for j in array: - hash=generate_hash(f,hash_function=j,verbose=\ - "VERBOSE" in self.settings) - myf.write(hash) - myf.close() - - def purge(self): - countdown(10,"Purging Caches ...") - if any(k in self.settings for k in ("PURGE","PURGEONLY","PURGETMPONLY")): - print "clearing autoresume ..." - self.clear_autoresume() - - print "clearing chroot ..." - self.clear_chroot() - - if "PURGETMPONLY" not in self.settings: - print "clearing package cache ..." - self.clear_packages() - - print "clearing kerncache ..." - self.clear_kerncache() - -# vim: ts=4 sw=4 sta et sts=4 ai diff --git a/catalyst/modules/generic_target.py b/catalyst/modules/generic_target.py deleted file mode 100644 index de51994..0000000 --- a/catalyst/modules/generic_target.py +++ /dev/null @@ -1,11 +0,0 @@ -from catalyst.support import * - -class generic_target: - """ - The toplevel class for generic_stage_target. This is about as generic as we get. - """ - def __init__(self,myspec,addlargs): - addl_arg_parse(myspec,addlargs,self.required_values,self.valid_values) - self.settings=myspec - self.env={} - self.env["PATH"]="/bin:/sbin:/usr/bin:/usr/sbin" diff --git a/catalyst/modules/grp_target.py b/catalyst/modules/grp_target.py deleted file mode 100644 index 8e70042..0000000 --- a/catalyst/modules/grp_target.py +++ /dev/null @@ -1,118 +0,0 @@ -""" -Gentoo Reference Platform (GRP) target -""" -# NOTE: That^^ docstring has influence catalyst-spec(5) man page generation. - -import os,types,glob -from catalyst.support import * -from generic_stage_target import * - -class grp_target(generic_stage_target): - """ - The builder class for GRP (Gentoo Reference Platform) builds. - """ - def __init__(self,spec,addlargs): - self.required_values=["version_stamp","target","subarch",\ - "rel_type","profile","snapshot","source_subpath"] - - self.valid_values=self.required_values[:] - self.valid_values.extend(["grp/use"]) - if "grp" not in addlargs: - raise CatalystError,"Required value \"grp\" not specified in spec." - - self.required_values.extend(["grp"]) - if type(addlargs["grp"])==types.StringType: - addlargs["grp"]=[addlargs["grp"]] - - if "grp/use" in addlargs: - if type(addlargs["grp/use"])==types.StringType: - addlargs["grp/use"]=[addlargs["grp/use"]] - - for x in addlargs["grp"]: - self.required_values.append("grp/"+x+"/packages") - self.required_values.append("grp/"+x+"/type") - - generic_stage_target.__init__(self,spec,addlargs) - - def set_target_path(self): - self.settings["target_path"]=normpath(self.settings["storedir"]+"/builds/"+self.settings["target_subpath"]+"/") - if "AUTORESUME" in self.settings \ - and os.path.exists(self.settings["autoresume_path"]+"setup_target_path"): - print "Resume point detected, skipping target path setup operation..." - else: - # first clean up any existing target stuff - #if os.path.isdir(self.settings["target_path"]): - #cmd("rm -rf "+self.settings["target_path"], - #"Could not remove existing directory: "+self.settings["target_path"],env=self.env) - if not os.path.exists(self.settings["target_path"]): - os.makedirs(self.settings["target_path"]) - - touch(self.settings["autoresume_path"]+"setup_target_path") - - def run_local(self): - for pkgset in self.settings["grp"]: - # example call: "grp.sh run pkgset cd1 xmms vim sys-apps/gleep" - mypackages=list_bashify(self.settings["grp/"+pkgset+"/packages"]) - try: - cmd("/bin/bash "+self.settings["controller_file"]+" run "+self.settings["grp/"+pkgset+"/type"]\ - +" "+pkgset+" "+mypackages,env=self.env) - - except CatalystError: - self.unbind() - raise CatalystError,"GRP build aborting due to error." - - def set_use(self): - generic_stage_target.set_use(self) - if "BINDIST" in self.settings: - if "use" in self.settings: - self.settings["use"].append("bindist") - else: - self.settings["use"]=["bindist"] - - def set_mounts(self): - self.mounts.append("/tmp/grp") - self.mountmap["/tmp/grp"]=self.settings["target_path"] - - def generate_digests(self): - for pkgset in self.settings["grp"]: - if self.settings["grp/"+pkgset+"/type"] == "pkgset": - destdir=normpath(self.settings["target_path"]+"/"+pkgset+"/All") - print "Digesting files in the pkgset....." - digests=glob.glob(destdir+'/*.DIGESTS') - for i in digests: - if os.path.exists(i): - os.remove(i) - - files=os.listdir(destdir) - #ignore files starting with '.' using list comprehension - files=[filename for filename in files if filename[0] != '.'] - for i in files: - if os.path.isfile(normpath(destdir+"/"+i)): - self.gen_contents_file(normpath(destdir+"/"+i)) - self.gen_digest_file(normpath(destdir+"/"+i)) - else: - destdir=normpath(self.settings["target_path"]+"/"+pkgset) - print "Digesting files in the srcset....." - - digests=glob.glob(destdir+'/*.DIGESTS') - for i in digests: - if os.path.exists(i): - os.remove(i) - - files=os.listdir(destdir) - #ignore files starting with '.' using list comprehension - files=[filename for filename in files if filename[0] != '.'] - for i in files: - if os.path.isfile(normpath(destdir+"/"+i)): - #self.gen_contents_file(normpath(destdir+"/"+i)) - self.gen_digest_file(normpath(destdir+"/"+i)) - - def set_action_sequence(self): - self.settings["action_sequence"]=["unpack","unpack_snapshot",\ - "config_profile_link","setup_confdir","portage_overlay","bind","chroot_setup",\ - "setup_environment","run_local","unbind",\ - "generate_digests","clear_autoresume"] - -def register(foo): - foo.update({"grp":grp_target}) - return foo diff --git a/catalyst/modules/livecd_stage1_target.py b/catalyst/modules/livecd_stage1_target.py deleted file mode 100644 index ac846ec..0000000 --- a/catalyst/modules/livecd_stage1_target.py +++ /dev/null @@ -1,75 +0,0 @@ -""" -LiveCD stage1 target -""" -# NOTE: That^^ docstring has influence catalyst-spec(5) man page generation. - -from catalyst.support import * -from generic_stage_target import * - -class livecd_stage1_target(generic_stage_target): - """ - Builder class for LiveCD stage1. - """ - def __init__(self,spec,addlargs): - self.required_values=["livecd/packages"] - self.valid_values=self.required_values[:] - - self.valid_values.extend(["livecd/use"]) - generic_stage_target.__init__(self,spec,addlargs) - - def set_action_sequence(self): - self.settings["action_sequence"]=["unpack","unpack_snapshot",\ - "config_profile_link","setup_confdir","portage_overlay",\ - "bind","chroot_setup","setup_environment","build_packages",\ - "unbind", "clean","clear_autoresume"] - - def set_target_path(self): - self.settings["target_path"]=normpath(self.settings["storedir"]+"/builds/"+self.settings["target_subpath"]) - if "AUTORESUME" in self.settings \ - and os.path.exists(self.settings["autoresume_path"]+"setup_target_path"): - print "Resume point detected, skipping target path setup operation..." - else: - # first clean up any existing target stuff - if os.path.exists(self.settings["target_path"]): - cmd("rm -rf "+self.settings["target_path"],\ - "Could not remove existing directory: "+self.settings["target_path"],env=self.env) - touch(self.settings["autoresume_path"]+"setup_target_path") - - if not os.path.exists(self.settings["target_path"]): - os.makedirs(self.settings["target_path"]) - - def set_target_path(self): - pass - - def set_spec_prefix(self): - self.settings["spec_prefix"]="livecd" - - def set_use(self): - generic_stage_target.set_use(self) - if "use" in self.settings: - self.settings["use"].append("livecd") - if "BINDIST" in self.settings: - self.settings["use"].append("bindist") - else: - self.settings["use"]=["livecd"] - if "BINDIST" in self.settings: - self.settings["use"].append("bindist") - - def set_packages(self): - generic_stage_target.set_packages(self) - if self.settings["spec_prefix"]+"/packages" in self.settings: - if type(self.settings[self.settings["spec_prefix"]+"/packages"]) == types.StringType: - self.settings[self.settings["spec_prefix"]+"/packages"] = \ - self.settings[self.settings["spec_prefix"]+"/packages"].split() - self.settings[self.settings["spec_prefix"]+"/packages"].append("app-misc/livecd-tools") - - def set_pkgcache_path(self): - if "pkgcache_path" in self.settings: - if type(self.settings["pkgcache_path"]) != types.StringType: - self.settings["pkgcache_path"]=normpath(string.join(self.settings["pkgcache_path"])) - else: - generic_stage_target.set_pkgcache_path(self) - -def register(foo): - foo.update({"livecd-stage1":livecd_stage1_target}) - return foo diff --git a/catalyst/modules/livecd_stage2_target.py b/catalyst/modules/livecd_stage2_target.py deleted file mode 100644 index 1bfd820..0000000 --- a/catalyst/modules/livecd_stage2_target.py +++ /dev/null @@ -1,146 +0,0 @@ -""" -LiveCD stage2 target, builds upon previous LiveCD stage1 tarball -""" -# NOTE: That^^ docstring has influence catalyst-spec(5) man page generation. - -import os,string,types,stat,shutil -from catalyst.support import * -from generic_stage_target import * - -class livecd_stage2_target(generic_stage_target): - """ - Builder class for a LiveCD stage2 build. - """ - def __init__(self,spec,addlargs): - self.required_values=["boot/kernel"] - - self.valid_values=[] - - self.valid_values.extend(self.required_values) - self.valid_values.extend(["livecd/cdtar","livecd/empty","livecd/rm",\ - "livecd/unmerge","livecd/iso","livecd/gk_mainargs","livecd/type",\ - "livecd/readme","livecd/motd","livecd/overlay",\ - "livecd/modblacklist","livecd/splash_theme","livecd/rcadd",\ - "livecd/rcdel","livecd/fsscript","livecd/xinitrc",\ - "livecd/root_overlay","livecd/users","portage_overlay",\ - "livecd/fstype","livecd/fsops","livecd/linuxrc","livecd/bootargs",\ - "gamecd/conf","livecd/xdm","livecd/xsession","livecd/volid"]) - - generic_stage_target.__init__(self,spec,addlargs) - if "livecd/type" not in self.settings: - self.settings["livecd/type"] = "generic-livecd" - - file_locate(self.settings, ["cdtar","controller_file"]) - - def set_source_path(self): - self.settings["source_path"]=normpath(self.settings["storedir"]+"/builds/"+self.settings["source_subpath"]+".tar.bz2") - if os.path.isfile(self.settings["source_path"]): - self.settings["source_path_hash"]=generate_hash(self.settings["source_path"]) - else: - self.settings["source_path"]=normpath(self.settings["storedir"]+"/tmp/"+self.settings["source_subpath"]+"/") - if not os.path.exists(self.settings["source_path"]): - raise CatalystError,"Source Path: "+self.settings["source_path"]+" does not exist." - - def set_spec_prefix(self): - self.settings["spec_prefix"]="livecd" - - def set_target_path(self): - self.settings["target_path"]=normpath(self.settings["storedir"]+"/builds/"+self.settings["target_subpath"]+"/") - if "AUTORESUME" in self.settings \ - and os.path.exists(self.settings["autoresume_path"]+"setup_target_path"): - print "Resume point detected, skipping target path setup operation..." - else: - # first clean up any existing target stuff - if os.path.isdir(self.settings["target_path"]): - cmd("rm -rf "+self.settings["target_path"], - "Could not remove existing directory: "+self.settings["target_path"],env=self.env) - touch(self.settings["autoresume_path"]+"setup_target_path") - if not os.path.exists(self.settings["target_path"]): - os.makedirs(self.settings["target_path"]) - - def run_local(self): - # what modules do we want to blacklist? - if "livecd/modblacklist" in self.settings: - try: - myf=open(self.settings["chroot_path"]+"/etc/modprobe.d/blacklist.conf","a") - except: - self.unbind() - raise CatalystError,"Couldn't open "+self.settings["chroot_path"]+"/etc/modprobe.d/blacklist.conf." - - myf.write("\n#Added by Catalyst:") - # workaround until config.py is using configparser - if isinstance(self.settings["livecd/modblacklist"], str): - self.settings["livecd/modblacklist"] = self.settings["livecd/modblacklist"].split() - for x in self.settings["livecd/modblacklist"]: - myf.write("\nblacklist "+x) - myf.close() - - def unpack(self): - unpack=True - display_msg=None - - clst_unpack_hash=read_from_clst(self.settings["autoresume_path"]+"unpack") - - if os.path.isdir(self.settings["source_path"]): - unpack_cmd="rsync -a --delete "+self.settings["source_path"]+" "+self.settings["chroot_path"] - display_msg="\nStarting rsync from "+self.settings["source_path"]+"\nto "+\ - self.settings["chroot_path"]+" (This may take some time) ...\n" - error_msg="Rsync of "+self.settings["source_path"]+" to "+self.settings["chroot_path"]+" failed." - invalid_snapshot=False - - if "AUTORESUME" in self.settings: - if os.path.isdir(self.settings["source_path"]) and \ - os.path.exists(self.settings["autoresume_path"]+"unpack"): - print "Resume point detected, skipping unpack operation..." - unpack=False - elif "source_path_hash" in self.settings: - if self.settings["source_path_hash"] != clst_unpack_hash: - invalid_snapshot=True - - if unpack: - self.mount_safety_check() - if invalid_snapshot: - print "No Valid Resume point detected, cleaning up ..." - #os.remove(self.settings["autoresume_path"]+"dir_setup") - self.clear_autoresume() - self.clear_chroot() - #self.dir_setup() - - if not os.path.exists(self.settings["chroot_path"]): - os.makedirs(self.settings["chroot_path"]) - - if not os.path.exists(self.settings["chroot_path"]+"/tmp"): - os.makedirs(self.settings["chroot_path"]+"/tmp",1777) - - if "PKGCACHE" in self.settings: - if not os.path.exists(self.settings["pkgcache_path"]): - os.makedirs(self.settings["pkgcache_path"],0755) - - if not display_msg: - raise CatalystError,"Could not find appropriate source. Please check the 'source_subpath' setting in the spec file." - - print display_msg - cmd(unpack_cmd,error_msg,env=self.env) - - if "source_path_hash" in self.settings: - myf=open(self.settings["autoresume_path"]+"unpack","w") - myf.write(self.settings["source_path_hash"]) - myf.close() - else: - touch(self.settings["autoresume_path"]+"unpack") - - def set_action_sequence(self): - self.settings["action_sequence"]=["unpack","unpack_snapshot",\ - "config_profile_link","setup_confdir","portage_overlay",\ - "bind","chroot_setup","setup_environment","run_local",\ - "build_kernel"] - if "FETCH" not in self.settings: - self.settings["action_sequence"] += ["bootloader","preclean",\ - "livecd_update","root_overlay","fsscript","rcupdate","unmerge",\ - "unbind","remove","empty","target_setup",\ - "setup_overlay","create_iso"] - self.settings["action_sequence"].append("clear_autoresume") - -def register(foo): - foo.update({"livecd-stage2":livecd_stage2_target}) - return foo diff --git a/catalyst/modules/netboot2_target.py b/catalyst/modules/netboot2_target.py deleted file mode 100644 index 2b3cd20..0000000 --- a/catalyst/modules/netboot2_target.py +++ /dev/null @@ -1,166 +0,0 @@ -""" -netboot target, version 2 -""" -# NOTE: That^^ docstring has influence catalyst-spec(5) man page generation. - -import os,string,types -from catalyst.support import * -from generic_stage_target import * - -class netboot2_target(generic_stage_target): - """ - Builder class for a netboot build, version 2 - """ - def __init__(self,spec,addlargs): - self.required_values=[ - "boot/kernel" - ] - self.valid_values=self.required_values[:] - self.valid_values.extend([ - "netboot2/packages", - "netboot2/use", - "netboot2/extra_files", - "netboot2/overlay", - "netboot2/busybox_config", - "netboot2/root_overlay", - "netboot2/linuxrc" - ]) - - try: - if "netboot2/packages" in addlargs: - if type(addlargs["netboot2/packages"]) == types.StringType: - loopy=[addlargs["netboot2/packages"]] - else: - loopy=addlargs["netboot2/packages"] - - for x in loopy: - self.valid_values.append("netboot2/packages/"+x+"/files") - except: - raise CatalystError,"configuration error in netboot2/packages." - - generic_stage_target.__init__(self,spec,addlargs) - self.set_build_kernel_vars() - self.settings["merge_path"]=normpath("/tmp/image/") - - def set_target_path(self): - self.settings["target_path"]=normpath(self.settings["storedir"]+"/builds/"+\ - self.settings["target_subpath"]+"/") - if "AUTORESUME" in self.settings \ - and os.path.exists(self.settings["autoresume_path"]+"setup_target_path"): - print "Resume point detected, skipping target path setup operation..." - else: - # first clean up any existing target stuff - if os.path.isfile(self.settings["target_path"]): - cmd("rm -f "+self.settings["target_path"], \ - "Could not remove existing file: "+self.settings["target_path"],env=self.env) - touch(self.settings["autoresume_path"]+"setup_target_path") - - if not os.path.exists(self.settings["storedir"]+"/builds/"): - os.makedirs(self.settings["storedir"]+"/builds/") - - def copy_files_to_image(self): - # copies specific files from the buildroot to merge_path - myfiles=[] - - # check for autoresume point - if "AUTORESUME" in self.settings \ - and os.path.exists(self.settings["autoresume_path"]+"copy_files_to_image"): - print "Resume point detected, skipping target path setup operation..." - else: - if "netboot2/packages" in self.settings: - if type(self.settings["netboot2/packages"]) == types.StringType: - loopy=[self.settings["netboot2/packages"]] - else: - loopy=self.settings["netboot2/packages"] - - for x in loopy: - if "netboot2/packages/"+x+"/files" in self.settings: - if type(self.settings["netboot2/packages/"+x+"/files"]) == types.ListType: - myfiles.extend(self.settings["netboot2/packages/"+x+"/files"]) - else: - myfiles.append(self.settings["netboot2/packages/"+x+"/files"]) - - if "netboot2/extra_files" in self.settings: - if type(self.settings["netboot2/extra_files"]) == types.ListType: - myfiles.extend(self.settings["netboot2/extra_files"]) - else: - myfiles.append(self.settings["netboot2/extra_files"]) - - try: - cmd("/bin/bash "+self.settings["controller_file"]+\ - " image " + list_bashify(myfiles),env=self.env) - except CatalystError: - self.unbind() - raise CatalystError,"Failed to copy files to image!" - - touch(self.settings["autoresume_path"]+"copy_files_to_image") - - def setup_overlay(self): - if "AUTORESUME" in self.settings \ - and os.path.exists(self.settings["autoresume_path"]+"setup_overlay"): - print "Resume point detected, skipping setup_overlay operation..." - else: - if "netboot2/overlay" in self.settings: - for x in self.settings["netboot2/overlay"]: - if os.path.exists(x): - cmd("rsync -a "+x+"/ "+\ - self.settings["chroot_path"] + self.settings["merge_path"], "netboot2/overlay: "+x+" copy failed.",env=self.env) - touch(self.settings["autoresume_path"]+"setup_overlay") - - def move_kernels(self): - # we're done, move the kernels to builds/* - # no auto resume here as we always want the - # freshest images moved - try: - cmd("/bin/bash "+self.settings["controller_file"]+\ - " final",env=self.env) - print ">>> Netboot Build Finished!" - except CatalystError: - self.unbind() - raise CatalystError,"Failed to move kernel images!" - - def remove(self): - if "AUTORESUME" in self.settings \ - and os.path.exists(self.settings["autoresume_path"]+"remove"): - print "Resume point detected, skipping remove operation..." - else: - if self.settings["spec_prefix"]+"/rm" in self.settings: - for x in self.settings[self.settings["spec_prefix"]+"/rm"]: - # we're going to shell out for all these cleaning operations, - # so we get easy glob handling - print "netboot2: removing " + x - os.system("rm -rf " + self.settings["chroot_path"] + self.settings["merge_path"] + x) - - def empty(self): - if "AUTORESUME" in self.settings \ - and os.path.exists(self.settings["autoresume_path"]+"empty"): - print "Resume point detected, skipping empty operation..." - else: - if "netboot2/empty" in self.settings: - if type(self.settings["netboot2/empty"])==types.StringType: - self.settings["netboot2/empty"]=self.settings["netboot2/empty"].split() - for x in self.settings["netboot2/empty"]: - myemp=self.settings["chroot_path"] + self.settings["merge_path"] + x - if not os.path.isdir(myemp): - print x,"not a directory or does not exist, skipping 'empty' operation." - continue - print "Emptying directory", x - # stat the dir, delete the dir, recreate the dir and set - # the proper perms and ownership - mystat=os.stat(myemp) - shutil.rmtree(myemp) - os.makedirs(myemp,0755) - os.chown(myemp,mystat[ST_UID],mystat[ST_GID]) - os.chmod(myemp,mystat[ST_MODE]) - touch(self.settings["autoresume_path"]+"empty") - - def set_action_sequence(self): - self.settings["action_sequence"]=["unpack","unpack_snapshot","config_profile_link", - "setup_confdir","portage_overlay","bind","chroot_setup",\ - "setup_environment","build_packages","root_overlay",\ - "copy_files_to_image","setup_overlay","build_kernel","move_kernels",\ - "remove","empty","unbind","clean","clear_autoresume"] - -def register(foo): - foo.update({"netboot2":netboot2_target}) - return foo diff --git a/catalyst/modules/netboot_target.py b/catalyst/modules/netboot_target.py deleted file mode 100644 index 9d01b7e..0000000 --- a/catalyst/modules/netboot_target.py +++ /dev/null @@ -1,128 +0,0 @@ -""" -netboot target, version 1 -""" -# NOTE: That^^ docstring has influence catalyst-spec(5) man page generation. - -import os,string,types -from catalyst.support import * -from generic_stage_target import * - -class netboot_target(generic_stage_target): - """ - Builder class for a netboot build. - """ - def __init__(self,spec,addlargs): - self.valid_values = [ - "netboot/kernel/sources", - "netboot/kernel/config", - "netboot/kernel/prebuilt", - - "netboot/busybox_config", - - "netboot/extra_files", - "netboot/packages" - ] - self.required_values=[] - - try: - if "netboot/packages" in addlargs: - if type(addlargs["netboot/packages"]) == types.StringType: - loopy=[addlargs["netboot/packages"]] - else: - loopy=addlargs["netboot/packages"] - - # for x in loopy: - # self.required_values.append("netboot/packages/"+x+"/files") - except: - raise CatalystError,"configuration error in netboot/packages." - - generic_stage_target.__init__(self,spec,addlargs) - self.set_build_kernel_vars(addlargs) - if "netboot/busybox_config" in addlargs: - file_locate(self.settings, ["netboot/busybox_config"]) - - # Custom Kernel Tarball --- use that instead ... - - # unless the user wants specific CFLAGS/CXXFLAGS, let's use -Os - - for envvar in "CFLAGS", "CXXFLAGS": - if envvar not in os.environ and envvar not in addlargs: - self.settings[envvar] = "-Os -pipe" - - def set_root_path(self): - # ROOT= variable for emerges - self.settings["root_path"]=normpath("/tmp/image") - print "netboot root path is "+self.settings["root_path"] - -# def build_packages(self): -# # build packages -# if "netboot/packages" in self.settings: -# mypack=list_bashify(self.settings["netboot/packages"]) -# try: -# cmd("/bin/bash "+self.settings["controller_file"]+" packages "+mypack,env=self.env) -# except CatalystError: -# self.unbind() -# raise CatalystError,"netboot build aborting due to error." - - def build_busybox(self): - # build busybox - if "netboot/busybox_config" in self.settings: - mycmd = self.settings["netboot/busybox_config"] - else: - mycmd = "" - try: - cmd("/bin/bash "+self.settings["controller_file"]+" busybox "+ mycmd,env=self.env) - except CatalystError: - self.unbind() - raise CatalystError,"netboot build aborting due to error." - - def copy_files_to_image(self): - # create image - myfiles=[] - if "netboot/packages" in self.settings: - if type(self.settings["netboot/packages"]) == types.StringType: - loopy=[self.settings["netboot/packages"]] - else: - loopy=self.settings["netboot/packages"] - - for x in loopy: - if "netboot/packages/"+x+"/files" in self.settings: - if type(self.settings["netboot/packages/"+x+"/files"]) == types.ListType: - myfiles.extend(self.settings["netboot/packages/"+x+"/files"]) - else: - myfiles.append(self.settings["netboot/packages/"+x+"/files"]) - - if "netboot/extra_files" in self.settings: - if type(self.settings["netboot/extra_files"]) == types.ListType: - myfiles.extend(self.settings["netboot/extra_files"]) - else: - myfiles.append(self.settings["netboot/extra_files"]) - - try: - cmd("/bin/bash "+self.settings["controller_file"]+\ - " image " + list_bashify(myfiles),env=self.env) - except CatalystError: - self.unbind() - raise CatalystError,"netboot build aborting due to error." - - def create_netboot_files(self): - # finish it all up - try: - cmd("/bin/bash "+self.settings["controller_file"]+" finish",env=self.env) - except CatalystError: - self.unbind() - raise CatalystError,"netboot build aborting due to error." - - # end - print "netboot: build finished !" - - def set_action_sequence(self): - self.settings["action_sequence"]=["unpack","unpack_snapshot", - "config_profile_link","setup_confdir","bind","chroot_setup",\ - "setup_environment","build_packages","build_busybox",\ - "build_kernel","copy_files_to_image",\ - "clean","create_netboot_files","unbind","clear_autoresume"] - -def register(foo): - foo.update({"netboot":netboot_target}) - return foo diff --git a/catalyst/modules/snapshot_target.py b/catalyst/modules/snapshot_target.py deleted file mode 100644 index e21bd1a..0000000 --- a/catalyst/modules/snapshot_target.py +++ /dev/null @@ -1,91 +0,0 @@ -""" -Snapshot target -""" - -import os -from catalyst.support import * -from generic_stage_target import * - -class snapshot_target(generic_stage_target): - """ - Builder class for snapshots. - """ - def __init__(self,myspec,addlargs): - self.required_values=["version_stamp","target"] - self.valid_values=["version_stamp","target"] - - generic_target.__init__(self,myspec,addlargs) - self.settings=myspec - self.settings["target_subpath"]="portage" - st=self.settings["storedir"] - self.settings["snapshot_path"]=normpath(st + "/snapshots/" - + self.settings["snapshot_name"] - + self.settings["version_stamp"] + ".tar.bz2") - self.settings["tmp_path"]=normpath(st+"/tmp/"+self.settings["target_subpath"]) - - def setup(self): - x=normpath(self.settings["storedir"]+"/snapshots") - if not os.path.exists(x): - os.makedirs(x) - - def mount_safety_check(self): - pass - - def run(self): - if "PURGEONLY" in self.settings: - self.purge() - return - - if "PURGE" in self.settings: - self.purge() - - self.setup() - print "Creating Portage tree snapshot "+self.settings["version_stamp"]+\ - " from "+self.settings["portdir"]+"..." - - mytmp=self.settings["tmp_path"] - if not os.path.exists(mytmp): - os.makedirs(mytmp) - - cmd("rsync -a --delete --exclude /packages/ --exclude /distfiles/ " + - "--exclude /local/ --exclude CVS/ --exclude .svn --filter=H_**/files/digest-* " + - self.settings["portdir"] + "/ " + mytmp + "/%s/" % self.settings["repo_name"], - "Snapshot failure",env=self.env) - - print "Compressing Portage snapshot tarball..." - cmd("tar -I lbzip2 -cf " + self.settings["snapshot_path"] + " -C " + - mytmp + " %s" % self.settings["repo_name"], - "Snapshot creation failure",env=self.env) - - self.gen_contents_file(self.settings["snapshot_path"]) - self.gen_digest_file(self.settings["snapshot_path"]) - - self.cleanup() - print "snapshot: complete!" - - def kill_chroot_pids(self): - pass - - def cleanup(self): - print "Cleaning up..." - - def purge(self): - myemp=self.settings["tmp_path"] - if os.path.isdir(myemp): - print "Emptying directory",myemp - """ - stat the dir, delete the dir, recreate the dir and set - the proper perms and ownership - """ - mystat=os.stat(myemp) - """ There's no easy way to change flags recursively in python """ - if os.uname()[0] == "FreeBSD": - os.system("chflags -R noschg "+myemp) - shutil.rmtree(myemp) - os.makedirs(myemp,0755) - os.chown(myemp,mystat[ST_UID],mystat[ST_GID]) - os.chmod(myemp,mystat[ST_MODE]) - -def register(foo): - foo.update({"snapshot":snapshot_target}) - return foo diff --git a/catalyst/modules/stage1_target.py b/catalyst/modules/stage1_target.py deleted file mode 100644 index 25f7116..0000000 --- a/catalyst/modules/stage1_target.py +++ /dev/null @@ -1,96 +0,0 @@ -""" -stage1 target -""" -# NOTE: That^^ docstring has influence catalyst-spec(5) man page generation. - -from catalyst.support import * -from generic_stage_target import * - -class stage1_target(generic_stage_target): - """ - Builder class for a stage1 installation tarball build. - """ - def __init__(self,spec,addlargs): - self.required_values=[] - self.valid_values=["chost"] - self.valid_values.extend(["update_seed","update_seed_command"]) - generic_stage_target.__init__(self,spec,addlargs) - - def set_stage_path(self): - self.settings["stage_path"]=normpath(self.settings["chroot_path"]+self.settings["root_path"]) - print "stage1 stage path is "+self.settings["stage_path"] - - def set_root_path(self): - # sets the root path, relative to 'chroot_path', of the stage1 root - self.settings["root_path"]=normpath("/tmp/stage1root") - print "stage1 root path is "+self.settings["root_path"] - - def set_cleanables(self): - generic_stage_target.set_cleanables(self) - self.settings["cleanables"].extend([\ - "/usr/share/zoneinfo", "/etc/portage/package*"]) - - # XXX: How do these override_foo() functions differ from the ones in generic_stage_target and why aren't they in stage3_target? - - def override_chost(self): - if "chost" in self.settings: - self.settings["CHOST"]=list_to_string(self.settings["chost"]) - - def override_cflags(self): - if "cflags" in self.settings: - self.settings["CFLAGS"]=list_to_string(self.settings["cflags"]) - - def override_cxxflags(self): - if "cxxflags" in self.settings: - self.settings["CXXFLAGS"]=list_to_string(self.settings["cxxflags"]) - - def override_ldflags(self): - if "ldflags" in self.settings: - self.settings["LDFLAGS"]=list_to_string(self.settings["ldflags"]) - - def set_portage_overlay(self): - generic_stage_target.set_portage_overlay(self) - if "portage_overlay" in self.settings: - print "\nWARNING !!!!!" - print "\tUsing an portage overlay for earlier stages could cause build issues." - print "\tIf you break it, you buy it. Don't complain to us about it." - print "\tDont say we did not warn you\n" - - def base_dirs(self): - if os.uname()[0] == "FreeBSD": - # baselayout no longer creates the .keep files in proc and dev for FreeBSD as it - # would create them too late...we need them earlier before bind mounting filesystems - # since proc and dev are not writeable, so...create them here - if not os.path.exists(self.settings["stage_path"]+"/proc"): - os.makedirs(self.settings["stage_path"]+"/proc") - if not os.path.exists(self.settings["stage_path"]+"/dev"): - os.makedirs(self.settings["stage_path"]+"/dev") - if not os.path.isfile(self.settings["stage_path"]+"/proc/.keep"): - try: - proc_keepfile = open(self.settings["stage_path"]+"/proc/.keep","w") - proc_keepfile.write('') - proc_keepfile.close() - except IOError: - print "!!! Failed to create %s" % (self.settings["stage_path"]+"/dev/.keep") - if not os.path.isfile(self.settings["stage_path"]+"/dev/.keep"): - try: - dev_keepfile = open(self.settings["stage_path"]+"/dev/.keep","w") - dev_keepfile.write('') - dev_keepfile.close() - except IOError: - print "!!! Failed to create %s" % (self.settings["stage_path"]+"/dev/.keep") - else: - pass - - def set_mounts(self): - # stage_path/proc probably doesn't exist yet, so create it - if not os.path.exists(self.settings["stage_path"]+"/proc"): - os.makedirs(self.settings["stage_path"]+"/proc") - - # alter the mount mappings to bind mount proc onto it - self.mounts.append("/tmp/stage1root/proc") - self.mountmap["/tmp/stage1root/proc"]="/proc" - -def register(foo): - foo.update({"stage1":stage1_target}) - return foo diff --git a/catalyst/modules/stage2_target.py b/catalyst/modules/stage2_target.py deleted file mode 100644 index 15acdee..0000000 --- a/catalyst/modules/stage2_target.py +++ /dev/null @@ -1,62 +0,0 @@ -""" -stage2 target, builds upon previous stage1 tarball -""" -# NOTE: That^^ docstring has influence catalyst-spec(5) man page generation. - -from catalyst.support import * -from generic_stage_target import * - -class stage2_target(generic_stage_target): - """ - Builder class for a stage2 installation tarball build. - """ - def __init__(self,spec,addlargs): - self.required_values=[] - self.valid_values=["chost"] - generic_stage_target.__init__(self,spec,addlargs) - - def set_source_path(self): - if "SEEDCACHE" in self.settings and os.path.isdir(normpath(self.settings["storedir"]+"/tmp/"+self.settings["source_subpath"]+"/tmp/stage1root/")): - self.settings["source_path"]=normpath(self.settings["storedir"]+"/tmp/"+self.settings["source_subpath"]+"/tmp/stage1root/") - else: - self.settings["source_path"]=normpath(self.settings["storedir"]+"/builds/"+self.settings["source_subpath"]+".tar.bz2") - if os.path.isfile(self.settings["source_path"]): - if os.path.exists(self.settings["source_path"]): - # XXX: Is this even necessary if the previous check passes? - self.settings["source_path_hash"]=generate_hash(self.settings["source_path"],\ - hash_function=self.settings["hash_function"],verbose=False) - print "Source path set to "+self.settings["source_path"] - if os.path.isdir(self.settings["source_path"]): - print "\tIf this is not desired, remove this directory or turn of seedcache in the options of catalyst.conf" - print "\tthe source path will then be "+normpath(self.settings["storedir"]+"/builds/"+self.settings["source_subpath"]+".tar.bz2\n") - - # XXX: How do these override_foo() functions differ from the ones in - # generic_stage_target and why aren't they in stage3_target? - - def override_chost(self): - if "chost" in self.settings: - self.settings["CHOST"]=list_to_string(self.settings["chost"]) - - def override_cflags(self): - if "cflags" in self.settings: - self.settings["CFLAGS"]=list_to_string(self.settings["cflags"]) - - def override_cxxflags(self): - if "cxxflags" in self.settings: - self.settings["CXXFLAGS"]=list_to_string(self.settings["cxxflags"]) - - def override_ldflags(self): - if "ldflags" in self.settings: - self.settings["LDFLAGS"]=list_to_string(self.settings["ldflags"]) - - def set_portage_overlay(self): - generic_stage_target.set_portage_overlay(self) - if "portage_overlay" in self.settings: - print "\nWARNING !!!!!" - print "\tUsing an portage overlay for earlier stages could cause build issues." - print "\tIf you break it, you buy it. Don't complain to us about it." - print "\tDont say we did not warn you\n" - -def register(foo): - foo.update({"stage2":stage2_target}) - return foo diff --git a/catalyst/modules/stage3_target.py b/catalyst/modules/stage3_target.py deleted file mode 100644 index 89edd66..0000000 --- a/catalyst/modules/stage3_target.py +++ /dev/null @@ -1,31 +0,0 @@ -""" -stage3 target, builds upon previous stage2/stage3 tarball -""" -# NOTE: That^^ docstring has influence catalyst-spec(5) man page generation. - -from catalyst.support import * -from generic_stage_target import * - -class stage3_target(generic_stage_target): - """ - Builder class for a stage3 installation tarball build. - """ - def __init__(self,spec,addlargs): - self.required_values=[] - self.valid_values=[] - generic_stage_target.__init__(self,spec,addlargs) - - def set_portage_overlay(self): - generic_stage_target.set_portage_overlay(self) - if "portage_overlay" in self.settings: - print "\nWARNING !!!!!" - print "\tUsing an overlay for earlier stages could cause build issues." - print "\tIf you break it, you buy it. Don't complain to us about it." - print "\tDont say we did not warn you\n" - - def set_cleanables(self): - generic_stage_target.set_cleanables(self) - -def register(foo): - foo.update({"stage3":stage3_target}) - return foo diff --git a/catalyst/modules/stage4_target.py b/catalyst/modules/stage4_target.py deleted file mode 100644 index 9168f2e..0000000 --- a/catalyst/modules/stage4_target.py +++ /dev/null @@ -1,43 +0,0 @@ -""" -stage4 target, builds upon previous stage3/stage4 tarball -""" -# NOTE: That^^ docstring has influence catalyst-spec(5) man page generation. - -from catalyst.support import * -from generic_stage_target import * - -class stage4_target(generic_stage_target): - """ - Builder class for stage4. - """ - def __init__(self,spec,addlargs): - self.required_values=["stage4/packages"] - self.valid_values=self.required_values[:] - self.valid_values.extend(["stage4/use","boot/kernel",\ - "stage4/root_overlay","stage4/fsscript",\ - "stage4/gk_mainargs","splash_theme",\ - "portage_overlay","stage4/rcadd","stage4/rcdel",\ - "stage4/linuxrc","stage4/unmerge","stage4/rm","stage4/empty"]) - generic_stage_target.__init__(self,spec,addlargs) - - def set_cleanables(self): - self.settings["cleanables"]=["/var/tmp/*","/tmp/*"] - - def set_action_sequence(self): - self.settings["action_sequence"]=["unpack","unpack_snapshot",\ - "config_profile_link","setup_confdir","portage_overlay",\ - "bind","chroot_setup","setup_environment","build_packages",\ - "build_kernel","bootloader","root_overlay","fsscript",\ - "preclean","rcupdate","unmerge","unbind","remove","empty",\ - "clean"] - -# if "TARBALL" in self.settings or \ -# "FETCH" not in self.settings: - if "FETCH" not in self.settings: - self.settings["action_sequence"].append("capture") - self.settings["action_sequence"].append("clear_autoresume") - -def register(foo): - foo.update({"stage4":stage4_target}) - return foo - diff --git a/catalyst/modules/tinderbox_target.py b/catalyst/modules/tinderbox_target.py deleted file mode 100644 index 5985c5b..0000000 --- a/catalyst/modules/tinderbox_target.py +++ /dev/null @@ -1,44 +0,0 @@ -""" -Tinderbox target -""" -# NOTE: That^^ docstring has influence catalyst-spec(5) man page generation. - -from catalyst.support import * -from generic_stage_target import * - -class tinderbox_target(generic_stage_target): - """ - Builder class for the tinderbox target - """ - def __init__(self,spec,addlargs): - self.required_values=["tinderbox/packages"] - self.valid_values=self.required_values[:] - self.valid_values.extend(["tinderbox/use"]) - generic_stage_target.__init__(self,spec,addlargs) - - def run_local(self): - # tinderbox - # example call: "grp.sh run xmms vim sys-apps/gleep" - try: - if os.path.exists(self.settings["controller_file"]): - cmd("/bin/bash "+self.settings["controller_file"]+" run "+\ - list_bashify(self.settings["tinderbox/packages"]),"run script failed.",env=self.env) - - except CatalystError: - self.unbind() - raise CatalystError,"Tinderbox aborting due to error." - - def set_cleanables(self): - self.settings["cleanables"]=["/etc/resolv.conf","/var/tmp/*","/root/*", - self.settings['portdir']] - - def set_action_sequence(self): - #Default action sequence for run method - self.settings["action_sequence"]=["unpack","unpack_snapshot",\ - "config_profile_link","setup_confdir","bind","chroot_setup",\ - "setup_environment","run_local","preclean","unbind","clean",\ - "clear_autoresume"] - -def register(foo): - foo.update({"tinderbox":tinderbox_target}) - return foo diff --git a/catalyst/targets/__init__.py b/catalyst/targets/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/catalyst/targets/__init__.py @@ -0,0 +1 @@ + diff --git a/catalyst/targets/embedded_target.py b/catalyst/targets/embedded_target.py new file mode 100644 index 0000000..7cee7a6 --- /dev/null +++ b/catalyst/targets/embedded_target.py @@ -0,0 +1,51 @@ +""" +Enbedded target, similar to the stage2 target, builds upon a stage2 tarball. + +A stage2 tarball is unpacked, but instead +of building a stage3, it emerges @system into another directory +inside the stage2 system. This way, we do not have to emerge GCC/portage +into the staged system. +It may sound complicated but basically it runs +ROOT=/tmp/submerge emerge --something foo bar . +""" +# NOTE: That^^ docstring has influence catalyst-spec(5) man page generation. + +import os,string,imp,types,shutil +from catalyst.support import * +from generic_stage_target import * +from stat import * + +class embedded_target(generic_stage_target): + """ + Builder class for embedded target + """ + def __init__(self,spec,addlargs): + self.required_values=[] + self.valid_values=[] + self.valid_values.extend(["embedded/empty","embedded/rm","embedded/unmerge","embedded/fs-prepare","embedded/fs-finish","embedded/mergeroot","embedded/packages","embedded/fs-type","embedded/runscript","boot/kernel","embedded/linuxrc"]) + self.valid_values.extend(["embedded/use"]) + if "embedded/fs-type" in addlargs: + self.valid_values.append("embedded/fs-ops") + + generic_stage_target.__init__(self,spec,addlargs) + self.set_build_kernel_vars(addlargs) + + def set_action_sequence(self): + self.settings["action_sequence"]=["dir_setup","unpack","unpack_snapshot",\ + "config_profile_link","setup_confdir",\ + "portage_overlay","bind","chroot_setup",\ + "setup_environment","build_kernel","build_packages",\ + "bootloader","root_overlay","fsscript","unmerge",\ + "unbind","remove","empty","clean","capture","clear_autoresume"] + + def set_stage_path(self): + self.settings["stage_path"]=normpath(self.settings["chroot_path"]+"/tmp/mergeroot") + print "embedded stage path is "+self.settings["stage_path"] + + def set_root_path(self): + self.settings["root_path"]=normpath("/tmp/mergeroot") + print "embedded root path is "+self.settings["root_path"] + +def register(foo): + foo.update({"embedded":embedded_target}) + return foo diff --git a/catalyst/targets/generic_stage_target.py b/catalyst/targets/generic_stage_target.py new file mode 100644 index 0000000..5200d8a --- /dev/null +++ b/catalyst/targets/generic_stage_target.py @@ -0,0 +1,1691 @@ +import os,string,imp,types,shutil +from catalyst.support import * +from generic_target import * +from stat import * +from catalyst.lock import LockDir + +class generic_stage_target(generic_target): + """ + This class does all of the chroot setup, copying of files, etc. It is + the driver class for pretty much everything that Catalyst does. + """ + def __init__(self,myspec,addlargs): + self.required_values.extend(["version_stamp","target","subarch",\ + "rel_type","profile","snapshot","source_subpath"]) + + self.valid_values.extend(["version_stamp","target","subarch",\ + "rel_type","profile","snapshot","source_subpath","portage_confdir",\ + "cflags","cxxflags","ldflags","cbuild","hostuse","portage_overlay",\ + "distcc_hosts","makeopts","pkgcache_path","kerncache_path"]) + + self.set_valid_build_kernel_vars(addlargs) + generic_target.__init__(self,myspec,addlargs) + + """ + The semantics of subarchmap and machinemap changed a bit in 2.0.3 to + work better with vapier's CBUILD stuff. I've removed the "monolithic" + machinemap from this file and split up its contents amongst the + various arch/foo.py files. + + When register() is called on each module in the arch/ dir, it now + returns a tuple instead of acting on the subarchmap dict that is + passed to it. The tuple contains the values that were previously + added to subarchmap as well as a new list of CHOSTs that go along + with that arch. This allows us to build machinemap on the fly based + on the keys in subarchmap and the values of the 2nd list returned + (tmpmachinemap). + + Also, after talking with vapier. I have a slightly better idea of what + certain variables are used for and what they should be set to. Neither + 'buildarch' or 'hostarch' are used directly, so their value doesn't + really matter. They are just compared to determine if we are + cross-compiling. Because of this, they are just set to the name of the + module in arch/ that the subarch is part of to make things simpler. + The entire build process is still based off of 'subarch' like it was + previously. -agaffney + """ + + self.archmap = {} + self.subarchmap = {} + machinemap = {} + arch_dir = self.settings["PythonDir"] + "/arch/" + for x in [x[:-3] for x in os.listdir(arch_dir) if x.endswith(".py")]: + try: + fh=open(arch_dir + x + ".py") + """ + This next line loads the plugin as a module and assigns it to + archmap[x] + """ + self.archmap[x]=imp.load_module(x,fh,"../arch/" + x + ".py", + (".py", "r", imp.PY_SOURCE)) + """ + This next line registers all the subarches supported in the + plugin + """ + tmpsubarchmap, tmpmachinemap = self.archmap[x].register() + self.subarchmap.update(tmpsubarchmap) + for machine in tmpmachinemap: + machinemap[machine] = x + for subarch in tmpsubarchmap: + machinemap[subarch] = x + fh.close() + except IOError: + """ + This message should probably change a bit, since everything in + the dir should load just fine. If it doesn't, it's probably a + syntax error in the module + """ + msg("Can't find/load " + x + ".py plugin in " + arch_dir) + + if "chost" in self.settings: + hostmachine = self.settings["chost"].split("-")[0] + if hostmachine not in machinemap: + raise CatalystError, "Unknown host machine type "+hostmachine + self.settings["hostarch"]=machinemap[hostmachine] + else: + hostmachine = self.settings["subarch"] + if hostmachine in machinemap: + hostmachine = machinemap[hostmachine] + self.settings["hostarch"]=hostmachine + if "cbuild" in self.settings: + buildmachine = self.settings["cbuild"].split("-")[0] + else: + buildmachine = os.uname()[4] + if buildmachine not in machinemap: + raise CatalystError, "Unknown build machine type "+buildmachine + self.settings["buildarch"]=machinemap[buildmachine] + self.settings["crosscompile"]=(self.settings["hostarch"]!=\ + self.settings["buildarch"]) + + """ Call arch constructor, pass our settings """ + try: + self.arch=self.subarchmap[self.settings["subarch"]](self.settings) + except KeyError: + print "Invalid subarch: "+self.settings["subarch"] + print "Choose one of the following:", + for x in self.subarchmap: + print x, + print + sys.exit(2) + + print "Using target:",self.settings["target"] + """ Print a nice informational message """ + if self.settings["buildarch"]==self.settings["hostarch"]: + print "Building natively for",self.settings["hostarch"] + elif self.settings["crosscompile"]: + print "Cross-compiling on",self.settings["buildarch"],\ + "for different machine type",self.settings["hostarch"] + else: + print "Building on",self.settings["buildarch"],\ + "for alternate personality type",self.settings["hostarch"] + + """ This must be set first as other set_ options depend on this """ + self.set_spec_prefix() + + """ Define all of our core variables """ + self.set_target_profile() + self.set_target_subpath() + self.set_source_subpath() + + """ Set paths """ + self.set_snapshot_path() + self.set_root_path() + self.set_source_path() + self.set_snapcache_path() + self.set_chroot_path() + self.set_autoresume_path() + self.set_dest_path() + self.set_stage_path() + self.set_target_path() + + self.set_controller_file() + self.set_action_sequence() + self.set_use() + self.set_cleanables() + self.set_iso_volume_id() + self.set_build_kernel_vars() + self.set_fsscript() + self.set_install_mask() + self.set_rcadd() + self.set_rcdel() + self.set_cdtar() + self.set_fstype() + self.set_fsops() + self.set_iso() + self.set_packages() + self.set_rm() + self.set_linuxrc() + self.set_busybox_config() + self.set_overlay() + self.set_portage_overlay() + self.set_root_overlay() + + """ + This next line checks to make sure that the specified variables exist + on disk. + """ + #pdb.set_trace() + file_locate(self.settings,["source_path","snapshot_path","distdir"],\ + expand=0) + """ If we are using portage_confdir, check that as well. """ + if "portage_confdir" in self.settings: + file_locate(self.settings,["portage_confdir"],expand=0) + + """ Setup our mount points """ + if "SNAPCACHE" in self.settings: + self.mounts=["/proc","/dev","/usr/portage","/usr/portage/distfiles","/var/tmp/portage"] + self.mountmap={"/proc":"/proc","/dev":"/dev","/dev/pts":"/dev/pts",\ + "/usr/portage":self.settings["snapshot_cache_path"]+"/portage",\ + "/usr/portage/distfiles":self.settings["distdir"],"/var/tmp/portage":"tmpfs"} + else: + self.mounts=["proc","dev", "distdir", "port_tmpdir"] + self.mountmap={"proc":"/proc", "dev":"/dev", "pts":"/dev/pts", + "distdir":self.settings["distdir"], "port_tmpdir":"tmpfs"} + if os.uname()[0] == "Linux": + self.mounts.append("pts") + + self.set_mounts() + + """ + Configure any user specified options (either in catalyst.conf or on + the command line). + """ + if "PKGCACHE" in self.settings: + self.set_pkgcache_path() + print "Location of the package cache is "+\ + self.settings["pkgcache_path"] + self.mounts.append("packagedir") + self.mountmap["packagedir"] = self.settings["pkgcache_path"] + + if "KERNCACHE" in self.settings: + self.set_kerncache_path() + print "Location of the kerncache is "+\ + self.settings["kerncache_path"] + self.mounts.append("kerncache") + self.mountmap["kerncache"]=self.settings["kerncache_path"] + + if "CCACHE" in self.settings: + if "CCACHE_DIR" in os.environ: + ccdir=os.environ["CCACHE_DIR"] + del os.environ["CCACHE_DIR"] + else: + ccdir="/root/.ccache" + if not os.path.isdir(ccdir): + raise CatalystError,\ + "Compiler cache support can't be enabled (can't find "+\ + ccdir+")" + self.mounts.append("ccache") + self.mountmap["ccache"]=ccdir + """ for the chroot: """ + self.env["CCACHE_DIR"]="/var/tmp/ccache" + + if "ICECREAM" in self.settings: + self.mounts.append("/var/cache/icecream") + self.mountmap["/var/cache/icecream"]="/var/cache/icecream" + self.env["PATH"]="/usr/lib/icecc/bin:"+self.env["PATH"] + + if "port_logdir" in self.settings: + self.mounts.append("/var/log/portage") + self.mountmap["/var/log/portage"]=self.settings["port_logdir"] + self.env["PORT_LOGDIR"]="/var/log/portage" + self.env["PORT_LOGDIR_CLEAN"]='find "${PORT_LOGDIR}" -type f ! -name "summary.log*" -mtime +30 -delete' + + def override_cbuild(self): + if "CBUILD" in self.makeconf: + self.settings["CBUILD"]=self.makeconf["CBUILD"] + + def override_chost(self): + if "CHOST" in self.makeconf: + self.settings["CHOST"]=self.makeconf["CHOST"] + + def override_cflags(self): + if "CFLAGS" in self.makeconf: + self.settings["CFLAGS"]=self.makeconf["CFLAGS"] + + def override_cxxflags(self): + if "CXXFLAGS" in self.makeconf: + self.settings["CXXFLAGS"]=self.makeconf["CXXFLAGS"] + + def override_ldflags(self): + if "LDFLAGS" in self.makeconf: + self.settings["LDFLAGS"]=self.makeconf["LDFLAGS"] + + def set_install_mask(self): + if "install_mask" in self.settings: + if type(self.settings["install_mask"])!=types.StringType: + self.settings["install_mask"]=\ + string.join(self.settings["install_mask"]) + + def set_spec_prefix(self): + self.settings["spec_prefix"]=self.settings["target"] + + def set_target_profile(self): + self.settings["target_profile"]=self.settings["profile"] + + def set_target_subpath(self): + self.settings["target_subpath"]=self.settings["rel_type"]+"/"+\ + self.settings["target"]+"-"+self.settings["subarch"]+"-"+\ + self.settings["version_stamp"] + + def set_source_subpath(self): + if type(self.settings["source_subpath"])!=types.StringType: + raise CatalystError,\ + "source_subpath should have been a string. Perhaps you have something wrong in your spec file?" + + def set_pkgcache_path(self): + if "pkgcache_path" in self.settings: + if type(self.settings["pkgcache_path"])!=types.StringType: + self.settings["pkgcache_path"]=\ + normpath(string.join(self.settings["pkgcache_path"])) + else: + self.settings["pkgcache_path"]=\ + normpath(self.settings["storedir"]+"/packages/"+\ + self.settings["target_subpath"]+"/") + + def set_kerncache_path(self): + if "kerncache_path" in self.settings: + if type(self.settings["kerncache_path"])!=types.StringType: + self.settings["kerncache_path"]=\ + normpath(string.join(self.settings["kerncache_path"])) + else: + self.settings["kerncache_path"]=normpath(self.settings["storedir"]+\ + "/kerncache/"+self.settings["target_subpath"]+"/") + + def set_target_path(self): + self.settings["target_path"]=normpath(self.settings["storedir"]+\ + "/builds/"+self.settings["target_subpath"]+".tar.bz2") + if "AUTORESUME" in self.settings\ + and os.path.exists(self.settings["autoresume_path"]+\ + "setup_target_path"): + print \ + "Resume point detected, skipping target path setup operation..." + else: + """ First clean up any existing target stuff """ + # XXX WTF are we removing the old tarball before we start building the + # XXX new one? If the build fails, you don't want to be left with + # XXX nothing at all +# if os.path.isfile(self.settings["target_path"]): +# cmd("rm -f "+self.settings["target_path"],\ +# "Could not remove existing file: "\ +# +self.settings["target_path"],env=self.env) + touch(self.settings["autoresume_path"]+"setup_target_path") + + if not os.path.exists(self.settings["storedir"]+"/builds/"): + os.makedirs(self.settings["storedir"]+"/builds/") + + def set_fsscript(self): + if self.settings["spec_prefix"]+"/fsscript" in self.settings: + self.settings["fsscript"]=\ + self.settings[self.settings["spec_prefix"]+"/fsscript"] + del self.settings[self.settings["spec_prefix"]+"/fsscript"] + + def set_rcadd(self): + if self.settings["spec_prefix"]+"/rcadd" in self.settings: + self.settings["rcadd"]=\ + self.settings[self.settings["spec_prefix"]+"/rcadd"] + del self.settings[self.settings["spec_prefix"]+"/rcadd"] + + def set_rcdel(self): + if self.settings["spec_prefix"]+"/rcdel" in self.settings: + self.settings["rcdel"]=\ + self.settings[self.settings["spec_prefix"]+"/rcdel"] + del self.settings[self.settings["spec_prefix"]+"/rcdel"] + + def set_cdtar(self): + if self.settings["spec_prefix"]+"/cdtar" in self.settings: + self.settings["cdtar"]=\ + normpath(self.settings[self.settings["spec_prefix"]+"/cdtar"]) + del self.settings[self.settings["spec_prefix"]+"/cdtar"] + + def set_iso(self): + if self.settings["spec_prefix"]+"/iso" in self.settings: + if self.settings[self.settings["spec_prefix"]+"/iso"].startswith('/'): + self.settings["iso"]=\ + normpath(self.settings[self.settings["spec_prefix"]+"/iso"]) + else: + # This automatically prepends the build dir to the ISO output path + # if it doesn't start with a / + self.settings["iso"] = normpath(self.settings["storedir"] + \ + "/builds/" + self.settings["rel_type"] + "/" + \ + self.settings[self.settings["spec_prefix"]+"/iso"]) + del self.settings[self.settings["spec_prefix"]+"/iso"] + + def set_fstype(self): + if self.settings["spec_prefix"]+"/fstype" in self.settings: + self.settings["fstype"]=\ + self.settings[self.settings["spec_prefix"]+"/fstype"] + del self.settings[self.settings["spec_prefix"]+"/fstype"] + + if "fstype" not in self.settings: + self.settings["fstype"]="normal" + for x in self.valid_values: + if x == self.settings["spec_prefix"]+"/fstype": + print "\n"+self.settings["spec_prefix"]+\ + "/fstype is being set to the default of \"normal\"\n" + + def set_fsops(self): + if "fstype" in self.settings: + self.valid_values.append("fsops") + if self.settings["spec_prefix"]+"/fsops" in self.settings: + self.settings["fsops"]=\ + self.settings[self.settings["spec_prefix"]+"/fsops"] + del self.settings[self.settings["spec_prefix"]+"/fsops"] + + def set_source_path(self): + if "SEEDCACHE" in self.settings\ + and os.path.isdir(normpath(self.settings["storedir"]+"/tmp/"+\ + self.settings["source_subpath"]+"/")): + self.settings["source_path"]=normpath(self.settings["storedir"]+\ + "/tmp/"+self.settings["source_subpath"]+"/") + else: + self.settings["source_path"]=normpath(self.settings["storedir"]+\ + "/builds/"+self.settings["source_subpath"]+".tar.bz2") + if os.path.isfile(self.settings["source_path"]): + # XXX: Is this even necessary if the previous check passes? + if os.path.exists(self.settings["source_path"]): + self.settings["source_path_hash"]=\ + generate_hash(self.settings["source_path"],\ + hash_function=self.settings["hash_function"],\ + verbose=False) + print "Source path set to "+self.settings["source_path"] + if os.path.isdir(self.settings["source_path"]): + print "\tIf this is not desired, remove this directory or turn off" + print "\tseedcache in the options of catalyst.conf the source path" + print "\twill then be "+\ + normpath(self.settings["storedir"]+"/builds/"+\ + self.settings["source_subpath"]+".tar.bz2\n") + + def set_dest_path(self): + if "root_path" in self.settings: + self.settings["destpath"]=normpath(self.settings["chroot_path"]+\ + self.settings["root_path"]) + else: + self.settings["destpath"]=normpath(self.settings["chroot_path"]) + + def set_cleanables(self): + self.settings["cleanables"]=["/etc/resolv.conf","/var/tmp/*","/tmp/*",\ + "/root/*", self.settings["portdir"]] + + def set_snapshot_path(self): + self.settings["snapshot_path"]=normpath(self.settings["storedir"]+\ + "/snapshots/" + self.settings["snapshot_name"] + + self.settings["snapshot"]+".tar.xz") + + if os.path.exists(self.settings["snapshot_path"]): + self.settings["snapshot_path_hash"]=\ + generate_hash(self.settings["snapshot_path"],\ + hash_function=self.settings["hash_function"],verbose=False) + else: + self.settings["snapshot_path"]=normpath(self.settings["storedir"]+\ + "/snapshots/" + self.settings["snapshot_name"] + + self.settings["snapshot"]+".tar.bz2") + + if os.path.exists(self.settings["snapshot_path"]): + self.settings["snapshot_path_hash"]=\ + generate_hash(self.settings["snapshot_path"],\ + hash_function=self.settings["hash_function"],verbose=False) + + def set_snapcache_path(self): + if "SNAPCACHE" in self.settings: + self.settings["snapshot_cache_path"]=\ + normpath(self.settings["snapshot_cache"]+"/"+\ + self.settings["snapshot"]+"/") + self.snapcache_lock=\ + LockDir(self.settings["snapshot_cache_path"]) + print "Caching snapshot to "+self.settings["snapshot_cache_path"] + + def set_chroot_path(self): + """ + NOTE: the trailing slash is very important! + Things *will* break without it! + """ + self.settings["chroot_path"]=normpath(self.settings["storedir"]+\ + "/tmp/"+self.settings["target_subpath"]+"/") + self.chroot_lock=LockDir(self.settings["chroot_path"]) + + def set_autoresume_path(self): + self.settings["autoresume_path"]=normpath(self.settings["storedir"]+\ + "/tmp/"+self.settings["rel_type"]+"/"+".autoresume-"+\ + self.settings["target"]+"-"+self.settings["subarch"]+"-"+\ + self.settings["version_stamp"]+"/") + if "AUTORESUME" in self.settings: + print "The autoresume path is " + self.settings["autoresume_path"] + if not os.path.exists(self.settings["autoresume_path"]): + os.makedirs(self.settings["autoresume_path"],0755) + + def set_controller_file(self): + self.settings["controller_file"]=normpath(self.settings["sharedir"]+\ + "/targets/"+self.settings["target"]+"/"+self.settings["target"]+\ + "-controller.sh") + + def set_iso_volume_id(self): + if self.settings["spec_prefix"]+"/volid" in self.settings: + self.settings["iso_volume_id"]=\ + self.settings[self.settings["spec_prefix"]+"/volid"] + if len(self.settings["iso_volume_id"])>32: + raise CatalystError,\ + "ISO volume ID must not exceed 32 characters." + else: + self.settings["iso_volume_id"]="catalyst "+self.settings["snapshot"] + + def set_action_sequence(self): + """ Default action sequence for run method """ + self.settings["action_sequence"]=["unpack","unpack_snapshot",\ + "setup_confdir","portage_overlay",\ + "base_dirs","bind","chroot_setup","setup_environment",\ + "run_local","preclean","unbind","clean"] +# if "TARBALL" in self.settings or \ +# "FETCH" not in self.settings: + if "FETCH" not in self.settings: + self.settings["action_sequence"].append("capture") + self.settings["action_sequence"].append("clear_autoresume") + + def set_use(self): + if self.settings["spec_prefix"]+"/use" in self.settings: + self.settings["use"]=\ + self.settings[self.settings["spec_prefix"]+"/use"] + del self.settings[self.settings["spec_prefix"]+"/use"] + if "use" not in self.settings: + self.settings["use"]="" + if type(self.settings["use"])==types.StringType: + self.settings["use"]=self.settings["use"].split() + + # Force bindist when options ask for it + if "BINDIST" in self.settings: + self.settings["use"].append("bindist") + + def set_stage_path(self): + self.settings["stage_path"]=normpath(self.settings["chroot_path"]) + + def set_mounts(self): + pass + + def set_packages(self): + pass + + def set_rm(self): + if self.settings["spec_prefix"]+"/rm" in self.settings: + if type(self.settings[self.settings["spec_prefix"]+\ + "/rm"])==types.StringType: + self.settings[self.settings["spec_prefix"]+"/rm"]=\ + self.settings[self.settings["spec_prefix"]+"/rm"].split() + + def set_linuxrc(self): + if self.settings["spec_prefix"]+"/linuxrc" in self.settings: + if type(self.settings[self.settings["spec_prefix"]+\ + "/linuxrc"])==types.StringType: + self.settings["linuxrc"]=\ + self.settings[self.settings["spec_prefix"]+"/linuxrc"] + del self.settings[self.settings["spec_prefix"]+"/linuxrc"] + + def set_busybox_config(self): + if self.settings["spec_prefix"]+"/busybox_config" in self.settings: + if type(self.settings[self.settings["spec_prefix"]+\ + "/busybox_config"])==types.StringType: + self.settings["busybox_config"]=\ + self.settings[self.settings["spec_prefix"]+"/busybox_config"] + del self.settings[self.settings["spec_prefix"]+"/busybox_config"] + + def set_portage_overlay(self): + if "portage_overlay" in self.settings: + if type(self.settings["portage_overlay"])==types.StringType: + self.settings["portage_overlay"]=\ + self.settings["portage_overlay"].split() + print "portage_overlay directories are set to: \""+\ + string.join(self.settings["portage_overlay"])+"\"" + + def set_overlay(self): + if self.settings["spec_prefix"]+"/overlay" in self.settings: + if type(self.settings[self.settings["spec_prefix"]+\ + "/overlay"])==types.StringType: + self.settings[self.settings["spec_prefix"]+"/overlay"]=\ + self.settings[self.settings["spec_prefix"]+\ + "/overlay"].split() + + def set_root_overlay(self): + if self.settings["spec_prefix"]+"/root_overlay" in self.settings: + if type(self.settings[self.settings["spec_prefix"]+\ + "/root_overlay"])==types.StringType: + self.settings[self.settings["spec_prefix"]+"/root_overlay"]=\ + self.settings[self.settings["spec_prefix"]+\ + "/root_overlay"].split() + + def set_root_path(self): + """ ROOT= variable for emerges """ + self.settings["root_path"]="/" + + def set_valid_build_kernel_vars(self,addlargs): + if "boot/kernel" in addlargs: + if type(addlargs["boot/kernel"])==types.StringType: + loopy=[addlargs["boot/kernel"]] + else: + loopy=addlargs["boot/kernel"] + + for x in loopy: + self.valid_values.append("boot/kernel/"+x+"/aliases") + self.valid_values.append("boot/kernel/"+x+"/config") + self.valid_values.append("boot/kernel/"+x+"/console") + self.valid_values.append("boot/kernel/"+x+"/extraversion") + self.valid_values.append("boot/kernel/"+x+"/gk_action") + self.valid_values.append("boot/kernel/"+x+"/gk_kernargs") + self.valid_values.append("boot/kernel/"+x+"/initramfs_overlay") + self.valid_values.append("boot/kernel/"+x+"/machine_type") + self.valid_values.append("boot/kernel/"+x+"/sources") + self.valid_values.append("boot/kernel/"+x+"/softlevel") + self.valid_values.append("boot/kernel/"+x+"/use") + self.valid_values.append("boot/kernel/"+x+"/packages") + if "boot/kernel/"+x+"/packages" in addlargs: + if type(addlargs["boot/kernel/"+x+\ + "/packages"])==types.StringType: + addlargs["boot/kernel/"+x+"/packages"]=\ + [addlargs["boot/kernel/"+x+"/packages"]] + + def set_build_kernel_vars(self): + if self.settings["spec_prefix"]+"/gk_mainargs" in self.settings: + self.settings["gk_mainargs"]=\ + self.settings[self.settings["spec_prefix"]+"/gk_mainargs"] + del self.settings[self.settings["spec_prefix"]+"/gk_mainargs"] + + def kill_chroot_pids(self): + print "Checking for processes running in chroot and killing them." + + """ + Force environment variables to be exported so script can see them + """ + self.setup_environment() + + if os.path.exists(self.settings["sharedir"]+\ + "/targets/support/kill-chroot-pids.sh"): + cmd("/bin/bash "+self.settings["sharedir"]+\ + "/targets/support/kill-chroot-pids.sh",\ + "kill-chroot-pids script failed.",env=self.env) + + def mount_safety_check(self): + mypath=self.settings["chroot_path"] + + """ + Check and verify that none of our paths in mypath are mounted. We don't + want to clean up with things still mounted, and this allows us to check. + Returns 1 on ok, 0 on "something is still mounted" case. + """ + + if not os.path.exists(mypath): + return + + for x in self.mounts: + if not os.path.exists(mypath + self.mountmap[x]): + continue + + if ismount(mypath +self.mountmap[x]): + """ Something is still mounted "" """ + try: + print self.mountmap[x] + " is still mounted; performing auto-bind-umount...", + """ Try to umount stuff ourselves """ + self.unbind() + if ismount(mypath + self.mountmap[x]): + raise CatalystError, "Auto-unbind failed for " + self.mountmap[x] + else: + print "Auto-unbind successful..." + except CatalystError: + raise CatalystError, "Unable to auto-unbind " + self.mountmap[x] + + def unpack(self): + unpack=True + + clst_unpack_hash=read_from_clst(self.settings["autoresume_path"]+\ + "unpack") + + if "SEEDCACHE" in self.settings: + if os.path.isdir(self.settings["source_path"]): + """ SEEDCACHE Is a directory, use rsync """ + unpack_cmd="rsync -a --delete "+self.settings["source_path"]+\ + " "+self.settings["chroot_path"] + display_msg="\nStarting rsync from "+\ + self.settings["source_path"]+"\nto "+\ + self.settings["chroot_path"]+\ + " (This may take some time) ...\n" + error_msg="Rsync of "+self.settings["source_path"]+" to "+\ + self.settings["chroot_path"]+" failed." + else: + """ SEEDCACHE is a not a directory, try untar'ing """ + print "Referenced SEEDCACHE does not appear to be a directory, trying to untar..." + display_msg="\nStarting tar extract from "+\ + self.settings["source_path"]+"\nto "+\ + self.settings["chroot_path"]+\ + " (This may take some time) ...\n" + if "bz2" == self.settings["chroot_path"][-3:]: + unpack_cmd="tar -I lbzip2 -xpf "+self.settings["source_path"]+" -C "+\ + self.settings["chroot_path"] + else: + unpack_cmd="tar -I lbzip2 -xpf "+self.settings["source_path"]+" -C "+\ + self.settings["chroot_path"] + error_msg="Tarball extraction of "+\ + self.settings["source_path"]+" to "+\ + self.settings["chroot_path"]+" failed." + else: + """ No SEEDCACHE, use tar """ + display_msg="\nStarting tar extract from "+\ + self.settings["source_path"]+"\nto "+\ + self.settings["chroot_path"]+\ + " (This may take some time) ...\n" + if "bz2" == self.settings["chroot_path"][-3:]: + unpack_cmd="tar -I lbzip2 -xpf "+self.settings["source_path"]+" -C "+\ + self.settings["chroot_path"] + else: + unpack_cmd="tar -I lbzip2 -xpf "+self.settings["source_path"]+" -C "+\ + self.settings["chroot_path"] + error_msg="Tarball extraction of "+self.settings["source_path"]+\ + " to "+self.settings["chroot_path"]+" failed." + + if "AUTORESUME" in self.settings: + if os.path.isdir(self.settings["source_path"]) \ + and os.path.exists(self.settings["autoresume_path"]+"unpack"): + """ Autoresume is valid, SEEDCACHE is valid """ + unpack=False + invalid_snapshot=False + + elif os.path.isfile(self.settings["source_path"]) \ + and self.settings["source_path_hash"]==clst_unpack_hash: + """ Autoresume is valid, tarball is valid """ + unpack=False + invalid_snapshot=True + + elif os.path.isdir(self.settings["source_path"]) \ + and not os.path.exists(self.settings["autoresume_path"]+\ + "unpack"): + """ Autoresume is invalid, SEEDCACHE """ + unpack=True + invalid_snapshot=False + + elif os.path.isfile(self.settings["source_path"]) \ + and self.settings["source_path_hash"]!=clst_unpack_hash: + """ Autoresume is invalid, tarball """ + unpack=True + invalid_snapshot=True + else: + """ No autoresume, SEEDCACHE """ + if "SEEDCACHE" in self.settings: + """ SEEDCACHE so let's run rsync and let it clean up """ + if os.path.isdir(self.settings["source_path"]): + unpack=True + invalid_snapshot=False + elif os.path.isfile(self.settings["source_path"]): + """ Tarball so unpack and remove anything already there """ + unpack=True + invalid_snapshot=True + """ No autoresume, no SEEDCACHE """ + else: + """ Tarball so unpack and remove anything already there """ + if os.path.isfile(self.settings["source_path"]): + unpack=True + invalid_snapshot=True + elif os.path.isdir(self.settings["source_path"]): + """ We should never reach this, so something is very wrong """ + raise CatalystError,\ + "source path is a dir but seedcache is not enabled" + + if unpack: + self.mount_safety_check() + + if invalid_snapshot: + if "AUTORESUME" in self.settings: + print "No Valid Resume point detected, cleaning up..." + + self.clear_autoresume() + self.clear_chroot() + + if not os.path.exists(self.settings["chroot_path"]): + os.makedirs(self.settings["chroot_path"]) + + if not os.path.exists(self.settings["chroot_path"]+"/tmp"): + os.makedirs(self.settings["chroot_path"]+"/tmp",1777) + + if "PKGCACHE" in self.settings: + if not os.path.exists(self.settings["pkgcache_path"]): + os.makedirs(self.settings["pkgcache_path"],0755) + + if "KERNCACHE" in self.settings: + if not os.path.exists(self.settings["kerncache_path"]): + os.makedirs(self.settings["kerncache_path"],0755) + + print display_msg + cmd(unpack_cmd,error_msg,env=self.env) + + if "source_path_hash" in self.settings: + myf=open(self.settings["autoresume_path"]+"unpack","w") + myf.write(self.settings["source_path_hash"]) + myf.close() + else: + touch(self.settings["autoresume_path"]+"unpack") + else: + print "Resume point detected, skipping unpack operation..." + + def unpack_snapshot(self): + unpack=True + snapshot_hash=read_from_clst(self.settings["autoresume_path"]+\ + "unpack_portage") + + if "SNAPCACHE" in self.settings: + snapshot_cache_hash=\ + read_from_clst(self.settings["snapshot_cache_path"]+\ + "catalyst-hash") + destdir=self.settings["snapshot_cache_path"] + if "bz2" == self.settings["chroot_path"][-3:]: + unpack_cmd="tar -I lbzip2 -xpf "+self.settings["snapshot_path"]+" -C "+destdir + else: + unpack_cmd="tar xpf "+self.settings["snapshot_path"]+" -C "+destdir + unpack_errmsg="Error unpacking snapshot" + cleanup_msg="Cleaning up invalid snapshot cache at \n\t"+\ + self.settings["snapshot_cache_path"]+\ + " (This can take a long time)..." + cleanup_errmsg="Error removing existing snapshot cache directory." + self.snapshot_lock_object=self.snapcache_lock + + if self.settings["snapshot_path_hash"]==snapshot_cache_hash: + print "Valid snapshot cache, skipping unpack of portage tree..." + unpack=False + else: + destdir=normpath(self.settings["chroot_path"] + self.settings["portdir"]) + cleanup_errmsg="Error removing existing snapshot directory." + cleanup_msg=\ + "Cleaning up existing portage tree (This can take a long time)..." + if "bz2" == self.settings["chroot_path"][-3:]: + unpack_cmd="tar -I lbzip2 -xpf "+self.settings["snapshot_path"]+" -C "+\ + self.settings["chroot_path"]+"/usr" + else: + unpack_cmd="tar xpf "+self.settings["snapshot_path"]+" -C "+\ + self.settings["chroot_path"]+"/usr" + unpack_errmsg="Error unpacking snapshot" + + if "AUTORESUME" in self.settings \ + and os.path.exists(self.settings["chroot_path"]+\ + self.settings["portdir"]) \ + and os.path.exists(self.settings["autoresume_path"]\ + +"unpack_portage") \ + and self.settings["snapshot_path_hash"] == snapshot_hash: + print \ + "Valid Resume point detected, skipping unpack of portage tree..." + unpack=False + + if unpack: + if "SNAPCACHE" in self.settings: + self.snapshot_lock_object.write_lock() + if os.path.exists(destdir): + print cleanup_msg + cleanup_cmd="rm -rf "+destdir + cmd(cleanup_cmd,cleanup_errmsg,env=self.env) + if not os.path.exists(destdir): + os.makedirs(destdir,0755) + + print "Unpacking portage tree (This can take a long time) ..." + cmd(unpack_cmd,unpack_errmsg,env=self.env) + + if "SNAPCACHE" in self.settings: + myf=open(self.settings["snapshot_cache_path"]+"catalyst-hash","w") + myf.write(self.settings["snapshot_path_hash"]) + myf.close() + else: + print "Setting snapshot autoresume point" + myf=open(self.settings["autoresume_path"]+"unpack_portage","w") + myf.write(self.settings["snapshot_path_hash"]) + myf.close() + + if "SNAPCACHE" in self.settings: + self.snapshot_lock_object.unlock() + + def config_profile_link(self): + if "AUTORESUME" in self.settings \ + and os.path.exists(self.settings["autoresume_path"]+\ + "config_profile_link"): + print \ + "Resume point detected, skipping config_profile_link operation..." + else: + # TODO: zmedico and I discussed making this a directory and pushing + # in a parent file, as well as other user-specified configuration. + print "Configuring profile link..." + cmd("rm -f "+self.settings["chroot_path"]+"/etc/portage/make.profile",\ + "Error zapping profile link",env=self.env) + cmd("mkdir -p "+self.settings["chroot_path"]+"/etc/portage/") + cmd("ln -sf ../.." + self.settings["portdir"] + "/profiles/"+\ + self.settings["target_profile"]+" "+\ + self.settings["chroot_path"]+"/etc/portage/make.profile",\ + "Error creating profile link",env=self.env) + touch(self.settings["autoresume_path"]+"config_profile_link") + + def setup_confdir(self): + if "AUTORESUME" in self.settings \ + and os.path.exists(self.settings["autoresume_path"]+\ + "setup_confdir"): + print "Resume point detected, skipping setup_confdir operation..." + else: + if "portage_confdir" in self.settings: + print "Configuring /etc/portage..." + cmd("rsync -a "+self.settings["portage_confdir"]+"/ "+\ + self.settings["chroot_path"]+"/etc/portage/",\ + "Error copying /etc/portage",env=self.env) + touch(self.settings["autoresume_path"]+"setup_confdir") + + def portage_overlay(self): + """ We copy the contents of our overlays to /usr/local/portage """ + if "portage_overlay" in self.settings: + for x in self.settings["portage_overlay"]: + if os.path.exists(x): + print "Copying overlay dir " +x + cmd("mkdir -p "+self.settings["chroot_path"]+\ + self.settings["local_overlay"],\ + "Could not make portage_overlay dir",env=self.env) + cmd("cp -R "+x+"/* "+self.settings["chroot_path"]+\ + self.settings["local_overlay"],\ + "Could not copy portage_overlay",env=self.env) + + def root_overlay(self): + """ Copy over the root_overlay """ + if self.settings["spec_prefix"]+"/root_overlay" in self.settings: + for x in self.settings[self.settings["spec_prefix"]+\ + "/root_overlay"]: + if os.path.exists(x): + print "Copying root_overlay: "+x + cmd("rsync -a "+x+"/ "+\ + self.settings["chroot_path"],\ + self.settings["spec_prefix"]+"/root_overlay: "+x+\ + " copy failed.",env=self.env) + + def base_dirs(self): + pass + + def bind(self): + for x in self.mounts: + if not os.path.exists(self.settings["chroot_path"] + self.mountmap[x]): + os.makedirs(self.settings["chroot_path"]+x,0755) + + if not os.path.exists(self.mountmap[x]): + if not self.mountmap[x] == "tmpfs": + os.makedirs(self.mountmap[x],0755) + + src=self.mountmap[x] + if "SNAPCACHE" in self.settings and x == "/usr/portage": + self.snapshot_lock_object.read_lock() + if os.uname()[0] == "FreeBSD": + if src == "/dev": + retval=os.system("mount -t devfs none " + + self.settings["chroot_path"] + src) + else: + retval=os.system("mount_nullfs " + src + " " + + self.settings["chroot_path"] + src) + else: + if src == "tmpfs": + if "var_tmpfs_portage" in self.settings: + retval=os.system("mount -t tmpfs -o size="+\ + self.settings["var_tmpfs_portage"]+"G "+src+" "+\ + self.settings["chroot_path"]+x) + else: + retval=os.system("mount --bind " + src + " " + + self.settings["chroot_path"] + src) + if retval!=0: + self.unbind() + raise CatalystError,"Couldn't bind mount " + src + + def unbind(self): + ouch=0 + mypath=self.settings["chroot_path"] + myrevmounts=self.mounts[:] + myrevmounts.reverse() + """ Unmount in reverse order for nested bind-mounts """ + for x in myrevmounts: + if not os.path.exists(mypath + self.mountmap[x]): + continue + + if not ismount(mypath + self.mountmap[x]): + continue + + retval=os.system("umount "+\ + os.path.join(mypath, self.mountmap[x].lstrip(os.path.sep))) + + if retval!=0: + warn("First attempt to unmount: " + mypath + + self.mountmap[x] +" failed.") + warn("Killing any pids still running in the chroot") + + self.kill_chroot_pids() + + retval2=os.system("umount " + mypath + self.mountmap[x]) + if retval2!=0: + ouch=1 + warn("Couldn't umount bind mount: " + mypath + self.mountmap[x]) + + if "SNAPCACHE" in self.settings and x == "/usr/portage": + try: + """ + It's possible the snapshot lock object isn't created yet. + This is because mount safety check calls unbind before the + target is fully initialized + """ + self.snapshot_lock_object.unlock() + except: + pass + if ouch: + """ + if any bind mounts really failed, then we need to raise + this to potentially prevent an upcoming bash stage cleanup script + from wiping our bind mounts. + """ + raise CatalystError,\ + "Couldn't umount one or more bind-mounts; aborting for safety." + + def chroot_setup(self): + self.makeconf=read_makeconf(self.settings["chroot_path"]+\ + "/etc/portage/make.conf") + self.override_cbuild() + self.override_chost() + self.override_cflags() + self.override_cxxflags() + self.override_ldflags() + if "AUTORESUME" in self.settings \ + and os.path.exists(self.settings["autoresume_path"]+"chroot_setup"): + print "Resume point detected, skipping chroot_setup operation..." + else: + print "Setting up chroot..." + + #self.makeconf=read_makeconf(self.settings["chroot_path"]+"/etc/portage/make.conf") + + cmd("cp /etc/resolv.conf "+self.settings["chroot_path"]+"/etc",\ + "Could not copy resolv.conf into place.",env=self.env) + + """ Copy over the envscript, if applicable """ + if "ENVSCRIPT" in self.settings: + if not os.path.exists(self.settings["ENVSCRIPT"]): + raise CatalystError,\ + "Can't find envscript "+self.settings["ENVSCRIPT"] + + print "\nWarning!!!!" + print "\tOverriding certain env variables may cause catastrophic failure." + print "\tIf your build fails look here first as the possible problem." + print "\tCatalyst assumes you know what you are doing when setting" + print "\t\tthese variables." + print "\tCatalyst Maintainers use VERY minimal envscripts if used at all" + print "\tYou have been warned\n" + + cmd("cp "+self.settings["ENVSCRIPT"]+" "+\ + self.settings["chroot_path"]+"/tmp/envscript",\ + "Could not copy envscript into place.",env=self.env) + + """ + Copy over /etc/hosts from the host in case there are any + specialties in there + """ + if os.path.exists(self.settings["chroot_path"]+"/etc/hosts"): + cmd("mv "+self.settings["chroot_path"]+"/etc/hosts "+\ + self.settings["chroot_path"]+"/etc/hosts.catalyst",\ + "Could not backup /etc/hosts",env=self.env) + cmd("cp /etc/hosts "+self.settings["chroot_path"]+"/etc/hosts",\ + "Could not copy /etc/hosts",env=self.env) + + """ Modify and write out make.conf (for the chroot) """ + cmd("rm -f "+self.settings["chroot_path"]+"/etc/portage/make.conf",\ + "Could not remove "+self.settings["chroot_path"]+\ + "/etc/portage/make.conf",env=self.env) + myf=open(self.settings["chroot_path"]+"/etc/portage/make.conf","w") + myf.write("# These settings were set by the catalyst build script that automatically\n# built this stage.\n") + myf.write("# Please consult /usr/share/portage/config/make.conf.example for a more\n# detailed example.\n") + if "CFLAGS" in self.settings: + myf.write('CFLAGS="'+self.settings["CFLAGS"]+'"\n') + if "CXXFLAGS" in self.settings: + if self.settings["CXXFLAGS"]!=self.settings["CFLAGS"]: + myf.write('CXXFLAGS="'+self.settings["CXXFLAGS"]+'"\n') + else: + myf.write('CXXFLAGS="${CFLAGS}"\n') + else: + myf.write('CXXFLAGS="${CFLAGS}"\n') + + if "LDFLAGS" in self.settings: + myf.write("# LDFLAGS is unsupported. USE AT YOUR OWN RISK!\n") + myf.write('LDFLAGS="'+self.settings["LDFLAGS"]+'"\n') + if "CBUILD" in self.settings: + myf.write("# This should not be changed unless you know exactly what you are doing. You\n# should probably be using a different stage, instead.\n") + myf.write('CBUILD="'+self.settings["CBUILD"]+'"\n') + + myf.write("# WARNING: Changing your CHOST is not something that should be done lightly.\n# Please consult http://www.gentoo.org/doc/en/change-chost.xml before changing.\n") + myf.write('CHOST="'+self.settings["CHOST"]+'"\n') + + """ Figure out what our USE vars are for building """ + myusevars=[] + if "HOSTUSE" in self.settings: + myusevars.extend(self.settings["HOSTUSE"]) + + if "use" in self.settings: + myusevars.extend(self.settings["use"]) + + if myusevars: + myf.write("# These are the USE flags that were used in addition to what is provided by the\n# profile used for building.\n") + myusevars = sorted(set(myusevars)) + myf.write('USE="'+string.join(myusevars)+'"\n') + if '-*' in myusevars: + print "\nWarning!!! " + print "\tThe use of -* in "+self.settings["spec_prefix"]+\ + "/use will cause portage to ignore" + print "\tpackage.use in the profile and portage_confdir. You've been warned!" + + myf.write('PORTDIR="%s"\n' % self.settings['portdir']) + myf.write('DISTDIR="%s"\n' % self.settings['distdir']) + myf.write('PKGDIR="%s"\n' % self.settings['packagedir']) + + """ Setup the portage overlay """ + if "portage_overlay" in self.settings: + myf.write('PORTDIR_OVERLAY="/usr/local/portage"\n') + + myf.close() + cmd("cp "+self.settings["chroot_path"]+"/etc/portage/make.conf "+\ + self.settings["chroot_path"]+"/etc/portage/make.conf.catalyst",\ + "Could not backup /etc/portage/make.conf",env=self.env) + touch(self.settings["autoresume_path"]+"chroot_setup") + + def fsscript(self): + if "AUTORESUME" in self.settings \ + and os.path.exists(self.settings["autoresume_path"]+"fsscript"): + print "Resume point detected, skipping fsscript operation..." + else: + if "fsscript" in self.settings: + if os.path.exists(self.settings["controller_file"]): + cmd("/bin/bash "+self.settings["controller_file"]+\ + " fsscript","fsscript script failed.",env=self.env) + touch(self.settings["autoresume_path"]+"fsscript") + + def rcupdate(self): + if "AUTORESUME" in self.settings \ + and os.path.exists(self.settings["autoresume_path"]+"rcupdate"): + print "Resume point detected, skipping rcupdate operation..." + else: + if os.path.exists(self.settings["controller_file"]): + cmd("/bin/bash "+self.settings["controller_file"]+" rc-update",\ + "rc-update script failed.",env=self.env) + touch(self.settings["autoresume_path"]+"rcupdate") + + def clean(self): + if "AUTORESUME" in self.settings \ + and os.path.exists(self.settings["autoresume_path"]+"clean"): + print "Resume point detected, skipping clean operation..." + else: + for x in self.settings["cleanables"]: + print "Cleaning chroot: "+x+"... " + cmd("rm -rf "+self.settings["destpath"]+x,"Couldn't clean "+\ + x,env=self.env) + + """ Put /etc/hosts back into place """ + if os.path.exists(self.settings["chroot_path"]+"/etc/hosts.catalyst"): + cmd("mv -f "+self.settings["chroot_path"]+"/etc/hosts.catalyst "+\ + self.settings["chroot_path"]+"/etc/hosts",\ + "Could not replace /etc/hosts",env=self.env) + + """ Remove our overlay """ + if os.path.exists(self.settings["chroot_path"] + self.settings["local_overlay"]): + cmd("rm -rf " + self.settings["chroot_path"] + self.settings["local_overlay"], + "Could not remove " + self.settings["local_overlay"], env=self.env) + cmd("sed -i '/^PORTDIR_OVERLAY/d' "+self.settings["chroot_path"]+\ + "/etc/portage/make.conf",\ + "Could not remove PORTDIR_OVERLAY from make.conf",env=self.env) + + """ Clean up old and obsoleted files in /etc """ + if os.path.exists(self.settings["stage_path"]+"/etc"): + cmd("find "+self.settings["stage_path"]+\ + "/etc -maxdepth 1 -name \"*-\" | xargs rm -f",\ + "Could not remove stray files in /etc",env=self.env) + + if os.path.exists(self.settings["controller_file"]): + cmd("/bin/bash "+self.settings["controller_file"]+" clean",\ + "clean script failed.",env=self.env) + touch(self.settings["autoresume_path"]+"clean") + + def empty(self): + if "AUTORESUME" in self.settings \ + and os.path.exists(self.settings["autoresume_path"]+"empty"): + print "Resume point detected, skipping empty operation..." + else: + if self.settings["spec_prefix"]+"/empty" in self.settings: + if type(self.settings[self.settings["spec_prefix"]+\ + "/empty"])==types.StringType: + self.settings[self.settings["spec_prefix"]+"/empty"]=\ + self.settings[self.settings["spec_prefix"]+\ + "/empty"].split() + for x in self.settings[self.settings["spec_prefix"]+"/empty"]: + myemp=self.settings["destpath"]+x + if not os.path.isdir(myemp) or os.path.islink(myemp): + print x,"not a directory or does not exist, skipping 'empty' operation." + continue + print "Emptying directory",x + """ + stat the dir, delete the dir, recreate the dir and set + the proper perms and ownership + """ + mystat=os.stat(myemp) + shutil.rmtree(myemp) + os.makedirs(myemp,0755) + os.chown(myemp,mystat[ST_UID],mystat[ST_GID]) + os.chmod(myemp,mystat[ST_MODE]) + touch(self.settings["autoresume_path"]+"empty") + + def remove(self): + if "AUTORESUME" in self.settings \ + and os.path.exists(self.settings["autoresume_path"]+"remove"): + print "Resume point detected, skipping remove operation..." + else: + if self.settings["spec_prefix"]+"/rm" in self.settings: + for x in self.settings[self.settings["spec_prefix"]+"/rm"]: + """ + We're going to shell out for all these cleaning + operations, so we get easy glob handling. + """ + print "livecd: removing "+x + os.system("rm -rf "+self.settings["chroot_path"]+x) + try: + if os.path.exists(self.settings["controller_file"]): + cmd("/bin/bash "+self.settings["controller_file"]+\ + " clean","Clean failed.",env=self.env) + touch(self.settings["autoresume_path"]+"remove") + except: + self.unbind() + raise + + def preclean(self): + if "AUTORESUME" in self.settings \ + and os.path.exists(self.settings["autoresume_path"]+"preclean"): + print "Resume point detected, skipping preclean operation..." + else: + try: + if os.path.exists(self.settings["controller_file"]): + cmd("/bin/bash "+self.settings["controller_file"]+\ + " preclean","preclean script failed.",env=self.env) + touch(self.settings["autoresume_path"]+"preclean") + + except: + self.unbind() + raise CatalystError, "Build failed, could not execute preclean" + + def capture(self): + if "AUTORESUME" in self.settings \ + and os.path.exists(self.settings["autoresume_path"]+"capture"): + print "Resume point detected, skipping capture operation..." + else: + """ Capture target in a tarball """ + mypath=self.settings["target_path"].split("/") + """ Remove filename from path """ + mypath=string.join(mypath[:-1],"/") + + """ Now make sure path exists """ + if not os.path.exists(mypath): + os.makedirs(mypath) + + print "Creating stage tarball..." + + cmd("tar -I lbzip2 -cpf "+self.settings["target_path"]+" -C "+\ + self.settings["stage_path"]+" .",\ + "Couldn't create stage tarball",env=self.env) + + self.gen_contents_file(self.settings["target_path"]) + self.gen_digest_file(self.settings["target_path"]) + + touch(self.settings["autoresume_path"]+"capture") + + def run_local(self): + if "AUTORESUME" in self.settings \ + and os.path.exists(self.settings["autoresume_path"]+"run_local"): + print "Resume point detected, skipping run_local operation..." + else: + try: + if os.path.exists(self.settings["controller_file"]): + cmd("/bin/bash "+self.settings["controller_file"]+" run",\ + "run script failed.",env=self.env) + touch(self.settings["autoresume_path"]+"run_local") + + except CatalystError: + self.unbind() + raise CatalystError,"Stage build aborting due to error." + + def setup_environment(self): + """ + Modify the current environment. This is an ugly hack that should be + fixed. We need this to use the os.system() call since we can't + specify our own environ + """ + for x in self.settings.keys(): + """ Sanitize var names by doing "s|/-.|_|g" """ + varname="clst_"+string.replace(x,"/","_") + varname=string.replace(varname,"-","_") + varname=string.replace(varname,".","_") + if type(self.settings[x])==types.StringType: + """ Prefix to prevent namespace clashes """ + #os.environ[varname]=self.settings[x] + self.env[varname]=self.settings[x] + elif type(self.settings[x])==types.ListType: + #os.environ[varname]=string.join(self.settings[x]) + self.env[varname]=string.join(self.settings[x]) + elif type(self.settings[x])==types.BooleanType: + if self.settings[x]: + self.env[varname]="true" + else: + self.env[varname]="false" + if "makeopts" in self.settings: + self.env["MAKEOPTS"]=self.settings["makeopts"] + + def run(self): + self.chroot_lock.write_lock() + + """ Kill any pids in the chroot "" """ + self.kill_chroot_pids() + + """ Check for mounts right away and abort if we cannot unmount them """ + self.mount_safety_check() + + if "CLEAR_AUTORESUME" in self.settings: + self.clear_autoresume() + + if "PURGETMPONLY" in self.settings: + self.purge() + return + + if "PURGEONLY" in self.settings: + self.purge() + return + + if "PURGE" in self.settings: + self.purge() + + for x in self.settings["action_sequence"]: + print "--- Running action sequence: "+x + sys.stdout.flush() + try: + apply(getattr(self,x)) + except: + self.mount_safety_check() + raise + + self.chroot_lock.unlock() + + def unmerge(self): + if "AUTORESUME" in self.settings \ + and os.path.exists(self.settings["autoresume_path"]+"unmerge"): + print "Resume point detected, skipping unmerge operation..." + else: + if self.settings["spec_prefix"]+"/unmerge" in self.settings: + if type(self.settings[self.settings["spec_prefix"]+\ + "/unmerge"])==types.StringType: + self.settings[self.settings["spec_prefix"]+"/unmerge"]=\ + [self.settings[self.settings["spec_prefix"]+"/unmerge"]] + myunmerge=\ + self.settings[self.settings["spec_prefix"]+"/unmerge"][:] + + for x in range(0,len(myunmerge)): + """ + Surround args with quotes for passing to bash, allows + things like "<" to remain intact + """ + myunmerge[x]="'"+myunmerge[x]+"'" + myunmerge=string.join(myunmerge) + + """ Before cleaning, unmerge stuff """ + try: + cmd("/bin/bash "+self.settings["controller_file"]+\ + " unmerge "+ myunmerge,"Unmerge script failed.",\ + env=self.env) + print "unmerge shell script" + except CatalystError: + self.unbind() + raise + touch(self.settings["autoresume_path"]+"unmerge") + + def target_setup(self): + if "AUTORESUME" in self.settings \ + and os.path.exists(self.settings["autoresume_path"]+"target_setup"): + print "Resume point detected, skipping target_setup operation..." + else: + print "Setting up filesystems per filesystem type" + cmd("/bin/bash "+self.settings["controller_file"]+\ + " target_image_setup "+ self.settings["target_path"],\ + "target_image_setup script failed.",env=self.env) + touch(self.settings["autoresume_path"]+"target_setup") + + def setup_overlay(self): + if "AUTORESUME" in self.settings \ + and os.path.exists(self.settings["autoresume_path"]+"setup_overlay"): + print "Resume point detected, skipping setup_overlay operation..." + else: + if self.settings["spec_prefix"]+"/overlay" in self.settings: + for x in self.settings[self.settings["spec_prefix"]+"/overlay"]: + if os.path.exists(x): + cmd("rsync -a "+x+"/ "+\ + self.settings["target_path"],\ + self.settings["spec_prefix"]+"overlay: "+x+\ + " copy failed.",env=self.env) + touch(self.settings["autoresume_path"]+"setup_overlay") + + def create_iso(self): + if "AUTORESUME" in self.settings \ + and os.path.exists(self.settings["autoresume_path"]+"create_iso"): + print "Resume point detected, skipping create_iso operation..." + else: + """ Create the ISO """ + if "iso" in self.settings: + cmd("/bin/bash "+self.settings["controller_file"]+" iso "+\ + self.settings["iso"],"ISO creation script failed.",\ + env=self.env) + self.gen_contents_file(self.settings["iso"]) + self.gen_digest_file(self.settings["iso"]) + touch(self.settings["autoresume_path"]+"create_iso") + else: + print "WARNING: livecd/iso was not defined." + print "An ISO Image will not be created." + + def build_packages(self): + if "AUTORESUME" in self.settings \ + and os.path.exists(self.settings["autoresume_path"]+\ + "build_packages"): + print "Resume point detected, skipping build_packages operation..." + else: + if self.settings["spec_prefix"]+"/packages" in self.settings: + if "AUTORESUME" in self.settings \ + and os.path.exists(self.settings["autoresume_path"]+\ + "build_packages"): + print "Resume point detected, skipping build_packages operation..." + else: + mypack=\ + list_bashify(self.settings[self.settings["spec_prefix"]\ + +"/packages"]) + try: + cmd("/bin/bash "+self.settings["controller_file"]+\ + " build_packages "+mypack,\ + "Error in attempt to build packages",env=self.env) + touch(self.settings["autoresume_path"]+"build_packages") + except CatalystError: + self.unbind() + raise CatalystError,self.settings["spec_prefix"]+\ + "build aborting due to error." + + def build_kernel(self): + "Build all configured kernels" + if "AUTORESUME" in self.settings \ + and os.path.exists(self.settings["autoresume_path"]+"build_kernel"): + print "Resume point detected, skipping build_kernel operation..." + else: + if "boot/kernel" in self.settings: + try: + mynames=self.settings["boot/kernel"] + if type(mynames)==types.StringType: + mynames=[mynames] + """ + Execute the script that sets up the kernel build environment + """ + cmd("/bin/bash "+self.settings["controller_file"]+\ + " pre-kmerge ","Runscript pre-kmerge failed",\ + env=self.env) + for kname in mynames: + self._build_kernel(kname=kname) + touch(self.settings["autoresume_path"]+"build_kernel") + except CatalystError: + self.unbind() + raise CatalystError,\ + "build aborting due to kernel build error." + + def _build_kernel(self, kname): + "Build a single configured kernel by name" + if "AUTORESUME" in self.settings \ + and os.path.exists(self.settings["autoresume_path"]\ + +"build_kernel_"+kname): + print "Resume point detected, skipping build_kernel for "+kname+" operation..." + return + self._copy_kernel_config(kname=kname) + + """ + If we need to pass special options to the bootloader + for this kernel put them into the environment + """ + if "boot/kernel/"+kname+"/kernelopts" in self.settings: + myopts=self.settings["boot/kernel/"+kname+\ + "/kernelopts"] + + if type(myopts) != types.StringType: + myopts = string.join(myopts) + self.env[kname+"_kernelopts"]=myopts + + else: + self.env[kname+"_kernelopts"]="" + + if "boot/kernel/"+kname+"/extraversion" not in self.settings: + self.settings["boot/kernel/"+kname+\ + "/extraversion"]="" + + self.env["clst_kextraversion"]=\ + self.settings["boot/kernel/"+kname+\ + "/extraversion"] + + self._copy_initramfs_overlay(kname=kname) + + """ Execute the script that builds the kernel """ + cmd("/bin/bash "+self.settings["controller_file"]+\ + " kernel "+kname,\ + "Runscript kernel build failed",env=self.env) + + if "boot/kernel/"+kname+"/initramfs_overlay" in self.settings: + if os.path.exists(self.settings["chroot_path"]+\ + "/tmp/initramfs_overlay/"): + print "Cleaning up temporary overlay dir" + cmd("rm -R "+self.settings["chroot_path"]+\ + "/tmp/initramfs_overlay/",env=self.env) + + touch(self.settings["autoresume_path"]+\ + "build_kernel_"+kname) + + """ + Execute the script that cleans up the kernel build + environment + """ + cmd("/bin/bash "+self.settings["controller_file"]+\ + " post-kmerge ", + "Runscript post-kmerge failed",env=self.env) + + def _copy_kernel_config(self, kname): + if "boot/kernel/"+kname+"/config" in self.settings: + if not os.path.exists(self.settings["boot/kernel/"+kname+"/config"]): + self.unbind() + raise CatalystError,\ + "Can't find kernel config: "+\ + self.settings["boot/kernel/"+kname+\ + "/config"] + + try: + cmd("cp "+self.settings["boot/kernel/"+kname+\ + "/config"]+" "+\ + self.settings["chroot_path"]+"/var/tmp/"+\ + kname+".config",\ + "Couldn't copy kernel config: "+\ + self.settings["boot/kernel/"+kname+\ + "/config"],env=self.env) + + except CatalystError: + self.unbind() + + def _copy_initramfs_overlay(self, kname): + if "boot/kernel/"+kname+"/initramfs_overlay" in self.settings: + if os.path.exists(self.settings["boot/kernel/"+\ + kname+"/initramfs_overlay"]): + print "Copying initramfs_overlay dir "+\ + self.settings["boot/kernel/"+kname+\ + "/initramfs_overlay"] + + cmd("mkdir -p "+\ + self.settings["chroot_path"]+\ + "/tmp/initramfs_overlay/"+\ + self.settings["boot/kernel/"+kname+\ + "/initramfs_overlay"],env=self.env) + + cmd("cp -R "+self.settings["boot/kernel/"+\ + kname+"/initramfs_overlay"]+"/* "+\ + self.settings["chroot_path"]+\ + "/tmp/initramfs_overlay/"+\ + self.settings["boot/kernel/"+kname+\ + "/initramfs_overlay"],env=self.env) + + def bootloader(self): + if "AUTORESUME" in self.settings \ + and os.path.exists(self.settings["autoresume_path"]+"bootloader"): + print "Resume point detected, skipping bootloader operation..." + else: + try: + cmd("/bin/bash "+self.settings["controller_file"]+\ + " bootloader " + self.settings["target_path"],\ + "Bootloader script failed.",env=self.env) + touch(self.settings["autoresume_path"]+"bootloader") + except CatalystError: + self.unbind() + raise CatalystError,"Script aborting due to error." + + def livecd_update(self): + if "AUTORESUME" in self.settings \ + and os.path.exists(self.settings["autoresume_path"]+\ + "livecd_update"): + print "Resume point detected, skipping build_packages operation..." + else: + try: + cmd("/bin/bash "+self.settings["controller_file"]+\ + " livecd-update","livecd-update failed.",env=self.env) + touch(self.settings["autoresume_path"]+"livecd_update") + + except CatalystError: + self.unbind() + raise CatalystError,"build aborting due to livecd_update error." + + def clear_chroot(self): + myemp=self.settings["chroot_path"] + if os.path.isdir(myemp): + print "Emptying directory",myemp + """ + stat the dir, delete the dir, recreate the dir and set + the proper perms and ownership + """ + mystat=os.stat(myemp) + #cmd("rm -rf "+myemp, "Could not remove existing file: "+myemp,env=self.env) + """ There's no easy way to change flags recursively in python """ + if os.uname()[0] == "FreeBSD": + os.system("chflags -R noschg "+myemp) + shutil.rmtree(myemp) + os.makedirs(myemp,0755) + os.chown(myemp,mystat[ST_UID],mystat[ST_GID]) + os.chmod(myemp,mystat[ST_MODE]) + + def clear_packages(self): + if "PKGCACHE" in self.settings: + print "purging the pkgcache ..." + + myemp=self.settings["pkgcache_path"] + if os.path.isdir(myemp): + print "Emptying directory",myemp + """ + stat the dir, delete the dir, recreate the dir and set + the proper perms and ownership + """ + mystat=os.stat(myemp) + #cmd("rm -rf "+myemp, "Could not remove existing file: "+myemp,env=self.env) + shutil.rmtree(myemp) + os.makedirs(myemp,0755) + os.chown(myemp,mystat[ST_UID],mystat[ST_GID]) + os.chmod(myemp,mystat[ST_MODE]) + + def clear_kerncache(self): + if "KERNCACHE" in self.settings: + print "purging the kerncache ..." + + myemp=self.settings["kerncache_path"] + if os.path.isdir(myemp): + print "Emptying directory",myemp + """ + stat the dir, delete the dir, recreate the dir and set + the proper perms and ownership + """ + mystat=os.stat(myemp) + #cmd("rm -rf "+myemp, "Could not remove existing file: "+myemp,env=self.env) + shutil.rmtree(myemp) + os.makedirs(myemp,0755) + os.chown(myemp,mystat[ST_UID],mystat[ST_GID]) + os.chmod(myemp,mystat[ST_MODE]) + + def clear_autoresume(self): + """ Clean resume points since they are no longer needed """ + if "AUTORESUME" in self.settings: + print "Removing AutoResume Points: ..." + myemp=self.settings["autoresume_path"] + if os.path.isdir(myemp): + if "AUTORESUME" in self.settings: + print "Emptying directory",myemp + """ + stat the dir, delete the dir, recreate the dir and set + the proper perms and ownership + """ + mystat=os.stat(myemp) + if os.uname()[0] == "FreeBSD": + cmd("chflags -R noschg "+myemp,\ + "Could not remove immutable flag for file "\ + +myemp) + #cmd("rm -rf "+myemp, "Could not remove existing file: "+myemp,env-self.env) + shutil.rmtree(myemp) + os.makedirs(myemp,0755) + os.chown(myemp,mystat[ST_UID],mystat[ST_GID]) + os.chmod(myemp,mystat[ST_MODE]) + + def gen_contents_file(self,file): + if os.path.exists(file+".CONTENTS"): + os.remove(file+".CONTENTS") + if "contents" in self.settings: + if os.path.exists(file): + myf=open(file+".CONTENTS","w") + keys={} + for i in self.settings["contents"].split(): + keys[i]=1 + array=keys.keys() + array.sort() + for j in array: + contents=generate_contents(file,contents_function=j,\ + verbose="VERBOSE" in self.settings) + if contents: + myf.write(contents) + myf.close() + + def gen_digest_file(self,file): + if os.path.exists(file+".DIGESTS"): + os.remove(file+".DIGESTS") + if "digests" in self.settings: + if os.path.exists(file): + myf=open(file+".DIGESTS","w") + keys={} + for i in self.settings["digests"].split(): + keys[i]=1 + array=keys.keys() + array.sort() + for f in [file, file+'.CONTENTS']: + if os.path.exists(f): + if "all" in array: + for k in hash_map.keys(): + hash=generate_hash(f,hash_function=k,verbose=\ + "VERBOSE" in self.settings) + myf.write(hash) + else: + for j in array: + hash=generate_hash(f,hash_function=j,verbose=\ + "VERBOSE" in self.settings) + myf.write(hash) + myf.close() + + def purge(self): + countdown(10,"Purging Caches ...") + if any(k in self.settings for k in ("PURGE","PURGEONLY","PURGETMPONLY")): + print "clearing autoresume ..." + self.clear_autoresume() + + print "clearing chroot ..." + self.clear_chroot() + + if "PURGETMPONLY" not in self.settings: + print "clearing package cache ..." + self.clear_packages() + + print "clearing kerncache ..." + self.clear_kerncache() + +# vim: ts=4 sw=4 sta et sts=4 ai diff --git a/catalyst/targets/generic_target.py b/catalyst/targets/generic_target.py new file mode 100644 index 0000000..de51994 --- /dev/null +++ b/catalyst/targets/generic_target.py @@ -0,0 +1,11 @@ +from catalyst.support import * + +class generic_target: + """ + The toplevel class for generic_stage_target. This is about as generic as we get. + """ + def __init__(self,myspec,addlargs): + addl_arg_parse(myspec,addlargs,self.required_values,self.valid_values) + self.settings=myspec + self.env={} + self.env["PATH"]="/bin:/sbin:/usr/bin:/usr/sbin" diff --git a/catalyst/targets/grp_target.py b/catalyst/targets/grp_target.py new file mode 100644 index 0000000..8e70042 --- /dev/null +++ b/catalyst/targets/grp_target.py @@ -0,0 +1,118 @@ +""" +Gentoo Reference Platform (GRP) target +""" +# NOTE: That^^ docstring has influence catalyst-spec(5) man page generation. + +import os,types,glob +from catalyst.support import * +from generic_stage_target import * + +class grp_target(generic_stage_target): + """ + The builder class for GRP (Gentoo Reference Platform) builds. + """ + def __init__(self,spec,addlargs): + self.required_values=["version_stamp","target","subarch",\ + "rel_type","profile","snapshot","source_subpath"] + + self.valid_values=self.required_values[:] + self.valid_values.extend(["grp/use"]) + if "grp" not in addlargs: + raise CatalystError,"Required value \"grp\" not specified in spec." + + self.required_values.extend(["grp"]) + if type(addlargs["grp"])==types.StringType: + addlargs["grp"]=[addlargs["grp"]] + + if "grp/use" in addlargs: + if type(addlargs["grp/use"])==types.StringType: + addlargs["grp/use"]=[addlargs["grp/use"]] + + for x in addlargs["grp"]: + self.required_values.append("grp/"+x+"/packages") + self.required_values.append("grp/"+x+"/type") + + generic_stage_target.__init__(self,spec,addlargs) + + def set_target_path(self): + self.settings["target_path"]=normpath(self.settings["storedir"]+"/builds/"+self.settings["target_subpath"]+"/") + if "AUTORESUME" in self.settings \ + and os.path.exists(self.settings["autoresume_path"]+"setup_target_path"): + print "Resume point detected, skipping target path setup operation..." + else: + # first clean up any existing target stuff + #if os.path.isdir(self.settings["target_path"]): + #cmd("rm -rf "+self.settings["target_path"], + #"Could not remove existing directory: "+self.settings["target_path"],env=self.env) + if not os.path.exists(self.settings["target_path"]): + os.makedirs(self.settings["target_path"]) + + touch(self.settings["autoresume_path"]+"setup_target_path") + + def run_local(self): + for pkgset in self.settings["grp"]: + # example call: "grp.sh run pkgset cd1 xmms vim sys-apps/gleep" + mypackages=list_bashify(self.settings["grp/"+pkgset+"/packages"]) + try: + cmd("/bin/bash "+self.settings["controller_file"]+" run "+self.settings["grp/"+pkgset+"/type"]\ + +" "+pkgset+" "+mypackages,env=self.env) + + except CatalystError: + self.unbind() + raise CatalystError,"GRP build aborting due to error." + + def set_use(self): + generic_stage_target.set_use(self) + if "BINDIST" in self.settings: + if "use" in self.settings: + self.settings["use"].append("bindist") + else: + self.settings["use"]=["bindist"] + + def set_mounts(self): + self.mounts.append("/tmp/grp") + self.mountmap["/tmp/grp"]=self.settings["target_path"] + + def generate_digests(self): + for pkgset in self.settings["grp"]: + if self.settings["grp/"+pkgset+"/type"] == "pkgset": + destdir=normpath(self.settings["target_path"]+"/"+pkgset+"/All") + print "Digesting files in the pkgset....." + digests=glob.glob(destdir+'/*.DIGESTS') + for i in digests: + if os.path.exists(i): + os.remove(i) + + files=os.listdir(destdir) + #ignore files starting with '.' using list comprehension + files=[filename for filename in files if filename[0] != '.'] + for i in files: + if os.path.isfile(normpath(destdir+"/"+i)): + self.gen_contents_file(normpath(destdir+"/"+i)) + self.gen_digest_file(normpath(destdir+"/"+i)) + else: + destdir=normpath(self.settings["target_path"]+"/"+pkgset) + print "Digesting files in the srcset....." + + digests=glob.glob(destdir+'/*.DIGESTS') + for i in digests: + if os.path.exists(i): + os.remove(i) + + files=os.listdir(destdir) + #ignore files starting with '.' using list comprehension + files=[filename for filename in files if filename[0] != '.'] + for i in files: + if os.path.isfile(normpath(destdir+"/"+i)): + #self.gen_contents_file(normpath(destdir+"/"+i)) + self.gen_digest_file(normpath(destdir+"/"+i)) + + def set_action_sequence(self): + self.settings["action_sequence"]=["unpack","unpack_snapshot",\ + "config_profile_link","setup_confdir","portage_overlay","bind","chroot_setup",\ + "setup_environment","run_local","unbind",\ + "generate_digests","clear_autoresume"] + +def register(foo): + foo.update({"grp":grp_target}) + return foo diff --git a/catalyst/targets/livecd_stage1_target.py b/catalyst/targets/livecd_stage1_target.py new file mode 100644 index 0000000..ac846ec --- /dev/null +++ b/catalyst/targets/livecd_stage1_target.py @@ -0,0 +1,75 @@ +""" +LiveCD stage1 target +""" +# NOTE: That^^ docstring has influence catalyst-spec(5) man page generation. + +from catalyst.support import * +from generic_stage_target import * + +class livecd_stage1_target(generic_stage_target): + """ + Builder class for LiveCD stage1. + """ + def __init__(self,spec,addlargs): + self.required_values=["livecd/packages"] + self.valid_values=self.required_values[:] + + self.valid_values.extend(["livecd/use"]) + generic_stage_target.__init__(self,spec,addlargs) + + def set_action_sequence(self): + self.settings["action_sequence"]=["unpack","unpack_snapshot",\ + "config_profile_link","setup_confdir","portage_overlay",\ + "bind","chroot_setup","setup_environment","build_packages",\ + "unbind", "clean","clear_autoresume"] + + def set_target_path(self): + self.settings["target_path"]=normpath(self.settings["storedir"]+"/builds/"+self.settings["target_subpath"]) + if "AUTORESUME" in self.settings \ + and os.path.exists(self.settings["autoresume_path"]+"setup_target_path"): + print "Resume point detected, skipping target path setup operation..." + else: + # first clean up any existing target stuff + if os.path.exists(self.settings["target_path"]): + cmd("rm -rf "+self.settings["target_path"],\ + "Could not remove existing directory: "+self.settings["target_path"],env=self.env) + touch(self.settings["autoresume_path"]+"setup_target_path") + + if not os.path.exists(self.settings["target_path"]): + os.makedirs(self.settings["target_path"]) + + def set_target_path(self): + pass + + def set_spec_prefix(self): + self.settings["spec_prefix"]="livecd" + + def set_use(self): + generic_stage_target.set_use(self) + if "use" in self.settings: + self.settings["use"].append("livecd") + if "BINDIST" in self.settings: + self.settings["use"].append("bindist") + else: + self.settings["use"]=["livecd"] + if "BINDIST" in self.settings: + self.settings["use"].append("bindist") + + def set_packages(self): + generic_stage_target.set_packages(self) + if self.settings["spec_prefix"]+"/packages" in self.settings: + if type(self.settings[self.settings["spec_prefix"]+"/packages"]) == types.StringType: + self.settings[self.settings["spec_prefix"]+"/packages"] = \ + self.settings[self.settings["spec_prefix"]+"/packages"].split() + self.settings[self.settings["spec_prefix"]+"/packages"].append("app-misc/livecd-tools") + + def set_pkgcache_path(self): + if "pkgcache_path" in self.settings: + if type(self.settings["pkgcache_path"]) != types.StringType: + self.settings["pkgcache_path"]=normpath(string.join(self.settings["pkgcache_path"])) + else: + generic_stage_target.set_pkgcache_path(self) + +def register(foo): + foo.update({"livecd-stage1":livecd_stage1_target}) + return foo diff --git a/catalyst/targets/livecd_stage2_target.py b/catalyst/targets/livecd_stage2_target.py new file mode 100644 index 0000000..1bfd820 --- /dev/null +++ b/catalyst/targets/livecd_stage2_target.py @@ -0,0 +1,146 @@ +""" +LiveCD stage2 target, builds upon previous LiveCD stage1 tarball +""" +# NOTE: That^^ docstring has influence catalyst-spec(5) man page generation. + +import os,string,types,stat,shutil +from catalyst.support import * +from generic_stage_target import * + +class livecd_stage2_target(generic_stage_target): + """ + Builder class for a LiveCD stage2 build. + """ + def __init__(self,spec,addlargs): + self.required_values=["boot/kernel"] + + self.valid_values=[] + + self.valid_values.extend(self.required_values) + self.valid_values.extend(["livecd/cdtar","livecd/empty","livecd/rm",\ + "livecd/unmerge","livecd/iso","livecd/gk_mainargs","livecd/type",\ + "livecd/readme","livecd/motd","livecd/overlay",\ + "livecd/modblacklist","livecd/splash_theme","livecd/rcadd",\ + "livecd/rcdel","livecd/fsscript","livecd/xinitrc",\ + "livecd/root_overlay","livecd/users","portage_overlay",\ + "livecd/fstype","livecd/fsops","livecd/linuxrc","livecd/bootargs",\ + "gamecd/conf","livecd/xdm","livecd/xsession","livecd/volid"]) + + generic_stage_target.__init__(self,spec,addlargs) + if "livecd/type" not in self.settings: + self.settings["livecd/type"] = "generic-livecd" + + file_locate(self.settings, ["cdtar","controller_file"]) + + def set_source_path(self): + self.settings["source_path"]=normpath(self.settings["storedir"]+"/builds/"+self.settings["source_subpath"]+".tar.bz2") + if os.path.isfile(self.settings["source_path"]): + self.settings["source_path_hash"]=generate_hash(self.settings["source_path"]) + else: + self.settings["source_path"]=normpath(self.settings["storedir"]+"/tmp/"+self.settings["source_subpath"]+"/") + if not os.path.exists(self.settings["source_path"]): + raise CatalystError,"Source Path: "+self.settings["source_path"]+" does not exist." + + def set_spec_prefix(self): + self.settings["spec_prefix"]="livecd" + + def set_target_path(self): + self.settings["target_path"]=normpath(self.settings["storedir"]+"/builds/"+self.settings["target_subpath"]+"/") + if "AUTORESUME" in self.settings \ + and os.path.exists(self.settings["autoresume_path"]+"setup_target_path"): + print "Resume point detected, skipping target path setup operation..." + else: + # first clean up any existing target stuff + if os.path.isdir(self.settings["target_path"]): + cmd("rm -rf "+self.settings["target_path"], + "Could not remove existing directory: "+self.settings["target_path"],env=self.env) + touch(self.settings["autoresume_path"]+"setup_target_path") + if not os.path.exists(self.settings["target_path"]): + os.makedirs(self.settings["target_path"]) + + def run_local(self): + # what modules do we want to blacklist? + if "livecd/modblacklist" in self.settings: + try: + myf=open(self.settings["chroot_path"]+"/etc/modprobe.d/blacklist.conf","a") + except: + self.unbind() + raise CatalystError,"Couldn't open "+self.settings["chroot_path"]+"/etc/modprobe.d/blacklist.conf." + + myf.write("\n#Added by Catalyst:") + # workaround until config.py is using configparser + if isinstance(self.settings["livecd/modblacklist"], str): + self.settings["livecd/modblacklist"] = self.settings["livecd/modblacklist"].split() + for x in self.settings["livecd/modblacklist"]: + myf.write("\nblacklist "+x) + myf.close() + + def unpack(self): + unpack=True + display_msg=None + + clst_unpack_hash=read_from_clst(self.settings["autoresume_path"]+"unpack") + + if os.path.isdir(self.settings["source_path"]): + unpack_cmd="rsync -a --delete "+self.settings["source_path"]+" "+self.settings["chroot_path"] + display_msg="\nStarting rsync from "+self.settings["source_path"]+"\nto "+\ + self.settings["chroot_path"]+" (This may take some time) ...\n" + error_msg="Rsync of "+self.settings["source_path"]+" to "+self.settings["chroot_path"]+" failed." + invalid_snapshot=False + + if "AUTORESUME" in self.settings: + if os.path.isdir(self.settings["source_path"]) and \ + os.path.exists(self.settings["autoresume_path"]+"unpack"): + print "Resume point detected, skipping unpack operation..." + unpack=False + elif "source_path_hash" in self.settings: + if self.settings["source_path_hash"] != clst_unpack_hash: + invalid_snapshot=True + + if unpack: + self.mount_safety_check() + if invalid_snapshot: + print "No Valid Resume point detected, cleaning up ..." + #os.remove(self.settings["autoresume_path"]+"dir_setup") + self.clear_autoresume() + self.clear_chroot() + #self.dir_setup() + + if not os.path.exists(self.settings["chroot_path"]): + os.makedirs(self.settings["chroot_path"]) + + if not os.path.exists(self.settings["chroot_path"]+"/tmp"): + os.makedirs(self.settings["chroot_path"]+"/tmp",1777) + + if "PKGCACHE" in self.settings: + if not os.path.exists(self.settings["pkgcache_path"]): + os.makedirs(self.settings["pkgcache_path"],0755) + + if not display_msg: + raise CatalystError,"Could not find appropriate source. Please check the 'source_subpath' setting in the spec file." + + print display_msg + cmd(unpack_cmd,error_msg,env=self.env) + + if "source_path_hash" in self.settings: + myf=open(self.settings["autoresume_path"]+"unpack","w") + myf.write(self.settings["source_path_hash"]) + myf.close() + else: + touch(self.settings["autoresume_path"]+"unpack") + + def set_action_sequence(self): + self.settings["action_sequence"]=["unpack","unpack_snapshot",\ + "config_profile_link","setup_confdir","portage_overlay",\ + "bind","chroot_setup","setup_environment","run_local",\ + "build_kernel"] + if "FETCH" not in self.settings: + self.settings["action_sequence"] += ["bootloader","preclean",\ + "livecd_update","root_overlay","fsscript","rcupdate","unmerge",\ + "unbind","remove","empty","target_setup",\ + "setup_overlay","create_iso"] + self.settings["action_sequence"].append("clear_autoresume") + +def register(foo): + foo.update({"livecd-stage2":livecd_stage2_target}) + return foo diff --git a/catalyst/targets/netboot2_target.py b/catalyst/targets/netboot2_target.py new file mode 100644 index 0000000..2b3cd20 --- /dev/null +++ b/catalyst/targets/netboot2_target.py @@ -0,0 +1,166 @@ +""" +netboot target, version 2 +""" +# NOTE: That^^ docstring has influence catalyst-spec(5) man page generation. + +import os,string,types +from catalyst.support import * +from generic_stage_target import * + +class netboot2_target(generic_stage_target): + """ + Builder class for a netboot build, version 2 + """ + def __init__(self,spec,addlargs): + self.required_values=[ + "boot/kernel" + ] + self.valid_values=self.required_values[:] + self.valid_values.extend([ + "netboot2/packages", + "netboot2/use", + "netboot2/extra_files", + "netboot2/overlay", + "netboot2/busybox_config", + "netboot2/root_overlay", + "netboot2/linuxrc" + ]) + + try: + if "netboot2/packages" in addlargs: + if type(addlargs["netboot2/packages"]) == types.StringType: + loopy=[addlargs["netboot2/packages"]] + else: + loopy=addlargs["netboot2/packages"] + + for x in loopy: + self.valid_values.append("netboot2/packages/"+x+"/files") + except: + raise CatalystError,"configuration error in netboot2/packages." + + generic_stage_target.__init__(self,spec,addlargs) + self.set_build_kernel_vars() + self.settings["merge_path"]=normpath("/tmp/image/") + + def set_target_path(self): + self.settings["target_path"]=normpath(self.settings["storedir"]+"/builds/"+\ + self.settings["target_subpath"]+"/") + if "AUTORESUME" in self.settings \ + and os.path.exists(self.settings["autoresume_path"]+"setup_target_path"): + print "Resume point detected, skipping target path setup operation..." + else: + # first clean up any existing target stuff + if os.path.isfile(self.settings["target_path"]): + cmd("rm -f "+self.settings["target_path"], \ + "Could not remove existing file: "+self.settings["target_path"],env=self.env) + touch(self.settings["autoresume_path"]+"setup_target_path") + + if not os.path.exists(self.settings["storedir"]+"/builds/"): + os.makedirs(self.settings["storedir"]+"/builds/") + + def copy_files_to_image(self): + # copies specific files from the buildroot to merge_path + myfiles=[] + + # check for autoresume point + if "AUTORESUME" in self.settings \ + and os.path.exists(self.settings["autoresume_path"]+"copy_files_to_image"): + print "Resume point detected, skipping target path setup operation..." + else: + if "netboot2/packages" in self.settings: + if type(self.settings["netboot2/packages"]) == types.StringType: + loopy=[self.settings["netboot2/packages"]] + else: + loopy=self.settings["netboot2/packages"] + + for x in loopy: + if "netboot2/packages/"+x+"/files" in self.settings: + if type(self.settings["netboot2/packages/"+x+"/files"]) == types.ListType: + myfiles.extend(self.settings["netboot2/packages/"+x+"/files"]) + else: + myfiles.append(self.settings["netboot2/packages/"+x+"/files"]) + + if "netboot2/extra_files" in self.settings: + if type(self.settings["netboot2/extra_files"]) == types.ListType: + myfiles.extend(self.settings["netboot2/extra_files"]) + else: + myfiles.append(self.settings["netboot2/extra_files"]) + + try: + cmd("/bin/bash "+self.settings["controller_file"]+\ + " image " + list_bashify(myfiles),env=self.env) + except CatalystError: + self.unbind() + raise CatalystError,"Failed to copy files to image!" + + touch(self.settings["autoresume_path"]+"copy_files_to_image") + + def setup_overlay(self): + if "AUTORESUME" in self.settings \ + and os.path.exists(self.settings["autoresume_path"]+"setup_overlay"): + print "Resume point detected, skipping setup_overlay operation..." + else: + if "netboot2/overlay" in self.settings: + for x in self.settings["netboot2/overlay"]: + if os.path.exists(x): + cmd("rsync -a "+x+"/ "+\ + self.settings["chroot_path"] + self.settings["merge_path"], "netboot2/overlay: "+x+" copy failed.",env=self.env) + touch(self.settings["autoresume_path"]+"setup_overlay") + + def move_kernels(self): + # we're done, move the kernels to builds/* + # no auto resume here as we always want the + # freshest images moved + try: + cmd("/bin/bash "+self.settings["controller_file"]+\ + " final",env=self.env) + print ">>> Netboot Build Finished!" + except CatalystError: + self.unbind() + raise CatalystError,"Failed to move kernel images!" + + def remove(self): + if "AUTORESUME" in self.settings \ + and os.path.exists(self.settings["autoresume_path"]+"remove"): + print "Resume point detected, skipping remove operation..." + else: + if self.settings["spec_prefix"]+"/rm" in self.settings: + for x in self.settings[self.settings["spec_prefix"]+"/rm"]: + # we're going to shell out for all these cleaning operations, + # so we get easy glob handling + print "netboot2: removing " + x + os.system("rm -rf " + self.settings["chroot_path"] + self.settings["merge_path"] + x) + + def empty(self): + if "AUTORESUME" in self.settings \ + and os.path.exists(self.settings["autoresume_path"]+"empty"): + print "Resume point detected, skipping empty operation..." + else: + if "netboot2/empty" in self.settings: + if type(self.settings["netboot2/empty"])==types.StringType: + self.settings["netboot2/empty"]=self.settings["netboot2/empty"].split() + for x in self.settings["netboot2/empty"]: + myemp=self.settings["chroot_path"] + self.settings["merge_path"] + x + if not os.path.isdir(myemp): + print x,"not a directory or does not exist, skipping 'empty' operation." + continue + print "Emptying directory", x + # stat the dir, delete the dir, recreate the dir and set + # the proper perms and ownership + mystat=os.stat(myemp) + shutil.rmtree(myemp) + os.makedirs(myemp,0755) + os.chown(myemp,mystat[ST_UID],mystat[ST_GID]) + os.chmod(myemp,mystat[ST_MODE]) + touch(self.settings["autoresume_path"]+"empty") + + def set_action_sequence(self): + self.settings["action_sequence"]=["unpack","unpack_snapshot","config_profile_link", + "setup_confdir","portage_overlay","bind","chroot_setup",\ + "setup_environment","build_packages","root_overlay",\ + "copy_files_to_image","setup_overlay","build_kernel","move_kernels",\ + "remove","empty","unbind","clean","clear_autoresume"] + +def register(foo): + foo.update({"netboot2":netboot2_target}) + return foo diff --git a/catalyst/targets/netboot_target.py b/catalyst/targets/netboot_target.py new file mode 100644 index 0000000..9d01b7e --- /dev/null +++ b/catalyst/targets/netboot_target.py @@ -0,0 +1,128 @@ +""" +netboot target, version 1 +""" +# NOTE: That^^ docstring has influence catalyst-spec(5) man page generation. + +import os,string,types +from catalyst.support import * +from generic_stage_target import * + +class netboot_target(generic_stage_target): + """ + Builder class for a netboot build. + """ + def __init__(self,spec,addlargs): + self.valid_values = [ + "netboot/kernel/sources", + "netboot/kernel/config", + "netboot/kernel/prebuilt", + + "netboot/busybox_config", + + "netboot/extra_files", + "netboot/packages" + ] + self.required_values=[] + + try: + if "netboot/packages" in addlargs: + if type(addlargs["netboot/packages"]) == types.StringType: + loopy=[addlargs["netboot/packages"]] + else: + loopy=addlargs["netboot/packages"] + + # for x in loopy: + # self.required_values.append("netboot/packages/"+x+"/files") + except: + raise CatalystError,"configuration error in netboot/packages." + + generic_stage_target.__init__(self,spec,addlargs) + self.set_build_kernel_vars(addlargs) + if "netboot/busybox_config" in addlargs: + file_locate(self.settings, ["netboot/busybox_config"]) + + # Custom Kernel Tarball --- use that instead ... + + # unless the user wants specific CFLAGS/CXXFLAGS, let's use -Os + + for envvar in "CFLAGS", "CXXFLAGS": + if envvar not in os.environ and envvar not in addlargs: + self.settings[envvar] = "-Os -pipe" + + def set_root_path(self): + # ROOT= variable for emerges + self.settings["root_path"]=normpath("/tmp/image") + print "netboot root path is "+self.settings["root_path"] + +# def build_packages(self): +# # build packages +# if "netboot/packages" in self.settings: +# mypack=list_bashify(self.settings["netboot/packages"]) +# try: +# cmd("/bin/bash "+self.settings["controller_file"]+" packages "+mypack,env=self.env) +# except CatalystError: +# self.unbind() +# raise CatalystError,"netboot build aborting due to error." + + def build_busybox(self): + # build busybox + if "netboot/busybox_config" in self.settings: + mycmd = self.settings["netboot/busybox_config"] + else: + mycmd = "" + try: + cmd("/bin/bash "+self.settings["controller_file"]+" busybox "+ mycmd,env=self.env) + except CatalystError: + self.unbind() + raise CatalystError,"netboot build aborting due to error." + + def copy_files_to_image(self): + # create image + myfiles=[] + if "netboot/packages" in self.settings: + if type(self.settings["netboot/packages"]) == types.StringType: + loopy=[self.settings["netboot/packages"]] + else: + loopy=self.settings["netboot/packages"] + + for x in loopy: + if "netboot/packages/"+x+"/files" in self.settings: + if type(self.settings["netboot/packages/"+x+"/files"]) == types.ListType: + myfiles.extend(self.settings["netboot/packages/"+x+"/files"]) + else: + myfiles.append(self.settings["netboot/packages/"+x+"/files"]) + + if "netboot/extra_files" in self.settings: + if type(self.settings["netboot/extra_files"]) == types.ListType: + myfiles.extend(self.settings["netboot/extra_files"]) + else: + myfiles.append(self.settings["netboot/extra_files"]) + + try: + cmd("/bin/bash "+self.settings["controller_file"]+\ + " image " + list_bashify(myfiles),env=self.env) + except CatalystError: + self.unbind() + raise CatalystError,"netboot build aborting due to error." + + def create_netboot_files(self): + # finish it all up + try: + cmd("/bin/bash "+self.settings["controller_file"]+" finish",env=self.env) + except CatalystError: + self.unbind() + raise CatalystError,"netboot build aborting due to error." + + # end + print "netboot: build finished !" + + def set_action_sequence(self): + self.settings["action_sequence"]=["unpack","unpack_snapshot", + "config_profile_link","setup_confdir","bind","chroot_setup",\ + "setup_environment","build_packages","build_busybox",\ + "build_kernel","copy_files_to_image",\ + "clean","create_netboot_files","unbind","clear_autoresume"] + +def register(foo): + foo.update({"netboot":netboot_target}) + return foo diff --git a/catalyst/targets/snapshot_target.py b/catalyst/targets/snapshot_target.py new file mode 100644 index 0000000..e21bd1a --- /dev/null +++ b/catalyst/targets/snapshot_target.py @@ -0,0 +1,91 @@ +""" +Snapshot target +""" + +import os +from catalyst.support import * +from generic_stage_target import * + +class snapshot_target(generic_stage_target): + """ + Builder class for snapshots. + """ + def __init__(self,myspec,addlargs): + self.required_values=["version_stamp","target"] + self.valid_values=["version_stamp","target"] + + generic_target.__init__(self,myspec,addlargs) + self.settings=myspec + self.settings["target_subpath"]="portage" + st=self.settings["storedir"] + self.settings["snapshot_path"]=normpath(st + "/snapshots/" + + self.settings["snapshot_name"] + + self.settings["version_stamp"] + ".tar.bz2") + self.settings["tmp_path"]=normpath(st+"/tmp/"+self.settings["target_subpath"]) + + def setup(self): + x=normpath(self.settings["storedir"]+"/snapshots") + if not os.path.exists(x): + os.makedirs(x) + + def mount_safety_check(self): + pass + + def run(self): + if "PURGEONLY" in self.settings: + self.purge() + return + + if "PURGE" in self.settings: + self.purge() + + self.setup() + print "Creating Portage tree snapshot "+self.settings["version_stamp"]+\ + " from "+self.settings["portdir"]+"..." + + mytmp=self.settings["tmp_path"] + if not os.path.exists(mytmp): + os.makedirs(mytmp) + + cmd("rsync -a --delete --exclude /packages/ --exclude /distfiles/ " + + "--exclude /local/ --exclude CVS/ --exclude .svn --filter=H_**/files/digest-* " + + self.settings["portdir"] + "/ " + mytmp + "/%s/" % self.settings["repo_name"], + "Snapshot failure",env=self.env) + + print "Compressing Portage snapshot tarball..." + cmd("tar -I lbzip2 -cf " + self.settings["snapshot_path"] + " -C " + + mytmp + " %s" % self.settings["repo_name"], + "Snapshot creation failure",env=self.env) + + self.gen_contents_file(self.settings["snapshot_path"]) + self.gen_digest_file(self.settings["snapshot_path"]) + + self.cleanup() + print "snapshot: complete!" + + def kill_chroot_pids(self): + pass + + def cleanup(self): + print "Cleaning up..." + + def purge(self): + myemp=self.settings["tmp_path"] + if os.path.isdir(myemp): + print "Emptying directory",myemp + """ + stat the dir, delete the dir, recreate the dir and set + the proper perms and ownership + """ + mystat=os.stat(myemp) + """ There's no easy way to change flags recursively in python """ + if os.uname()[0] == "FreeBSD": + os.system("chflags -R noschg "+myemp) + shutil.rmtree(myemp) + os.makedirs(myemp,0755) + os.chown(myemp,mystat[ST_UID],mystat[ST_GID]) + os.chmod(myemp,mystat[ST_MODE]) + +def register(foo): + foo.update({"snapshot":snapshot_target}) + return foo diff --git a/catalyst/targets/stage1_target.py b/catalyst/targets/stage1_target.py new file mode 100644 index 0000000..25f7116 --- /dev/null +++ b/catalyst/targets/stage1_target.py @@ -0,0 +1,96 @@ +""" +stage1 target +""" +# NOTE: That^^ docstring has influence catalyst-spec(5) man page generation. + +from catalyst.support import * +from generic_stage_target import * + +class stage1_target(generic_stage_target): + """ + Builder class for a stage1 installation tarball build. + """ + def __init__(self,spec,addlargs): + self.required_values=[] + self.valid_values=["chost"] + self.valid_values.extend(["update_seed","update_seed_command"]) + generic_stage_target.__init__(self,spec,addlargs) + + def set_stage_path(self): + self.settings["stage_path"]=normpath(self.settings["chroot_path"]+self.settings["root_path"]) + print "stage1 stage path is "+self.settings["stage_path"] + + def set_root_path(self): + # sets the root path, relative to 'chroot_path', of the stage1 root + self.settings["root_path"]=normpath("/tmp/stage1root") + print "stage1 root path is "+self.settings["root_path"] + + def set_cleanables(self): + generic_stage_target.set_cleanables(self) + self.settings["cleanables"].extend([\ + "/usr/share/zoneinfo", "/etc/portage/package*"]) + + # XXX: How do these override_foo() functions differ from the ones in generic_stage_target and why aren't they in stage3_target? + + def override_chost(self): + if "chost" in self.settings: + self.settings["CHOST"]=list_to_string(self.settings["chost"]) + + def override_cflags(self): + if "cflags" in self.settings: + self.settings["CFLAGS"]=list_to_string(self.settings["cflags"]) + + def override_cxxflags(self): + if "cxxflags" in self.settings: + self.settings["CXXFLAGS"]=list_to_string(self.settings["cxxflags"]) + + def override_ldflags(self): + if "ldflags" in self.settings: + self.settings["LDFLAGS"]=list_to_string(self.settings["ldflags"]) + + def set_portage_overlay(self): + generic_stage_target.set_portage_overlay(self) + if "portage_overlay" in self.settings: + print "\nWARNING !!!!!" + print "\tUsing an portage overlay for earlier stages could cause build issues." + print "\tIf you break it, you buy it. Don't complain to us about it." + print "\tDont say we did not warn you\n" + + def base_dirs(self): + if os.uname()[0] == "FreeBSD": + # baselayout no longer creates the .keep files in proc and dev for FreeBSD as it + # would create them too late...we need them earlier before bind mounting filesystems + # since proc and dev are not writeable, so...create them here + if not os.path.exists(self.settings["stage_path"]+"/proc"): + os.makedirs(self.settings["stage_path"]+"/proc") + if not os.path.exists(self.settings["stage_path"]+"/dev"): + os.makedirs(self.settings["stage_path"]+"/dev") + if not os.path.isfile(self.settings["stage_path"]+"/proc/.keep"): + try: + proc_keepfile = open(self.settings["stage_path"]+"/proc/.keep","w") + proc_keepfile.write('') + proc_keepfile.close() + except IOError: + print "!!! Failed to create %s" % (self.settings["stage_path"]+"/dev/.keep") + if not os.path.isfile(self.settings["stage_path"]+"/dev/.keep"): + try: + dev_keepfile = open(self.settings["stage_path"]+"/dev/.keep","w") + dev_keepfile.write('') + dev_keepfile.close() + except IOError: + print "!!! Failed to create %s" % (self.settings["stage_path"]+"/dev/.keep") + else: + pass + + def set_mounts(self): + # stage_path/proc probably doesn't exist yet, so create it + if not os.path.exists(self.settings["stage_path"]+"/proc"): + os.makedirs(self.settings["stage_path"]+"/proc") + + # alter the mount mappings to bind mount proc onto it + self.mounts.append("/tmp/stage1root/proc") + self.mountmap["/tmp/stage1root/proc"]="/proc" + +def register(foo): + foo.update({"stage1":stage1_target}) + return foo diff --git a/catalyst/targets/stage2_target.py b/catalyst/targets/stage2_target.py new file mode 100644 index 0000000..15acdee --- /dev/null +++ b/catalyst/targets/stage2_target.py @@ -0,0 +1,62 @@ +""" +stage2 target, builds upon previous stage1 tarball +""" +# NOTE: That^^ docstring has influence catalyst-spec(5) man page generation. + +from catalyst.support import * +from generic_stage_target import * + +class stage2_target(generic_stage_target): + """ + Builder class for a stage2 installation tarball build. + """ + def __init__(self,spec,addlargs): + self.required_values=[] + self.valid_values=["chost"] + generic_stage_target.__init__(self,spec,addlargs) + + def set_source_path(self): + if "SEEDCACHE" in self.settings and os.path.isdir(normpath(self.settings["storedir"]+"/tmp/"+self.settings["source_subpath"]+"/tmp/stage1root/")): + self.settings["source_path"]=normpath(self.settings["storedir"]+"/tmp/"+self.settings["source_subpath"]+"/tmp/stage1root/") + else: + self.settings["source_path"]=normpath(self.settings["storedir"]+"/builds/"+self.settings["source_subpath"]+".tar.bz2") + if os.path.isfile(self.settings["source_path"]): + if os.path.exists(self.settings["source_path"]): + # XXX: Is this even necessary if the previous check passes? + self.settings["source_path_hash"]=generate_hash(self.settings["source_path"],\ + hash_function=self.settings["hash_function"],verbose=False) + print "Source path set to "+self.settings["source_path"] + if os.path.isdir(self.settings["source_path"]): + print "\tIf this is not desired, remove this directory or turn of seedcache in the options of catalyst.conf" + print "\tthe source path will then be "+normpath(self.settings["storedir"]+"/builds/"+self.settings["source_subpath"]+".tar.bz2\n") + + # XXX: How do these override_foo() functions differ from the ones in + # generic_stage_target and why aren't they in stage3_target? + + def override_chost(self): + if "chost" in self.settings: + self.settings["CHOST"]=list_to_string(self.settings["chost"]) + + def override_cflags(self): + if "cflags" in self.settings: + self.settings["CFLAGS"]=list_to_string(self.settings["cflags"]) + + def override_cxxflags(self): + if "cxxflags" in self.settings: + self.settings["CXXFLAGS"]=list_to_string(self.settings["cxxflags"]) + + def override_ldflags(self): + if "ldflags" in self.settings: + self.settings["LDFLAGS"]=list_to_string(self.settings["ldflags"]) + + def set_portage_overlay(self): + generic_stage_target.set_portage_overlay(self) + if "portage_overlay" in self.settings: + print "\nWARNING !!!!!" + print "\tUsing an portage overlay for earlier stages could cause build issues." + print "\tIf you break it, you buy it. Don't complain to us about it." + print "\tDont say we did not warn you\n" + +def register(foo): + foo.update({"stage2":stage2_target}) + return foo diff --git a/catalyst/targets/stage3_target.py b/catalyst/targets/stage3_target.py new file mode 100644 index 0000000..89edd66 --- /dev/null +++ b/catalyst/targets/stage3_target.py @@ -0,0 +1,31 @@ +""" +stage3 target, builds upon previous stage2/stage3 tarball +""" +# NOTE: That^^ docstring has influence catalyst-spec(5) man page generation. + +from catalyst.support import * +from generic_stage_target import * + +class stage3_target(generic_stage_target): + """ + Builder class for a stage3 installation tarball build. + """ + def __init__(self,spec,addlargs): + self.required_values=[] + self.valid_values=[] + generic_stage_target.__init__(self,spec,addlargs) + + def set_portage_overlay(self): + generic_stage_target.set_portage_overlay(self) + if "portage_overlay" in self.settings: + print "\nWARNING !!!!!" + print "\tUsing an overlay for earlier stages could cause build issues." + print "\tIf you break it, you buy it. Don't complain to us about it." + print "\tDont say we did not warn you\n" + + def set_cleanables(self): + generic_stage_target.set_cleanables(self) + +def register(foo): + foo.update({"stage3":stage3_target}) + return foo diff --git a/catalyst/targets/stage4_target.py b/catalyst/targets/stage4_target.py new file mode 100644 index 0000000..9168f2e --- /dev/null +++ b/catalyst/targets/stage4_target.py @@ -0,0 +1,43 @@ +""" +stage4 target, builds upon previous stage3/stage4 tarball +""" +# NOTE: That^^ docstring has influence catalyst-spec(5) man page generation. + +from catalyst.support import * +from generic_stage_target import * + +class stage4_target(generic_stage_target): + """ + Builder class for stage4. + """ + def __init__(self,spec,addlargs): + self.required_values=["stage4/packages"] + self.valid_values=self.required_values[:] + self.valid_values.extend(["stage4/use","boot/kernel",\ + "stage4/root_overlay","stage4/fsscript",\ + "stage4/gk_mainargs","splash_theme",\ + "portage_overlay","stage4/rcadd","stage4/rcdel",\ + "stage4/linuxrc","stage4/unmerge","stage4/rm","stage4/empty"]) + generic_stage_target.__init__(self,spec,addlargs) + + def set_cleanables(self): + self.settings["cleanables"]=["/var/tmp/*","/tmp/*"] + + def set_action_sequence(self): + self.settings["action_sequence"]=["unpack","unpack_snapshot",\ + "config_profile_link","setup_confdir","portage_overlay",\ + "bind","chroot_setup","setup_environment","build_packages",\ + "build_kernel","bootloader","root_overlay","fsscript",\ + "preclean","rcupdate","unmerge","unbind","remove","empty",\ + "clean"] + +# if "TARBALL" in self.settings or \ +# "FETCH" not in self.settings: + if "FETCH" not in self.settings: + self.settings["action_sequence"].append("capture") + self.settings["action_sequence"].append("clear_autoresume") + +def register(foo): + foo.update({"stage4":stage4_target}) + return foo + diff --git a/catalyst/targets/tinderbox_target.py b/catalyst/targets/tinderbox_target.py new file mode 100644 index 0000000..5985c5b --- /dev/null +++ b/catalyst/targets/tinderbox_target.py @@ -0,0 +1,44 @@ +""" +Tinderbox target +""" +# NOTE: That^^ docstring has influence catalyst-spec(5) man page generation. + +from catalyst.support import * +from generic_stage_target import * + +class tinderbox_target(generic_stage_target): + """ + Builder class for the tinderbox target + """ + def __init__(self,spec,addlargs): + self.required_values=["tinderbox/packages"] + self.valid_values=self.required_values[:] + self.valid_values.extend(["tinderbox/use"]) + generic_stage_target.__init__(self,spec,addlargs) + + def run_local(self): + # tinderbox + # example call: "grp.sh run xmms vim sys-apps/gleep" + try: + if os.path.exists(self.settings["controller_file"]): + cmd("/bin/bash "+self.settings["controller_file"]+" run "+\ + list_bashify(self.settings["tinderbox/packages"]),"run script failed.",env=self.env) + + except CatalystError: + self.unbind() + raise CatalystError,"Tinderbox aborting due to error." + + def set_cleanables(self): + self.settings["cleanables"]=["/etc/resolv.conf","/var/tmp/*","/root/*", + self.settings['portdir']] + + def set_action_sequence(self): + #Default action sequence for run method + self.settings["action_sequence"]=["unpack","unpack_snapshot",\ + "config_profile_link","setup_confdir","bind","chroot_setup",\ + "setup_environment","run_local","preclean","unbind","clean",\ + "clear_autoresume"] + +def register(foo): + foo.update({"tinderbox":tinderbox_target}) + return foo -- 1.8.3.2