summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2007-06-22 08:47:02 +0000
committerZac Medico <zmedico@gentoo.org>2007-06-22 08:47:02 +0000
commite8fa32b8a6342ba4dff2333abd2af0a89fb25ca2 (patch)
treefa24058ed5db4a7048107712701ba31ea7a6ef1e
parent83878c034e3d6be49165f4e06afe97a5084af2e6 (diff)
downloadportage-e8fa32b8a6342ba4dff2333abd2af0a89fb25ca2.tar.gz
portage-e8fa32b8a6342ba4dff2333abd2af0a89fb25ca2.tar.bz2
portage-e8fa32b8a6342ba4dff2333abd2af0a89fb25ca2.zip
For bug #182428, make quickpkg exclude config files that are protected by CONFIG_PROTECT. Add a --include-config option that includes all config files and a --include-unmodified-config that includes config files that have not been modified since installation (matching md5sum).
svn path=/main/trunk/; revision=6945
-rwxr-xr-xbin/quickpkg45
-rw-r--r--pym/portage/dbapi/vartree.py20
2 files changed, 56 insertions, 9 deletions
diff --git a/bin/quickpkg b/bin/quickpkg
index 17611d6ed..0ae9fd61b 100755
--- a/bin/quickpkg
+++ b/bin/quickpkg
@@ -8,9 +8,10 @@ import errno, signal, sys, os
def quickpkg_main(options, args, eout):
from portage import catsplit, dep_expand, flatten, isvalidatom, xpak
from portage.dep import use_reduce, paren_reduce
- from portage.util import ensure_dirs
+ from portage.util import ConfigProtect, ensure_dirs
from portage.exception import InvalidData, InvalidDependString
from portage.dbapi.vartree import dblink, tar_contents
+ from portage.checksum import perform_md5
import tarfile
import portage
root = portage.settings["ROOT"]
@@ -23,6 +24,9 @@ def quickpkg_main(options, args, eout):
return errno.EACCES
successes = []
missing = []
+ config_files_excluded = 0
+ include_config = options.include_config == "y"
+ include_unmodified_config = options.include_unmodified_config == "y"
for arg in args:
try:
atom = dep_expand(arg, mydb=vardb, settings=vartree.settings)
@@ -45,6 +49,7 @@ def quickpkg_main(options, args, eout):
matches = vardb.match(atom)
pkgs_for_arg = 0
for cpv in matches:
+ excluded_config_files = []
bintree.prevent_collision(cpv)
cat, pkg = catsplit(cpv)
dblnk = dblink(cat, pkg, root,
@@ -76,12 +81,29 @@ def quickpkg_main(options, args, eout):
eout.ebegin("Building package for %s" % cpv)
pkgs_for_arg += 1
contents = dblnk.getcontents()
+ protect = None
+ if not include_config:
+ confprot = ConfigProtect(root,
+ portage.settings.get("CONFIG_PROTECT","").split(),
+ portage.settings.get("CONFIG_PROTECT_MASK","").split())
+ def protect(filename):
+ if not confprot.isprotected(filename):
+ return False
+ if include_unmodified_config:
+ file_data = contents[filename]
+ if file_data[0] == "obj":
+ orig_md5 = file_data[2].lower()
+ cur_md5 = perform_md5(filename, calc_prelink=1)
+ if orig_md5 == cur_md5:
+ return False
+ excluded_config_files.append(filename)
+ return True
xpdata = xpak.xpak(dblnk.dbdir)
binpkg_tmpfile = os.path.join(bintree.pkgdir,
cpv + ".tbz2." + str(os.getpid()))
ensure_dirs(os.path.dirname(binpkg_tmpfile))
tar = tarfile.open(binpkg_tmpfile, "w:bz2")
- tar_contents(contents, root, tar)
+ tar_contents(contents, root, tar, protect=protect)
tar.close()
xpak.tbz2(binpkg_tmpfile).recompose_mem(xpdata)
finally:
@@ -99,6 +121,9 @@ def quickpkg_main(options, args, eout):
else:
eout.eend(0)
successes.append((cpv, s.st_size))
+ config_files_excluded += len(excluded_config_files)
+ for filename in excluded_config_files:
+ eout.ewarn("Excluded config: '%s'" % filename)
if not pkgs_for_arg:
eout.eerror("Could not find anything " + \
"to match '%s'; skipping" % arg)
@@ -129,6 +154,10 @@ def quickpkg_main(options, args, eout):
else:
size_str = str(size)
eout.einfo("%s: %s" % (cpv, size_str))
+ if config_files_excluded:
+ print
+ eout.ewarn("Excluded config files: %d" % config_files_excluded)
+ eout.ewarn("See --help if you would like to include config files.")
if missing:
print
eout.ewarn("The following packages could not be found:")
@@ -146,6 +175,18 @@ if __name__ == "__main__":
parser.add_option("--ignore-default-opts",
action="store_true",
help="do not use the QUICKPKG_DEFAULT_OPTS environment variable")
+ parser.add_option("--include-config",
+ type="choice",
+ choices=["y","n"],
+ default="n",
+ metavar="<y|n>",
+ help="include all files protected by CONFIG_PROTECT (as a security precaution, default is 'n')")
+ parser.add_option("--include-unmodified-config",
+ type="choice",
+ choices=["y","n"],
+ default="n",
+ metavar="<y|n>",
+ help="include files protected by CONFIG_PROTECT that have not been modified since installation (as a security precaution, default is 'n')")
options, args = parser.parse_args(sys.argv[1:])
if not options.ignore_default_opts:
from portage import settings
diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py
index 50b9d9d94..641d4942b 100644
--- a/pym/portage/dbapi/vartree.py
+++ b/pym/portage/dbapi/vartree.py
@@ -2127,8 +2127,8 @@ 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 tar_contents(contents, root, tar, onProgress=None):
- from portage import normalize_path
+def tar_contents(contents, root, tar, protect=None, onProgress=None):
+ from portage.util import normalize_path
root = normalize_path(root).rstrip(os.path.sep) + os.path.sep
id_strings = {}
maxval = len(contents)
@@ -2168,11 +2168,17 @@ def tar_contents(contents, root, tar, onProgress=None):
tarinfo.gname = id_strings.setdefault(tarinfo.gid, str(tarinfo.gid))
if stat.S_ISREG(lst.st_mode):
- f = file(path)
- try:
- tar.addfile(tarinfo, f)
- finally:
- f.close()
+ if protect and protect(path):
+ # Create an empty file as a place holder in order to avoid
+ # potential collision-protect issues.
+ tarinfo.size = 0
+ tar.addfile(tarinfo)
+ else:
+ f = open(path)
+ try:
+ tar.addfile(tarinfo, f)
+ finally:
+ f.close()
else:
tar.addfile(tarinfo)
if onProgress: