Nix-Darwin setup and /etc symbolic links PLS HELP

I seem to have an issue with the symbolic links generated on build and rebuilding.
Using Nix 2.14.0, Nixpks 2.11, nix-darwin and Home-Manager 2.11
I have been using default installation instructions. Here are the strange things it is doing.

I am finding that I have /etc/static as a symbolic link

/etc/static/
└── etc -> /nix/store/1xk4ypir42279hkgxy8rd34gpd7hpq4d-etc/etc

this is causing /etc/static/etc/

> tree 
/etc/static/etc
├── bashrc -> /nix/store/q5jjg7vp22fsg1bpnxsppv5mp9lan13b-etc-bashrc
├── nix
│   ├── nix.conf -> /nix/store/91j4y88z6al6cdl6bdzxj0jfi4ydxqkw-nix.conf
│   └── registry.json -> /nix/store/zvsi8bmc6zf3jbzg8wm0iiz84563vy64-etc-registry.json
├── ssh
│   └── ssh_known_hosts -> /nix/store/5y45aahllnwyyx1l6kpfmwvbskk2xwmj-etc-ssh_known_hosts
├── ssl
│   └── certs
│       └── ca-certificates.crt -> /nix/store/554gcphg8qxm45abgz3059kkk9bwwdqi-ca-certificates.crt
├── zprofile -> /nix/store/rb0xxj1akrgr6xad9bs0kcn9mp0ny9bg-etc-zprofile
├── zshenv -> /nix/store/lfrq5p0bwhxkmf1w30l2202xlfmnxabw-etc-zshenv
└── zshrc -> /nix/store/lrz98x881l75d82rr64wc9xjwv3jf5j4-etc-zshrc

therefore its not picking up /etc/static/zsh* /etc/static/bash* and etc

e.g in /etc/bashrc
if test -e /etc/static/bashrc; then . /etc/static/bashrc; fi

I find that I have a the unsual /etc/etc -> /etc/static/etc

and /etc/nix is pointing to /etc/static/nix so is dangling

Nix 2.14.0, Nixpks 2.11, nix-darwin and Home-Manager 2.11
M1 MBP 2020
MacOS 13.3.1 (a) (22E772610a)

I’m unsure what’s the problem, but here’s what I see on my system just to confirm:

  1. I do have a symlink on /etc/static pointing to .../etc on the store
    static -> /nix/store/zpajk44sjh7ymbyimv88xksd858f45al-etc/etc
  2. /etc/nix is not a symlink, but contains only symlinks to files under /etc/static/nix/...
  3. Similarly, /etc/zshrc points to /etc/static/zshrc
  4. There’s no /etc/static/etc

It may be useful to share some of your nix-darwin/home-manager configuration.
Were you able to reproduce it with smaller/simpler setups?

Versions
Inputs:
├───darwin: github:lnl7/nix-darwin/379d42fad6bc5c28f79d5f7ff2fa5f1c90cb7bf8
├───home-manager: github:nix-community/home-manager/0e4c33d76006c9080d2f228ba1c2308e3e4d7be6
├───nixpkgs: github:NixOS/nixpkgs/8670e496ffd093b60e74e7fa53526aa5920d09eb
$> nix --version     
nix (Nix) 2.13.3

Many thanks

Yes it is a simple setup and found these issue before I setup my flake for the system. I do have some questions

  • did you setup nix-channel for all those inputs as well?
  • did you install nix using its installer before nix-darwin?
    (I think you can use the Nix Darwin installer to install both initially)

It seems to be here things start to go wrong

This works fine…

nix-build https://github.com/LnL7/nix-darwin/archive/379d42fad6bc5c28f79d5f7ff2fa5f1c90cb7bf8.tar.gz -A installer
./result/bin/darwin-installer

However the version of nix-darwin added to nix-channels is wrong i.e using master
So I remove it and add the one I wish to use

nix-channel -add  https://github.com/LnL7/nix-darwin/archive/379d42fad6bc5c28f79d5f7ff2fa5f1c90cb7bf8.tar.gz darwin
nix-channel -update

Now I can not rebuild-darwin and when I reboot all symbolic links are broken in /etc

Nope, those are all flakes!

$> nix-channel --list                        
(empty)

Yup, I used the standard multi-user installer

Thanks that might be where things have been going wrong I have been mixing methods.
I didn’t know if nix-darwin full supported flakes as an installation method. I will try again.

Hi

Still pulling my hair out over this one. It still tries to create /etc/etc and /etc/static/etc
I cannot get it to install tumx either but I have commented it out for the time being.
This is my installation. Can you see anything wrong please.

> bash <(curl -L https://releases.nixos.org/nix/nix-2.14.0/install)
[restart]
> mkdir ~/.config/nix
> echo "experimental-features = nix-command flakes" >> ~/.config/nix/nix.conf
> nix build --extra-experimental-features 'nix-command flakes' .#darwinConfigurations.Andrews-MBP.system
> /result/activate
 setting up /Applications/Nix Apps...
 setting up pam...
 applying patches...
 setting up /etc...
 ln: failed to create symbolic link '/etc/static/etc': Permission denied
> sudo ./result/activate                                                                                         198ms X 12:55:38
 setting up /Applications/Nix Apps...
 setting up pam...
 applying patches...
 setting up /etc...
 system defaults...
 setting up launchd services...
 creating service org.nixos.activate-system
 reloading service org.nixos.nix-daemon
 reloading nix-daemon...
 waiting for nix-daemon
 waiting for nix-daemon
 configuring networking...
 ln: failed to create symbolic link '/run': Read-only file system
> printf 'run\tprivate/var/run\n' | sudo tee -a /etc/synthetic.conf
> /System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -t # For Big Sur and later
> ./result/sw/bin/darwin-rebuild switch --flake .#Andrews-MBP --verbose

flake.nix

{
  description = "Andrews MBP";
  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/bf554dabe0b0eb07d9148fedcf67adb9583217b8";
    nix-darwin.url = "github:lnl7/nix-darwin/379d42fad6bc5c28f79d5f7ff2fa5f1c90cb7bf8";
    nix-darwin.inputs.nixpkgs.follows = "nixpkgs";
    home-manager.url = "github:nix-community/home-manager/0e4c33d76006c9080d2f228ba1c2308e3e4d7be6";
    home-manager.inputs.nixpkgs.follows = "nixpkgs";
  };
  outputs = inputs:
    let
      flakeContext = {
        inherit inputs;
      };
    in
    {
      darwinConfigurations = {
        Andrews-MBP = import ./darwinConfigurations/Andrews-MBP.nix flakeContext;
      };
      homeConfigurations = {
        andrew = import ./homeConfigurations/andrew.nix flakeContext;
      };
    };
}

./darwinConfigurations/Andrews-MBP.nix

{ inputs, ... }@flakeContext:
let
  darwinModule = { config, lib, pkgs, ... }: {
    config = {
      documentation = {
        enable = false;
      };
      programs = {
        bash = {
          enable = true;
        };
        zsh = {
          enable = true;
        };
        # tmux.enable = true;
      };
      services = {
        nix-daemon = {
          enable = true;
        };
      };
      users.users.andrew = {
        home = "/Users/andrew";
	};
      system = {
        stateVersion = 4;
      };
   };
  };
in
inputs.nix-darwin.lib.darwinSystem {
  modules = [
    darwinModule
  ];
  system = "aarch64-darwin";
}

./homeConfigurations/andrew.nix

{ inputs, ... }@flakeContext:
let
  homeModule = { config, lib, pkgs, ... }: {
    config = {
      home = {
        stateVersion = "22.11";
      };
#    programs = {                            # Shell needs to be enabled
#    tmux.enable = true;
#    };

    };
  };
  nixosModule = { ... }: {
    home-manager.users.andrew = homeModule;
  };
in
(
  (
    inputs.home-manager.lib.homeManagerConfiguration {
      modules = [
        homeModule
      ];
      pkgs = inputs.nixpkgs.legacyPackages.aarch64-darwin;
    }
  ) // { inherit nixosModule; }
)

this is the ./result/activate script it produced

cat ./result/activate

#! /nix/store/z1yy2vigwp1ggvyizskwil61rjhsbxjf-bash-5.1-p16/bin/bash
set -e
set -o pipefail
export PATH="/nix/store/yplkfzn4wnjcyvc37m1iyd4din2kzwz3-gnugrep-3.7/bin:/nix/store/pi5gzs3772xp6mnlmq96kw36z0jl4nbw-coreutils-9.1/bin:/nix/store/ncfgmsw8dgmjcj35k31dj6cdbgfgjgzn-darwin-system-22.11.20230507.bf554da+darwin4.379d42f/sw/bin:/usr/bin:/bin:/usr/sbin:/sbin"

systemConfig=/nix/store/ncfgmsw8dgmjcj35k31dj6cdbgfgjgzn-darwin-system-22.11.20230507.bf554da+darwin4.379d42f

_status=0
trap "_status=1" ERR

# Ensure a consistent umask.
umask 0022






# Set up applications.
echo "setting up /Applications/Nix Apps..." >&2

ourLink () {
  local link
  link=$(readlink "$1")
  [ -L "$1" ] && [ "${link#*-}" = 'system-applications/Applications' ]
}

# Clean up for links created at the old location in HOME
if ourLink ~/Applications; then
  rm ~/Applications
elif ourLink ~/Applications/'Nix Apps'; then
  rm ~/Applications/'Nix Apps'
fi

