-
-
Notifications
You must be signed in to change notification settings - Fork 59
nixos: add --target-host
and --build-host
options
#276
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
Conversation
This is pretty neat. Viper and I have been discussing how we would handle remote deployments, but I guess simple was how we should've gone about it. Not on my PC currently, so cannot provide a complete review. Until then, two things
Other than that I have no notes, I'll review in detail when I get back to my system. |
I'll see what i can do about --build-host, should be simple enough cause its just adding a .ssh to the build command. Another issue i did just discover is if your ssh key is password protected and you havnt dont ssh-add yet, it would be ideal if we cant prompt the user in the beginning to do ssh-add |
The problem with this is that it requires one ssh connection per command, which can be a pain (related: serokell/deploy-rs#54) I thought about using https://crates.io/crates/libssh-rs to maintain a single SSH connection, but I don't know how hard it would be to implement. |
the refactor to maintain an ssh connection will probably be a pain, espeically with stuff like shelling out to |
oh i just realized im not handling the nvd diff correct, and that doing so is gonna be real annoying unless nvd just works over ssh |
I don't think it does, but @bloxx12 and I are currently working on an alternative diff implementation that I'm hoping to replace nvd with in nh as a smaller, faster implementation. Maybe we could also try taking a shot at diff over ssh? |
We can disable nvd for SSH connection and merge this as is. And in the future replace nvd with an ssh-capable rewrite. |
well diff over ssh is technically not required, if you had like an equivalent to |
managed to get the ssh-add thingy working 🎉 |
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 like the spirit of those changes, but I really must defer to Viper here for a second opinion. We're messing with SSH, and I'd rather do everything correctly. So far I have a bunch of issues that are plaguing me. The liberal use of .unwrap()
is one and I find it to be a fragile. Please consider using ?
or .expect()
with descriptive error messages. Speaking of, error messages would benefit from making a little more explicit. The edge cases should be rare, but not none. Lastly, and this is a little bit speculative, it’s worth validating all inputs that eventually reach shell commands. We do not want to be opening the door to weird command injections, no matter how unlikely.
Also, I'd appreciate some tests but it might be a little difficult add them without a good mock testing in place. #258 is supposed to address this... eventually.
} | ||
|
||
/// Prompts the user for ssh key login if needed | ||
pub fn ensure_ssh_key_login() -> Result<()> { |
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 want to be too nitpicky, but there are three things I would like to note here:
- Execution of this function appears a little... fragile to me. It assumes
ssh-add
is available, and will degrade user experience if it's missing. Maybe we could check forssh-add
early and explicitly. - The
.unwrap()
calls (e.g.,Command::new("ssh-add").spawn()?.wait()?
) could cause panics if errors occur. I'm not religiously opposed to unwraps and similar error handling, but for an operation as sensitive as SSH we would like to bevery explicit. - This is a bit of a stretch and mostly optional.
Stdio::inherit
makes sense here for user interaction but could lead to unexpected behavior if nh is run in a non-interactive environment. This will likely not be the case since we don't support headless usage (not explicitly, at least) but implicit behaviour might be confusing. Take this comment with a grain of salt, I leave it to your best judgement.
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.
not nipicky at all, youre right, i should make sure to not unwrap at the call site so that we arent ever dependant on ssh-add
src/util.rs
Outdated
pub fn get_current_system() -> Result<String> { | ||
let output = Command::new("nix") | ||
.args([ | ||
"eval", | ||
"--impure", | ||
"--raw", | ||
"--expr", | ||
"builtins.currentSystem", | ||
]) | ||
.output()?; | ||
let output_str = str::from_utf8(&output.stdout)?; | ||
Ok(output_str.to_string()) | ||
} |
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.
Okay I'm really not sure about this. Surely there is a way we can get the current system purely without having to evaluate currentSystem
. Maybe we can evaluate nixpkgs.hostPlatform
or some modular attribute inside the evaluated configuration? CC @viperML on this for installable context related woes.
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.
actually this shouldnt be needed, i can just use -
to get the builders
argument to use the default
Exec::cmd("ssh") | ||
.arg("-T") | ||
.arg(ssh) | ||
.stdin(cmd.to_cmdline_lossy().as_str()) |
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.
Are we sure that cmd.to_cmdline_lossy()
doesn't pass unescaped
inputs to the SSH command? I can't exactly imagine an "attack" vector here, but this seems a little dangerous.
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 did check that i did do escaping when implementing it, not as much for security as in the case of it would break on weird input like a '
or smth, i cant vouch for their implementation of escaping being correct, but they atleast do something
Sorry, there seems to be a small merge conflict. I couldn't fix it on Github's web UI very well. Would you mind fixing it? Looks like we're using both NH's own |
np, thanks for trying, im currently visiting my in-laws, so cant promise it'll be today, so at the latest it'll be sunday |
No worries, I'll see what I can do if I can get to my system later. I'm also visiting family, so not sure if I'll have the time today. |
managed to find some time with the laptop, to do the quick fix. it would require quite a few additions to the internal NH command struct work for the |
--target-host
and --build-host
options
LGTM. I have a few notes, but I think I've nitted this PR enough-- I can cover those later on my own accord. Is this ready to merge? |
for my sake its ready to merge |
Thank you for your efforts :) |
Seems like this broke compare changes diff and introduced a warning on every build saying it's guessing host name and it's building for a VM. |
I'm doing a little cleanup in the platform commands right now. It will be pushed to a new branch later today, and should avoid the breakage as I think I caught the issue and fixed it anyway. |
fwiw i'm still seeing this message using the latest version from the repo's flake. |
Please see if #281 resolves the issue for you. I'm currently preoccupied with personal projects and can't make too much progress on that PR, but it should already contain the fix for the error reported. |
part of #254
not sure if the right move here is to invoke
ln -s
over ssh to make sure the out_path is symlinked correctly on the target machine, or if just canonicalize'ing the paths is the right move, i went for canonicalize just because it felt less hacky than invokingln -s
over sshit currently works for me on my own local server