nix-darwin
nix-darwin copied to clipboard
`users.users.<name>.shell` does not update the user's shell
For example, setting this in ~/.config/nix-darwin/flake.nix
still requires running chsh -s /run/current-system/sw/bin/fish
.
programs.fish.enable = true;
environment.shells = [pkgs.fish];
users.users.${mainUser} = {
home = "/Users/${mainUser}";
shell = pkgs.fish;
};
Also, should setting users.users.<name>.shell
automatically add the shell to environment.shells
?
Closing as duplicate of #122
This looks to me like a separate to the one in #122
@Enzime I agree that this should be separate - the issue I think is that one very recent (out of the many ) comments there did put the two issues together and this is now seen - I think that it would be easier to see the issues to ignore that comment.
@bestlem I am not even sure they are related anymore: even after manually changing my shell on my machine, the path issue was not fixed.
@Samuel-Martineau That is our point they have always been two separate issues.
The comment I referred to has confused them and should be ignored. That thread deals with what should be in fish's startup files/
Your issue is about how to set fish as the login shell. (I thought this had been raised before)
What is the best way to resolve this for now? To set fish as the default login shell using nix?
Has this been resolved?
This should’ve been fixed by #818
This should’ve been fixed by #818
So now, in theory, I would just need:
programs.fish.enable = true;
users.users = {
<name> = {
home = "/Users/<name>";
shell = pkgs.fish;
};
};
and it should "just work"?
Yeah that should work, feel free to comment if it doesn’t work
It definitely doesn't work for me. I see the correct location in /etc/shells
at /run/current-systems/sw/bin/fish
. There is a very real chance it is a GIGO issue. I pushed my proof-of-concept config if that is helpful to rule out User error.
https://github.com/spcutrell/nix/tree/main
Hoping to reopen this issue. It doesn't seem fixed for me.
Steps to recreate:
- Fresh install on M1 (Sonoma 14.5)
- Nix installation using Determinate Installer
- Create
~/.config/nix/flake.nix
(see below for content) - Create
~/.config/nix/modules/darwin/default.nix
(see below for content) - Run
nix run nix-darwin -- switch --flake ~/.config/nix/
- Run
/run/current-system/sw/bin/darwin-rebuild switch --flake ~/.config/nix
for good measure - Reboot for good measure
{
# ~/.config/nix/flake.nix
description = "Entry flake";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
darwin.url = "github:LnL7/nix-darwin";
darwin.inputs.nixpkgs.follows = "nixpkgs";
};
outputs = inputs@{ self, nixpkgs, darwin, home-manager, ... }: {
darwinConfigurations."My-MacBook-Air" = darwin.lib.darwinSystem {
system = "aarch64-darwin";
pkgs = import nixpkgs {
system = "aarch64-darwin";
config.allowUnfree = true;
};
modules = [ ./modules/darwin ];
};
};
}
{ pkgs, ... } : {
# ~/.config/nix/modules/darwin/default.nix
programs.fish.enable = true;
environment.shells = [pkgs.fish];
users.users.myUser = {
home = /Users/myUser;
shell = pkgs.fish;
};
nix.extraOptions = ''
experimental-features = nix-command flakes
'';
services.nix-daemon.enable = true;
system.stateVersion = 4;
}
cat /etc/shells
to prove that the build is working:
# Ftpd will not allow users to connect who are not using
# one of these shells.
/bin/bash
/bin/csh
/bin/dash
/bin/ksh
/bin/sh
/bin/tcsh
/bin/zsh
# List of shells managed by nix.
/run/current-system/sw/bin/fish
Now from here, I am not really sure what I expect. However, opening up terminal is still zsh and echo $SHELL
still shows /bin/zsh
and chsh -s /run/current-system/sw/bin/fish
correctly sets shell to fish as expected (showing that nix properly installed it).
I don't have the time to investigate and fix this now, I'll just leave some notes here for anyone who wants to test it out and make a PR
I suspect it'll have something to do with this command
https://github.com/LnL7/nix-darwin/blob/cf297a8d248db6a455b60133f6c0029c04ebe50e/modules/users/default.nix#L175
Possibly -create
doesn't work if shell is already defined and we might need to use a different flag instead for dscl
Possibly -create doesn't work if shell is already defined and we might need to use a different flag instead for dscl
@Enzime when I run the same command manually it works fine even if the shell is already set
sudo dscl . -create /Users/me UserShell /run/current-system/sw/bin/fish
I tried to to debug the path being set by adding an echo
I don't see it logged any where during system activation. What am I missing?
I think the only way that code doesn’t run is if your user’s uid doesn’t match the one set in nix-darwin (I think the default is 501), if that’s the case a warning should be emitted
My user ID is 501 🤔
$ dscl . -read /Users/z0al UniqueID
UniqueID: 501
Can you test if the dscl
command can change your shell to zsh
or bash
? You might need to restart before the change is reflected
Yep, I did that and it works without restarting.
$ dscl . -read /Users/z0al UserShell
UserShell: /run/current-system/sw/bin/fish
$ sudo dscl . -create /Users/z0al UserShell /run/current-system/sw/bin/bash
$ dscl . -read /Users/z0al UserShell
UserShell: /run/current-system/sw/bin/bash
$ sudo dscl . -create /Users/z0al UserShell /run/current-system/sw/bin/fish
$ dscl . -read /Users/z0al UserShell
UserShell: /run/current-system/sw/bin/fish
~~To throw a wrinkle into this, my shell doesn't change using the dscl
command. UserId is 501.~~
That's weird. In my case, this works just fine. Can you give it a shot @spcutrell ?
system.activationScripts.setFishAsShell.text = ''
dscl . -create /Users/${user} UserShell /run/current-system/sw/bin/fish
'';
Well... forget what I posted. It is working now. I thought I was pretty thorough, but I'm going to chalk this up to user error for now.
The dscl . -create
command works.
I figured it out (at least for my own setup). As I mentioned earlier, the activation script doesn't run at all since I don't see logs e.g setting up users
Looking at the script, it's behind a condition mkIf (cfg.knownUsers != [])
🤦🏻♂️ . So the fix was as simple as adding this to my config:
users.knownUsers = [ user ];
users.users.${user}.uid = 501; # or whatever your user id is
And boom! I now see the logs and the shell is correctly set up 🎉
Edit: I think nix-darwin should warn users if the list of knownUsers
is empty. I didn't know this config even existed and could easily miss it even if I did.
Confirming that it works for me as well.
I'm not sure what mac views as "admin", but is there any concern about this from the docs?
users.knownUsers List of users owned and managed by nix-darwin. Used to indicate what users are safe to create/delete based on the configuration. Don’t add the admin user or other system users to this.
I'm not sure what mac views as "admin", but is there any concern about this from the docs?
I'm also not sure. My user is definitely an admin and I'd expect every other single-user setups to have the same issue.
Well in any case, great work and thanks for your help. Not sure if this is expected behavior or how the maintainers would like to proceed, but it is pseudo-resolved imo.
Side note: I decided I would learn Nix by just slowly building out a nix-darwin set-up, and my first goal was to get the shell changed from zsh... didn't realize I stepped into a trap!
Funnily enough, I also stumbled across the same issue last year while building my nix-darwin/nixos setup. I made a home-manager script that calls chsh -s /path/to/fish
at the time and it worked just fine.
Today, however, I was doing a major refactoring to my setup and and decided to check if the issue is still open 😄
I wasn't around when this option was created, so I don't know for sure, but my instinct is that that warning is there because letting nix-darwin manage your primary/admin user could potentially really screw up your system. I would strongly recommend not putting your user in users.knownUsers
and would instead run dscl . -create /Users/${user} UserShell /run/current-system/sw/bin/fish
or chsh -s /run/current-system/sw/bin/fish
in an activation script
It's not just about the shell though, most if not all of the options under users.users.<user>
are set within that same script so that renders all of them useless?
Yes, I think the status quo is that you shouldn’t use the users.users.*
arguments on your main user, but frankly I forget why.
you shouldn’t use the
users.users.*
arguments on your main user
Coming from NixOS background that's quite the surprise frankly.
I suggest making that more prominent in the official docs to avoid confusion