summaryrefslogtreecommitdiffstats
path: root/pym
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2006-09-23 22:14:31 +0000
committerZac Medico <zmedico@gentoo.org>2006-09-23 22:14:31 +0000
commit484293180a8dbe02e992bd479cf3d4b7304fe9de (patch)
tree5dc0b857e19a961e6525435d0b09498f968392be /pym
parent0a0ae63bd937f1b86c83e88f582a577da98ef639 (diff)
downloadportage-484293180a8dbe02e992bd479cf3d4b7304fe9de.tar.gz
portage-484293180a8dbe02e992bd479cf3d4b7304fe9de.tar.bz2
portage-484293180a8dbe02e992bd479cf3d4b7304fe9de.zip
Fix portage.pkgmerge() so that it locks files and directories when in use.
svn path=/main/trunk/; revision=4520
Diffstat (limited to 'pym')
-rw-r--r--pym/portage.py158
1 files changed, 94 insertions, 64 deletions
diff --git a/pym/portage.py b/pym/portage.py
index a68a2be73..238363417 100644
--- a/pym/portage.py
+++ b/pym/portage.py
@@ -6547,14 +6547,6 @@ class FetchlistDict(UserDict.DictMixin):
"""Returns keys for all packages within pkgdir"""
return self.portdb.cp_list(self.cp, mytree=self.mytree)
-def cleanup_pkgmerge(mypkg, origdir, settings=None):
- if settings is None:
- settings = globals()["settings"]
- shutil.rmtree(settings["PORTAGE_TMPDIR"]+"/binpkgs/"+mypkg)
- if os.path.exists(settings["PORTAGE_TMPDIR"]+"/portage/"+mypkg+"/temp/environment"):
- os.unlink(settings["PORTAGE_TMPDIR"]+"/portage/"+mypkg+"/temp/environment")
- os.chdir(origdir)
-
def pkgmerge(mytbz2, myroot, mysettings, mydbapi=None, vartree=None, prev_mtimes=None):
"""will merge a .tbz2 file, returning a list of runtime dependencies
that must be satisfied, or None if there was a merge error. This
@@ -6567,64 +6559,102 @@ def pkgmerge(mytbz2, myroot, mysettings, mydbapi=None, vartree=None, prev_mtimes
if mytbz2[-5:]!=".tbz2":
print "!!! Not a .tbz2 file"
return None
- mypkg=os.path.basename(mytbz2)[:-5]
- xptbz2=xpak.tbz2(mytbz2)
- pkginfo={}
- mycat=xptbz2.getfile("CATEGORY")
- if not mycat:
- print "!!! CATEGORY info missing from info chunk, aborting..."
- return None
- mycat=mycat.strip()
- mycatpkg=mycat+"/"+mypkg
- tmploc=mysettings["PORTAGE_TMPDIR"]+"/binpkgs/"
- pkgloc=tmploc+"/"+mypkg+"/bin/"
- infloc=tmploc+"/"+mypkg+"/inf/"
- myebuild=tmploc+"/"+mypkg+"/inf/"+os.path.basename(mytbz2)[:-4]+"ebuild"
- if os.path.exists(tmploc+"/"+mypkg):
- shutil.rmtree(tmploc+"/"+mypkg,1)
- os.makedirs(pkgloc)
- os.makedirs(infloc)
- writemsg_stdout(">>> Extracting info\n")
- xptbz2.unpackinfo(infloc)
- # run pkg_setup early, so we can bail out early
- # (before extracting binaries) if there's a problem
- origdir=getcwd()
- os.chdir(pkgloc)
-
- # Save the md5sum for later.
- fp = open(os.path.join(infloc, "BINPKGMD5"), "w")
- fp.write(str(portage_checksum.perform_md5(mytbz2))+"\n")
- fp.close()
-
- mysettings.configdict["pkg"]["CATEGORY"] = mycat;
- # Eventually we'd like to pass in the saved ebuild env here.
- # Do cleanup=1 to ensure that there is no cruft prior to the setup phase.
- a = doebuild(myebuild, "setup", myroot, mysettings, tree="bintree",
- cleanup=1, mydbapi=mydbapi, vartree=vartree)
- writemsg_stdout(">>> Extracting %s\n" % mypkg)
- notok=spawn("bzip2 -dqc -- '"+mytbz2+"' | tar xpf -",mysettings,free=1)
- if notok:
- print "!!! Error Extracting",mytbz2
- cleanup_pkgmerge(mypkg, origdir, settings=mysettings)
- return None
- # the merge takes care of pre/postinst and old instance
- # auto-unmerge, virtual/provides updates, etc.
- mysettings.load_infodir(infloc)
- mylink = dblink(mycat, mypkg, myroot, mysettings, vartree=vartree,
- treetype="bintree")
- mylink.merge(pkgloc, infloc, myroot, myebuild, cleanup=1, mydbapi=mydbapi,
- prev_mtimes=prev_mtimes)
+ tbz2_lock = None
+ binpkg_tmpdir_lock = None
+ builddir_lock = None
+ try:
+ tbz2_lock = portage_locks.lockfile(mytbz2, wantnewlockfile=1)
- if not os.path.exists(infloc+"/RDEPEND"):
- returnme=""
- else:
- #get runtime dependencies
- a=open(infloc+"/RDEPEND","r")
- returnme=string.join(string.split(a.read())," ")
- a.close()
- cleanup_pkgmerge(mypkg, origdir, settings=mysettings)
- return returnme
+ mypkg = os.path.basename(mytbz2)[:-5]
+ xptbz2 = xpak.tbz2(mytbz2)
+ mycat = xptbz2.getfile("CATEGORY")
+ if not mycat:
+ writemsg("!!! CATEGORY info missing from info chunk, aborting...\n",
+ noiselevel=-1)
+ return None
+ mycat = mycat.strip()
+ mycatpkg = "%s/%s" % (mycat, mypkg)
+
+ binpkg_tmpdir = os.path.join(
+ mysettings["PORTAGE_TMPDIR"], "binpkgs", mypkg)
+ pkgloc = os.path.join(binpkg_tmpdir, "bin")
+ infloc = os.path.join(binpkg_tmpdir, "inf")
+ myebuild = os.path.join(
+ infloc, os.path.basename(mytbz2)[:-4] + "ebuild")
+ binpkg_tmp_lock = portage_locks.lockdir(binpkg_tmpdir)
+ try:
+ shutil.rmtree(binpkg_tmpdir)
+ except (IOError, OSError), e:
+ if e.errno != errno.ENOENT:
+ raise
+ del e
+ for mydir in (binpkg_tmpdir, pkgloc, infloc):
+ portage_util.ensure_dirs(mydir, gid=portage_gid, mode=070)
+ writemsg_stdout(">>> Extracting info\n")
+ xptbz2.unpackinfo(infloc)
+ # Store the md5sum in the vdb.
+ fp = open(os.path.join(infloc, "BINPKGMD5"), "w")
+ fp.write(str(portage_checksum.perform_md5(mytbz2))+"\n")
+ fp.close()
+
+ mysettings.configdict["pkg"]["CATEGORY"] = mycat;
+
+ debug = mysettings.get("PORTAGE_DEBUG", "") == "1"
+ doebuild_environment(myebuild, "setup", myroot,
+ mysettings, debug, 1, mydbapi)
+ portage_util.ensure_dirs(
+ os.path.dirname(mysettings["PORTAGE_BUILDDIR"]),
+ gid=portage_gid, mode=070, mask=02)
+ builddir = mysettings["PORTAGE_BUILDDIR"]
+ builddir_lock = portage_locks.lockdir(builddir)
+
+ # Eventually we'd like to pass in the saved ebuild env here.
+ # Do cleanup=1 to ensure that there is no cruft prior to the setup phase.
+ retval = doebuild(myebuild, "setup", myroot, mysettings, tree="bintree",
+ cleanup=1, mydbapi=mydbapi, vartree=vartree)
+ if retval != os.EX_OK:
+ writemsg("!!! Setup failed: %s\n" % retval, noiselevel=-1)
+ return None
+
+ writemsg_stdout(">>> Extracting %s\n" % mypkg)
+ retval = portage_exec.spawn_bash(
+ "bzip2 -dqc -- '%s' | tar -xp -C '%s' -f -" % (mytbz2, pkgloc),
+ env=mysettings.environ())
+ if retval != os.EX_OK:
+ writemsg("!!! Error Extracting '%s'\n" % mytbz2, noiselevel=-1)
+ return None
+ portage_locks.unlockfile(tbz2_lock)
+ tbz2_lock = None
+
+ mysettings.load_infodir(infloc)
+ mylink = dblink(mycat, mypkg, myroot, mysettings, vartree=vartree,
+ treetype="bintree")
+ mylink.merge(pkgloc, infloc, myroot, myebuild, cleanup=0,
+ mydbapi=mydbapi, prev_mtimes=prev_mtimes)
+
+ try:
+ f = open(os.path.join(infloc, "RDEPEND", "r"))
+ try:
+ return " ".join(f.read().split())
+ finally:
+ f.close()
+ except (IOError, OSError):
+ return ""
+ finally:
+ if tbz2_lock:
+ portage_locks.unlockfile(tbz2_lock)
+ if binpkg_tmp_lock:
+ shutil.rmtree(binpkg_tmpdir)
+ portage_locks.unlockdir(binpkg_tmp_lock)
+ if builddir_lock:
+ try:
+ shutil.rmtree(builddir)
+ except (IOError, OSError), e:
+ if e.errno != errno.ENOENT:
+ raise
+ del e
+ portage_locks.unlockdir(builddir_lock)
def deprecated_profile_check():
if not os.access(DEPRECATED_PROFILE_FILE, os.R_OK):