public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-commits] proj/portage:master commit in: man/, pym/portage/dbapi/, bin/, pym/portage/
@ 2012-07-01  7:54 Zac Medico
  0 siblings, 0 replies; only message in thread
From: Zac Medico @ 2012-07-01  7:54 UTC (permalink / raw
  To: gentoo-commits

commit:     f807bb54317db5f8073f8904897cf4b9d87bf2cd
Author:     Zac Medico <zmedico <AT> gentoo <DOT> org>
AuthorDate: Sun Jul  1 07:53:52 2012 +0000
Commit:     Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Sun Jul  1 07:53:52 2012 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=f807bb54

Support FEATURES={downgrade,unmerge}-backup

This will fix bug #156282 and bug #424275.

---
 bin/quickpkg                 |   15 ++++---
 man/make.conf.5              |   13 +++++-
 pym/portage/const.py         |    4 +-
 pym/portage/dbapi/vartree.py |   93 +++++++++++++++++++++++++++++++++++++----
 4 files changed, 108 insertions(+), 17 deletions(-)

diff --git a/bin/quickpkg b/bin/quickpkg
index d908c03..a6bd4d4 100755
--- a/bin/quickpkg
+++ b/bin/quickpkg
@@ -1,5 +1,5 @@
 #!/usr/bin/python
-# Copyright 1999-2010 Gentoo Foundation
+# Copyright 1999-2012 Gentoo Foundation
 # Distributed under the terms of the GNU General Public License v2
 
 from __future__ import print_function
@@ -68,11 +68,14 @@ def quickpkg_atom(options, infos, arg, eout):
 		bintree.prevent_collision(cpv)
 		dblnk = vardb._dblink(cpv)
 		have_lock = False
-		try:
-			dblnk.lockdb()
-			have_lock = True
-		except PermissionDenied:
-			pass
+
+		if "__PORTAGE_INHERIT_VARDB_LOCK" not in settings:
+			try:
+				dblnk.lockdb()
+				have_lock = True
+			except PermissionDenied:
+				pass
+
 		try:
 			if not dblnk.exists():
 				# unmerged by a concurrent process

diff --git a/man/make.conf.5 b/man/make.conf.5
index 7d07344..876a8a3 100644
--- a/man/make.conf.5
+++ b/man/make.conf.5
@@ -1,4 +1,4 @@
-.TH "MAKE.CONF" "5" "May 2012" "Portage VERSION" "Portage"
+.TH "MAKE.CONF" "5" "Jul 2012" "Portage VERSION" "Portage"
 .SH "NAME"
 make.conf \- custom settings for Portage
 .SH "SYNOPSIS"
@@ -293,6 +293,12 @@ strangely configured Samba server (oplocks off, NFS re\-export). A tool
 /usr/lib/portage/bin/clean_locks exists to help handle lock issues
 when a problem arises (normally due to a crash or disconnect).
 .TP
+.B downgrade\-backup
+When a package is downgraded to a lower version, call \fBquickpkg\fR(1)
+in order to create a backup of the installed version before it is
+unmerged (if a binary package of the same version does not already
+exist). Also see the related \fIunmerge\-backup\fR feature.
+.TP
 .B ebuild\-locks
 Use locks to ensure that unsandboxed ebuild phases never execute
 concurrently. Also see \fIparallel\-install\fR.
@@ -514,6 +520,11 @@ continue to execute the remaining phases as if the failure had not occurred.
 Note that the test phase for a specific package may be disabled by masking
 the "test" \fBUSE\fR flag in \fBpackage.use.mask\fR (see \fBportage\fR(5)).
 .TP
+.B unmerge\-backup
+Call \fBquickpkg\fR(1) to create a backup of each package before it is
+unmerged (if a binary package of the same version does not already exist).
+Also see the related \fIdowngrade\-backup\fR feature.
+.TP
 .B unmerge\-logs
 Keep logs from successful unmerge phases. This is relevant only when
 \fBPORT_LOGDIR\fR is set.

diff --git a/pym/portage/const.py b/pym/portage/const.py
index 3607df0..4a07710 100644
--- a/pym/portage/const.py
+++ b/pym/portage/const.py
@@ -90,7 +90,8 @@ SUPPORTED_FEATURES       = frozenset([
                            "ccache", "chflags", "clean-logs",
                            "collision-protect", "compress-build-logs", "compressdebug",
                            "config-protect-if-modified",
-                           "digest", "distcc", "distcc-pump", "distlocks", "ebuild-locks", "fakeroot",
+                           "digest", "distcc", "distcc-pump", "distlocks",
+                           "downgrade-backup", "ebuild-locks", "fakeroot",
                            "fail-clean", "force-mirror", "force-prefix", "getbinpkg",
                            "installsources", "keeptemp", "keepwork", "fixlafiles", "lmirror",
                            "metadata-transfer", "mirror", "multilib-strict", "news",
@@ -103,6 +104,7 @@ SUPPORTED_FEATURES       = frozenset([
                            "sign", "skiprocheck", "split-elog", "split-log", "splitdebug",
                            "strict", "stricter", "suidctl", "test", "test-fail-continue",
                            "unknown-features-filter", "unknown-features-warn",
+                           "unmerge-backup",
                            "unmerge-logs", "unmerge-orphans", "userfetch", "userpriv",
                            "usersandbox", "usersync", "webrsync-gpg", "xattr"])
 

diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py
index 34098ea..0d7327a 100644
--- a/pym/portage/dbapi/vartree.py
+++ b/pym/portage/dbapi/vartree.py
@@ -21,6 +21,7 @@ portage.proxy.lazyimport.lazyimport(globals(),
 	'portage.package.ebuild.doebuild:doebuild_environment,' + \
 		'_merge_unicode_error', '_spawn_phase',
 	'portage.package.ebuild.prepare_build_dirs:prepare_build_dirs',
+	'portage.package.ebuild._ipc.QueryCommand:QueryCommand',
 	'portage.update:fixdbentries',
 	'portage.util:apply_secpass_permissions,ConfigProtect,ensure_dirs,' + \
 		'writemsg,writemsg_level,write_atomic,atomic_ofstream,writedict,' + \
@@ -62,6 +63,7 @@ from _emerge.EbuildPhase import EbuildPhase
 from _emerge.emergelog import emergelog
 from _emerge.PollScheduler import PollScheduler
 from _emerge.MiscFunctionsProcess import MiscFunctionsProcess
+from _emerge.SpawnProcess import SpawnProcess
 
 import errno
 import fnmatch
@@ -1777,6 +1779,11 @@ class dblink(object):
 		showMessage = self._display_merge
 		if self.vartree.dbapi._categories is not None:
 			self.vartree.dbapi._categories = None
+
+		# When others_in_slot is not None, the backup has already been
+		# handled by the caller.
+		caller_handles_backup = others_in_slot is not None
+
 		# When others_in_slot is supplied, the security check has already been
 		# done for this slot, so it shouldn't be repeated until the next
 		# replacement or unmerge operation.
@@ -1842,6 +1849,11 @@ class dblink(object):
 				prepare_build_dirs(settings=self.settings, cleanup=True)
 				log_path = self.settings.get("PORTAGE_LOG_FILE")
 
+			if not caller_handles_backup:
+				retval = self._pre_unmerge_backup(background)
+				if retval != os.EX_OK:
+					return retval
+
 			# Log the error after PORTAGE_LOG_FILE is initialized
 			# by prepare_build_dirs above.
 			if eapi_unsupported:
@@ -3833,6 +3845,20 @@ class dblink(object):
 		self.delete()
 		ensure_dirs(self.dbtmpdir)
 
+		downgrade = False
+		if self._installed_instance is not None and \
+			vercmp(self.mycpv.version,
+			self._installed_instance.mycpv.version) < 0:
+			downgrade = True
+
+		if self._installed_instance is not None:
+			rval = self._pre_merge_backup(self._installed_instance, downgrade)
+			if rval != os.EX_OK:
+				showMessage(_("!!! FAILED preinst: ") +
+					"quickpkg: %s\n" % rval,
+					level=logging.ERROR, noiselevel=-1)
+				return rval
+
 		# run preinst script
 		showMessage(_(">>> Merging %(cpv)s to %(destroot)s\n") % \
 			{"cpv":self.mycpv, "destroot":destroot})
@@ -3866,20 +3892,15 @@ class dblink(object):
 		#if we have a file containing previously-merged config file md5sums, grab it.
 		self.vartree.dbapi._fs_lock()
 		try:
+			# Always behave like --noconfmem is enabled for downgrades
+			# so that people who don't know about this option are less
+			# likely to get confused when doing upgrade/downgrade cycles.
 			cfgfiledict = grabdict(self.vartree.dbapi._conf_mem_file)
-			if "NOCONFMEM" in self.settings:
+			if "NOCONFMEM" in self.settings or downgrade:
 				cfgfiledict["IGNORE"]=1
 			else:
 				cfgfiledict["IGNORE"]=0
 
-			# Always behave like --noconfmem is enabled for downgrades
-			# so that people who don't know about this option are less
-			# likely to get confused when doing upgrade/downgrade cycles.
-			for other in others_in_slot:
-				if vercmp(self.mycpv.version, other.mycpv.version) < 0:
-					cfgfiledict["IGNORE"] = 1
-					break
-
 			rval = self._merge_contents(srcroot, destroot, cfgfiledict)
 			if rval != os.EX_OK:
 				return rval
@@ -4682,6 +4703,60 @@ class dblink(object):
 		"Is this a regular package (does it have a CATEGORY file?  A dblink can be virtual *and* regular)"
 		return os.path.exists(os.path.join(self.dbdir, "CATEGORY"))
 
+	def _pre_merge_backup(self, backup_dblink, downgrade):
+
+		if ("unmerge-backup" in self.settings.features or
+			(downgrade and "downgrade-backup" in self.settings.features)):
+			return self._quickpkg_dblink(backup_dblink, False, None)
+
+		return os.EX_OK
+
+	def _pre_unmerge_backup(self, background):
+
+		if "unmerge-backup" in self.settings.features :
+			logfile = None
+			if self.settings.get("PORTAGE_BACKGROUND") != "subprocess":
+				logfile = self.settings.get("PORTAGE_LOG_FILE")
+			return self._quickpkg_dblink(self, background, logfile)
+
+		return os.EX_OK
+
+	def _quickpkg_dblink(self, backup_dblink, background, logfile):
+
+		trees = QueryCommand.get_db()[self.settings["EROOT"]]
+		bintree = trees["bintree"]
+		binpkg_path = bintree.getname(backup_dblink.mycpv)
+		if os.path.exists(binpkg_path) and \
+			backup_dblink.mycpv not in bintree.invalids:
+			return os.EX_OK
+
+		self.lockdb()
+		try:
+
+			if not backup_dblink.exists():
+				# It got unmerged by a concurrent process.
+				return os.EX_OK
+
+			# Call quickpkg for support of QUICKPKG_DEFAULT_OPTS and stuff.
+			quickpkg_binary = os.path.join(self.settings["PORTAGE_BIN_PATH"],
+				"quickpkg")
+
+			# Let quickpkg inherit the global vartree config's env.
+			env = dict(self.vartree.settings.items())
+			env["__PORTAGE_INHERIT_VARDB_LOCK"] = "1"
+
+			quickpkg_proc = SpawnProcess(
+				args=[portage._python_interpreter, quickpkg_binary,
+					"=%s" % (backup_dblink.mycpv,)],
+				background=background, env=env,
+				scheduler=self._scheduler, logfile=logfile)
+			quickpkg_proc.start()
+
+			return quickpkg_proc.wait()
+
+		finally:
+			self.unlockdb()
+
 def merge(mycat, mypkg, pkgloc, infloc,
 	myroot=None, settings=None, myebuild=None,
 	mytree=None, mydbapi=None, vartree=None, prev_mtimes=None, blockers=None,



^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2012-07-01  7:54 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-07-01  7:54 [gentoo-commits] proj/portage:master commit in: man/, pym/portage/dbapi/, bin/, pym/portage/ Zac Medico

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox