-
Notifications
You must be signed in to change notification settings - Fork 264
[CLI] devbox shell --pure #1084
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
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.
- Yes, I do think we need the flag for shellenv and run
- And yes, I do think we need to ensure devbox binary is included.
Could we add some testscript unit-tests for pure versus impure?
Some prelim comments. Need to go to a meeting....
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.
nice!
- Yes, I do think we need the flag for shellenv and run
- And yes, I do think we need to ensure devbox binary is included.
Could we add some testscript unit-tests for pure versus impure?
Some prelim comments. Need to go to a meeting....
79aa6a9
to
f2d3b84
Compare
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.
Nice, this is looking more promising. I had a few thoughts inline, and below:
1.CreateWrappers
sets up the wrapper.sh.tmpl
which calls shellenv
: https://github.com/jetpack-io/devbox/blob/main/internal/wrapnix/wrapper.sh.tmpl#L29.
I tried reasoning thru whether we need to invoke --pure
here as well, or not. But this is pretty confusing when I think of various scenarios (devbox add
within a pure
shell etc.), but my head is hurting now.
@mikeland86 thoughts?
-
I think we need the
.envrc
file that is generated for direnv to also incorporate--pure
? Maybe in a follow up PR... -
When I start
devbox shell --pure
, I get:
(mohsen--pure-shell)> devbox shell --pure
Starting a devbox shell...
Error: We found a /nix directory but nix binary is not in your PATH and we were not able to find it in the usual locations. Your nix installation might be broken. If restarting your terminal or reinstalling nix doesn't work, please create an issue at https://github.com/jetpack-io/devbox/issues
My nix is in /nix/var/nix/profiles/default/bin
(IIRC its from the default devbox install). Do we need to ensure that this is in PATH? One solution is to make the following edit inside computeNixEnv
function:
currentEnvPath := env["PATH"]
+ if currentEnvPath == "" {
+ currentEnvPath = "/nix/var/nix/profiles/default/bin"
+ }
devbox add
doesn't seem to work for me inside a pure shell:
(devbox) Savil-Srivastavas-MacBook-Pro:devbox savil$ devbox add ripgrep
Error: There was an error installing nix packages
source: exec: "git": executable file not found in $PATH
(devbox) Savil-Srivastavas-MacBook-Pro:devbox savil$
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 PR as is makes me a bit nervous. Like @savil said, it's difficult to reason about what needs pure vs impure environments. Additionally adding boolean params everywhere makes code more difficult to read (and 1 boolean leads to 2, 3.....)
Open to ideas, but I think we can make 2 changes that will reduce the size of this PR a bunch.
- Remove
pure
from CreateWrappers and just create the symlink unconditionally. I'm not sure this is the right place, but it's simple. - Change
devbox.Open(dir string, writer io.Writer)
to bedevbox.Open(dir string, writer io.Writer, devbox.Opts{})
and addpure
as a field in thedevbox
struct. This way you don't need to passpure
everywhere. You have it when you need it. The only downside to this is that you can't have a single devbox object producepure
andimpure
outcomes, but I think thats OK.
env["PATH"] = JoinPathLists(nixEnvPath, originalPath) | ||
debug.Log("computed environment PATH is: %s", env["PATH"]) | ||
|
||
d.setCommonHelperEnvVars(env) |
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 unsure if these should go in pure or not. cc: @gcurtis
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 we still want LD_LIBRARY_PATH
and LIBRARY_PATH
, but without the current environment's values appended. Since it looks like env["LIBRARY_PATH"]
and env["LD_LIBRARY_PATH"]
will always be empty, I think this is okay as-is.
@mikeland86 @savil
|
|
||
currentEnvPath := env["PATH"] | ||
if d.pure { // make nix available inside pure shell - necessary for devbox add to work | ||
currentEnvPath = "/nix/var/nix/profiles/default/bin" |
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.
Is this needed? devbox should not need nix in path to work
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.
@mikeland86 It is! you can test it. In a pure shell, devbox add
throws this error:
Error: We found a /nix directory but nix binary is not in your PATH and we were not
able to find it in the usual locations. Your nix installation might be broken.
If restarting your terminal or reinstalling nix doesn't work, please create an issue at
https://github.com/jetpack-io/devbox/issues
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.
hm, OK. I'm not 100% sure this works in all cases (e.g. single user installs).
I just tested and single user on ubuntu installed:
$ which nix
/home/mike/.nix-profile/bin/nix
See https://github.com/jetpack-io/devbox/blob/main/internal/nix/source.go#L32-L32
For some reason, we are not sourcing nix correctly. In the pure shell, is __ETC_PROFILE_NIX_SOURCED=1
set?
If that is set, then we may need a different approach.
One possible approach is to look in $PATH
and try to find:
/nix/var/nix/profiles/default/bin
OR
$HOME/.nix-profile/bin/nix
and keep them around.
There's also :
xdg.StateSubpath("nix/profile/etc/profile.d/nix.sh"),
xdg.StateSubpath("nix/profiles/profile/etc/profile.d/nix.sh"),
I'm not sure if nix also stores bins there.
So in short, I think you need to look in path for any of these:
/nix/var/nix/profiles/default/bin
$HOME/.nix-profile/bin
xdg.StateSubpath(/nix/profile/bin)
xdg.StateSubpath(nix/profiles/profile/bin)
If any of those are in PATH, then they need to be retained. In practice it will only be one of them.
I'm not 100% sure there are no other nix paths, but this should cover all the cases we currently consider.
internal/impl/shell.go
Outdated
if !pure { | ||
// First, check the SHELL environment variable. | ||
path = os.Getenv(envir.Shell) | ||
if path != "" { | ||
debug.Log("Using SHELL env var for shell binary path: %s\n", path) | ||
return path, nil | ||
} |
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.
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 here we should ignore it and always use Nix's bash shell. IMO the shell can have a pretty big impact on the environment.
I agree with the use-case of letting the user override the shell, but it might make more sense to do that through a new devbox.json field. That way it can be a Nix-installed shell that's guaranteed to be the same for everyone.
@mikeland86 Addressed the nit feedback. Not sure about the |
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 all my last round of comments can be done in a follow up. The only semi-urgent one is to search PATH for a few places nix binary can be and not just a single hard coded one. This gives us a better chance of finding it in all types of installations.
Since this PR is already really large, you should merge and do a fast follow with a fix for that. Other nits can be addressed after that.
|
||
currentEnvPath := env["PATH"] | ||
if d.pure { // make nix available inside pure shell - necessary for devbox add to work | ||
currentEnvPath = "/nix/var/nix/profiles/default/bin" |
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.
hm, OK. I'm not 100% sure this works in all cases (e.g. single user installs).
I just tested and single user on ubuntu installed:
$ which nix
/home/mike/.nix-profile/bin/nix
See https://github.com/jetpack-io/devbox/blob/main/internal/nix/source.go#L32-L32
For some reason, we are not sourcing nix correctly. In the pure shell, is __ETC_PROFILE_NIX_SOURCED=1
set?
If that is set, then we may need a different approach.
One possible approach is to look in $PATH
and try to find:
/nix/var/nix/profiles/default/bin
OR
$HOME/.nix-profile/bin/nix
and keep them around.
There's also :
xdg.StateSubpath("nix/profile/etc/profile.d/nix.sh"),
xdg.StateSubpath("nix/profiles/profile/etc/profile.d/nix.sh"),
I'm not sure if nix also stores bins there.
So in short, I think you need to look in path for any of these:
/nix/var/nix/profiles/default/bin
$HOME/.nix-profile/bin
xdg.StateSubpath(/nix/profile/bin)
xdg.StateSubpath(nix/profiles/profile/bin)
If any of those are in PATH, then they need to be retained. In practice it will only be one of them.
I'm not 100% sure there are no other nix paths, but this should cover all the cases we currently consider.
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.
Much nicer!
As some followups, I think we will want to enable a direnv user to opt-into pure mode
It would also be great to add some testscript unit-tests under |
d13545a
to
5cd0413
Compare
Merging this now, will followup with another PR addressing nix in PATH issue. |
## Summary This is a follow up PR from as a result of [this discussion](#1084 (comment)). Note, xdg dirs don't keep any nix executables as far as I know. Single user and multi user nix installation put the nix executable in `~/.nix-profile/bin/` and `/nix/var/nix/profiles/default/bin` respectively. Also added tests for devbox run pure mode. For `devbox shellenv`, pure mode doesn't really make sense to write tests for, and for `devbox shell` it's not possible to write testscript tests. ## How was it tested? - in a single user nix installed env, run `./devbox shell --pure` - `devbox add which` - `which nix` should point to `~/.nix-profile/bin/nix` - in a multi-user nix, same test should point to `/nix/var/nix/profiles/default/bin/nix`
Summary
I added a
--pure
flag fordevbox shell
to create an isolated env without variables leaking from the parent shell.Q: Should I add a --pure flag for
devbox run
anddevbox shellenv
?A: Yes
Q2: Because the created shell is "pure" the devbox command is also not available inside the pure shell. Should that be an exception?
A: Yes
Note: in pure mode, the
$HOME
env variable has to leak in because the devbox binary relies on it.How was it tested?
export FOO=bar
./devbox shell --pure
echo $FOO
should show no value./devbox run --pure -- echo $FOO
should show no value