Gentoo Archives: gentoo-portage-dev

From: Zac Medico <zmedico@g.o>
To: gentoo-portage-dev@l.g.o, "Michał Górny" <mgorny@g.o>
Subject: Re: [gentoo-portage-dev] [PATCH] Support disabling docompress for binary package builds
Date: Fri, 02 Nov 2018 19:23:02
Message-Id: ca9263c7-721b-9c2e-4f2a-8fc56c0fc8a7@gentoo.org
In Reply to: Re: [gentoo-portage-dev] [PATCH] Support disabling docompress for binary package builds by "Michał Górny"
1 On 11/02/2018 12:16 PM, Michał Górny wrote:
2 > On Fri, 2018-11-02 at 11:49 -0700, Zac Medico wrote:
3 >> On 11/01/2018 02:50 AM, Michał Górny wrote:
4 >>> Add FEATURES=binpkg-docompress that can be used whether docompress
5 >>> compression is performed before or after creating binary packages. With
6 >>> the feature enabled (the default), the current behavior of storing
7 >>> compressed files in binpkg is preserved. With it disabled, uncompressed
8 >>> files are stored inside binary package and are compressed when
9 >>> installing.
10 >>>
11 >>> Storing uncompressed files in binary packages has two advantages:
12 >>>
13 >>> 1. Avoids the double-compression penalty, effectively improving binary
14 >>> package compression speed and compression ratio.
15 >>>
16 >>> 2. Allows the same packages to be reused on systems with different
17 >>> docompress configurations.
18 >>>
19 >>> The option is roughly backwards compatible. Old Portage versions will
20 >>> install packages created with FEATURES=-binpkg-docompress correctly,
21 >>> albeit without compression. Portage with FEATURES=binpkg-docompress
22 >>> should install old binpackages semi-correctly, potentially recompressing
23 >>> them (and throwing already-compressed warnings on format mismatch).
24 >>> The new behavior is left off by default to avoid those problems.
25 >>>
26 >>> Signed-off-by: Michał Górny <mgorny@g.o>
27 >>> ---
28 >>> bin/misc-functions.sh | 34 +++++++++++++++++++++++---
29 >>> cnf/make.globals | 2 +-
30 >>> lib/portage/const.py | 1 +
31 >>> lib/portage/dbapi/vartree.py | 12 +++++++++
32 >>> lib/portage/package/ebuild/doebuild.py | 3 ++-
33 >>> man/make.conf.5 | 6 +++++
34 >>> 6 files changed, 52 insertions(+), 6 deletions(-)
35 >>>
36 >>> diff --git a/bin/misc-functions.sh b/bin/misc-functions.sh
37 >>> index db7aaed5a..96aa66611 100755
38 >>> --- a/bin/misc-functions.sh
39 >>> +++ b/bin/misc-functions.sh
40 >>> @@ -109,10 +109,13 @@ install_qa_check() {
41 >>>
42 >>> [[ -d ${ED%/}/usr/share/info ]] && prepinfo
43 >>>
44 >>> - # Apply compression.
45 >>> - "${PORTAGE_BIN_PATH}"/ecompress --queue "${PORTAGE_DOCOMPRESS[@]}"
46 >>> - "${PORTAGE_BIN_PATH}"/ecompress --ignore "${PORTAGE_DOCOMPRESS_SKIP[@]}"
47 >>> - "${PORTAGE_BIN_PATH}"/ecompress --dequeue
48 >>> + # If binpkg-docompress is enabled, apply compression before creating
49 >>> + # the binary package.
50 >>> + if has binpkg-docompress ${FEATURES}; then
51 >>> + "${PORTAGE_BIN_PATH}"/ecompress --queue "${PORTAGE_DOCOMPRESS[@]}"
52 >>> + "${PORTAGE_BIN_PATH}"/ecompress --ignore "${PORTAGE_DOCOMPRESS_SKIP[@]}"
53 >>> + "${PORTAGE_BIN_PATH}"/ecompress --dequeue
54 >>> + fi
55 >>>
56 >>> export STRIP_MASK
57 >>> if ___eapi_has_dostrip; then
58 >>> @@ -160,6 +163,29 @@ install_qa_check() {
59 >>> rm -f "${ED%/}"/usr/share/info/dir{,.gz,.bz2} || die "rm failed!"
60 >>> }
61 >>>
62 >>> +__dyn_instprep() {
63 >>> + if has chflags ${FEATURES}; then
64 >>> + # Save all the file flags for restoration afterwards.
65 >>> + mtree -c -p "${ED}" -k flags > "${T}/bsdflags.mtree"
66 >>> + # Remove all the file flags so that we can do anything necessary.
67 >>> + chflags -R noschg,nouchg,nosappnd,nouappnd "${ED}"
68 >>> + chflags -R nosunlnk,nouunlnk "${ED}" 2>/dev/null
69 >>> + fi
70 >>> +
71 >>> + # If binpkg-docompress is disabled, we need to apply compression
72 >>> + # before installing.
73 >>> + if ! has binpkg-docompress ${FEATURES}; then
74 >>> + "${PORTAGE_BIN_PATH}"/ecompress --queue "${PORTAGE_DOCOMPRESS[@]}"
75 >>> + "${PORTAGE_BIN_PATH}"/ecompress --ignore "${PORTAGE_DOCOMPRESS_SKIP[@]}"
76 >>> + "${PORTAGE_BIN_PATH}"/ecompress --dequeue
77 >>> + fi
78 >>> +
79 >>> + if has chflags ${FEATURES}; then
80 >>> + # Restore all the file flags that were saved earlier on.
81 >>> + mtree -U -e -p "${ED}" -k flags < "${T}/bsdflags.mtree" &> /dev/null
82 >>> + fi
83 >>> +}
84 >>> +
85 >>> preinst_qa_check() {
86 >>> postinst_qa_check preinst
87 >>> }
88 >>> diff --git a/cnf/make.globals b/cnf/make.globals
89 >>> index 04a708af8..72b567e98 100644
90 >>> --- a/cnf/make.globals
91 >>> +++ b/cnf/make.globals
92 >>> @@ -50,7 +50,7 @@ RESUMECOMMAND_SSH=${FETCHCOMMAND_SSH}
93 >>> 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}\""
94 >>>
95 >>> # Default user options
96 >>> -FEATURES="assume-digests binpkg-logs
97 >>> +FEATURES="assume-digests binpkg-docompress binpkg-logs
98 >>> config-protect-if-modified distlocks ebuild-locks
99 >>> fixlafiles merge-sync multilib-strict news
100 >>> parallel-fetch preserve-libs protect-owned
101 >>> diff --git a/lib/portage/const.py b/lib/portage/const.py
102 >>> index 7f84bf0e9..a343fc040 100644
103 >>> --- a/lib/portage/const.py
104 >>> +++ b/lib/portage/const.py
105 >>> @@ -122,6 +122,7 @@ EBUILD_PHASES = (
106 >>> )
107 >>> SUPPORTED_FEATURES = frozenset([
108 >>> "assume-digests",
109 >>> + "binpkg-docompress",
110 >>> "binpkg-logs",
111 >>> "binpkg-multi-instance",
112 >>> "buildpkg",
113 >>> diff --git a/lib/portage/dbapi/vartree.py b/lib/portage/dbapi/vartree.py
114 >>> index c16fdfe88..fd8aaeb8e 100644
115 >>> --- a/lib/portage/dbapi/vartree.py
116 >>> +++ b/lib/portage/dbapi/vartree.py
117 >>> @@ -3719,6 +3719,7 @@ class dblink(object):
118 >>>
119 >>> This function does the following:
120 >>>
121 >>> + calls doebuild(mydo=instprep)
122 >>> calls get_ro_checker to retrieve a function for checking whether Portage
123 >>> will write to a read-only filesystem, then runs it against the directory list
124 >>> calls self._preserve_libs if FEATURES=preserve-libs
125 >>> @@ -3768,6 +3769,17 @@ class dblink(object):
126 >>> level=logging.ERROR, noiselevel=-1)
127 >>> return 1
128 >>>
129 >>> + # run instprep internal phase
130 >>> + doebuild_environment(myebuild, "instprep",
131 >>> + settings=self.settings, db=mydbapi)
132 >>> + phase = EbuildPhase(background=False, phase="instprep",
133 >>> + scheduler=self._scheduler, settings=self.settings)
134 >>> + phase.start()
135 >>> + if phase.wait() != os.EX_OK:
136 >>> + showMessage(_("!!! instprep failed\n"),
137 >>> + level=logging.ERROR, noiselevel=-1)
138 >>> + return 1
139 >>> +
140 >>> is_binpkg = self.settings.get("EMERGE_FROM") == "binary"
141 >>> slot = ''
142 >>> for var_name in ('CHOST', 'SLOT'):
143 >>> diff --git a/lib/portage/package/ebuild/doebuild.py b/lib/portage/package/ebuild/doebuild.py
144 >>> index 9706de422..d7b535698 100644
145 >>> --- a/lib/portage/package/ebuild/doebuild.py
146 >>> +++ b/lib/portage/package/ebuild/doebuild.py
147 >>> @@ -674,7 +674,7 @@ def doebuild(myebuild, mydo, _unused=DeprecationWarning, settings=None, debug=0,
148 >>> "config", "info", "setup", "depend", "pretend",
149 >>> "fetch", "fetchall", "digest",
150 >>> "unpack", "prepare", "configure", "compile", "test",
151 >>> - "install", "rpm", "qmerge", "merge",
152 >>> + "install", "instprep", "rpm", "qmerge", "merge",
153 >>> "package", "unmerge", "manifest", "nofetch"]
154 >>>
155 >>> if mydo not in validcommands:
156 >>> @@ -1402,6 +1402,7 @@ def _spawn_actionmap(settings):
157 >>> "compile": {"cmd":ebuild_sh, "args":{"droppriv":droppriv, "free":nosandbox, "sesandbox":sesandbox, "fakeroot":0}},
158 >>> "test": {"cmd":ebuild_sh, "args":{"droppriv":droppriv, "free":nosandbox, "sesandbox":sesandbox, "fakeroot":0}},
159 >>> "install": {"cmd":ebuild_sh, "args":{"droppriv":0, "free":0, "sesandbox":sesandbox, "fakeroot":fakeroot}},
160 >>> +"instprep": {"cmd":misc_sh, "args":{"droppriv":0, "free":0, "sesandbox":sesandbox, "fakeroot":fakeroot}},
161 >>> "rpm": {"cmd":misc_sh, "args":{"droppriv":0, "free":0, "sesandbox":0, "fakeroot":fakeroot}},
162 >>> "package": {"cmd":misc_sh, "args":{"droppriv":0, "free":0, "sesandbox":0, "fakeroot":fakeroot}},
163 >>> }
164 >>
165 >> The feature seems find but the instprep phase is not needed if we use
166 >> MiscFunctionsProcess instead of EbuildPhase. Here's a list of odd things
167 >> about the instprep ebuild phase implementation as it is:
168 >>
169 >> 1) You can call instprep explicitly via the ebuild(1) command, but I
170 >> doubt that we really want or need to allow that.
171 >
172 > I was actually wondering about that. I suppose it might be useful for
173 > debugging purposes. However, since I wasn't able to figure out how to
174 > fully integrate it with the phase machinery, I went for the minimal set
175 > of code that wouldn't be definitive either way.
176 >
177 >> 2) Unlinke other ebuild phases, the doebuild function doesn't created a
178 >> .instpreped file to indicate when the instprep phase has executed.
179 >
180 > I suppose I can try to do that if that's desirable.
181 >
182 >> 3) Currently instprep executes when FEATURES=binpkg-docompress is
183 >> enabled, even though it does nothing of value. I think we should instead
184 >> generate a relevant list of MiscFunctionsProcess commands for the
185 >> enabled FEATURES, and only start a MiscFunctionsProcess instance if the
186 >> list of commands is non-empty.
187 >
188 > That sounds like premature optimization with a bit of going against
189 > principle of least surprise. Given it's a phase function with specific
190 > implementation that could be extended in the future, I'd rather avoid
191 > hiding additional conditions for running it elsewhere, as it opens
192 > a strong possibility that somebody adds additional functionality but
193 > forgets to update the condition resulting either in immediate WTF
194 > or the new code being skipped only for some users, with even harder-to-
195 > debug WTF.
196
197 I wasn't really sure that instprep deserved to be a full-fledged phase
198 at this point. I guess you're planning to add more stuff there?
199 --
200 Thanks,
201 Zac

Attachments

File name MIME type
signature.asc application/pgp-signature

Replies