Contents of /xml/htdocs/proj/en/glep/glep-0033.txt

Parent Directory Parent Directory | Revision Log Revision Log

Revision 1.3 - (show annotations) (download)
Sun Mar 6 20:39:19 2005 UTC (14 years ago) by g2boojum
Branch: MAIN
Changes since 1.2: +10 -8 lines
File MIME type: text/plain

1 GLEP: 33
2 Title: Eclass Restructure/Redesign
3 Version: $Revision: 1.2 $
4 Last-Modified: $Date: 2005/03/06 20:33:20 $
5 Author: Brian Harring <ferringb@gentoo.org>, John Mylchreest <johnm@gentoo.org>
6 Status: Draft
7 Type: Standards Track
8 Content-Type: text/x-rst
9 Created: 29-Jan-2005
10 Post-History: 29-Jan-2005 6-Mar-2005
13 Abstract
14 ========
16 For any design, the transition from theoretical to applied exposes inadequacies
17 in the original design. This document is intended to document, and propose a
18 revision of the current eclass setup to address current eclass inadequacies.
20 This document proposes several things- the creation of ebuild libraries, 'elibs',
21 a narrowing of the focus of eclasses, a move of eclasses w/in the tree, the
22 addition of changelogs, and a way to allow for simple eclass gpg signing.
23 In general, a large scale restructuring of what eclasses are and how they're
24 implemented. Essentially version two of the eclass setup.
27 Terminology
28 ===========
30 From this point on, the proposed eclass setup will be called 'new eclasses', the
31 existing crop (as of this writing) will be referenced as 'old eclasses'. The
32 distinction is elaborated on within this document.
35 Motivation and Rationale
36 ========================
38 Eclasses within the tree currently are a bit of a mess- they're forced to
39 maintain backwards compatibility w/ all previous functionality. In effect,
40 their api is constant, and can only be added to- never changing the existing
41 functionality. This obviously is quite limiting, and leads to cruft accruing in
42 eclasses as a eclasses design is refined. This needs to be dealt with prior to
43 eclass code reaching a critical mass where they become unmanageable/fragile
44 (recent pushes for eclass versioning could be interpreted as proof of this).
46 Beyond that, eclasses were originally intended as a method to allow for ebuilds
47 to use a pre-existing block of code, rather then having to duplicate the code in
48 each ebuild. This is a good thing, but there are ill effects that result from
49 the current design. Eclasses inherit other eclasses to get a single function- in
50 doing so, modifying the the exported 'template' (default src_compile, default
51 src_unpack, various vars, etc). All the eclass designer was after was reusing a
52 function, not making their eclass sensitive to changes in the template of the
53 eclass it's inheriting. The eclass designer -should- be aware of changes in the
54 function they're using, but shouldn't have to worry about their default src_*
55 and pkg_* functions being overwritten, let alone the env changes.
57 Addressing up front why a collection of eclass refinements are being rolled into
58 a single set of changes, parts of this proposal -could- be split into multiple
59 phases. Why do it though? It's simpler for developers to know that the first
60 eclass specification was this, and that the second specification is that,
61 rather then requiring them to be aware of what phase of eclass changes is in
62 progress.
64 By rolling all changes into one large change, a line is intentionally drawn in
65 the sand. Old eclasses allowed for this, behaved this way. New eclasses allow
66 for that, and behave this way. This should reduce misconceptions about what is
67 allowed/possible with eclasses, thus reducing bugs that result from said
68 misconceptions.
70 A few words on elibs- think of them as a clear definition between behavioral
71 functionality of an eclass, and the library functionality. Eclass's modify
72 template data, and are the basis for other ebuilds- elibs, however are *just*
73 common bash functionality.
75 Consider the majority of the portage bin/* scripts- these all are candidates for
76 being added to the tree as elibs, as is the bulk of eutils.
79 Specification.
80 ==============
82 The various parts of this proposal are broken down into a set of changes and
83 elaborations on why a proposed change is preferable. It's advisable to the
84 reader that this be read serially, rather then jumping around.
87 Ebuild Libraries (elibs for short)
88 ----------------------------------
90 As briefly touched upon in Motivation and Rationale, the original eclass design
91 allowed for the eclass to modify the metadata of an ebuild, metadata being the
92 DEPENDS, RDEPENDS, SRC_URI, IUSE, etc, vars that are required to be constant,
93 and used by portage for dep resolution, fetching, etc. Using the earlier
94 example, if you're after a single function from an eclass (say epatch from
95 eutils), you -don't- want the metadata modifications the eclass you're
96 inheriting might do. You want to treat the eclass you're pulling from as a
97 library, pure and simple.
99 A new directory named elib should be added to the top level of the tree to serve
100 as a repository of ebuild function libraries. Rather then relying on using the
101 source command, an 'elib' function should be added to portage to import that
102 libraries functionality. The reason for the indirection via the function is
103 mostly related to portage internals, but it does serve as an abstraction such
104 that (for example) zsh compatibility hacks could be hidden in the elib function.
106 Elib's will be collections of bash functions- they're not allowed to do anything
107 in the global scope aside from function definition, and any -minimal-
108 initialization of the library that is absolutely needed. Additionally, they
109 cannot modify any ebuild template functions- src_compile, src_unpack. Since they are
110 required to not modify the metadata keys, nor in any way affect the ebuild aside
111 from providing functionality, they can be conditionally pulled in. They also
112 are allowed to pull in other elibs, but strictly just elibs- no eclasses, just
113 other elibs. A real world example would be the eutils eclass.
115 Portage, since the elib's don't modify metadata, isn't required to track elibs
116 as it tracks eclasses. Thus a change in an elib doesn't result in half the tree
117 forced to be regenerated/marked stale when changed (this is more of an infra
118 benefit, although regen's that take too long due to eclass changes have been
119 known to cause rsync issues due to missing timestamps).
121 Elibs will not be available in the global scope of an eclass, or ebuild- nor during the
122 depends phase (basically a phase that sources the ebuild, to get it's metadata). Elib
123 calls in the global scope will be tracked, but the elib will not be loaded till just before
124 the setup phase (pkg_setup). There are two reasons for this- first, it ensures elibs are
125 completely incapable of modifying metadata. There is no room for confusion, late loading
126 of elibs gives you the functionality for all phases, except for depends- depends being the
127 only phase that is capable of specifying metadata. Second, as an added bonus, late
128 loading reduces the amount of bash sourced for a regen- faster regens. This however is minor,
129 and is an ancillary benefit of the first reason.
131 There are a few further restrictions with elibs--mainly, elibs to load can only be specified
132 in either global scope, or in the setup, unpack, compile, test, and install phases. You can
133 not load elibs in prerm, postrm, preinst, and postinst. The reason being, for \*rm phases,
134 installed pkgs will have to look to the tree for the elib, which allows for api drift to cause
135 breakage. For \*inst phases, same thing, except the culprit is binpkgs.
137 There is a final restriction--elibs cannot change their exported api dependent on the api
138 (as some eclass do for example). The reason mainly being that elibs are loaded once--not
139 multiple times, as eclasses are.
141 To clarify, for example this is invalid.
142 ::
144 if [[ -n ${SOME_VAR} ]]; then
145 func x() { echo "I'm accessible only via tweaking some var";}
146 else
147 func x() { echo "this is invalid, do not do it."; }
148 fi
151 Regarding maintainability of elibs, it should be a less of a load then old
152 eclasses. One of the major issues with old eclasses is that their functions are
153 quite incestuous- they're bound tightly to the env they're defined in. This
154 makes eclass functions a bit fragile- the restrictions on what can, and cannot
155 be done in elibs will address this, making functionality less fragile (thus a
156 bit more maintainable).
158 There is no need for backwards compatibility with elibs- they just must work
159 against the current tree. Thus elibs can be removed when the tree no longer
160 needs them. The reasons for this are explained below.
162 Structuring of the elibs directory will be exactly the same as that of the new
163 eclass directory (detailed below), sans a different extension.
165 As to why their are so many restrictions, the answer is simple- the definition of
166 what elibs are, what they are capable of, and how to use them is nailed down as much as
167 possible to avoid *any* ambiguity related to them. The intention is to make it clear,
168 such that no misconceptions occur, resulting in bugs.
170 The reduced role of Eclasses, and a clarification of existing Eclass requirements
171 ---------------------------------------------------------------------------------
173 Since elibs are now intended on holding common bash functionality, the focus of
174 eclasses should be in defining an appropriate template for ebuilds. For example,
175 defining common DEPENDS, RDEPENDS, src_compile functions, src_unpack, etc.
176 Additionally, eclasses should pull in any elibs they need for functionality.
178 Eclass functionality that isn't directly related to the metadata, or src_* and
179 pkg_* funcs should be shifted into elibs to allow for maximal code reuse. This
180 however isn't a hard requirement, merely a strongly worded suggestion.
182 Previously, it was 'strongly' suggested by developers to avoid having any code
183 executed in the global scope that wasn't required. This suggestion is now a
184 requirement. Execute only what must be executed in the global scope. Any code
185 executed in the global scope that is related to configuring/building the package
186 must be placed in pkg_setup. Metadata keys (already a rule, but now stated as
187 an absolute requirement to clarify it) *must* be constant. The results of
188 metadata keys exported from an ebuild on system A, must be *exactly* the same as
189 the keys exported on system B.
191 If an eclass (or ebuild for that matter) violates this constant requirement, it
192 leads to portage doing the wrong thing for rsync users- for example, wrong deps
193 pulled in, leading to compilation failure, or dud deps.
195 If the existing metadata isn't flexible enough for what is required for a
196 package, the parsing of the metadata is changed to address that. Cases where
197 the constant requirement is violated are known, and a select few are allowed-
198 these are exceptions to the rule that are required due to inadequacies in
199 portage. Any case where it's determined the constant requirement may need to be
200 violated the dev must make it aware to the majority of devs, along with the portage
201 devs. This should be done prior to committing.
203 It's quite likely there is a way to allow what you're attempting- if you just go
204 and do it, the rsync users (our user base) suffer the results of compilation
205 failures and unneeded deps being pulled in.
207 After that stern reminder, back to new eclasses. Defining INHERITED and ECLASS
208 within the eclass is no longer required. Portage already handles those vars if
209 they aren't defined.
211 As with elibs, it's no longer required that backwards compatibility be maintained
212 indefinitely- compatibility must be maintained against the current tree, but
213 just that. As such new eclasses (the true distinction of new vs old is
214 elaborated in the next section) can be removed from the tree once they're no
215 longer in use.
218 The end of backwards compatibility...
219 -------------------------------------
221 With current eclasses, once the eclass is in use, it's api can no longer be
222 changed, nor can the eclass ever be removed from the tree. This is why we still
223 have *ancient* eclasses that are completely unused sitting in the tree, for
224 example inherit.eclass . The reason for this, not surprisingly is a portage
225 deficiency- on unmerging an installed ebuild, portage used the eclass from the
226 current tree.
228 For a real world example of this, if you merged a glibc 2 years back, whatever
229 eclasses it used must still be compatible, or you may not be able to unmerge the
230 older glibc version during an upgrade to a newer version. So either the glibc
231 maintainer is left with the option of leaving people using ancient versions out
232 in the rain, or maintaining an ever increasing load of backwards compatibility
233 cruft in any used eclasses.
235 Binpkgs suffer a similar fate. Merging of a binpkg pulls needed eclasses from
236 the tree, so you may not be able to even merge a binpkg if the eclasses api has
237 changed. If the eclass was removed, you can't even merge the binpkg, period.
239 The next major release of portage will address this- the environment that the
240 ebuild was built in already contains the eclasses functions, as such the env can
241 be re-used rather then relying on the eclass. In other words, binpkgs and
242 installed ebuilds will no longer go and pull needed eclasses from the tree,
243 they'll use the 'saved' version of the eclass they were built/merged with.
245 So the backwards compatibility requirement for users of the next major portage
246 version (and beyond) isn't required. All the cruft can be dropped.
248 The problem is that there will be users using older versions of portage that don't
249 support this functionality- these older installations *cannot* use the
250 new eclasses, due to the fact that their portage version is incapable of
251 properly relying on the env- in other words, the varying api of the eclass will
252 result in user-visible failures during unmerging.
254 So we're able to do a clean break of all old eclasses, and api cruft, but we need
255 a means to basically disallow access to the new eclasses for all portage versions
256 incapable of properly handling the env requirements.
258 Unfortunately, we cannot just rely on a different grouping/naming convention within
259 the old eclass directory. The new eclasses must be inaccessible, and portage throws
260 a snag into this- the existing inherit function that is used to handle existing
261 eclasses. Basically, whatever it's passed (inherit kernel or inherit
262 kernel/kernel) it will pull in (kernel.eclass, and kernel/kernel.eclass
263 respectively). So even if the new eclasses were implemented within a
264 subdirectory of the eclass dir in the tree, all current portage versions would
265 still be able to access them.
267 In other words, these new eclasses would in effect, be old eclasses since older
268 portage versions could still access them.
271 Tree restructuring.
272 -------------------
274 There are only two way to block the existing (as of this writing) inherit
275 functionality from accessing the new eclasses- either change the extension of
276 eclasses to something other then 'eclass', or to have them stored in a separate
277 subdirectory of the tree then eclass.
279 The latter is preferable, and the proposed solution. Reasons are- the current
280 eclass directory is already overgrown. Structuring of the new eclass dir
281 (clarified below) will allow for easier signing, ChangeLogs, and grouping of
282 eclasses. New eclasses allow for something akin to a clean break and have new
283 capabilities/requirements, thus it's advisable to start with a clean directory,
284 devoid of all cruft from the old eclass implementation.
286 If it's unclear as to why the old inherit function *cannot* access the new
287 eclasses, please reread the previous section. It's unfortunately a requirement
288 to take advantage of all that the next major portage release will allow.
290 The proposed directory structure is ${PORTDIR}/include/{eclass,elib}.
291 Something like ${PORTDIR}/new-eclass, or ${PORTDIR}/eclass-ng could be used
292 (although many would cringe at the -ng), but such a name is unwise. Consider the
293 possibility (likely a fact) that new eclasses someday may be found lacking, and
294 refined further (version three as it were). Or perhaps we want to add yet more
295 functionality with direct relation to sourcing new files, and we would then need
296 to further populate ${PORTDIR}.
298 The new-eclass directory will be (at least) 2 levels deep- for example:
300 ::
301 kernel/
302 kernel/linux-info.eclass
303 kernel/linux-mod.eclass
304 kernel/kernel-2.6.eclass
305 kernel/kernel-2.4.eclass
306 kernel/ChangeLog
307 kernel/Manifest
309 No eclasses will be allowed in the base directory- grouping of new eclasses will
310 be required to help keep things tidy, and for the following reasons. Grouping
311 of eclasses allows for the addition of ChangeLogs that are specific to that
312 group of eclasses, grouping of files/patches as needed, and allows for
313 saner/easier signing of eclasses- you can just stick a signed
314 Manifest file w/in that grouping, thus providing the information portage needs
315 to ensure no files are missing, and that nothing has been tainted.
317 The elib directory will be structured in the same way, for the same reasons.
319 Repoman will have to be extended to work within new eclass and elib groups, and
320 to handle signing and committing. This is intentional, and a good thing. This
321 gives repoman the possibility of doing sanity checks on elibs/new eclasses.
323 Note these checks will not prevent developers from doing dumb things with eclass-
324 these checks would only be capable of doing basic sanity checks, such as syntax checks.
325 There is no way to prevent people from doing dumb things (exempting perhaps repeated
326 applications of a cattle prod)- these are strictly automatic checks, akin to repoman's
327 dependency checks.
330 The start of a different phase of backwards compatibility
331 ---------------------------------------------------------
333 As clarified above, new eclasses will exist in a separate directory that will be
334 intentionally inaccessible to the inherit function. As such, users of older
335 portage versions *will* have to upgrade to merge any ebuild that uses elibs/new
336 eclasses. A depend on the next major portage version would transparently handle
337 this for rsync users.
339 There still is the issue of users who haven't upgraded to the required portage
340 version. This is a minor concern frankly- portage releases include new
341 functionality, and bug fixes. If they won't upgrade, it's assumed they have
342 their reasons and are big boys, thus able to handle the complications themselves.
344 The real issue is broken envs, whether in binpkgs, or for installed packages.
345 Two options exist- either the old eclasses are left in the tree indefinitely, or
346 they're left for N months, then shifted out of the tree, and into a tarball that
347 can be merged.
349 Shifting them out of the tree is advisable for several reasons- less cruft in
350 the tree, but more importantly the fact that they are not signed (thus an angle
351 for attack). Note that the proposed method of eclass signing doesn't even try
352 to address them. Frankly, it's not worth the effort supporting two variations
353 of eclass signing, when the old eclass setup isn't designed to allow for easy
354 signing.
356 If this approach is taken, then either the old eclasses would have to be merged
357 to an overlay directory's eclass directory (ugly), or to a safe location that
358 portage's inherit function knows to look for (less ugly).
360 For users who do not upgrade within the window of N months while the old
361 eclasses are in the tree, as stated, it's assumed they know what they are doing.
362 If they specifically block the new portage version, as the ebuilds in the tree
363 migrate to the new eclasses, they will have less and less ebuilds available to
364 them. If they tried injecting the new portage version (lying to portage,
365 essentially), portage would bail since it cannot find the new eclass.
366 For ebuilds that use the new eclasses, there really isn't any way to sidestep
367 the portage version requirement- same as it has been for other portage features.
369 What is a bit more annoying is that once the old eclasses are out of the tree,
370 if a user has not upgraded to a portage version supporting env processing, they
371 will lose the ability to unmerge any installed ebuild that used an old
372 eclass. Same cause, different symptom being they will lose the ability to merge
373 any tbz2 that uses old eclasses also.
375 There is one additional case that is a rarity, but should be noted- if a user
376 has suffered significant corruption of their installed package database (vdb). This is
377 ignoring the question of whether the vdb is even usable at this point, but the possibility
378 exists for the saved envs to be non usable due to either A) missing, or B) corrupted.
379 In such a case, even with the new portage capabilities, they would need
380 the old eclass compat ebuild.
382 Note for this to happen requires either rather... unwise uses of root, or significant
383 fs corruption. Regardless of the cause, it's quite likely for this to even become an
384 issue, the system's vdb is completely unusable. It's a moot issue at that point.
385 If you lose your vdb, or it gets seriously damaged, it's akin to lobotomizing portage-
386 it doesn't know what's installed, it doesn't know of it's own files, and in general,
387 a rebuilding of the system is about the only sane course of action. The missing env is
388 truly the least of the users concern in such a case.
390 Continuing with the more likely scenario, users unwilling to upgrade portage will
391 *not* be left out in the rain. Merging the old eclass compat ebuild will provide
392 the missing eclasses, thus providing that lost functionality .
394 Note the intention isn't to force them to upgrade, hence the ability to restore the
395 lost functionality. The intention is to clean up the existing mess, and allow us
396 to move forward. The saying "you've got to break a few eggs to make an omelet"
397 is akin, exempting the fact we're providing a way to make the eggs whole again
398 (the king's men would've loved such an option).
401 Migrating to the new setup
402 --------------------------
404 As has been done in the past whenever a change in the tree results in ebuilds
405 requiring a specific version of portage, as ebuilds migrate to the new eclasses,
406 they should depend on a version of portage that supports it. From the users
407 viewpoint, this transparently handles the migration.
409 This isn't so transparent for devs or a particular infrastructure server however.
410 Devs, due to them using cvs for their tree, lack the pregenerated cache rsync
411 users have. Devs will have to be early adopters of the new portage. Older
412 portage versions won't be able to access the new eclasses, thus the local cache
413 generation for that ebuild will fail, ergo the depends on a newer portage
414 version won't transparently handle it for them.
416 Additionally, prior to any ebuilds in the tree using the new eclasses, the
417 infrastructure server that generates the cache for rsync users will have to
418 either be upgraded to a version of portage supporting new eclasses, or patched.
419 The former being much more preferable then the latter for the portage devs.
421 Beyond that, an appropriate window for old eclasses to exist in the tree must be
422 determined, and prior to that window passing an ebuild must be added to the tree
423 so users can get the old eclasses if needed.
425 For eclass devs to migrate from old to new, it is possible for them to just
426 transfer the old eclass into an appropriate grouping in the new eclass directory,
427 although it's advisable they cleanse all cruft out of the eclass. You can
428 migrate ebuilds gradually over to the new eclass, and don't have to worry about
429 having to support ebuilds from X years back.
431 Essentially, you have a chance to nail the design perfectly/cleanly, and have a
432 window in which to redesign it. It's humbly suggested eclass devs take
433 advantage of it. :)
436 Backwards Compatibility
437 =======================
439 All backwards compatibility issues are addressed in line, but a recap is offered-
440 it's suggested that if the a particular compatibility issue is
441 questioned/worried over, the reader read the relevant section. There should be
442 a more in depth discussion of the issue, along with a more extensive explanation
443 of the potential solutions, and reasons for the chosen solution.
445 To recap:
446 ::
448 New eclasses and elib functionality will be tied to a specific portage
449 version. A DEPENDs on said portage version should address this for rsync
450 users who refuse to upgrade to a portage version that supports the new
451 eclasses/elibs and will gradually be unable to merge ebuilds that use said
452 functionality. It is their choice to upgrade, as such, the gradual
453 'thinning' of available ebuilds should they block the portage upgrade is
454 their responsibility.
456 Old eclasses at some point in the future should be removed from the tree,
457 and released in a tarball/ebuild. This will cause installed ebuilds that
458 rely on the old eclass to be unable to unmerge, with the same applying for
459 merging of binpkgs dependent on the following paragraph.
461 The old eclass-compat is only required for users who do not upgrade their
462 portage installation, and one further exemption- if the user has somehow
463 corrupted/destroyed their installed pkgs database (/var/db/pkg currently),
464 in the process, they've lost their saved environments. The eclass-compat
465 ebuild would be required for ebuilds that required older eclasses in such a
466 case. Note, this case is rare also- as clarified above, it's mentioned
467 strictly to be complete, it's not much of a real world scenario as elaborated
468 above.
471 Copyright
472 =========
474 This document has been placed in the public domain.

  ViewVC Help
Powered by ViewVC 1.1.20