if [ ! -e '/Applications/Nix Apps' ] \
   || ourLink '/Applications/Nix Apps'; then
  ln -sfn /nix/store/3vxs012p38b34qnryxh01vjqpp7wwwf9-system-applications/Applications '/Applications/Nix Apps'
else
  echo "warning: /Applications/Nix Apps is not owned by nix-darwin, skipping App linking..." >&2
fi

# PAM settings
echo >&2 "setting up pam..."
# Disable sudo Touch ID authentication, if added by nix-darwin
if grep 'security.pam.enableSudoTouchIdAuth' /etc/pam.d/sudo > /dev/null; then
  /nix/store/47i4bgm0rj0vjs3h30v0l5s01yslagni-gnused-4.8/bin/sed -i '/security.pam.enableSudoTouchIdAuth/d' /etc/pam.d/sudo
fi



# Applying patches to /.
echo "applying patches..." >&2

for f in $(ls /run/current-system/patches 2> /dev/null); do
    if test ! -e "/nix/store/iw6innlp038km65v2c7sfmql2gzwav2w-patches/patches/$f"; then
        patch --reverse --backup -d / -p1 < "/run/current-system/patches/$f" || true
    fi
done



# Set up the statically computed bits of /etc.
echo "setting up /etc..." >&2

declare -A etcSha256Hashes
etcSha256Hashes['/etc/bashrc']='444c716ac2ccd9e1e3347858cb08a00d2ea38e8c12fdc5798380dc261e32e9ef 617b39e36fa69270ddbee19ddc072497dbe7ead840cbd442d9f7c22924f116f4 6be16cf7c24a3c6f7ae535c913347a3be39508b3426f5ecd413e636e21031e66'
etcSha256Hashes['/etc/nix/nix.conf']='7c2d80499b39256b03ee9abd3d6258343718306aca8d472c26ac32c9b0949093 19299897fa312d9d32b3c968c2872dd143085aa727140cec51f57c59083e93b9 c4ecc3d541c163c8fcc954ccae6b8cab28c973dc283fea5995c69aaabcdf785f'
etcSha256Hashes['/etc/nix/registry.json']=''
etcSha256Hashes['/etc/ssh/ssh_known_hosts']=''
etcSha256Hashes['/etc/ssl/certs/ca-certificates.crt']=''
etcSha256Hashes['/etc/zprofile']='db8422f92d8cff684e418f2dcffbb98c10fe544b5e8cd588b2009c7fa89559c5 0235d3c1b6cf21e7043fbc98e239ee4bc648048aafaf6be1a94a576300584ef2'
etcSha256Hashes['/etc/zshenv']=''
etcSha256Hashes['/etc/zshrc']='19a2d673ffd47b8bed71c5218ff6617dfc5e8533b240b9ba79142a45f8823c23 fb5827cb4712b7e7932d438067ec4852c8955a9ff0f55e282473684623ebdfa1 c5a00c072c920f46216454978c44df044b2ec6d03409dc492c7bdcd92c94a110 40b0d8751adae5b0100a4f863be5b75613a49f62706427e92604f7e04d2e2261'

ln -sfn "$(readlink -f $systemConfig/etc)" /etc/static

for f in $(find /etc/static/* -type l); do
  l=/etc/${f#/etc/static/}
  d=${l%/*}
  if [ ! -e "$d" ]; then
    mkdir -p "$d"
  fi
  if [ -e "$l" ]; then
    if [ "$(readlink "$l")" != "$f" ]; then
      if ! grep -q /etc/static "$l"; then
        o=$(shasum -a256 "$l")
        o=${o%% *}
        for h in ${etcSha256Hashes["$l"]}; do
          if [ "$o" = "$h" ]; then
            mv "$l" "$l.orig"
            ln -s "$f" "$l"
            break
          else
            h=
          fi
        done

        if [ -z "$h" ]; then
          echo "error: not linking environment.etc.\"${l#/etc/}\" because $l already exists, skipping..." >&2
          echo "existing file has unknown content $o, move and activate again to apply" >&2
        fi
      fi
    fi
  else
    ln -s "$f" "$l"
  fi
done

for l in $(find /etc/* -type l 2> /dev/null); do
  f="$(echo $l | sed 's,/etc/,/etc/static/,')"
  f=/etc/static/${l#/etc/}
  if [ "$(readlink "$l")" = "$f" -a ! -e "$(readlink -f "$l")" ]; then
    rm "$l"
  fi
done

# Set defaults
echo >&2 "system defaults..."






# Set up launchd services in /Library/LaunchAgents and /Library/LaunchDaemons
echo "setting up launchd services..." >&2




if ! diff '/nix/store/w4fkqfm33d05scx5frr4x91yq2g2cjk9-launchd/Library/LaunchDaemons/org.nixos.activate-system.plist' '/Library/LaunchDaemons/org.nixos.activate-system.plist' &> /dev/null; then
  if test -f '/Library/LaunchDaemons/org.nixos.activate-system.plist'; then
    echo "reloading service $(basename org.nixos.activate-system.plist .plist)" >&2
    launchctl unload '/Library/LaunchDaemons/org.nixos.activate-system.plist' || true
  else
    echo "creating service $(basename org.nixos.activate-system.plist .plist)" >&2
  fi
  if test -L '/Library/LaunchDaemons/org.nixos.activate-system.plist'; then
    rm '/Library/LaunchDaemons/org.nixos.activate-system.plist'
  fi
  cp -f '/nix/store/w4fkqfm33d05scx5frr4x91yq2g2cjk9-launchd/Library/LaunchDaemons/org.nixos.activate-system.plist' '/Library/LaunchDaemons/org.nixos.activate-system.plist'
  launchctl load -w '/Library/LaunchDaemons/org.nixos.activate-system.plist'
fi

if ! diff '/nix/store/w4fkqfm33d05scx5frr4x91yq2g2cjk9-launchd/Library/LaunchDaemons/org.nixos.nix-daemon.plist' '/Library/LaunchDaemons/org.nixos.nix-daemon.plist' &> /dev/null; then
  if test -f '/Library/LaunchDaemons/org.nixos.nix-daemon.plist'; then
    echo "reloading service $(basename org.nixos.nix-daemon.plist .plist)" >&2
    launchctl unload '/Library/LaunchDaemons/org.nixos.nix-daemon.plist' || true
  else
    echo "creating service $(basename org.nixos.nix-daemon.plist .plist)" >&2
  fi
  if test -L '/Library/LaunchDaemons/org.nixos.nix-daemon.plist'; then
    rm '/Library/LaunchDaemons/org.nixos.nix-daemon.plist'
  fi
  cp -f '/nix/store/w4fkqfm33d05scx5frr4x91yq2g2cjk9-launchd/Library/LaunchDaemons/org.nixos.nix-daemon.plist' '/Library/LaunchDaemons/org.nixos.nix-daemon.plist'
  launchctl load -w '/Library/LaunchDaemons/org.nixos.nix-daemon.plist'
fi


for f in $(ls /run/current-system/Library/LaunchAgents 2> /dev/null); do
  if test ! -e "/nix/store/w4fkqfm33d05scx5frr4x91yq2g2cjk9-launchd/Library/LaunchAgents/$f"; then
    echo "removing service $(basename $f .plist)" >&2
    launchctl unload "/Library/LaunchAgents/$f" || true
    if test -e "/Library/LaunchAgents/$f"; then rm -f "/Library/LaunchAgents/$f"; fi
  fi
done

for f in $(ls /run/current-system/Library/LaunchDaemons 2> /dev/null); do
  if test ! -e "/nix/store/w4fkqfm33d05scx5frr4x91yq2g2cjk9-launchd/Library/LaunchDaemons/$f"; then
    echo "removing service $(basename $f .plist)" >&2
    launchctl unload "/Library/LaunchDaemons/$f" || true
    if test -e "/Library/LaunchDaemons/$f"; then rm -f "/Library/LaunchDaemons/$f"; fi
  fi
done

if ! diff /etc/nix/nix.conf /run/current-system/etc/nix/nix.conf &> /dev/null; then
    echo "reloading nix-daemon..." >&2
    launchctl kill HUP system/org.nixos.nix-daemon
fi
while ! nix-store --store daemon -q --hash /nix/store/z1yy2vigwp1ggvyizskwil61rjhsbxjf-bash-5.1-p16/bin/bash &>/dev/null; do
    echo "waiting for nix-daemon" >&2
    launchctl kickstart system/org.nixos.nix-daemon
done


echo "configuring networking..." >&2












# Ensure /run exists.
if [ ! -e /run ]; then
  ln -sfn private/var/run /run
fi

# Make this configuration the current configuration.
# The readlink is there to ensure that when $systemConfig = /system
# (which is a symlink to the store), /run/current-system is still
# used as a garbage collection root.
ln -sfn "$(readlink -f "$systemConfig")" /run/current-system

# Prevent the current configuration from being garbage-collected.
ln -sfn /run/current-system /nix/var/nix/gcroots/current-system

exit $_status

I fixed it by using nix-2.13.3 I am not entirely sure how and why but nix-2.14.0 ./result/action script used by darwin-rebuild doesn’t create the symbolic link to /etc/static but creates /etc/static/etc

1 Like

I was going to suggest reporting it on nix-darwin, but it looks like you already did!

You mentioned opening a new issue, but I couldn’t find it!

2 Likes

Yes I didn’t have time and forgot sorry there now

Nix 2.14 /etc symbolic link bug? #651

2 Likes