Skip to content
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

Closed

Conversation

noyez
Copy link

@noyez noyez commented Aug 8, 2022

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.

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.
Copy link
Collaborator

@mcginty mcginty left a 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.

wireguard-control/src/backends/userspace.rs Outdated Show resolved Hide resolved
wireguard-control/src/backends/userspace.rs Outdated Show resolved Hide resolved
wireguard-control/src/backends/userspace.rs Outdated Show resolved Hide resolved
@noyez
Copy link
Author

noyez commented Aug 12, 2022

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.

Copy link
Collaborator

@mcginty mcginty left a 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.

wireguard-control/src/backends/userspace.rs Outdated Show resolved Hide resolved
@bschwind
Copy link
Member

@noyez if we get the merge conflict resolved and apply @mcginty 's suggestion, we can get this merged and release the next version of innernet :)

@noyez
Copy link
Author

noyez commented Jun 13, 2023

@noyez if we get the merge conflict resolved and apply @mcginty 's suggestion, we can get this merged and release the next version of innernet :)

next release? ... let's get this merged then. I'm looking forward to the new release! thanks!

Copy link
Collaborator

@mcginty mcginty left a 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!

@bschwind
Copy link
Member

next release? ... let's get this merged then. I'm looking forward to the new release! thanks!

Yep next release. It seems the merge conflict is still there though so we'll have to resolve that first.

@bschwind
Copy link
Member

For the conflicting line, I think you just want it to be this:

let mut command = Command::new(get_userspace_implementation()?);

@bschwind
Copy link
Member

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() {
Copy link
Member

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.

Copy link
Collaborator

@mcginty mcginty Aug 23, 2023

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.

Copy link
Author

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

Copy link
Collaborator

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.

Copy link
Author

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?

Copy link
Member

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),
    }
}

Copy link
Collaborator

@mcginty mcginty Aug 24, 2023

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.

Copy link
Author

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.

Copy link
Collaborator

@mcginty mcginty Aug 24, 2023

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.

Copy link
Member

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.

Copy link
Member

@bschwind bschwind left a 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.

@noyez
Copy link
Author

noyez commented Aug 26, 2023

Closing this PR in favor of : #284

@noyez noyez closed this Aug 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants