-
Notifications
You must be signed in to change notification settings - Fork 4.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
tags propagation: Starlark rules part #8612
Conversation
Tags declared on targets are not propagated to actions and therefore are not taken into consideration by bazel. This causes some issues, for instance, target marked with a tag 'no-remote' will still be executed remotely. As it was agreed in the design doc (see bazelbuild#7766 for a link), set of tags to be propagated to actions as a first iteration. This change is responsible for that first step for the Starlark Rules. RELNOTES: tags 'no-remote', 'no-cache', 'no-remote-cache', 'no-remote-exec', 'no-sandbox' are propagated now to the actions from targets. Closes bazelbuild#7766
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not a fan of white listing tags. It's error prone. Couldn't we apply the same filter that we apply to execution_info also to tags? What's the downside?
// we do not want to propagate custom user's tags or create potential conflicts | ||
// with execution requirements declared on the rules. | ||
// See https://github.com/bazelbuild/bazel/issues/7766 for details. | ||
private static final Predicate<String> TAGS_PROPAGATED_TO_EXEC_INFO = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how is this compatible with LEGAL_EXEC_INFO_KEYS
defined a few lines above, which also filters exec requirements and the comment says "We also don't want to exhaustively enumerate all the legal values here.". Couldn't we unify these two predicates?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we could, but this is not what we've agreed on in the initial design.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Independent what's in the design doc, let's not do it if it makes no sense? :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it makes sense to keep them separate because they serve different purposes: LEGAL_EXEC_INFO_KEYS
specifies the universe of execution info keys, and TAGS_PROPAGATED_TO_EXEC_INFO
specifies the specific tags that can be propagated.
TAGS_PROPAGATED_TO_EXEC_INFO
is a subset of LEGAL_EXEC_INFO_KEYS
In getExecutionInfoFromTags
, we only propagate tags that satisfy TAGS_PROPAGATED_TO_EXEC_INFO
, irrespective of whether they satisfy LEGAL_EXEC_INFO_KEYS
; I don't see how we'd do this check if the two predicates were combined.
|| tag.equals("no-cache") | ||
|| tag.equals("no-sandbox") | ||
|| tag.equals("no-remote-exec") | ||
|| tag.equals("no-remote-cache"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Afaik no-remote-exec
and no-remote-cache
don't exist as execution requirements (yet)? Also take a look at the ExecutionRequirements
where we define names for all the available tags.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also can't find any reference to those two tags having special meaning here: https://docs.bazel.build/versions/master/be/common-definitions.html#common-attributes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah they're planned tags for more control over remote caching: #7932 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, those are only planned, but I decided to add them to the whitelist from the beginning. I'll think about it, perhaps to avoid confusions it would be better to not include them here and just add a comment for the future task #7932, where they will be introduced.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
Map<String, String> map = new HashMap<>(); | ||
for (String tag : | ||
NonconfigurableAttributeMapper.of(rule).get(CONSTRAINTS_ATTR, Type.STRING_LIST)) { | ||
// We don't want to pollute the execution info with random things, and we also need to reserve |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
serious question: what's the downside of "polluting" execution info?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed this comment block at all - should have been more careful with copy-pasting :)
map.put(tag, ""); | ||
} | ||
} | ||
return ImmutableMap.copyOf(map); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead of a copy use an ImmutableMap in the first place?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
for (String tag : | ||
NonconfigurableAttributeMapper.of(rule).get(CONSTRAINTS_ATTR, Type.STRING_LIST)) { | ||
// We don't want to pollute the execution info with random things, and we also need to reserve | ||
// some internal tags that we don't allow to be set on targets. We also don't want to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
couldn't we prevent that by prefixing internal execution requirements with "internal-" or so? also which are those?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed this comment block at all :)
* Only supported tags are included into the execution info, | ||
* see {@link #LEGAL_EXEC_INFO_KEYS} and {@link #TAGS_PROPAGATED_TO_EXEC_INFO}. | ||
*/ | ||
public static Map<String, String> getFilteredExecutionInfo(Object executionRequirementsUnchecked, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a javadoc describing the expected type of executionRequirementsUnchecked
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
*/ | ||
public static Map<String, String> getFilteredExecutionInfo(Object executionRequirementsUnchecked, | ||
Rule rule) throws EvalException { | ||
Map<String, String> executionInfo = Maps.newLinkedHashMap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why the LinkedHashMap
as opposed to an immutablemap?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
changed.
This is what we've agreed on in the design doc - propagate only a fixed set of tags for now. If we apply the same filter as for execution_info, more tags will be propagated. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for working on this! Only minor things.
"execution_requirements"))); | ||
} | ||
|
||
Map<String, String> executionInfo = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: ImmutableMap
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
} | ||
|
||
Map<String, String> executionInfo = | ||
TargetUtils.getFilteredExecutionInfo(executionRequirementsUnchecked, ruleContext.getRule()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it make sense to do the validation here and pass "checked" execution requirements to the TargetUtils method?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have a strong opinion on this, but IMO it's better to keep it all in one place. And it's easier to test is this way ;)
// with execution requirements declared on the rules. | ||
// See https://github.com/bazelbuild/bazel/issues/7766 for details. | ||
private static final Predicate<String> TAGS_PROPAGATED_TO_EXEC_INFO = | ||
tag -> tag.equals("no-remote") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As somebody completely ignorant of these things my first reaction is hmm where can I find out what these do. Wdyt about making these constants, and adding javadoc and document (or reference existing documentation) from these constants?
Map<String, String> executionInfo = Maps.newLinkedHashMap(); | ||
executionInfo.putAll(getExecutionInfoFromTags(rule)); | ||
|
||
if (executionRequirementsUnchecked != Runtime.NONE) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ignoring my comment above to validate the input before entering this method, do we need to check for None at all when we call castSkylarkDictOrNoneToDict anyway?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
true, we don't need it at all
*/ | ||
private static Map<String, String> getExecutionInfoFromTags(Rule rule) { | ||
// tags may contain duplicate values. | ||
Map<String, String> map = new HashMap<>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: ImmutableMap.builder()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
|
||
# Test a basic skylark ctx.actions.run rule which has tags, that should be propagated, | ||
# when the rule also has execution_info | ||
function test_tags_propagated_to_run_with_exec_info_шт_кгду() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
:))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ups 🙃
Two things:
The question to answer before we move forward with this implementation is why does it need to be a whitelist and can't just be the existing filters? |
Of course, and I'm not arguing with this :)
The initial idea was to propagate all* tags, but it's not clear what to do in case of conflicts. Currently there is only one example of a conflict Theoretically, we could just use the current filter and in case of conflicts: 1) do nothing and introduce unpredictable behavior, as mentioned above; 2) allow tags to override exec_requirements declared on rules; 3) rise an exception. And it is not obvious which one to choose or whether we should choose it now. Therefore I got an idea to propagate only the tags we are sure about. Why do you think that whiltelist is so much worse that the existing filters? *all - something similar to the current execution info filter |
Probably but I don't recall and it doesn't really matter - I reserve the right to change my opinion :). I am happy for us to go with a whitelist in the face of good arguments for it but I haven't seen any so far.
Looking at the change history of |
okay, then why do we need the design doc discussion-approval process at all? :)
and
If an execution strategy adds a new execution requirement it's easy to miss that there is a potential conflict.
Do you mean that it hasn't changed recently/often? This doesn't mean that it won't :) |
I think it would be more productive to put forward the argument in favor of having a white list. |
Ok, back to the discussion. Pros(+) and cons(-) for both options: Whitelisting: FIX: I can just a simple tests that would fail for every new execution requirement => the person who added it would need to decide - to propagate it or not. (+) easy to implement More generic filtering: ** Potential FIX**: add a test that would check new exec requirements for potential conflicts => the person who added it would need to decide what to do with it. + would be nice to enforce a proper documentation on this. For example, as for (+) not that difficult to implement either Suggestion Do you have any other arguments that I've missed? |
As I wrote above the current behavior is to forward both tags as execution requirements:
We have code to deal with this https://source.bazel.build/bazel/+/master:src/main/java/com/google/devtools/build/lib/actions/Spawns.java;l=44?q=Spawns.java. "blocks-network" takes precedence. We'll not introduce different behavior for test rules and build rules. |
Yes, I have seen this and mentioned in my previous comment that we deal with this couple of exec requirements already. What I am trying to say is that we will not add any mechanism to prevent potential conflicts in the future, while will open the door to it. Okay, I am still not convinced, but this discussion takes too long already. I will switch to the current filter and will try to think of a way to prevent potential conflicts. If it will take more that 1-2 hours, I will just add a comment to the ExecutionRequirements class, so that future developers are aware of the potential problems. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
"tests/BUILD", | ||
"sh_binary(name = 'with-prefix-block', srcs=['sh.sh'], tags=['block-some-feature', 'block-network', 'wrong-tag'])", | ||
"sh_binary(name = 'with-prefix-cpu', srcs=['sh.sh'], tags=['cpu:123', 'wrong-tag'])", | ||
"sh_binary(name = 'with-local-tag', srcs=['sh.sh'], tags=['local', 'some-tag'])" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove the above two lines. they are not used in the test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done, thanks :)
@laurentlb @hlopko please let me know your thought. This is a short summary of what happened:
Therefore it is safe to assume that we can re-use existing filter, as it was introduced with the same purpose - filter tag that should be propagated to the actions. Please let me know your thoughts, as I'd like to merge this change before the Summit next week :) |
…n target and in a rule
@laurentlb @hlopko friendly ping :) Please let me know whether you are interested in looking into this change. If not - I'll just merge it. |
Based on your last summary, LGTM (sorry for the delay!) |
Tags declared on targets are not propagated to actions and therefore are not taken into consideration by bazel. This causes some issues, for instance, target marked with a tag 'no-remote' will still be executed remotely. As it was agreed in the design doc (see [doc](https://docs.google.com/document/d/1X2GtuuNT6UqYYOK5lJWQEdPjAgsbdB3nFjjmjso-XHo/edit#heading=h.5mcn15i0e1ch) and bazelbuild#7766 for details), set of tags to be propagated to actions as a first iteration. This change is responsible for that first step for the Starlark Rules. RELNOTES: tags 'no-remote', 'no-cache', 'no-remote-cache', 'no-remote-exec', 'no-sandbox' are propagated now to the actions from targets. Closes bazelbuild#7766 Closes bazelbuild#8612. PiperOrigin-RevId: 256369636
Tags declared on targets are not propagated to actions and therefore are not taken into consideration by bazel. This causes some issues, for instance, target marked with a tag 'no-remote' will still be executed remotely. As it was agreed in the design doc (see [doc](https://docs.google.com/document/d/1X2GtuuNT6UqYYOK5lJWQEdPjAgsbdB3nFjjmjso-XHo/edit#heading=h.5mcn15i0e1ch) and bazelbuild#7766 for details), set of tags to be propagated to actions as a first iteration. This change is responsible for that first step for the Starlark Rules. RELNOTES: tags 'no-remote', 'no-cache', 'no-remote-cache', 'no-remote-exec', 'no-sandbox' are propagated now to the actions from targets. Closes bazelbuild#7766 Closes bazelbuild#8612. PiperOrigin-RevId: 256369636
Tags declared on targets are not propagated to actions and therefore are not taken into consideration by bazel. This causes some issues, for instance, target marked with a tag 'no-remote' will still be executed remotely.
As it was agreed in the design doc (see doc and #7766 for details), set of tags to be propagated to actions as a first iteration.
This change is responsible for that first step for the Starlark Rules.
RELNOTES: tags 'no-remote', 'no-cache', 'no-remote-cache', 'no-remote-exec', 'no-sandbox' are propagated now to the actions from targets.
Closes #7766