-
Notifications
You must be signed in to change notification settings - Fork 196
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
Permit multiple patterns for the driver globs in match (LP: #1918421) #202
Conversation
Codecov Report
@@ Coverage Diff @@
## master #202 +/- ##
=======================================
Coverage 99.00% 99.00%
=======================================
Files 54 54
Lines 8316 8322 +6
=======================================
+ Hits 8233 8239 +6
Misses 83 83
Continue to review full report at Codecov.
|
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.
Thank you very much @waveform80 for working on this!
Well, this is a though one... I think providing a whitespace separated list was never meant to be supported (at least it is not documented anywhere or part of any test case). But apparently it has been working (and been used; although not widely) in prior versions.
So it seems to be a regression at the same time as being "unsupported".
At very least I would not want to expose this whitespace separated list publicly in the documentation/examples, but maybe keep it as a hidden, unsupported but still working "workaround". As it does not fit the YAML schema.
I wonder, though, if we should rather adopt/fix parse.c
to:
Throw anyaml_error()
inhandle_generic_str()
if a whitespace separated list is detected- Change
match_handlers[]->driver
toYAML_NO_NODE
- Add a new
handle_match_driver()
function, similar tohandle_tunnel_key_mapping()
acceptingYAML_SCALAR_NODE
&YAML_SEQUENCE_NODE
This new function could then re-combine the sequence/list to a whitespace separated string for internal data storage (parse.h: match->driver
) for now, to keep things simple and considering that it is the format of the only currently supported backend (networkd) for this feature.
Let me check back with the team in the next Netplan sync, to see how we want to move forward here.
Sounds good - happy to handle that, if that's decided it's the right way to proceed. |
Hey @waveform80 ! After some discussion we found the following consensus: The behavior is currently unspecified and neither a whitespace separated list nor a sequence/list OR scalar/string field feels correct with regard to the YAML schema. What we want to support going forward is a (pseudo-) RegEx like syntax, which would be a normal string/scalar supporting simple shell-style glob matching (like Example:
What do you think, does this make sense to you? In a next step, we could extend the driver matching for the |
I'd certainly agree that the whitespace separated list isn't in keeping with the YAML schema (or the YAML language more generally). I'm slightly surprised the sequence/list-or-scalar/string field isn't. Whilst a pure sequence/list is obviously the "right" thing, it would be a backwards incompatible breaking change, which seems sufficient justification to me to permit the alternate singular case.
Erm, not really. Obviously, it's not my place to dictate things, so please feel free to ignore the following, but here are my thoughts on this design: Semantically it doesn't solve anything. The original objection to the space separated string points out (entirely correctly) this isn't in keeping with YAML. But neither is this. In fact, at its simplest this is just another "character-separated string" scheme that just happens to use "|" instead of " " as its separator. Now let's look at it from the user's point of view. Imperfect as the space separated string scheme was, it was at least consistent with:
I'm not attempting to argue that the above means the space separated string design is good or even acceptable, but now let's compare the bar-separated string design:
For me, the bar-separated design fails the "obviousness" test which I generally consider rather important with configuration files. It's not obvious to write (users familiar with YAML won't expect it, users familiar with networkd won't expect it, and users generally familiar with globbing won't expect it), and although it might be semi-obvious to read, the bars the confuse the meaning of any globbing operators that appear in the components. If it were up to me, I would reject my space separated string PR for the hack that it is, and go for the sequence-or-string option in the YAML (treating the string option as a special case of a one-item list). That seems to me to be in keeping with YAML's format (mostly) and, while different to networkd's underlying format, it should be reasonably obviousi to users given that the YAML list syntax is used plenty of other places in the schema, and trivial to transform to/from networkd's space separated syntax. It also doesn't confuse the operation of the globbing characters, or suggest a regular expression facility that doesn't exist. Anyway, that's my thoughts -- but obviously I'm happy to accept whatever the netplan team decide is best. |
Thank you very much for your constructive feedback!
True! The previous space-separated style was consistent with networkd and shell globbing (although not really specified). But we also have users expecting a more RegEx style format: https://askubuntu.com/questions/1326021/netplan-match-physical-ifs-only
You're making some very strong points here; and I agree. It isn't a regular expression and we should make it look like one.
Yeah, you swayed me and I'm back to my original idea of supporting the sequence-or-string format, where a sequence would be the officially documented style and (single word, single match) string would be a fallback option, to stay backwards compatible with existing configs, printing a deprecation warning when used. Still, i'd like to get a 2nd opinion (or ACK) from @vorlonofportland here. |
The fix for LP: #1922266 means that the driver match (which doesn't work anyway due to canonical/netplan#202) is now redundant and can be removed.
Sorry for taking a long time to find a definite answer to this design question!
After some more discussion with the netplan team, we're now all on the same page about implementing the "sequence-or-string" format, so that a single driver can be matched by passing a single, simple glob string (scalar) and multiple drivers can be matched by passing a list of glob strings (sequence). E.g.:
@waveform80 would you still be interested to get that implemented? |
Yup, leave it with me and I'll see what I can do! Not sure whether you want a separate issue for this, or if it's preferable to just re-write the commits for this one, but if you want to close this and create a new issue covering it, feel free to stick my face on it! |
Thanks! Re-writing the commits for this one is fine, so we can keep the discussions and resolutions to a common place. |
Codecov Report
@@ Coverage Diff @@
## main #202 +/- ##
=======================================
Coverage 99.13% 99.14%
=======================================
Files 60 60
Lines 10432 10490 +58
=======================================
+ Hits 10342 10400 +58
Misses 90 90
Continue to review full report at Codecov.
|
@waveform80 Hey Dave! I took this one over, as I'd like to get it included in the pending 0.104 release. Let me know what you think! |
Before I actually review the code, glancing at the commit list I'm guessing the PR description is out of date and we went to a list of patterns instead of using whitespace as a pattern separator? |
Indeed, I forgot to update the PR description. Did that now. |
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.
Overall, LGTM.
However, aside from nitpicks, I have a small question regarding the choice of separator in the C field.
The nice thing here is that the space-separated list can be used as is in the generated systemd-networkd output.. But I can certainly re-work it to store it in a more explicit `\t`-separated string and convert back in `networkd.c`.
I have a slight preference for internal consistency vs ease of
conversion to external formats, but I'm fine if you want it to remain as
such.
|
Co-authored-by: Lukas Märdian <slyon@ubuntu.com>
Co-authored-by: Lukas Märdian <slyon@ubuntu.com>
Thanks for your comments @schopin-pro Feel free to (squash) merge, once you're +1 on this! |
Merging :) |
static const mapping_entry_handler match_handlers[] = { | ||
{"driver", YAML_SCALAR_NODE, {.generic=handle_netdef_str}, netdef_offset(match.driver)}, | ||
{"driver", YAML_NO_NODE, {.generic=handle_match_driver}}, |
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.
So, funny story: this is actually buggy. I don't exactly understand why it works, but the YAML_NO_NODE
tag means that the union is supposed to contain a .variable
callback, which has a different parameter count.
Honestly, it's my bad. Manually tagged unions are a footgun, I should have stuck to plain structs -_-'
{"driver", YAML_NO_NODE, {.variable=handle_match_driver}},
That would introduce a compilation error since the signature has changed
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 providing a follow up in #257
Description
The networkd backend, which is the only backend currently supporting driver matches, permits multiple whitespace separated globs. Netplan will happily generate a
.link
file containing the full list of driver globs (which will subsequently work withnetworkctl
) but fails to match the driver to the interface itself, meaning the initial apply during boot fails. This is observed with the current Raspberry Pi focal images.Enhance the handling of
match.driver
to accept a single driver glob (as before) or a sequence of driver globs (new feature).Example:
LP: #1918421
Checklist
make check
successfully.make check-coverage
).