From: "Michał Górny" <mgorny@gentoo.org>
To: gentoo-portage-dev@lists.gentoo.org
Cc: "Michał Górny" <mgorny@gentoo.org>
Subject: [gentoo-portage-dev] [PATCH 2/3] portage.dbapi.vartree: Move INSTALL_MASK handling into merging
Date: Thu, 15 Mar 2018 20:22:10 +0100 [thread overview]
Message-ID: <20180315192212.13454-3-mgorny@gentoo.org> (raw)
In-Reply-To: <20180315192212.13454-1-mgorny@gentoo.org>
Introduce a new logic for INSTALL_MASK handling in merging code,
replacing the old code that removed matching files and directories
from imagedir in bash. The new code actually ignores matching files
on-the-fly while testing for file collisions and merging files.
The files are still written to CONTENTS, and output using "###" zing
to indicate being masked, yet are not actually merged to the filesystem.
---
bin/misc-functions.sh | 17 ------
pym/portage/dbapi/vartree.py | 102 ++++++++++++++++++++++-------------
pym/portage/package/ebuild/config.py | 3 +-
3 files changed, 66 insertions(+), 56 deletions(-)
diff --git a/bin/misc-functions.sh b/bin/misc-functions.sh
index 6a5c2ea05..59391816b 100755
--- a/bin/misc-functions.sh
+++ b/bin/misc-functions.sh
@@ -361,23 +361,6 @@ install_mask() {
set -${shopts}
}
-preinst_mask() {
- if [ -z "${D}" ]; then
- eerror "${FUNCNAME}: D is unset"
- return 1
- fi
-
- if ! ___eapi_has_prefix_variables; then
- local ED=${D}
- fi
-
- # Make sure $PWD is not ${D} so that we don't leave gmon.out files
- # in there in case any tools were built with -pg in CFLAGS.
- cd "${T}"
-
- install_mask "${ED}" "${INSTALL_MASK}"
-}
-
preinst_sfperms() {
if [ -z "${D}" ]; then
eerror "${FUNCNAME}: D is unset"
diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py
index 8b1b77f7d..21904edca 100644
--- a/pym/portage/dbapi/vartree.py
+++ b/pym/portage/dbapi/vartree.py
@@ -2491,7 +2491,7 @@ class dblink(object):
(statobj.st_dev, statobj.st_ino),
[]).append(relative_path)
- if is_owned:
+ if is_owned and not self._is_install_masked(relative_path[1:]):
show_unmerge("---", unmerge_desc["replaced"], file_type, obj)
continue
elif relative_path in cfgfiledict:
@@ -3689,6 +3689,24 @@ class dblink(object):
def _emerge_log(self, msg):
emergelog(False, msg)
+ def _is_install_masked(self, relative_path):
+ ret = False
+ for pattern in self.settings.install_mask:
+ # absolute path pattern
+ if pattern.startswith('/'):
+ # match either exact path or one of parent dirs
+ # the latter is done via matching pattern/*
+ if (fnmatch.fnmatch(relative_path, pattern[1:])
+ or fnmatch.fnmatch(relative_path, pattern[1:] + '/*')):
+ ret = True
+ break
+ # filename
+ else:
+ if fnmatch.fnmatch(os.path.basename(relative_path), pattern):
+ ret = True
+ break
+ return ret
+
def treewalk(self, srcroot, destroot, inforoot, myebuild, cleanup=0,
mydbapi=None, prev_mtimes=None, counter=None):
"""
@@ -3848,16 +3866,6 @@ class dblink(object):
max_dblnk = dblnk
self._installed_instance = max_dblnk
- # Apply INSTALL_MASK before collision-protect, since it may
- # be useful to avoid collisions in some scenarios.
- # We cannot detect if this is needed or not here as INSTALL_MASK can be
- # modified by bashrc files.
- phase = MiscFunctionsProcess(background=False,
- commands=["preinst_mask"], phase="preinst",
- scheduler=self._scheduler, settings=self.settings)
- phase.start()
- phase.wait()
-
# We check for unicode encoding issues after src_install. However,
# the check must be repeated here for binary packages (it's
# inexpensive since we call os.walk() here anyway).
@@ -3929,6 +3937,10 @@ class dblink(object):
relative_path = fpath[srcroot_len:]
+ # filter on INSTALL_MASK
+ if self._is_install_masked(relative_path):
+ continue
+
if line_ending_re.search(relative_path) is not None:
paths_with_newlines.append(relative_path)
@@ -4658,6 +4670,7 @@ class dblink(object):
while mergelist:
relative_path = mergelist.pop()
+ instmasked = self._is_install_masked(relative_path)
mysrc = join(srcroot, relative_path)
mydest = join(destroot, relative_path)
# myrealdest is mydest without the $ROOT prefix (makes a difference if ROOT!="/")
@@ -4744,7 +4757,7 @@ class dblink(object):
destmd5 = None
moveme = True
- if protected:
+ if protected and not instmasked:
mydest, protected, moveme = self._protect(cfgfiledict,
protect_if_modified, mymd5, myto, mydest,
myrealdest, mydmode, destmd5, mydest_link)
@@ -4772,7 +4785,7 @@ class dblink(object):
# we can simply test for existence of this file to see if the target has been merged yet
myrealto = normalize_path(os.path.join(destroot, myabsto))
if mydmode is not None and stat.S_ISDIR(mydmode):
- if not protected:
+ if not protected and not instmasked:
# we can't merge a symlink over a directory
newdest = self._new_backup_path(mydest)
msg = []
@@ -4792,26 +4805,32 @@ class dblink(object):
# it later.
secondhand.append(mysrc[len(srcroot):])
continue
- # unlinking no longer necessary; "movefile" will overwrite symlinks atomically and correctly
- if moveme:
- zing = ">>>"
- mymtime = movefile(mysrc, mydest, newmtime=thismtime,
- sstat=mystat, mysettings=self.settings,
- encoding=_encodings['merge'])
- try:
- self._merged_path(mydest, os.lstat(mydest))
- except OSError:
- pass
+ if instmasked:
+ zing = "###"
+ # pass mymtime through from initial stat
+ else:
+ # unlinking no longer necessary; "movefile" will overwrite symlinks atomically and correctly
+ if moveme:
+ zing = ">>>"
+ mymtime = movefile(mysrc, mydest, newmtime=thismtime,
+ sstat=mystat, mysettings=self.settings,
+ encoding=_encodings['merge'])
+
+ try:
+ self._merged_path(mydest, os.lstat(mydest))
+ except OSError:
+ pass
if mymtime != None:
- # Use lexists, since if the target happens to be a broken
- # symlink then that should trigger an independent warning.
- if not (os.path.lexists(myrealto) or
- os.path.lexists(join(srcroot, myabsto))):
- self._eqawarn('preinst',
- [_("QA Notice: Symbolic link /%s points to /%s which does not exist.")
- % (relative_path, myabsto)])
+ if not instmasked:
+ # Use lexists, since if the target happens to be a broken
+ # symlink then that should trigger an independent warning.
+ if not (os.path.lexists(myrealto) or
+ os.path.lexists(join(srcroot, myabsto))):
+ self._eqawarn('preinst',
+ [_("QA Notice: Symbolic link /%s points to /%s which does not exist.")
+ % (relative_path, myabsto)])
showMessage("%s %s -> %s\n" % (zing, mydest, myto))
if sys.hexversion >= 0x3030000:
@@ -4826,7 +4845,9 @@ class dblink(object):
return 1
elif stat.S_ISDIR(mymode):
# we are merging a directory
- if mydmode != None:
+ if instmasked:
+ showMessage("### %s/\n" % mydest)
+ elif mydmode != None:
# destination exists
if bsd_chflags:
@@ -4913,10 +4934,11 @@ class dblink(object):
os.chown(mydest, mystat[4], mystat[5])
showMessage(">>> %s/\n" % mydest)
- try:
- self._merged_path(mydest, os.lstat(mydest))
- except OSError:
- pass
+ if not instmasked:
+ try:
+ self._merged_path(mydest, os.lstat(mydest))
+ except OSError:
+ pass
outfile.write("dir "+myrealdest+"\n")
# recurse and merge this directory
@@ -4925,7 +4947,7 @@ class dblink(object):
elif stat.S_ISREG(mymode):
# we are merging a regular file
- if not protected and \
+ if not protected and not instmasked and \
mydmode is not None and stat.S_ISDIR(mydmode):
# install of destination is blocked by an existing directory with the same name
newdest = self._new_backup_path(mydest)
@@ -4939,9 +4961,11 @@ class dblink(object):
self._eerror("preinst", msg)
mydest = newdest
+ if instmasked:
+ zing = "###"
# whether config protection or not, we merge the new file the
# same way. Unless moveme=0 (blocking directory)
- if moveme:
+ elif moveme:
# Create hardlinks only for source files that already exist
# as hardlinks (having identical st_dev and st_ino).
hardlink_key = (mystat.st_dev, mystat.st_ino)
@@ -4974,7 +4998,9 @@ class dblink(object):
else:
# we are merging a fifo or device node
zing = "!!!"
- if mydmode is None:
+ if instmasked:
+ zing = "###"
+ elif mydmode is None:
# destination doesn't exist
if movefile(mysrc, mydest, newmtime=thismtime,
sstat=mystat, mysettings=self.settings,
diff --git a/pym/portage/package/ebuild/config.py b/pym/portage/package/ebuild/config.py
index 3f575fcaf..d04baacf9 100644
--- a/pym/portage/package/ebuild/config.py
+++ b/pym/portage/package/ebuild/config.py
@@ -271,6 +271,7 @@ class config(object):
self.mycpv = clone.mycpv
self._setcpv_args_hash = clone._setcpv_args_hash
self._soname_provided = clone._soname_provided
+ self.install_mask = clone.install_mask
# immutable attributes (internal policy ensures lack of mutation)
self._locations_manager = clone._locations_manager
@@ -2473,7 +2474,7 @@ class config(object):
install_mask.append("/usr/share/info")
if 'noman' in self.features:
install_mask.append("/usr/share/man")
- self["INSTALL_MASK"] = ' '.join(install_mask)
+ self.install_mask = tuple(install_mask)
if self.mycpv is None:
# Generate global USE_EXPAND variables settings that are
--
2.16.2
next prev parent reply other threads:[~2018-03-15 19:22 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-03-15 19:22 [gentoo-portage-dev] [PATCH 0/3] INSTALL_MASK refurbishing resubmit Michał Górny
2018-03-15 19:22 ` [gentoo-portage-dev] [PATCH 1/3] portage.package.ebuild.config: Move FEATURES=no* handling there Michał Górny
2018-03-15 19:22 ` Michał Górny [this message]
2018-03-15 19:22 ` [gentoo-portage-dev] [PATCH 3/3] portage.dbapi.vartree: Support exclusions in INSTALL_MASK Michał Górny
2018-03-15 21:02 ` Alec Warner
2018-03-15 21:17 ` Michał Górny
2018-03-15 21:44 ` Joakim Tjernlund
2018-03-16 7:50 ` Michał Górny
2018-03-16 8:08 ` Joakim Tjernlund
2018-03-16 5:10 ` [gentoo-portage-dev] [PATCH 0/3] INSTALL_MASK refurbishing resubmit Zac Medico
2018-03-16 8:31 ` Joakim Tjernlund
2018-03-16 10:08 ` Michał Górny
2018-03-16 17:07 ` Zac Medico
2018-03-16 21:13 ` Michał Górny
2018-03-16 21:25 ` Zac Medico
2018-03-18 9:03 ` Michał Górny
2018-03-18 18:22 ` Zac Medico
2018-03-19 6:27 ` Joakim Tjernlund
2018-03-16 8:11 ` Joakim Tjernlund
2018-03-16 8:13 ` Michał Górny
2018-03-18 9:57 ` Joakim Tjernlund
2018-03-19 22:59 ` Zac Medico
2018-03-23 0:52 ` Joakim Tjernlund
2018-03-23 1:09 ` Zac Medico
2018-03-23 8:33 ` Michał Górny
2018-03-23 9:05 ` Joakim Tjernlund
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180315192212.13454-3-mgorny@gentoo.org \
--to=mgorny@gentoo.org \
--cc=gentoo-portage-dev@lists.gentoo.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox