On 11/02/2018 12:16 PM, Michał Górny wrote:
> On Fri, 2018-11-02 at 11:49 -0700, Zac Medico wrote:
>> On 11/01/2018 02:50 AM, Michał Górny wrote:
>>> Add FEATURES=binpkg-docompress that can be used whether docompress
>>> compression is performed before or after creating binary packages.  With
>>> the feature enabled (the default), the current behavior of storing
>>> compressed files in binpkg is preserved.  With it disabled, uncompressed
>>> files are stored inside binary package and are compressed when
>>> installing.
>>>
>>> Storing uncompressed files in binary packages has two advantages:
>>>
>>> 1. Avoids the double-compression penalty, effectively improving binary
>>>    package compression speed and compression ratio.
>>>
>>> 2. Allows the same packages to be reused on systems with different
>>>    docompress configurations.
>>>
>>> The option is roughly backwards compatible.  Old Portage versions will
>>> install packages created with FEATURES=-binpkg-docompress correctly,
>>> albeit without compression.  Portage with FEATURES=binpkg-docompress
>>> should install old binpackages semi-correctly, potentially recompressing
>>> them (and throwing already-compressed warnings on format mismatch).
>>> The new behavior is left off by default to avoid those problems.
>>>
>>> Signed-off-by: Michał Górny <mgo...@gentoo.org>
>>> ---
>>>  bin/misc-functions.sh                  | 34 +++++++++++++++++++++++---
>>>  cnf/make.globals                       |  2 +-
>>>  lib/portage/const.py                   |  1 +
>>>  lib/portage/dbapi/vartree.py           | 12 +++++++++
>>>  lib/portage/package/ebuild/doebuild.py |  3 ++-
>>>  man/make.conf.5                        |  6 +++++
>>>  6 files changed, 52 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/bin/misc-functions.sh b/bin/misc-functions.sh
>>> index db7aaed5a..96aa66611 100755
>>> --- a/bin/misc-functions.sh
>>> +++ b/bin/misc-functions.sh
>>> @@ -109,10 +109,13 @@ install_qa_check() {
>>>  
>>>     [[ -d ${ED%/}/usr/share/info ]] && prepinfo
>>>  
>>> -   # Apply compression.
>>> -   "${PORTAGE_BIN_PATH}"/ecompress --queue "${PORTAGE_DOCOMPRESS[@]}"
>>> -   "${PORTAGE_BIN_PATH}"/ecompress --ignore "${PORTAGE_DOCOMPRESS_SKIP[@]}"
>>> -   "${PORTAGE_BIN_PATH}"/ecompress --dequeue
>>> +   # If binpkg-docompress is enabled, apply compression before creating
>>> +   # the binary package.
>>> +   if has binpkg-docompress ${FEATURES}; then
>>> +           "${PORTAGE_BIN_PATH}"/ecompress --queue 
>>> "${PORTAGE_DOCOMPRESS[@]}"
>>> +           "${PORTAGE_BIN_PATH}"/ecompress --ignore 
>>> "${PORTAGE_DOCOMPRESS_SKIP[@]}"
>>> +           "${PORTAGE_BIN_PATH}"/ecompress --dequeue
>>> +   fi
>>>  
>>>     export STRIP_MASK
>>>     if ___eapi_has_dostrip; then
>>> @@ -160,6 +163,29 @@ install_qa_check() {
>>>     rm -f "${ED%/}"/usr/share/info/dir{,.gz,.bz2} || die "rm failed!"
>>>  }
>>>  
>>> +__dyn_instprep() {
>>> +   if has chflags ${FEATURES}; then
>>> +           # Save all the file flags for restoration afterwards.
>>> +           mtree -c -p "${ED}" -k flags > "${T}/bsdflags.mtree"
>>> +           # Remove all the file flags so that we can do anything 
>>> necessary.
>>> +           chflags -R noschg,nouchg,nosappnd,nouappnd "${ED}"
>>> +           chflags -R nosunlnk,nouunlnk "${ED}" 2>/dev/null
>>> +   fi
>>> +
>>> +   # If binpkg-docompress is disabled, we need to apply compression
>>> +   # before installing.
>>> +   if ! has binpkg-docompress ${FEATURES}; then
>>> +           "${PORTAGE_BIN_PATH}"/ecompress --queue 
>>> "${PORTAGE_DOCOMPRESS[@]}"
>>> +           "${PORTAGE_BIN_PATH}"/ecompress --ignore 
>>> "${PORTAGE_DOCOMPRESS_SKIP[@]}"
>>> +           "${PORTAGE_BIN_PATH}"/ecompress --dequeue
>>> +   fi
>>> +
>>> +   if has chflags ${FEATURES}; then
>>> +           # Restore all the file flags that were saved earlier on.
>>> +           mtree -U -e -p "${ED}" -k flags < "${T}/bsdflags.mtree" &> 
>>> /dev/null
>>> +   fi
>>> +}
>>> +
>>>  preinst_qa_check() {
>>>     postinst_qa_check preinst
>>>  }
>>> diff --git a/cnf/make.globals b/cnf/make.globals
>>> index 04a708af8..72b567e98 100644
>>> --- a/cnf/make.globals
>>> +++ b/cnf/make.globals
>>> @@ -50,7 +50,7 @@ RESUMECOMMAND_SSH=${FETCHCOMMAND_SSH}
>>>  FETCHCOMMAND_SFTP="bash -c \"x=\\\${2#sftp://} ; host=\\\${x%%/*} ; 
>>> port=\\\${host##*:} ; host=\\\${host%:*} ; [[ \\\${host} = \\\${port} ]] && 
>>> port= ; eval \\\"declare -a ssh_opts=(\\\${3})\\\" ; exec sftp 
>>> \\\${port:+-P \\\${port}} \\\"\\\${ssh_opts[@]}\\\" 
>>> \\\"\\\${host}:/\\\${x#*/}\\\" \\\"\\\$1\\\"\" sftp 
>>> \"\${DISTDIR}/\${FILE}\" \"\${URI}\" \"\${PORTAGE_SSH_OPTS}\""
>>>  
>>>  # Default user options
>>> -FEATURES="assume-digests binpkg-logs
>>> +FEATURES="assume-digests binpkg-docompress binpkg-logs
>>>            config-protect-if-modified distlocks ebuild-locks
>>>            fixlafiles merge-sync multilib-strict news
>>>            parallel-fetch preserve-libs protect-owned
>>> diff --git a/lib/portage/const.py b/lib/portage/const.py
>>> index 7f84bf0e9..a343fc040 100644
>>> --- a/lib/portage/const.py
>>> +++ b/lib/portage/const.py
>>> @@ -122,6 +122,7 @@ EBUILD_PHASES            = (
>>>  )
>>>  SUPPORTED_FEATURES       = frozenset([
>>>     "assume-digests",
>>> +   "binpkg-docompress",
>>>     "binpkg-logs",
>>>     "binpkg-multi-instance",
>>>     "buildpkg",
>>> diff --git a/lib/portage/dbapi/vartree.py b/lib/portage/dbapi/vartree.py
>>> index c16fdfe88..fd8aaeb8e 100644
>>> --- a/lib/portage/dbapi/vartree.py
>>> +++ b/lib/portage/dbapi/vartree.py
>>> @@ -3719,6 +3719,7 @@ class dblink(object):
>>>  
>>>             This function does the following:
>>>  
>>> +           calls doebuild(mydo=instprep)
>>>             calls get_ro_checker to retrieve a function for checking 
>>> whether Portage
>>>             will write to a read-only filesystem, then runs it against the 
>>> directory list
>>>             calls self._preserve_libs if FEATURES=preserve-libs
>>> @@ -3768,6 +3769,17 @@ class dblink(object):
>>>                             level=logging.ERROR, noiselevel=-1)
>>>                     return 1
>>>  
>>> +           # run instprep internal phase
>>> +           doebuild_environment(myebuild, "instprep",
>>> +                   settings=self.settings, db=mydbapi)
>>> +           phase = EbuildPhase(background=False, phase="instprep",
>>> +                   scheduler=self._scheduler, settings=self.settings)
>>> +           phase.start()
>>> +           if phase.wait() != os.EX_OK:
>>> +                   showMessage(_("!!! instprep failed\n"),
>>> +                           level=logging.ERROR, noiselevel=-1)
>>> +                   return 1
>>> +
>>>             is_binpkg = self.settings.get("EMERGE_FROM") == "binary"
>>>             slot = ''
>>>             for var_name in ('CHOST', 'SLOT'):
>>> diff --git a/lib/portage/package/ebuild/doebuild.py 
>>> b/lib/portage/package/ebuild/doebuild.py
>>> index 9706de422..d7b535698 100644
>>> --- a/lib/portage/package/ebuild/doebuild.py
>>> +++ b/lib/portage/package/ebuild/doebuild.py
>>> @@ -674,7 +674,7 @@ def doebuild(myebuild, mydo, 
>>> _unused=DeprecationWarning, settings=None, debug=0,
>>>                     "config", "info", "setup", "depend", "pretend",
>>>                     "fetch", "fetchall", "digest",
>>>                     "unpack", "prepare", "configure", "compile", "test",
>>> -                   "install", "rpm", "qmerge", "merge",
>>> +                   "install", "instprep", "rpm", "qmerge", "merge",
>>>                     "package", "unmerge", "manifest", "nofetch"]
>>>  
>>>     if mydo not in validcommands:
>>> @@ -1402,6 +1402,7 @@ def _spawn_actionmap(settings):
>>>  "compile":  {"cmd":ebuild_sh, "args":{"droppriv":droppriv, 
>>> "free":nosandbox, "sesandbox":sesandbox, "fakeroot":0}},
>>>  "test":     {"cmd":ebuild_sh, "args":{"droppriv":droppriv, 
>>> "free":nosandbox, "sesandbox":sesandbox, "fakeroot":0}},
>>>  "install":  {"cmd":ebuild_sh, "args":{"droppriv":0,        "free":0,       
>>>   "sesandbox":sesandbox, "fakeroot":fakeroot}},
>>> +"instprep": {"cmd":misc_sh,   "args":{"droppriv":0,        "free":0,       
>>>   "sesandbox":sesandbox, "fakeroot":fakeroot}},
>>>  "rpm":      {"cmd":misc_sh,   "args":{"droppriv":0,        "free":0,       
>>>   "sesandbox":0,         "fakeroot":fakeroot}},
>>>  "package":  {"cmd":misc_sh,   "args":{"droppriv":0,        "free":0,       
>>>   "sesandbox":0,         "fakeroot":fakeroot}},
>>>             }
>>
>> The feature seems find but the instprep phase is not needed if we use
>> MiscFunctionsProcess instead of EbuildPhase. Here's a list of odd things
>> about the instprep ebuild phase implementation as it is:
>>
>> 1) You can call instprep explicitly via the ebuild(1) command, but I
>> doubt that we really want or need to allow that.
> 
> I was actually wondering about that.  I suppose it might be useful for
> debugging purposes.  However, since I wasn't able to figure out how to
> fully integrate it with the phase machinery, I went for the minimal set
> of code that wouldn't be definitive either way.
> 
>> 2) Unlinke other ebuild phases, the doebuild function doesn't created a
>> .instpreped file to indicate when the instprep phase has executed.
> 
> I suppose I can try to do that if that's desirable.
> 
>> 3) Currently instprep executes when FEATURES=binpkg-docompress is
>> enabled, even though it does nothing of value. I think we should instead
>> generate a relevant list of MiscFunctionsProcess commands for the
>> enabled FEATURES, and only start a MiscFunctionsProcess instance if the
>> list of commands is non-empty.
> 
> That sounds like premature optimization with a bit of going against
> principle of least surprise.  Given it's a phase function with specific
> implementation that could be extended in the future, I'd rather avoid
> hiding additional conditions for running it elsewhere, as it opens
> a strong possibility that somebody adds additional functionality but
> forgets to update the condition resulting either in immediate WTF
> or the new code being skipped only for some users, with even harder-to-
> debug WTF.

I wasn't really sure that instprep deserved to be a full-fledged phase
at this point. I guess you're planning to add more stuff there?
-- 
Thanks,
Zac

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to