Gentoo Archives: gentoo-portage-dev

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

Attachments

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

Replies