Remove some troublesome trailing slashes from paths
[catalyst.git] / modules / generic_stage_target.py
index fc54fbf263f82bd5583101cf408029b79b26111c..89b891bb0d411b718a73e3cc9ccc3a5edae18364 100644 (file)
@@ -4,6 +4,36 @@ from generic_target import *
 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
@@ -173,17 +203,24 @@ class generic_stage_target(generic_target):
                        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()
 
@@ -195,16 +232,15 @@ class generic_stage_target(generic_target):
                        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:
@@ -216,21 +252,22 @@ class generic_stage_target(generic_target):
                                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:
@@ -410,7 +447,8 @@ class generic_stage_target(generic_target):
 
        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"]=\
@@ -418,7 +456,8 @@ class generic_stage_target(generic_target):
                                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"]=\
@@ -427,20 +466,20 @@ class generic_stage_target(generic_target):
 
        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):
@@ -601,33 +640,34 @@ class generic_stage_target(generic_target):
                                "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
@@ -767,8 +807,8 @@ class generic_stage_target(generic_target):
 
                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
@@ -821,7 +861,8 @@ class generic_stage_target(generic_target):
                        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:
@@ -872,10 +913,10 @@ class generic_stage_target(generic_target):
                                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):
@@ -895,35 +936,43 @@ class generic_stage_target(generic_target):
 
        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
@@ -932,25 +981,25 @@ class generic_stage_target(generic_target):
                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:
@@ -1066,7 +1115,7 @@ class generic_stage_target(generic_target):
 
                        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:
@@ -1116,9 +1165,9 @@ class generic_stage_target(generic_target):
                                "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)