Gentoo Archives: gentoo-dev

From: Alexis Ballier <aballier@g.o>
To: gentoo-dev@l.g.o
Subject: Re: [gentoo-dev] [RFC] Forced/automatic USE flag constraints (codename: ENFORCED_USE)
Date: Wed, 31 May 2017 17:39:39
Message-Id: 20170531193922.477245bb@gentoo.org
In Reply to: Re: [gentoo-dev] [RFC] Forced/automatic USE flag constraints (codename: ENFORCED_USE) by "Michał Górny"
1 On Wed, 31 May 2017 15:04:52 +0200
2 Michał Górny <mgorny@g.o> wrote:
3
4 > On śro, 2017-05-31 at 10:38 +0200, Alexis Ballier wrote:
5 > > > > What if I specifically set USE=-bar in make.conf ? Do we really
6 > > > > want PM to override that without telling me ?
7 > > >
8 > > > Yes. Unless you specifically and explicitly disable that
9 > > > (globally or for USE=bar), in which case the PM would just reject
10 > > > to proceed.
11 > >
12 > >
13 > > Then could you please explain how to get the list of useflags the
14 > > solver is allowed to toggle ? Preferably in a PMS-friendly way (aka
15 > > no USE=foo emerge). It's not clear to me what this would be and is
16 > > mandatory for determinism.
17 > >
18 > > Note that most definitions are acceptable, but there must be one.
19 >
20 > If we *really* want to set this for the users, it would simply be
21 > a variable defined in make.profile, e.g.:
22 >
23 > REQUIRED_USE_STRICT="foo bar"
24 >
25 > which would mean the solver is globally forbidden from touching those
26 > flags, i.e. if the solution would involve touching them, PM must fail
27 > and request user to manually resolve it.
28 >
29 > However, as far as I'm concerned we'd be good at keeping this purely
30 > as user configuration, alike FEATURES=i-do-not-want-automatic-solving.
31
32 Ok, why not.
33
34 > > > > I believe that, from the ebuild POV, the ternary useflag model
35 > > > > is more appropriate: You have a whole bunch of ways to specify
36 > > > > useflags with portage (make.conf, package.use, profiles, command
37 > > > > line, ...). From the ebuild those are collapsed into 'user
38 > > > > input'. You only have IUSE (with its defaults) and that's what
39 > > > > the auto-solver should play with: those are the flags that can
40 > > > > be toggled.
41 > > >
42 > > > I see your point. However, it's merely a preference problem and we
43 > > > really don't want the constraints to become ternary and/or PM try
44 > > > to force the reverse solutions. That's an easy way to lose
45 > > > predictability.
46 > >
47 > > They're not ternary anymore after processing ebuild: IUSE="foo +bar"
48 > > means instantiate foo as -foo if not specified, and bar as +bar.
49 > > The way I see it, ternary model is useful in the sense that the 3rd
50 > > undefined state is what the solver can toggle, the others are fixed
51 > > (either by user input or e.g. use.mask).
52 > >
53 > > Basically, I see automatic solving of REQUIRED_USE as dynamic IUSE
54 > > defaults. But see above, this might not be the best way.
55 >
56 > I'm lost on what you're trying to achieve here. Maybe give a full run-
57 > out based on Portage behavior -- i.e. involving all the places USE
58 > flags can be altered in Portage, and how they're going to affect the
59 > result. Don't forget about USE_ORDER.
60
61 What I'm suggesting is: Flags that can be toggled are the same that
62 would be affected by IUSE defaults. Others are fixed and the
63 REQUIRED_USE formula is instantiated & reduced with those values. If
64 there is a contradiction already, fail hard. If not, apply the
65 algorithm to determine a set of IUSE defaults that would make it
66 work. Process the ebuild as if it had those IUSE default.
67
68 You seem to be going in another direction which is unclear to me.
69
70 [...]
71 > > > > > Now, this also means that every constraint that can't be
72 > > > > > solved in this easy fashion is invalid. We want to detect
73 > > > > > that, and warn the developer. Some of those could be tricky.
74 > > > > > Simple example:
75 > > > > >
76 > > > > > foo? ( baz ) bar? ( !baz )
77 > > > > >
78 > > > > > This one is invalid because USE='foo bar' requires both 'baz'
79 > > > > > and '!baz' as a solution. Remember that we don't want to do
80 > > > > > any changes besides what's explicitly written there, no
81 > > > > > guessing.
82 > > > >
83 > > > > Besides that, what makes it invalid ?
84 > > >
85 > > > What makes it invalid is that you can't solve it in a predictable
86 > > > way.
87 > >
88 > > You can fail in a predictable way and ebuild writer can adjust it to
89 > > avoid that.
90 >
91 > If the point is to process constraints *automatically*, then failing
92 > is not the desired result. Yes, we can consider that a minor
93 > issue/warning level but it is still an issue. I named it 'invalid'
94 > because it prevents the automatic solving from working which is the
95 > purpose of this whole effort.
96
97 Ok. I was assuming we do not want to change anything user-specified.
98 When I set USE=foo, I want foo, not maybe foo. But why not: As you
99 noted this can be a PM feature and there's not much to be checked in
100 that case.
101
102 As for how to check that, it is still completely unclear to me if
103 there'd be anything better than enumerating all the possible inputs.
104
105
106 > > Again, you *need* to process the constraints in order. '!a?
107 > > ( b ) !b? ( a )' is not deterministic when none of a and b are
108 > > enabled otherwise.
109 >
110 > You can't rely on any particular order of constraints, especially when
111 > eclass stacking comes into play. You could try defining some
112 > constraint- sorting algorithm but it's going to be complex and it's
113 > usefulness will be limited anyway due to various kinds of grouping.
114
115
116 Better have some order: If half of the above constraint comes from
117 ebuild and the other half comes from eclass, then PM might toggle 'a' or
118 'b' depending on the phase of the moon which is specifically what we're
119 trying to avoid.
120
121 eclass stacking is not a problem: specify if it's append or prepend and
122 be done.
123
124 Note that if you want to remove the need for an order, you'll need to
125 ensure that all orderings of the constraints give the same result. It's
126 not sufficient to "only" check all possible inputs.
127
128 Also, what happens if we applied all the constraints and obtained some
129 useflags setting that still fails REQUIRED_USE check ?
130
131
132 > > You'll get a message like:
133 > > "
134 > > The constraint bar? ( !baz )' is violated.
135 > > bar is enabled because $reason (say, make.conf)
136 > > baz is enabled because of the constraint 'foo? ( baz )'
137 > > foo is enabled because $reason
138 > > "
139 >
140 > You = user or ebuild author? Because per my proposal, this construct
141 > should result in QA error/warning, telling the ebuild writer to use
142 > predictable constraints.
143 >
144 > Of course, we could still accept the ebuild and just fail hard on user
145 > side (alike REQUIRED_USE). But that's really getting out of scope.
146
147 you = user because he asked for an invalid combination. Note that you
148 have not yet given a proper definition of predictable constraint.
149
150
151 [...]
152 > >
153 > > > which gives a single predictable solution:
154 > >
155 > > Then ebuild writer should not write 'foo? ( baz ) bar? ( !baz )' but
156 > > rather: 'foo? ( !bar baz ) bar? ( !baz )', which should cover more
157 > > cases. With USE="foo bar", the message would then be:
158 > > "
159 > > The constraint 'foo? ( !bar )' is violated.
160 > > foo is enabled because $reason
161 > > bar is enabled because $reason
162 > > "
163 > > which is similar to the above except there's one less step for
164 > > explaining the reasons. It's not dramatic but it is, indeed,
165 > > desirable to have simple & clear reasons. I'd say that's more to
166 > > the argument for specifying completely how to solve that and leave
167 > > those small improvements to ebuild writers and/or QA.
168 >
169 > Is this message meant to be disabled for the purpose of explaining
170 > automatic decisions, or as an error?
171
172 As an error because user specified invalid combination, but now I see
173 your point: You want to override user settings too.
174
175 > Also, your example (unlike the one I gave in the original mail)
176 > prefers foo over bar. That's the only difference.
177
178 Yes, I realize that now :)
179
180 > >
181 > > [...]
182 > > > > > However, the
183 > > > > > following should be valid:
184 > > > > >
185 > > > > > foo? ( baz ) bar? ( !foo !baz )
186 > > > > >
187 > > > > > Because now we clearly indicate that USE=bar disables USE=foo,
188 > > > > > and therefore makes the first constraint inapplicable. It
189 > > > > > clearly indicates course of action for all combinations:
190 > > > >
191 > > > > Ok, I now think you're aiming for giving full power to the
192 > > > > solver, overriding user inputs if necessary. Before going
193 > > > > further, I think we should first agree on what are the useflags
194 > > > > such a solver can toggle. I'm not sure 'USE=foo emerge blah'
195 > > > > should disable foo instead of failing for example.
196 > > > >
197 > > >
198 > > > As I said, it's a matter of configuration to decide which flags
199 > > > should be touched, and which not. Of course if we find that
200 > > > necessary, we may go into defining a specific set in the profiles
201 > > > or metadata.
202 > > >
203 > > > However, I would rather focus on getting a PoC solver and checker
204 > > > first, and play with existing constraints to see how it all
205 > > > works.
206 > >
207 > > The solver seems on good tracks, at least from the algorithmic POV.
208 > > The checker, however, is not clear at all to me. The main reason is
209 > > that to determine if the solver will be able to solve it, it needs
210 > > to know what the solver can toggle and what not.
211 > >
212 >
213 > The point would be: by definition, the solver should be able to touch
214 > *any* USE flag. If it can't, it mostly implies that you can't use
215 > the automatic solver, and so the case is irrelevant for checking.
216 > Attempting to go beyond that is going to give a lot of complexity
217 > and most likely kill the whole idea.
218 >
219 > One thing we need to worry about are masks. We need to think about
220 > them.
221
222 It makes zero difference for any solver if you replace variables
223 (useflags) by 'true' or 'false' constants (masked/forced/user-forced
224 useflags). It's even simpler actually. Whether the formula is not
225 constantly 'true' (ie REQUIRED_USE is useless) or constantly
226 'false' (ie there's no way to solve it) is equivalent to solving SAT.
227 We likely don't want that for repoman running on php.
228
229 Alexis.

Replies