User:MGorny/GLEP:Mix-ins

Abstract
This GLEP proposes extending the Gentoo profile structure with additional mix-in profiles that can be enabled independently of one another and make it possible to easily extend the standard profiles with multiple choices. It addresses the problems of backwards compatibility and repoman support.

Motivation
At the moment of writing this GLEP, the Gentoo profiles.desc file lists 252 profiles (not counting those commented out). For example, an amd64 user can choose between 22 standard profiles. Many of these profiles differ little — generic, desktop, server. Desktop has subsequently GNOME and KDE flavors, they in turn have an additional systemd variant. After all, providing a few binary choices causes the profile count to grow quickly.

The large number of profiles causes major maintenance and usability problems. The more mixed profiles become, the harder it is to predict side effects of combining different profiles and avoid causing unintentional breakage. The more profiles are considered active, the slower repoman becomes. And finally, user trying to pick up the right mixture is getting confused by the unfriendly structure.

A solution to this problem has been already implemented in Funtoo Profiles. Funtoo has a completely mix-in profile system where the user's profile is built from multiple components. Some of them (like arch) are chosen on 1-of-n basis, some (mix-ins) are binary. This has been implemented using existing Portage features (/etc/portage/profile) but sadly without support for repoman.

Providing a complete mix-in system for Gentoo would be a very hard task, for three reasons:
 * 1) the current Gentoo profile structure is huge, complex and unpredictable, and therefore remaking it in one step would require a tremendous effort,
 * 2) the resulting number of profile combinations to be covered by repoman would be huge, therefore making it very slow,
 * 3) Gentoo needs to provide some degree of backwards compatibility for users, especially those using old versions of Portage.

Therefore, instead of trying to provide a completely new profile system, this GLEP aims to provide support for extending standard Gentoo profiles with mix-ins, while preserving backwards compatibility for old versions of Portage and repoman, and limiting the scope of repoman checks to most relevant profiles.

Mix-in profiles
A mix-in profile is a profile that can be injected on top of a standard Gentoo profile (base profile) to provide some degree of customization. Multiple mix-ins can be enabled simultaneously.

A mix-in profile should preferably be stand-alone, and must not inherit (specify in parent) any profile from the regular profile tree. If a profile A (either mix-in or base) inherits mix-in profile B, it is assumed that A requires and implicitly enables B.

A mix-in profile can have its visibility restricted to some other profile being used as the base profile. Mix-in profiles can also be blocked by other profiles (base or mix-in), in which case the mix-in can not be enabled while the blocking profile is used.

Mix-in profiles can be grouped in named groups. The groups can be used to specify dependencies and blocking profiles. If a profile blocks itself, the block does not count — in particular, if the profile blocks its own group then selecting any other profile that group unselects the profile in question. The groups can be also used to visually group profiles.

The list of mix-in profiles is stored in profiles.mixin file. The file specifies profile data in columns, whitespace-separated, one profile per row (alike profiles.desc. The columns are:
 * 1) profile group,
 * 2) profile path,
 * 3) required profiles,
 * 4) blocking profiles.

Required and blocking profiles can be comma-separated (,) lists or a hyphen (-) if empty. The list elements can either specify profile paths, or group names preceded by an at sign (@). If multiple profiles are specified, then any of them is acceptable.

Integration to user systems
To provide support for mix-in profiles, a new version of eselect-profile needs to be created. This version would read the profiles.mixin file and provide additional mix-in-oriented choices for the user.

To provide the mix-ins to Portage, the /etc/portage/make.profile symlinks needs to be replaced with a directory. This directory specifies a single parent file that lists all enabled profiles (the base profile and mix-ins).

Integration to repoman and old systems
To provide support for repoman and old systems (using old version of eselect-profile — e.g. for testing period), the most important mix-in variants can be integrated into regular profiles through specifying them in parent files. This both allows users to select them as base profiles and enables repoman testing for them.

Eventually, additional profiles will be specified in profiles.desc that would not be visible to users as base profiles but would nevertheless be tested by repoman.

Rationale
The structure was designed so that maximum backwards compatibility can be provided, and minimum changes to the existing tools can be made. Limiting repoman only to regular profiles both avoids the necessity of modifying it and avoids huge growth of number of scanned profile combinations in favor of testing a few specifically selected combinations.

Profile grouping was provided to allow better visual grouping of profiles and make the format more suitable for future extensions. In particular, it made switching mix-in groups to 1-of-N easy (via blocking the group itself). This may provide means to switch the whole structure to mix-ins in the future.

Requirements and blocks were provided to make it possible to properly inform user when some of the mix-ins apply only to specific group of base profiles, or can not be combined with another mix-in.

Backwards Compatibility
The additional mix-in profiles are fully compatible with regular profiles. They can be inherited in base profiles, to provide backwards compatibility with old systems and support current versions of repoman.

The support for selecting mix-ins is provided through upgrade of eselect profile, while preserving compatibility with current Portage versions.

Reference implementation
TODO

Copyright
This work is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/.