From da5030eb9bfad4e946e08fb1a873c1e959383c32 Mon Sep 17 00:00:00 2001 From: Daniel Robbins Date: Wed, 29 Oct 2003 06:52:15 +0000 Subject: [PATCH] continued work git-svn-id: svn+ssh://svn.gentoo.org/var/svnroot/catalyst/trunk@32 d1e1f19c-881f-0410-ab34-b69fee027534 --- catalyst | 6 ++- modules/catalyst_support.py | 15 ++++--- modules/targets.py | 79 +++++++++++++++++++++++++++---------- targets/stage3/stage3.sh | 27 +++++++++---- 4 files changed, 92 insertions(+), 35 deletions(-) diff --git a/catalyst b/catalyst index a209ffe2..6fa73889 100755 --- a/catalyst +++ b/catalyst @@ -31,7 +31,11 @@ myspec["sharedir"]="/usr/share/catalyst" #these would come from there too?: myspec["distdir"]="/mnt/misc/distfiles" myspec["portdir"]="/usr/portage" - +myspec["options"]="ccache pkgcache" +if "ccache" in string.split(myspec["options"]): + myspec["CCACHE"]="1" +if "pkgcache" in string.split(myspec["options"]): + myspec["PKGCACHE"]="1" #determine target, call target constructor and hand it the rest of the arguments try: diff --git a/modules/catalyst_support.py b/modules/catalyst_support.py index ad171679..0315aedd 100644 --- a/modules/catalyst_support.py +++ b/modules/catalyst_support.py @@ -1,10 +1,15 @@ import sys,string,os -config_file_values=["storedir","sharedir","distdir","portdir"] +required_config_file_values=["storedir","sharedir","distdir","portdir"] +valid_config_file_values=required_config_file_values[:] +valid_config_file_values.append("CCACHE") +valid_config_file_values.append("PKGCACHE") +valid_config_file_values.append("options") class CatalystError(Exception): def __init__(self, message): if message: + print print "catalyst: "+message def die(msg=None): warn(msg) @@ -27,7 +32,7 @@ def ismount(path): return 0 def arg_parse(mydict,remaining={}): - global config_file_values + global required_config_file_values for x in sys.argv[1:]: foo=string.split(x,"=") if len(foo)!=2: @@ -36,16 +41,16 @@ def arg_parse(mydict,remaining={}): if not remaining.has_key("target"): raise CatalystError, "Required value \"target\" not specified." mydict["target"]=remaining["target"] - for x in config_file_values: + for x in required_config_file_values: if not mydict.has_key(x): raise CatalystError, "Required config file value \""+x+"\" not found." def addl_arg_parse(myspec,addlargs,requiredspec,validspec): "helper function to help targets parse additional arguments" - global config_file_values + global valid_config_file_values for x in addlargs.keys(): - if x not in validspec and x not in config_file_values: + if x not in validspec and x not in valid_config_file_values: raise CatalystError, "Argument \""+x+"\" not recognized." else: myspec[x]=addlargs[x] diff --git a/modules/targets.py b/modules/targets.py index 9a86501e..e5d53628 100644 --- a/modules/targets.py +++ b/modules/targets.py @@ -36,9 +36,6 @@ class generic_stage_target(generic_target): if not machinemap.has_key(mymachine): raise CatalystError, "Unknown machine type "+mymachine self.settings["hostarch"]=machinemap[mymachine] - print "Host architecture:",self.settings["hostarch"] - print "Supported architectures for targets:",string.join(targetmap[self.settings["hostarch"]]) - print "Loading all valid plugins for this machine:", self.archmap={} self.subarchmap={} for x in targetmap[self.settings["hostarch"]]: @@ -48,9 +45,6 @@ class generic_stage_target(generic_target): #this next line registers all the subarches supported in the plugin self.archmap[x].register(self.subarchmap) fh.close() - print x, - print - print "Available subarches:",string.join(self.subarchmap.keys()) #call arch constructor, pass our settings self.arch=self.subarchmap[self.settings["subarch"]](self.settings) self.settings["target_subpath"]=self.settings["rel_type"]+"-"+self.settings["mainarch"]+"-"+self.settings["rel_version"] @@ -60,16 +54,25 @@ class generic_stage_target(generic_target): self.settings["target_path"]=st+"/builds/"+self.settings["target_subpath"]+".tar.bz2" self.settings["source_path"]=st+"/builds/"+self.settings["source_subpath"]+".tar.bz2" self.settings["chroot_path"]=st+"/tmp/"+self.settings["target_subpath"] - self.settings["pkgcache_path"]=st+"/packages/"+self.settings["target_subpath"] + + self.mounts=[ "/proc","/dev","/usr/portage/distfiles" ] + self.mountmap={"/proc":"/proc", "/dev":"/dev", "/usr/portage/distfiles":self.settings["distdir"]} + if self.settings.has_key("PKGCACHE"): + self.settings["pkgcache_path"]=st+"/packages/"+self.settings["target_subpath"] + self.mounts.append("/usr/portage/packages") + self.mountmap["/usr/portage/packages"]=self.settings["pkgcache_path"] + if self.settings.has_key("CCACHE"): + self.mounts.append("/root/.ccache") + self.mountmap["/root/.ccache"]="/root/.ccache" + 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. - paths=["/usr/portage/packages","/usr/portage/distfiles", "/var/tmp/distfiles", "/proc", "/root/.ccache", "/dev"] if not os.path.exists(mypath): return - for x in paths: + for x in self.mounts: if not os.path.exists(mypath+x): continue if ismount(mypath+x): @@ -77,6 +80,7 @@ class generic_stage_target(generic_target): raise CatalystError, x+" is still mounted; aborting." def dir_setup(self): + print "Setting up directories..." self.mount_safety_check() retval=os.system("rm -rf "+self.settings["chroot_path"]) if retval != 0: @@ -86,26 +90,27 @@ class generic_stage_target(generic_target): os.makedirs(self.settings["pkgcache_path"]) def unpack_and_bind(self): + print "Unpacking stage tarball..." retval=os.system("tar xjpf "+self.settings["source_path"]+" -C "+self.settings["chroot_path"]) if retval!=0: raise CatalystError,"Error unpacking tarball" + print "Unpacking portage tree snapshot..." retval=os.system("tar xjpf "+self.settings["snapshot_path"]+" -C "+self.settings["chroot_path"]+"/usr") if retval!=0: raise CatalystError,"Error unpacking snapshot" - for x in [[self.settings["distdir"],"/usr/portage/distfiles"], - ["/proc","/proc"],["/dev","/dev"]]: - if not os.path.exists(self.settings["chroot_path"]+x[1]): - os.makedirs(self.settings["chroot_path"]+x[1]) - - retval=os.system("mount --bind "+x[0]+" "+self.settings["chroot_path"]+x[1]) + for x in self.mounts: + if not os.path.exists(self.settings["chroot_path"]+x): + os.makedirs(self.settings["chroot_path"]+x) + src=self.mountmap[x] + retval=os.system("mount --bind "+src+" "+self.settings["chroot_path"]+x) if retval!=0: self.unbind() - raise CatalystError,"Couldn't bind mount "+x[0] + raise CatalystError,"Couldn't bind mount "+src def unbind(self): ouch=0 mypath=self.settings["chroot_path"] - for x in ["/usr/portage/distfiles","/proc","/dev"]: + for x in self.mounts: if not os.path.exists(mypath+x): continue if not ismount(mypath+x): @@ -122,28 +127,60 @@ class generic_stage_target(generic_target): raise CatalystError,"Couldn't umount one or more bind-mounts; aborting for safety." def chroot_setup(self): - self.unpack_and_bind() retval=os.system("cp /etc/resolv.conf "+self.settings["chroot_path"]+"/etc") if retval!=0: raise CatalystError,"Could not copy resolv.conf into place." + #Ugly bunch of sed commands to get /etc/make.conf to hold the correct default values for the stage + #we're building. This way, when a user uses a pentium4 stage3, it is set up to compile for pentium4 + #using the CFLAGS and USE settings we used. It's possible that this would look nicer written in + #python, even without using regexes which aren't really necessary. + mycmds=[] + mycmds.append("sed -i -e '/# catalyst start/,/# catalyst stop/d'") + mycmds.append("sed -i -e 's:^CFLAGS=:#&:' -e 's:^CXXFLAGS=:#&:' -e 's:^CHOST=:#&:' -e 's:^USE=:#&:'") + sedcmd="sed -i -e '5i\\' -e '# catalyst start\\' -e '# these settings were added by the catalyst build script" + sedcmd+=" that automatically built this stage\\' -e 'CFLAGS=\""+self.settings["CFLAGS"]+"\"\\'" + if self.settings.has_key("CXXFLAGS"): + sedcmd+=" -e 'CXXFLAGS=\""+self.settings["CXXFLAGS"]+"\"\\'" + else: + sedcmd+=" -e 'CXXFLAGS=\"${CFLAGS}\"\\'" + sedcmd+=" -e 'CHOST=\""+self.settings["CHOST"]+"\"\\'" + if self.settings.has_key("HOSTUSE"): + sedcmd+=" -e 'USE=\""+string.join(self.settings["HOSTUSE"])+"\"\\'" + sedcmd+=" -e '# catalyst end\\' -e ''" + mycmds.append(sedcmd) + for x in mycmds: + mycmd=x+" "+self.settings["chroot_path"]+"/etc/make.conf" + retval=os.system(mycmd) + if retval != 0: + raise CatalystError, "Sed command failed: "+mycmd def clean(self): "do not call without first unbinding" - retval=os.system("rm "+self.settings["chroot_path"]+"/etc/resolv.conf") + os.system("rm -f"+self.settings["chroot_path"]+"/etc/ld.so.preload") + retval=os.system("rm -f"+self.settings["chroot_path"]+"/etc/resolv.conf") if retval!=0: raise CatalystError,"Could not clean up resolv.conf." + retval=os.system("rm -f"+self.settings["chroot_path"]+"/usr/portage") + if retval!=0: + raise CatalystError,"Could not clean up Portage tree." retval=os.system(self.settings["storedir"]+"/targets/"+self.settings["target"]+"/"+self.settings["target"]+".sh clean") if retval!=0: raise CatalystError,"clean script failed." def run(self): self.dir_setup() - self.chroot_setup() + self.unpack_and_bind() + try: + self.chroot_setup() + except: + self.unbind() + raise #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(): if type(self.settings[x])==types.StringType: - os.environ[x]=self.settings[x] + #prefix to prevent namespace clashes: + os.environ["clst_"+x]=self.settings[x] try: retval=os.system(self.settings["storedir"]+"/targets/"+self.settings["target"]+"/"+self.settings["target"]+".sh run") if retval!=0: diff --git a/targets/stage3/stage3.sh b/targets/stage3/stage3.sh index d913fb57..a8a56c9a 100755 --- a/targets/stage3/stage3.sh +++ b/targets/stage3/stage3.sh @@ -1,33 +1,44 @@ # Copyright 1999-2003 Gentoo Technologies, Inc. # Distributed under the terms of the GNU General Public License v2 -# $Header: /var/cvsroot/gentoo/src/catalyst/targets/stage3/Attic/stage3.sh,v 1.2 2003/10/28 22:09:23 drobbins Exp $ +# $Header: /var/cvsroot/gentoo/src/catalyst/targets/stage3/Attic/stage3.sh,v 1.3 2003/10/29 06:52:15 drobbins Exp $ case $1 in enter) - $CHROOT $chroot_path + $clst_CHROOT $clst_chroot_path ;; run) - $CHROOT $chroot_path /bin/bash << EOF + $clst_CHROOT $clst_chroot_path /bin/bash << EOF env-update source /etc/profile - if [ -n "${CCACHE}" ] + if [ -n "${clst_CCACHE}" ] then + export FEATURES="ccache" emerge --oneshot --nodeps --usepkg --buildpkg ccache || exit 1 fi - if [ ${rel_type} = "hardened" ] + if [ ${clst_rel_type} = "hardened" ] then emerge --oneshot --nodeps hardened-gcc || exit 1 fi export CONFIG_PROTECT="-*" - emerge system --usepkg --buildpkg || exit 1 + + #portage needs to be merged manually with USE="build" set to avoid frying our + #make.conf. emerge system could merge it otherwise. + USE="build" emerge portage + + if [ -n "${clst_PKGCACHE}" ] + then + emerge system --usepkg --buildpkg || exit 1 + else + emerge system || exit 1 + fi EOF [ $? -ne 0 ] && exit 1 ;; clean) - $CHROOT $chroot_path /bin/bash << EOF + $clst_CHROOT $clst_chroot_path /bin/bash << EOF env-update source /etc/profile - if [ -n "${CCACHE}" ] + if [ -n "${clst_CCACHE}" ] then emerge -C ccache || exit 1 fi -- 2.26.2