from stat import *
import catalyst_lock
+
+PORT_LOGDIR_CLEAN = \
+ 'find "${PORT_LOGDIR}" -type f ! -name "summary.log*" -mtime +30 -delete'
+
+TARGET_MOUNTS_DEFAULTS = {
+ "ccache": "/var/tmp/ccache",
+ "dev": "/dev",
+ "devpts": "/dev/pts",
+ "distdir": "/usr/portage/distfiles",
+ "icecream": "/usr/lib/icecc/bin",
+ "kerncache": "/tmp/kerncache",
+ "packagedir": "/usr/portage/packages",
+ "portdir": "/usr/portage",
+ "port_tmpdir": "/var/tmp/portage",
+ "port_logdir": "/var/log/portage",
+ "proc": "/proc",
+ "shm": "/dev/shm",
+ }
+
+SOURCE_MOUNTS_DEFAULTS = {
+ "dev": "/dev",
+ "devpts": "/dev/pts",
+ "distdir": "/usr/portage/distfiles",
+ "portdir": "/usr/portage",
+ "port_tmpdir": "tmpfs",
+ "proc": "/proc",
+ "shm": "shmfs",
+ }
+
+
class generic_stage_target(generic_target):
"""
This class does all of the chroot setup, copying of files, etc. It is
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","/usr/portage/distfiles","/var/tmp/portage"]
- self.mountmap={"/proc":"/proc","/dev":"/dev","/dev/pts":"/dev/pts",\
- "/usr/portage/distfiles":self.settings["distdir"],"/var/tmp/portage":"tmpfs"}
+ # initialize our target mounts.
+ self.target_mounts = TARGET_MOUNTS_DEFAULTS.copy()
+
+ self.mounts = ["proc", "dev", "portdir", "distdir", "port_tmpdir"]
+ # initialize our source mounts
+ self.mountmap = SOURCE_MOUNTS_DEFAULTS.copy()
+ # update them from settings
+ self.mountmap["distdir"] = self.settings["distdir"]
+ self.mountmap["portdir"] = normpath("/".join([
+ self.settings["snapshot_cache_path"],
+ self.settings["repo_name"],
+ ]))
+ if "SNAPCACHE" not in self.settings:
+ self.mounts.remove("portdir")
+ #self.mountmap["portdir"] = None
if os.uname()[0] == "Linux":
- self.mounts.append("/dev/pts")
+ self.mounts.append("devpts")
+ self.mounts.append("shm")
self.set_mounts()
self.set_pkgcache_path()
print "Location of the package cache is "+\
self.settings["pkgcache_path"]
- self.mounts.append("/usr/portage/packages")
- self.mountmap["/usr/portage/packages"]=\
- 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("/tmp/kerncache")
- self.mountmap["/tmp/kerncache"]=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:
raise CatalystError,\
"Compiler cache support can't be enabled (can't find "+\
ccdir+")"
- self.mounts.append("/var/tmp/ccache")
- self.mountmap["/var/tmp/ccache"]=ccdir
+ self.mounts.append("ccache")
+ self.mountmap["ccache"] = ccdir
""" for the chroot: """
- self.env["CCACHE_DIR"]="/var/tmp/ccache"
+ self.env["CCACHE_DIR"] = self.target_mounts["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"]
+ self.mounts.append("icecream")
+ self.mountmap["icecream"] = self.settings["icecream"]
+ self.env["PATH"] = self.target_mounts["icecream"] + ":" + \
+ 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'
+ self.mounts.append("port_logdir")
+ self.mountmap["port_logdir"] = self.settings["port_logdir"]
+ self.env["PORT_LOGDIR"] = self.settings["port_logdir"]
+ self.env["PORT_LOGDIR_CLEAN"] = PORT_LOGDIR_CLEAN
def override_cbuild(self):
if "CBUILD" in self.makeconf:
def set_snapshot_path(self):
self.settings["snapshot_path"]=normpath(self.settings["storedir"]+\
- "/snapshots/portage-"+self.settings["snapshot"]+".tar.xz")
+ "/snapshots/" + self.settings["snapshot_name"] +
+ self.settings["snapshot"] + ".tar.xz")
if os.path.exists(self.settings["snapshot_path"]):
self.settings["snapshot_path_hash"]=\
hash_function=self.settings["hash_function"],verbose=False)
else:
self.settings["snapshot_path"]=normpath(self.settings["storedir"]+\
- "/snapshots/portage-"+self.settings["snapshot"]+".tar.bz2")
+ "/snapshots/" + self.settings["snapshot_name"] +
+ self.settings["snapshot"] + ".tar.bz2")
if os.path.exists(self.settings["snapshot_path"]):
self.settings["snapshot_path_hash"]=\
def set_snapcache_path(self):
if "SNAPCACHE" in self.settings:
- self.settings["snapshot_cache_path"]=\
- normpath(self.settings["snapshot_cache"]+"/"+\
- self.settings["snapshot"]+"/")
+ self.settings["snapshot_cache_path"] = \
+ normpath(self.settings["snapshot_cache"] + "/" +
+ self.settings["snapshot"])
self.snapcache_lock=\
catalyst_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!
+ NOTE: the trailing slash has been removed
+ Things *could* break if you don't use a proper join()
"""
self.settings["chroot_path"]=normpath(self.settings["storedir"]+\
- "/tmp/"+self.settings["target_subpath"]+"/")
+ "/tmp/"+self.settings["target_subpath"])
self.chroot_lock=catalyst_lock.LockDir(self.settings["chroot_path"])
def set_autoresume_path(self):
"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):
+ if not os.path.exists(self.settings["chroot_path"]):
return
+ print "self.mounts =", self.mounts
for x in self.mounts:
- if not os.path.exists(mypath+x):
+ target = normpath(self.settings["chroot_path"] + self.target_mounts[x])
+ print "mount_safety_check() x =", x, target
+ if not os.path.exists(target):
continue
- if ismount(mypath+x):
+ if ismount(target):
""" Something is still mounted "" """
try:
- print x+" is still mounted; performing auto-bind-umount...",
+ print target + " is still mounted; performing auto-bind-umount...",
""" Try to umount stuff ourselves """
self.unbind()
- if ismount(mypath+x):
- raise CatalystError, "Auto-unbind failed for "+x
+ if ismount(target):
+ raise CatalystError, "Auto-unbind failed for " + target
else:
print "Auto-unbind successful..."
except CatalystError:
- raise CatalystError, "Unable to auto-unbind "+x
+ raise CatalystError, "Unable to auto-unbind " + target
def unpack(self):
unpack=True
if "SNAPCACHE" in self.settings:
snapshot_cache_hash=\
- read_from_clst(self.settings["snapshot_cache_path"]+\
- "catalyst-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
cmd(unpack_cmd,unpack_errmsg,env=self.env)
if "SNAPCACHE" in self.settings:
- myf=open(self.settings["snapshot_cache_path"]+"catalyst-hash","w")
+ myf=open(self.settings["snapshot_cache_path"] +
+ "/" + "catalyst-hash","w")
myf.write(self.settings["snapshot_path_hash"])
myf.close()
else:
if os.path.exists(x):
print "Copying overlay dir " +x
cmd("mkdir -p "+self.settings["chroot_path"]+\
- "/usr/local/portage",\
+ self.settings["local_overlay"],\
"Could not make portage_overlay dir",env=self.env)
cmd("cp -R "+x+"/* "+self.settings["chroot_path"]+\
- "/usr/local/portage",\
+ self.settings["local_overlay"],\
"Could not copy portage_overlay",env=self.env)
def root_overlay(self):
def bind(self):
for x in self.mounts:
- if not os.path.exists(self.settings["chroot_path"]+x):
- os.makedirs(self.settings["chroot_path"]+x,0755)
+ #print "bind(); x =", x
+ target = normpath(self.settings["chroot_path"] + self.target_mounts[x])
+ if not os.path.exists(target):
+ os.makedirs(target, 0755)
if not os.path.exists(self.mountmap[x]):
- if not self.mountmap[x] == "tmpfs":
- os.makedirs(self.mountmap[x],0755)
+ if self.mountmap[x] not in ["tmpfs", "shmfs"]:
+ os.makedirs(self.mountmap[x], 0755)
src=self.mountmap[x]
- if "SNAPCACHE" in self.settings and x == "/usr/portage":
+ #print "bind(); src =", src
+ if "SNAPCACHE" in self.settings and x == "portdir":
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"]+x)
+ cmd = "mount -t devfs none " + target
+ retval=os.system(cmd)
else:
- retval=os.system("mount_nullfs "+src+" "+\
- self.settings["chroot_path"]+x)
+ cmd = "mount_nullfs " + src + " " + target
+ retval=os.system(cmd)
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)
+ cmd = "mount -t tmpfs -o size=" + \
+ self.settings["var_tmpfs_portage"] + "G " + \
+ src + " " + target
+ retval=os.system(cmd)
+ elif src == "shmfs":
+ cmd = "mount -t tmpfs -o noexec,nosuid,nodev shm " + target
+ retval=os.system(cmd)
else:
- retval=os.system("mount --bind "+src+" "+\
- self.settings["chroot_path"]+x)
+ cmd = "mount --bind " + src + " " + target
+ #print "bind(); cmd =", cmd
+ retval=os.system(cmd)
if retval!=0:
self.unbind()
- raise CatalystError,"Couldn't bind mount "+src
+ raise CatalystError,"Couldn't bind mount " + src
def unbind(self):
ouch=0
myrevmounts.reverse()
""" Unmount in reverse order for nested bind-mounts """
for x in myrevmounts:
- if not os.path.exists(mypath+x):
+ target = normpath(mypath + self.target_mounts[x])
+ if not os.path.exists(target):
continue
- if not ismount(mypath+x):
+ if not ismount(target):
continue
- retval=os.system("umount "+\
- os.path.join(mypath,x.lstrip(os.path.sep)))
+ retval=os.system("umount " + target)
if retval!=0:
- warn("First attempt to unmount: "+mypath+x+" failed.")
+ warn("First attempt to unmount: " + target + " failed.")
warn("Killing any pids still running in the chroot")
self.kill_chroot_pids()
- retval2=os.system("umount "+mypath+x)
+ retval2 = os.system("umount " + target)
if retval2!=0:
ouch=1
- warn("Couldn't umount bind mount: "+mypath+x)
+ warn("Couldn't umount bind mount: " + target)
if "SNAPCACHE" in self.settings and x == "/usr/portage":
try:
myf.write('PORTDIR="%s"\n' % self.settings['portdir'])
myf.write('DISTDIR="%s"\n' % self.settings['distdir'])
- myf.write('PKGDIR="${PORTDIR}/packages"\n')
+ myf.write('PKGDIR="%s"\n' % self.settings['packagedir'])
""" Setup the portage overlay """
if "portage_overlay" in self.settings:
"Could not replace /etc/hosts",env=self.env)
""" Remove our overlay """
- if os.path.exists(self.settings["chroot_path"]+"/usr/local/portage"):
- cmd("rm -rf "+self.settings["chroot_path"]+"/usr/local/portage",\
- "Could not remove /usr/local/portage",env=self.env)
+ 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)