From: Brian Dolbec <dolsen@gentoo.org>
To: gentoo-catalyst@lists.gentoo.org
Cc: Brian Dolbec <dolsen@gentoo.org>
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 [thread overview]
Message-ID: <1386991211-9296-4-git-send-email-dolsen@gentoo.org> (raw)
In-Reply-To: <1386991211-9296-1-git-send-email-dolsen@gentoo.org>
---
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
next prev parent reply other threads:[~2013-12-14 3:21 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-12-14 3:20 [gentoo-catalyst] rewrite-on-master patches, round-2 Brian Dolbec
2013-12-14 3:20 ` [gentoo-catalyst] [PATCH 1/4] Initial rearrangement of the python directories Brian Dolbec
2013-12-14 5:22 ` Matt Turner
2013-12-14 5:48 ` W. Trevor King
2013-12-14 12:12 ` Brian Dolbec
2013-12-14 14:17 ` Dylan Baker
2013-12-14 16:42 ` Brian Dolbec
2013-12-14 23:57 ` W. Trevor King
2013-12-14 3:20 ` [gentoo-catalyst] [PATCH 2/4] move catalyst_support, builder, catalyst_lock out of modules, into the catalyst's base namespace Brian Dolbec
2013-12-14 3:20 ` Brian Dolbec [this message]
2013-12-14 3:20 ` [gentoo-catalyst] [PATCH 4/4] rename files directory to etc to better reflect the directories contents Brian Dolbec
2013-12-15 4:39 ` W. Trevor King
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1386991211-9296-4-git-send-email-dolsen@gentoo.org \
--to=dolsen@gentoo.org \
--cc=gentoo-catalyst@lists.gentoo.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox