-
Notifications
You must be signed in to change notification settings - Fork 516
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
Add Whippet to bottlerocket #3270
Conversation
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.
Mostly nits since I know this is POC code.
The only thing I'd like us to investigate before merging is the fact the package is built for everything, not just variants using systemd-networkd.
default_path = "/org/freedesktop/network1", | ||
assume_defaults = false | ||
)] | ||
trait NetworkManager { |
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'm on the fence about including all of these. I do appreciate the effort it took to gather this information and the fact we could use them, but I think we should probably whittle this down to what we do use. I would like to save them for future reference and use, though... Perhaps we comment them out with a message "for potential future use" or something?
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 agree we should trim this down. These are autogenerated from zbus_xmlgen
so we can always go back and get them again. I think I can trim these down as long as I document where we got them and how one would efficiently add things back in.
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 pulled out many of the things we are unlikely to use (the write stuff) but left some of the other read functions since its still early and I realized we might have nicer ways to do this. For example, we might shift to get_link_by_name
vs list_links
. I also anticipate us finding edge cases where the *_state
calls might be needed. We can trim as we discover they are not needed as we test this code more.
Whippet is a D-Bus listener that subscribes to the network1 D-Bus service on the system bus. This listens for events that happen to the primary interface and call netdog to notify it so netdog can update anything that has changed with the primary interface configuration. This commit adds a rudimentary but functional version of whippet. There is more work to be done to make it a robust, reliable daemon. Signed-off-by: Matthew Yeazel <[email protected]>
This adds the whippet service file to os when compiling with systemd-networkd support enabled. This should only affect variants that are using systemd-networkd.
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'm good to merge this as POC code that won't be included in current variants. I'll pick up the torch once it's merged and can continue the outstanding items.
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.
Looks good to me. And if we find anything wrong, we have some time to correct and adjust. Probably better to have this in and usable to find out if that is the case.
%package -n %{_cross_os}whippet | ||
Summary: D-Bus listener and marshaller | ||
%description -n %{_cross_os}whippet | ||
%{summary}. | ||
|
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: you should make the whole sub-package conditional rather than creating an empty rpm with no files
@@ -0,0 +1,15 @@ | |||
[Unit] | |||
Description=Bottlerocket D-Bus listener for network events |
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: doesn't necessarily need to be Bottlerocket-specific
Description=Bottlerocket D-Bus listener for network events | |
Description=D-Bus listener for network events |
|
||
[dependencies] | ||
snafu = "0.7" | ||
zbus = "3.8.0" |
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'd rather not mix async runtimes:
zbus = "3.8.0" | |
zbus = { version = "3.8.0", default-features = false, features = ["tokio"] } |
# gptman is locked to older nix but is fine to move up | ||
# https://github.com/rust-disk-partition-management/gptman/pull/113 |
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.
That pull request was closed and says it's not fine to move up.
@@ -0,0 +1,164 @@ | |||
/*! | |||
whippet is a D-Bus listener that reponds to events on D-Bus. |
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.
whippet is a D-Bus listener that reponds to events on D-Bus. | |
whippet is a D-Bus listener that responds to events on D-Bus. |
// Call netdog primary-interface to get the name of the primary interface | ||
println!("Calling netdog to get primary interface"); | ||
let primary_interface_name_result = Command::new(NETDOG) | ||
.arg("primary-interface") | ||
.output() | ||
.context(error::NetdogExecutionSnafu)?; | ||
ensure!( | ||
primary_interface_name_result.status.success(), | ||
error::FailedNetdogSnafu { | ||
stderr: String::from_utf8_lossy(&primary_interface_name_result.stderr) | ||
} | ||
); | ||
|
||
let primary_interface_output_str = String::from_utf8(primary_interface_name_result.stdout) | ||
.context(error::PrimaryInterfaceStringSnafu {})?; | ||
let primary_interface: String = primary_interface_output_str | ||
.trim() | ||
.to_lowercase() | ||
.trim_matches('"') | ||
.to_string(); | ||
println!("Primary interface is {}", &primary_interface); | ||
|
||
// Put the path in an option since we might not find it | ||
let mut path_to_primary: Option<&OwnedObjectPath> = 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.
whippet should have a config file that tells it what interface(s) to watch and what commands to run in response.
println!( | ||
"Calling netdog write-primary-interface-status for {}", | ||
link_status.name | ||
); | ||
let primary_interface_status_result = Command::new(NETDOG) | ||
.arg("write-primary-interface-status") | ||
.output() | ||
.context(error::NetdogExecutionSnafu)?; | ||
ensure!( | ||
primary_interface_status_result.status.success(), | ||
error::FailedNetdogSnafu { | ||
stderr: String::from_utf8_lossy(&primary_interface_status_result.stderr) | ||
} | ||
); |
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 expect you'll want to use tokio::process::Command
to avoid causing problems with the async runtime.
This seems like it should be a log message, either a warning or an error, and not cause the process to terminate.
} else { | ||
println!("DEBUG: found {} but is not {}", name, &primary_interface); | ||
} |
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.
This should all be standard logging statements - debug!
, warn!
etc.
if link_status.administrative_state == "configured" { | ||
// call netdog now since its already configured, then the polling for changes can block | ||
println!( | ||
"Calling netdog write-primary-interface-status for {}", | ||
link_status.name | ||
); |
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.
This is racy because the interface may not be configured here, but may become configured before we are listening for the signal that tells us it's now configured.
Issue number: 2449
Description of changes:
This is an initial commit for whippet. There is more work to be done to make this robust, but this glues together the bits so that DNS works on top of #3266. With both of these changes, we should have a basic working stack.
This relies on systemd to restart
whippet
often if it fails. This works well enough for now, but the overall approach needs to be hardened up for a proper daemon that we want for this purpose.Things this doesn't do:
whippet
not die all the time.netdog
command and relies upon restart by systemdsystemctl
and more or less is functional, but there are likely edge cases that would make this less robust for productionprintln!()
There will be more work to come to make this better, but I wanted to get a starting point out in the wild for folks to look at.
I confirmed that when enabling the image-feature of systemd-networkd, whippet shows up in the image:
find /mnt -name "*whippet*" /mnt/x86_64-bottlerocket-linux-gnu/sys-root/usr/lib/systemd/system/whippet.service /mnt/x86_64-bottlerocket-linux-gnu/sys-root/usr/bin/whippet
and otherwise whippet is excluded from the image.
Testing done:
I have done a lot of manual testing on QEMU and EC2. I have basic output from my EC2 instance:
The output is rough for now and could be cleaned up.
Terms of contribution:
By submitting this pull request, I agree that this contribution is dual-licensed under the terms of both the Apache License, version 2.0, and the MIT license.