-
Notifications
You must be signed in to change notification settings - Fork 188
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 Error Message when wireguard-go
not found.
#232
Conversation
Previously when trying to add a peer, i for the following output, which was not helpful since i wasn't sure what file could not be found. bkn@mbp16 bkn % sudo /Users/bkn/.cargo/bin/innernet --verbose install mbp16.toml ✔ Interface name · chester [*] bringing up interface chester. [E] failed to start the interface: chester - No such file or directory (os error 2). [*] bringing down the interface. [!] failed to bring down interface: chester - WireGuard name file can't be read. [E] Failed to redeem invite. Now's a good time to make sure the server is started and accessible! [E] chester - No such file or directory (os error 2) After poking through the code I finally figured out the `No such file or directory` error was due to no wireguard implementation could be found. Now when running the above command i get the following output. bkn@mbp16 bkn % sudo /Users/bkn/source/rust/innernet/target/debug/innernet --verbose install mbp16.toml ✔ Interface name · chester [*] bringing up interface chester. [E] failed to start the interface: chester - Cannot find wireguard implementation 'wireguard-go', to specificy custom wireguard implementation set $WG_USERSPACE_IMPLEMENTATION to wiregaurd binary. [*] bringing down the interface. [!] failed to bring down interface: chester - WireGuard name file can't be read. [E] Failed to redeem invite. Now's a good time to make sure the server is started and accessible! [E] chester - Cannot find wireguard implementation 'wireguard-go', to specificy custom wireguard implementation set $WG_USERSPACE_IMPLEMENTATION to wiregaurd binary I find this error message to be more explicit and if a user encounters a similar problem its more clear how to remidy this specific error.
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! This should be helpful to folks. Just a few formatting/nitpick comments.
No worries. I made those changes. I'm on the road -- hence my interest in this project -- so my PR was kind of quick and dirty. let me know if you want any more changes. |
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 - sorry to have left this hanging.
Co-authored-by: Jake McGinty <[email protected]>
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! Thanks for updating it!
Yep next release. It seems the merge conflict is still there though so we'll have to resolve that first. |
For the conflicting line, I think you just want it to be this: let mut command = Command::new(get_userspace_implementation()?); |
Ah, it seems I can resolve the merge conflict myself, didn't know I could push to branches on forks. |
.or_else(|_| std::env::var("WG_QUICK_USERSPACE_IMPLEMENTATION")) | ||
.unwrap_or_else(|_| "wireguard-go".to_string()), | ||
); | ||
if !wg_path.exists() { |
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, the docker test is failing correctly.
We can find wireguard-go
directly in the previous code because it's in the PATH
. But now if we treat it as a PathBuf
and call .exists()
on it, we're asking if there's a wireguard-go
file in the default working directory of the container. So this function is returning an Error
, the container exits, and our docker test fails to find the peer container because it exited and disappeared.
We'll have to re-think how we detect if it's there or not. Maybe we just run the command and detect if we encounter an error, or maybe we use the which crate or something else to find the full path of the binary, or something else entirely.
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 yeah, maybe we want to rethink this as simply providing better output when we run the command in start_userspace_wireguard()
. Personally I don't think the benefits of adding a dependency are worth it compared to adding a better "wireguard-go failed to execute - is it installed?" type message to the user.
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 there is a switch for --version
in wireguard-go
. We could try to execute wireguard-go --version
. If that succeeds, then wireguard-go
exists in the path.
» /usr/bin/wireguard --version
wireguard-go v0.0.20220117
Userspace WireGuard daemon for linux-amd64.
Information available at https://www.wireguard.com.
Copyright (C) Jason A. Donenfeld <[email protected]>.
» echo $?
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.
@noyez I don't think that's necessary: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=d93bf64dbf49743403648a4dfebf8b46
We can just check the result of output()
and the result will be:
Err(Os { code: 2, kind: NotFound, message: "No such file or directory" })
when the binary is missing :).
So I think this PR is more about modifying start_userspace_wireguard()
to provide more informative error messages up the chain for the user.
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 if the output()
fails it could mean wireguard-go
doesn't exists, or perhaps there's another error with the configurations. In start_userspace_wireguard()
you already check if output()
returns an error status, if so it returns Err(io::ErrorKind::AddrNotAvailable.int())
.
Do you know to differentiate the different error codes?
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.
@noyez at first glance this looks reasonable, we can simplify it a bit and I think we don't want to return io::ErrorKind::AddrNotAvailable
if we get an error running the command (no output
was produced)
fn start_userspace_wireguard(iface: &InterfaceName) -> io::Result<Output> {
let mut command = Command::new(get_userspace_implementation());
let output_res = if cfg!(target_os = "linux") {
command.args(&[iface.to_string()]).output()
} else {
command
.env("WG_TUN_NAME_FILE", &format!("{VAR_RUN_PATH}/{iface}.name"))
.args(["utun"])
.output()
};
match output_res {
Ok(output) => {
if output.status.success() {
Ok(output)
} else {
Err(io::ErrorKind::AddrNotAvailable.into())
}
},
Err(e) if e.kind() == io::ErrorKind::NotFound => Err(io::Error::new(
io::ErrorKind::NotFound,
"Cannot find \"wireguard-go\". Specify a custom path with WG_USERSPACE_IMPLEMENTATION.",
)),
Err(e) => Err(e),
}
}
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.
Yeah, I actually also don't get why we're returning io::ErrorKind::AddrNotAvailable
for all errors, but I can fix that up in another PR since it's not related to wireguard-go being missing altogether and was already in the code.
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.
yeah, i didn't know what else to return, that's what was getting returned previously in the start_userspace_wireguard
function so i kept it, but can def be 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.
Yeah I think that one is my bad ;). It'd make this PR less "short and sweet" but I feel like maybe the right thing to do is to pack into the error the return code as well as possibly the stderr
output so that we can output it to the user.
Feel free to take that on if you wish, otherwise I can address it in a later PR since it's my oversight.
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 actually also don't get why we're returning io::ErrorKind::AddrNotAvailable for all errors
The previous code had a question mark operator:
command.args(&[iface.to_string()]).output()? |
So ErrorKind::AddrNotAvailable
is only returned when there's not a success status code after running the command. But you're right that we should return all the details to the caller.
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.
Requesting changes to fix the failing docker test, see my comment for details.
Closing this PR in favor of : #284 |
Previously when trying to add a peer, i for the following output, which
was not helpful since i wasn't sure what file could not be found.
After poking through the code I finally figured out the
No such file or directory
error was due to no wireguard implementation could be found.Now when running the above command i get the following output.
I find this error message to be more explicit and if a user encounters a
similar problem its more clear how to remidy this specific error.