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)
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:
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]
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"]]:
#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"]
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):
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:
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):
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:
# 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