mirror of
https://github.com/LnL7/nix-darwin.git
synced 2025-03-16 13:28:16 +00:00
Merge branch 'LnL7:master' into keyboard-shortcuts-update
This commit is contained in:
commit
07543d1519
71 changed files with 1869 additions and 1119 deletions
18
.github/workflows/build.yml
vendored
18
.github/workflows/build.yml
vendored
|
@ -1,18 +0,0 @@
|
||||||
name: "Build"
|
|
||||||
on:
|
|
||||||
# curl -fsSL -XPOST \
|
|
||||||
# -H "Accept: application/vnd.github.everest-preview+json" \
|
|
||||||
# -H "Authorization: token $GITHUB_TOKEN" \
|
|
||||||
# --data '{"event_type": "build", "client_payload": {"args": "-f channel:nixpkgs-unstable hello"}}' \
|
|
||||||
# https://api.github.com/repos/LnL7/nix-darwin/dispatches
|
|
||||||
repository_dispatch:
|
|
||||||
types:
|
|
||||||
- build
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: macos-12
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- uses: cachix/install-nix-action@v22
|
|
||||||
- run: |
|
|
||||||
nix build ${{ github.event.client_payload.args }} -vL
|
|
23
.github/workflows/debug.yml
vendored
23
.github/workflows/debug.yml
vendored
|
@ -1,23 +0,0 @@
|
||||||
name: "Debug"
|
|
||||||
on:
|
|
||||||
# curl -fsSL -XPOST \
|
|
||||||
# -H "Accept: application/vnd.github.everest-preview+json" \
|
|
||||||
# -H "Authorization: token $GITHUB_TOKEN" \
|
|
||||||
# --data '{"event_type": "debug"}' \
|
|
||||||
# https://api.github.com/repos/LnL7/nix-darwin/dispatches
|
|
||||||
repository_dispatch:
|
|
||||||
types:
|
|
||||||
- debug
|
|
||||||
jobs:
|
|
||||||
debug:
|
|
||||||
runs-on: macos-12
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- uses: cachix/install-nix-action@v22
|
|
||||||
- run: |
|
|
||||||
nix-channel --add https://nixos.org/channels/nixpkgs-unstable nixpkgs
|
|
||||||
nix-channel --update
|
|
||||||
- run: |
|
|
||||||
nix-shell -A installer
|
|
||||||
nix-shell -A installer.check
|
|
||||||
- uses: mxschmitt/action-tmate@v3
|
|
319
.github/workflows/test.yml
vendored
319
.github/workflows/test.yml
vendored
|
@ -2,144 +2,144 @@ name: "Test"
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
push:
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
|
||||||
env:
|
env:
|
||||||
CURRENT_STABLE_CHANNEL: nixpkgs-24.05-darwin
|
CURRENT_STABLE_CHANNEL: nixpkgs-24.05-darwin
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test-stable:
|
test-stable:
|
||||||
runs-on: macos-12
|
runs-on: macos-13
|
||||||
timeout-minutes: 30
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
# We use the Determinate Systems installer for 2.18 because the
|
|
||||||
# Sequoia UID/GID changes have not yet been backported to the
|
|
||||||
# official installer for that version.
|
|
||||||
- name: Install nix corresponding to latest stable channel
|
- name: Install nix corresponding to latest stable channel
|
||||||
uses: DeterminateSystems/nix-installer-action@main
|
uses: cachix/install-nix-action@v30
|
||||||
with:
|
with:
|
||||||
nix-package-url: https://releases.nixos.org/nix/nix-2.18.5/nix-2.18.5-x86_64-darwin.tar.xz
|
install_url: https://releases.nixos.org/nix/nix-2.18.8/install
|
||||||
- run: nix-build ./release.nix -I nixpkgs=channel:${{ env.CURRENT_STABLE_CHANNEL }} -I darwin=. -A tests
|
- run: nix flake check --override-input nixpkgs nixpkgs/${{ env.CURRENT_STABLE_CHANNEL }}
|
||||||
- run: nix-build ./release.nix -I nixpkgs=channel:${{ env.CURRENT_STABLE_CHANNEL }} -I darwin=. -A manpages
|
|
||||||
- run: nix-build ./release.nix -I nixpkgs=channel:${{ env.CURRENT_STABLE_CHANNEL }} -I darwin=. -A examples.simple
|
|
||||||
|
|
||||||
test-unstable:
|
test-unstable:
|
||||||
runs-on: macos-12
|
runs-on: macos-13
|
||||||
timeout-minutes: 30
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- name: Install nix from current unstable channel
|
- name: Install nix from current unstable channel
|
||||||
uses: cachix/install-nix-action@v27
|
uses: cachix/install-nix-action@v30
|
||||||
with:
|
with:
|
||||||
install_url: https://releases.nixos.org/nix/nix-2.24.6/install
|
install_url: https://releases.nixos.org/nix/nix-2.24.9/install
|
||||||
- run: nix-build ./release.nix -I nixpkgs=channel:nixpkgs-unstable -I darwin=. -A tests
|
- run: nix flake check --override-input nixpkgs nixpkgs/nixpkgs-unstable
|
||||||
- run: nix-build ./release.nix -I nixpkgs=channel:nixpkgs-unstable -I darwin=. -A manpages
|
|
||||||
- run: nix-build ./release.nix -I nixpkgs=channel:nixpkgs-unstable -I darwin=. -A examples.simple
|
|
||||||
|
|
||||||
install-against-stable:
|
install-against-stable:
|
||||||
runs-on: macos-12
|
runs-on: macos-13
|
||||||
timeout-minutes: 30
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
# We use the Determinate Systems installer for 2.18 because the
|
|
||||||
# Sequoia UID/GID changes have not yet been backported to the
|
|
||||||
# official installer for that version.
|
|
||||||
- name: Install nix corresponding to latest stable channel
|
- name: Install nix corresponding to latest stable channel
|
||||||
uses: DeterminateSystems/nix-installer-action@main
|
uses: cachix/install-nix-action@v30
|
||||||
with:
|
with:
|
||||||
nix-package-url: https://releases.nixos.org/nix/nix-2.18.5/nix-2.18.5-x86_64-darwin.tar.xz
|
install_url: https://releases.nixos.org/nix/nix-2.18.8/install
|
||||||
- name: Install ${{ env.CURRENT_STABLE_CHANNEL }} channel
|
nix_path: nixpkgs=channel:${{ env.CURRENT_STABLE_CHANNEL }}
|
||||||
|
- name: Install channels
|
||||||
run: |
|
run: |
|
||||||
|
nix-channel --add https://github.com/LnL7/nix-darwin/archive/master.tar.gz darwin
|
||||||
nix-channel --add https://nixos.org/channels/${{ env.CURRENT_STABLE_CHANNEL }} nixpkgs
|
nix-channel --add https://nixos.org/channels/${{ env.CURRENT_STABLE_CHANNEL }} nixpkgs
|
||||||
nix-channel --update
|
nix-channel --update
|
||||||
- name: Install nix-darwin and test
|
- name: Install nix-darwin
|
||||||
run: |
|
run: |
|
||||||
export NIX_PATH=nixpkgs=channel:${{ env.CURRENT_STABLE_CHANNEL }}
|
export NIX_PATH=$HOME/.nix-defexpr/channels
|
||||||
|
|
||||||
# We run nix-darwin twice to test that it can create darwin-configuration correctly for us
|
mkdir -p ~/.config/nix-darwin
|
||||||
# but we expect it to fail setting up /etc/nix/nix.conf
|
cp modules/examples/simple.nix ~/.config/nix-darwin/configuration.nix
|
||||||
nix-shell -A installer || true
|
|
||||||
|
|
||||||
nixConfHash=$(shasum -a 256 /etc/nix/nix.conf | cut -d ' ' -f 1)
|
nixConfHash=$(shasum -a 256 /etc/nix/nix.conf | cut -d ' ' -f 1)
|
||||||
/usr/bin/sed -i.bak \
|
/usr/bin/sed -i.bak \
|
||||||
"s/# nix.package = pkgs.nix;/nix.settings.access-tokens = [ \"github.com=\${{ secrets.GITHUB_TOKEN }}\" ]; environment.etc.\"nix\/nix.conf\".knownSha256Hashes = [ \"$nixConfHash\" ];/" \
|
"s/# programs.fish.enable = true;/nix.settings.access-tokens = [ \"github.com=\${{ secrets.GITHUB_TOKEN }}\" ]; environment.etc.\"nix\/nix.conf\".knownSha256Hashes = [ \"$nixConfHash\" ];/" \
|
||||||
~/.nixpkgs/darwin-configuration.nix
|
~/.config/nix-darwin/configuration.nix
|
||||||
|
|
||||||
nix-shell -A installer
|
nix run .#darwin-rebuild \
|
||||||
nix-shell -A installer.check
|
-- switch \
|
||||||
- name: Build and activate default derivation
|
-I darwin-config=$HOME/.config/nix-darwin/configuration.nix
|
||||||
|
- name: Switch to new configuration
|
||||||
run: |
|
run: |
|
||||||
. /etc/static/bashrc
|
. /etc/bashrc
|
||||||
|
|
||||||
|
/usr/bin/sed -i.bak \
|
||||||
|
"s/pkgs.vim/pkgs.hello/" \
|
||||||
|
~/.config/nix-darwin/configuration.nix
|
||||||
|
|
||||||
darwin-rebuild switch -I darwin=.
|
darwin-rebuild switch -I darwin=.
|
||||||
|
|
||||||
|
hello
|
||||||
- name: Test uninstallation of nix-darwin
|
- name: Test uninstallation of nix-darwin
|
||||||
run: |
|
run: |
|
||||||
export NIX_PATH=$HOME/.nix-defexpr/channels
|
# We need to specify `--extra-experimental-features` because `experimental-features` is set by
|
||||||
nix-shell -A uninstaller
|
# `cachix/install-nix-action` but not by our default config above
|
||||||
nix-shell -A uninstaller.check
|
nix run .#darwin-uninstaller \
|
||||||
- name: Debugging tmate session
|
--extra-experimental-features "nix-command flakes" \
|
||||||
if: ${{ failure() }}
|
--override-input nixpkgs nixpkgs/${{ env.CURRENT_STABLE_CHANNEL }}
|
||||||
uses: mxschmitt/action-tmate@v3
|
nix run .#darwin-uninstaller.tests.uninstaller \
|
||||||
timeout-minutes: 15
|
--extra-experimental-features "nix-command flakes" \
|
||||||
with:
|
--override-input nixpkgs nixpkgs/${{ env.CURRENT_STABLE_CHANNEL }}
|
||||||
limit-access-to-actor: true
|
|
||||||
|
|
||||||
install-against-unstable:
|
install-against-unstable:
|
||||||
runs-on: macos-12
|
runs-on: macos-13
|
||||||
timeout-minutes: 30
|
timeout-minutes: 30
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- name: Install nix from current unstable channel
|
- name: Install nix from current unstable channel
|
||||||
uses: cachix/install-nix-action@v27
|
uses: cachix/install-nix-action@v30
|
||||||
with:
|
with:
|
||||||
install_url: https://releases.nixos.org/nix/nix-2.24.6/install
|
install_url: https://releases.nixos.org/nix/nix-2.24.9/install
|
||||||
nix_path: nixpkgs=channel:nixpkgs-unstable
|
nix_path: nixpkgs=channel:nixpkgs-unstable
|
||||||
- name: Install nixpkgs-unstable channel
|
- name: Install channels
|
||||||
run: |
|
run: |
|
||||||
|
nix-channel --add https://github.com/LnL7/nix-darwin/archive/master.tar.gz darwin
|
||||||
nix-channel --add https://nixos.org/channels/nixpkgs-unstable nixpkgs
|
nix-channel --add https://nixos.org/channels/nixpkgs-unstable nixpkgs
|
||||||
nix-channel --update
|
nix-channel --update
|
||||||
- name: Install nix-darwin and test
|
- name: Install nix-darwin
|
||||||
run: |
|
run: |
|
||||||
export NIX_PATH=$HOME/.nix-defexpr/channels
|
export NIX_PATH=$HOME/.nix-defexpr/channels
|
||||||
|
|
||||||
# We run nix-darwin twice to test that it can create darwin-configuration correctly for us
|
mkdir -p ~/.config/nix-darwin
|
||||||
# but we expect it to fail setting up /etc/nix/nix.conf
|
cp modules/examples/simple.nix ~/.config/nix-darwin/configuration.nix
|
||||||
nix-shell -A installer || true
|
|
||||||
|
|
||||||
nixConfHash=$(shasum -a 256 /etc/nix/nix.conf | cut -d ' ' -f 1)
|
nixConfHash=$(shasum -a 256 /etc/nix/nix.conf | cut -d ' ' -f 1)
|
||||||
/usr/bin/sed -i.bak \
|
/usr/bin/sed -i.bak \
|
||||||
"s/# nix.package = pkgs.nix;/nix.settings.access-tokens = [ \"github.com=\${{ secrets.GITHUB_TOKEN }}\" ]; environment.etc.\"nix\/nix.conf\".knownSha256Hashes = [ \"$nixConfHash\" ];/" \
|
"s/# programs.fish.enable = true;/nix.settings.access-tokens = [ \"github.com=\${{ secrets.GITHUB_TOKEN }}\" ]; environment.etc.\"nix\/nix.conf\".knownSha256Hashes = [ \"$nixConfHash\" ];/" \
|
||||||
~/.nixpkgs/darwin-configuration.nix
|
~/.config/nix-darwin/configuration.nix
|
||||||
|
|
||||||
nix-shell -A installer
|
nix run .#darwin-rebuild \
|
||||||
nix-shell -A installer.check
|
-- switch \
|
||||||
- name: Build and activate default derivation
|
-I darwin-config=$HOME/.config/nix-darwin/configuration.nix
|
||||||
|
- name: Switch to new configuration
|
||||||
run: |
|
run: |
|
||||||
. /etc/static/bashrc
|
. /etc/bashrc
|
||||||
|
|
||||||
|
/usr/bin/sed -i.bak \
|
||||||
|
"s/pkgs.vim/pkgs.hello/" \
|
||||||
|
~/.config/nix-darwin/configuration.nix
|
||||||
|
|
||||||
darwin-rebuild switch -I darwin=.
|
darwin-rebuild switch -I darwin=.
|
||||||
|
|
||||||
|
hello
|
||||||
- name: Test uninstallation of nix-darwin
|
- name: Test uninstallation of nix-darwin
|
||||||
run: |
|
run: |
|
||||||
export NIX_PATH=$HOME/.nix-defexpr/channels
|
# We need to specify `--extra-experimental-features` because `experimental-features` is set by
|
||||||
nix-shell -A uninstaller
|
# `cachix/install-nix-action` but not by our default config above
|
||||||
nix-shell -A uninstaller.check
|
nix run .#darwin-uninstaller \
|
||||||
- name: Debugging tmate session
|
--extra-experimental-features "nix-command flakes" \
|
||||||
if: ${{ failure() }}
|
--override-input nixpkgs nixpkgs/nixpkgs-unstable
|
||||||
uses: mxschmitt/action-tmate@v3
|
nix run .#darwin-uninstaller.tests.uninstaller \
|
||||||
timeout-minutes: 15
|
--extra-experimental-features "nix-command flakes" \
|
||||||
with:
|
--override-input nixpkgs nixpkgs/nixpkgs-unstable
|
||||||
limit-access-to-actor: true
|
|
||||||
|
|
||||||
install-flake-against-stable:
|
install-flake-against-stable:
|
||||||
runs-on: macos-12
|
runs-on: macos-13
|
||||||
timeout-minutes: 30
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
# We use the Determinate Systems installer for 2.18 because the
|
- name: Install nix version corresponding to latest stable channel
|
||||||
# Sequoia UID/GID changes have not yet been backported to the
|
uses: cachix/install-nix-action@v30
|
||||||
# official installer for that version.
|
|
||||||
- name: Install nix corresponding to latest stable channel
|
|
||||||
uses: DeterminateSystems/nix-installer-action@main
|
|
||||||
with:
|
with:
|
||||||
nix-package-url: https://releases.nixos.org/nix/nix-2.18.5/nix-2.18.5-x86_64-darwin.tar.xz
|
install_url: https://releases.nixos.org/nix/nix-2.18.8/install
|
||||||
- name: Install nix-darwin
|
- name: Install nix-darwin
|
||||||
run: |
|
run: |
|
||||||
mkdir -p ~/.config/nix-darwin
|
mkdir -p ~/.config/nix-darwin
|
||||||
|
@ -148,81 +148,43 @@ jobs:
|
||||||
nix flake init -t $darwin
|
nix flake init -t $darwin
|
||||||
nixConfHash=$(shasum -a 256 /etc/nix/nix.conf | cut -d ' ' -f 1)
|
nixConfHash=$(shasum -a 256 /etc/nix/nix.conf | cut -d ' ' -f 1)
|
||||||
/usr/bin/sed -i.bak \
|
/usr/bin/sed -i.bak \
|
||||||
"s/# nix.package = pkgs.nix;/nix.settings.access-tokens = [ \"github.com=\${{ secrets.GITHUB_TOKEN }}\" ]; environment.etc.\"nix\/nix.conf\".knownSha256Hashes = [ \"$nixConfHash\" ];/" \
|
"s/# programs.fish.enable = true;/nix.settings.access-tokens = [ \"github.com=\${{ secrets.GITHUB_TOKEN }}\" ]; environment.etc.\"nix\/nix.conf\".knownSha256Hashes = [ \"$nixConfHash\" ];/" \
|
||||||
|
flake.nix
|
||||||
|
/usr/bin/sed -i.bak \
|
||||||
|
's/nixpkgs.hostPlatform = "aarch64-darwin";/nixpkgs.hostPlatform = "'$(nix eval --expr builtins.currentSystem --impure --raw)'";/' \
|
||||||
flake.nix
|
flake.nix
|
||||||
popd
|
popd
|
||||||
nix run .#darwin-rebuild -- \
|
nix run .#darwin-rebuild -- \
|
||||||
switch --flake ~/.config/nix-darwin#simple \
|
switch --flake ~/.config/nix-darwin#simple \
|
||||||
--override-input nix-darwin . \
|
--override-input nix-darwin . \
|
||||||
--override-input nixpkgs nixpkgs/${{ env.CURRENT_STABLE_CHANNEL }}
|
--override-input nixpkgs nixpkgs/${{ env.CURRENT_STABLE_CHANNEL }}
|
||||||
- name: Rebuild and activate simple flake, but this time using nix-darwin's flake interface
|
- name: Switch to new configuration
|
||||||
run: |
|
run: |
|
||||||
. /etc/static/bashrc
|
. /etc/bashrc
|
||||||
darwin-rebuild build --flake ./modules/examples/flake#simple --override-input nix-darwin . --override-input nixpkgs nixpkgs/${{ env.CURRENT_STABLE_CHANNEL }}
|
|
||||||
- name: Test git submodules
|
/usr/bin/sed -i.bak \
|
||||||
|
"s/pkgs.vim/pkgs.hello/" \
|
||||||
|
~/.config/nix-darwin/flake.nix
|
||||||
|
|
||||||
|
darwin-rebuild switch --flake ~/.config/nix-darwin#simple \
|
||||||
|
--override-input nix-darwin . \
|
||||||
|
--override-input nixpkgs nixpkgs/${{ env.CURRENT_STABLE_CHANNEL }}
|
||||||
|
|
||||||
|
hello
|
||||||
|
- name: Test uninstallation of nix-darwin
|
||||||
run: |
|
run: |
|
||||||
. /etc/static/bashrc
|
nix run .#darwin-uninstaller --override-input nixpkgs nixpkgs/${{ env.CURRENT_STABLE_CHANNEL }}
|
||||||
|
nix run .#darwin-uninstaller.tests.uninstaller --override-input nixpkgs nixpkgs/${{ env.CURRENT_STABLE_CHANNEL }}
|
||||||
mkdir -p /tmp/{test-nix-darwin-submodules,example-submodule}
|
|
||||||
|
|
||||||
pushd /tmp/example-submodule
|
|
||||||
echo '"hello"' > hello.nix
|
|
||||||
git init
|
|
||||||
git add .
|
|
||||||
git commit -m "add a submodule we will import"
|
|
||||||
popd
|
|
||||||
|
|
||||||
cp -a ./modules/examples/. /tmp/test-nix-darwin-submodules
|
|
||||||
cp -a ./modules/examples/flake/flake.nix /tmp/test-nix-darwin-submodules
|
|
||||||
|
|
||||||
pushd /tmp/test-nix-darwin-submodules
|
|
||||||
/usr/bin/sed -i.bak \
|
|
||||||
'\#modules = \[#s#configuration#configuration ./simple.nix#' \
|
|
||||||
./flake.nix
|
|
||||||
/usr/bin/sed -i.bak \
|
|
||||||
's#pkgs.vim#pkgs."${import ./submodule-test/hello.nix}"#' \
|
|
||||||
./simple.nix
|
|
||||||
git init
|
|
||||||
git add flake.nix simple.nix
|
|
||||||
git \
|
|
||||||
-c protocol.file.allow=always \
|
|
||||||
submodule add /tmp/example-submodule submodule-test
|
|
||||||
popd
|
|
||||||
|
|
||||||
# Should fail
|
|
||||||
darwin-rebuild build \
|
|
||||||
--flake /tmp/test-nix-darwin-submodules#simple \
|
|
||||||
--override-input nix-darwin . \
|
|
||||||
--override-input nixpkgs nixpkgs/${{ env.CURRENT_STABLE_CHANNEL }} \
|
|
||||||
&& {
|
|
||||||
printf 'succeeded while expecting failure due to submodule\n' >/dev/stderr
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
# Should also fail
|
|
||||||
darwin-rebuild build \
|
|
||||||
--flake /tmp/test-nix-darwin-submodules?submodules=0#simple \
|
|
||||||
--override-input nix-darwin . \
|
|
||||||
--override-input nixpkgs nixpkgs/${{ env.CURRENT_STABLE_CHANNEL }} \
|
|
||||||
&& {
|
|
||||||
printf 'succeeded while expecting failure due to submodule\n' >/dev/stderr
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
# Should succeed
|
|
||||||
darwin-rebuild build \
|
|
||||||
--flake /tmp/test-nix-darwin-submodules?submodules=1#simple \
|
|
||||||
--override-input nix-darwin . \
|
|
||||||
--override-input nixpkgs nixpkgs/${{ env.CURRENT_STABLE_CHANNEL }} \
|
|
||||||
|
|
||||||
install-flake-against-unstable:
|
install-flake-against-unstable:
|
||||||
runs-on: macos-12
|
runs-on: macos-13
|
||||||
timeout-minutes: 30
|
timeout-minutes: 30
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- name: Install nix from current unstable channel
|
- name: Install nix from current unstable channel
|
||||||
uses: cachix/install-nix-action@v27
|
uses: cachix/install-nix-action@v30
|
||||||
with:
|
with:
|
||||||
install_url: https://releases.nixos.org/nix/nix-2.24.6/install
|
install_url: https://releases.nixos.org/nix/nix-2.24.9/install
|
||||||
- name: Install nix-darwin
|
- name: Install nix-darwin
|
||||||
run: |
|
run: |
|
||||||
mkdir -p ~/.config/nix-darwin
|
mkdir -p ~/.config/nix-darwin
|
||||||
|
@ -231,75 +193,30 @@ jobs:
|
||||||
nix flake init -t $darwin
|
nix flake init -t $darwin
|
||||||
nixConfHash=$(shasum -a 256 /etc/nix/nix.conf | cut -d ' ' -f 1)
|
nixConfHash=$(shasum -a 256 /etc/nix/nix.conf | cut -d ' ' -f 1)
|
||||||
/usr/bin/sed -i.bak \
|
/usr/bin/sed -i.bak \
|
||||||
"s/# nix.package = pkgs.nix;/nix.settings.access-tokens = [ \"github.com=\${{ secrets.GITHUB_TOKEN }}\" ]; environment.etc.\"nix\/nix.conf\".knownSha256Hashes = [ \"$nixConfHash\" ];/" \
|
"s/# programs.fish.enable = true;/nix.settings.access-tokens = [ \"github.com=\${{ secrets.GITHUB_TOKEN }}\" ]; environment.etc.\"nix\/nix.conf\".knownSha256Hashes = [ \"$nixConfHash\" ];/" \
|
||||||
|
flake.nix
|
||||||
|
/usr/bin/sed -i.bak \
|
||||||
|
's/nixpkgs.hostPlatform = "aarch64-darwin";/nixpkgs.hostPlatform = "'$(nix eval --expr builtins.currentSystem --impure --raw)'";/' \
|
||||||
flake.nix
|
flake.nix
|
||||||
popd
|
popd
|
||||||
nix run .#darwin-rebuild -- \
|
nix run .#darwin-rebuild -- \
|
||||||
switch --flake ~/.config/nix-darwin#simple \
|
switch --flake ~/.config/nix-darwin#simple \
|
||||||
--override-input nix-darwin . \
|
--override-input nix-darwin . \
|
||||||
--override-input nixpkgs nixpkgs/nixpkgs-unstable
|
--override-input nixpkgs nixpkgs/nixpkgs-unstable
|
||||||
- name: Rebuild and activate simple flake, but this time using nix-darwin's flake interface
|
- name: Switch to new configuration
|
||||||
run: |
|
run: |
|
||||||
. /etc/static/bashrc
|
. /etc/bashrc
|
||||||
darwin-rebuild build --flake ./modules/examples/flake#simple --override-input nix-darwin . --override-input nixpkgs nixpkgs/nixpkgs-unstable
|
|
||||||
- name: Test git submodules
|
|
||||||
run: |
|
|
||||||
. /etc/static/bashrc
|
|
||||||
|
|
||||||
mkdir -p /tmp/{test-nix-darwin-submodules,example-submodule}
|
|
||||||
|
|
||||||
pushd /tmp/example-submodule
|
|
||||||
echo '"hello"' > hello.nix
|
|
||||||
git init
|
|
||||||
git add .
|
|
||||||
git commit -m "add a submodule we will import"
|
|
||||||
popd
|
|
||||||
|
|
||||||
cp -a ./modules/examples/. /tmp/test-nix-darwin-submodules
|
|
||||||
cp -a ./modules/examples/flake/flake.nix /tmp/test-nix-darwin-submodules
|
|
||||||
|
|
||||||
pushd /tmp/test-nix-darwin-submodules
|
|
||||||
/usr/bin/sed -i.bak \
|
/usr/bin/sed -i.bak \
|
||||||
'\#modules = \[#s#configuration#configuration ./simple.nix#' \
|
"s/pkgs.vim/pkgs.hello/" \
|
||||||
./flake.nix
|
~/.config/nix-darwin/flake.nix
|
||||||
/usr/bin/sed -i.bak \
|
|
||||||
's#pkgs.vim#pkgs."${import ./submodule-test/hello.nix}"#' \
|
|
||||||
./simple.nix
|
|
||||||
git init
|
|
||||||
git add flake.nix simple.nix
|
|
||||||
git \
|
|
||||||
-c protocol.file.allow=always \
|
|
||||||
submodule add /tmp/example-submodule submodule-test
|
|
||||||
popd
|
|
||||||
|
|
||||||
# Should fail
|
darwin-rebuild switch --flake ~/.config/nix-darwin#simple \
|
||||||
darwin-rebuild build \
|
|
||||||
--flake /tmp/test-nix-darwin-submodules#simple \
|
|
||||||
--override-input nix-darwin . \
|
|
||||||
--override-input nixpkgs nixpkgs/nixpkgs-unstable \
|
|
||||||
&& {
|
|
||||||
printf 'succeeded while expecting failure due to submodule\n' >/dev/stderr
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
# Should also fail
|
|
||||||
darwin-rebuild build \
|
|
||||||
--flake /tmp/test-nix-darwin-submodules?submodules=0#simple \
|
|
||||||
--override-input nix-darwin . \
|
|
||||||
--override-input nixpkgs nixpkgs/nixpkgs-unstable \
|
|
||||||
&& {
|
|
||||||
printf 'succeeded while expecting failure due to submodule\n' >/dev/stderr
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
# Should succeed
|
|
||||||
darwin-rebuild build \
|
|
||||||
--flake /tmp/test-nix-darwin-submodules?submodules=1#simple \
|
|
||||||
--override-input nix-darwin . \
|
--override-input nix-darwin . \
|
||||||
--override-input nixpkgs nixpkgs/nixpkgs-unstable
|
--override-input nixpkgs nixpkgs/nixpkgs-unstable
|
||||||
|
|
||||||
# Should also succeed
|
hello
|
||||||
darwin-rebuild build \
|
- name: Test uninstallation of nix-darwin
|
||||||
--flake git+file:///tmp/test-nix-darwin-submodules?submodules=1#simple \
|
run: |
|
||||||
--override-input nix-darwin . \
|
nix run .#darwin-uninstaller --override-input nixpkgs nixpkgs/nixpkgs-unstable
|
||||||
--override-input nixpkgs nixpkgs/nixpkgs-unstable
|
nix run .#darwin-uninstaller.tests.uninstaller --override-input nixpkgs nixpkgs/nixpkgs-unstable
|
||||||
|
|
10
.github/workflows/update-manual.yml
vendored
10
.github/workflows/update-manual.yml
vendored
|
@ -3,25 +3,23 @@ on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
paths:
|
|
||||||
- '**.nix'
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
update-manual:
|
update-manual:
|
||||||
runs-on: macos-12
|
runs-on: macos-13
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
# So that we fetch all branches, since we need to checkout the `gh-pages` branch later.
|
# So that we fetch all branches, since we need to checkout the `gh-pages` branch later.
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Install Nix
|
- name: Install Nix
|
||||||
uses: cachix/install-nix-action@v27
|
uses: cachix/install-nix-action@v30
|
||||||
|
|
||||||
- name: Build manual
|
- name: Build manual
|
||||||
run: |
|
run: |
|
||||||
nix-build ./release.nix -I nixpkgs=channel:nixpkgs-24.05-darwin -I darwin=. -A manualHTML
|
nix build .#manualHTML
|
||||||
|
|
||||||
- name: Push update to manual
|
- name: Push update to manual
|
||||||
run: |
|
run: |
|
||||||
|
|
143
README.md
143
README.md
|
@ -2,80 +2,30 @@
|
||||||
|
|
||||||
# nix-darwin
|
# nix-darwin
|
||||||
|
|
||||||

|
[](https://github.com/LnL7/nix-darwin/actions/workflows/test.yml)
|
||||||
|
|
||||||
Nix modules for darwin, `/etc/nixos/configuration.nix` for macOS.
|
Nix modules for darwin, `/etc/nixos/configuration.nix` for macOS.
|
||||||
|
|
||||||
This project aims to bring the convenience of a declarative system approach to macOS.
|
This project aims to bring the convenience of a declarative system approach to macOS.
|
||||||
nix-darwin is built up around [Nixpkgs](https://github.com/NixOS/nixpkgs), quite similar to [NixOS](https://nixos.org/).
|
nix-darwin is built up around [Nixpkgs](https://github.com/NixOS/nixpkgs), quite similar to [NixOS](https://nixos.org/).
|
||||||
|
|
||||||
## Installing
|
## Prerequisites
|
||||||
|
|
||||||
To install nix-darwin, a working installation of [Nix](https://github.com/NixOS/nix#installation) is required.
|
The only prerequisite is a Nix implementation, both Nix and Lix are supported.
|
||||||
|
|
||||||
If you wish to use nix-darwin with flakes, please refer to the [flakes](#flakes) section.
|
As the official Nix installer does not include an automated uninstaller, and manual uninstallation on macOS is a complex process, we recommend using one of the following installers instead:
|
||||||
|
|
||||||
```bash
|
- The [Nix installer from Determinate Systems](https://github.com/DeterminateSystems/nix-installer?tab=readme-ov-file#determinate-nix-installer) is only recommended for use with flake-based setups. **Make sure you use it without the `--determinate` flag**. The `--determinate` flag installs the Determinate Nix distribution which does not work out of the box with nix-darwin.
|
||||||
nix-build https://github.com/LnL7/nix-darwin/archive/master.tar.gz -A installer
|
* The [Lix installer](https://lix.systems/install/#on-any-other-linuxmacos-system) supports both flake-based and channel-based setups.
|
||||||
./result/bin/darwin-installer
|
|
||||||
```
|
|
||||||
|
|
||||||
> NOTE: the system activation scripts don't overwrite existing etc files, so files like `/etc/bashrc` and `/etc/zshrc` won't be
|
|
||||||
> updated by default. If you didn't use the installer or skipped some of the options you'll have to take care of this yourself.
|
|
||||||
> Either modify the existing file to source/import the one from `/etc/static` or remove it. Some examples:
|
|
||||||
|
|
||||||
- `mv /etc/bashrc /etc/bashrc.before-nix-darwin`
|
|
||||||
- `echo 'if test -e /etc/static/bashrc; then . /etc/static/bashrc; fi' | sudo tee -a /etc/bashrc`
|
|
||||||
|
|
||||||
## Updating
|
## Getting started
|
||||||
|
|
||||||
The installer will configure a channel for this repository.
|
Despite being an experimental feature in Nix currently, nix-darwin recommends that beginners use flakes to manage their nix-darwin configurations.
|
||||||
|
|
||||||
```bash
|
<details>
|
||||||
nix-channel --update darwin
|
<summary>Flakes (Recommended for beginners)</summary>
|
||||||
darwin-rebuild changelog
|
|
||||||
```
|
|
||||||
|
|
||||||
> NOTE: If you are using Nix as a daemon service the channel for that will be owned by root.
|
|
||||||
> Use `sudo -i nix-channel --update darwin` instead.
|
|
||||||
|
|
||||||
## Uninstalling
|
|
||||||
|
|
||||||
To run the latest version of the uninstaller, you can run the following command:
|
|
||||||
|
|
||||||
```
|
|
||||||
nix --extra-experimental-features "nix-command flakes" run nix-darwin#darwin-uninstaller
|
|
||||||
```
|
|
||||||
|
|
||||||
If that command doesn't work for you, you can try the locally installed uninstaller:
|
|
||||||
|
|
||||||
```
|
|
||||||
darwin-uninstaller
|
|
||||||
```
|
|
||||||
|
|
||||||
## Example configuration
|
|
||||||
|
|
||||||
Configuration lives in `~/.nixpkgs/darwin-configuration.nix`. Check out
|
|
||||||
[modules/examples](https://github.com/LnL7/nix-darwin/tree/master/modules/examples) for some example configurations.
|
|
||||||
|
|
||||||
```nix
|
|
||||||
{ pkgs, ... }:
|
|
||||||
{
|
|
||||||
# List packages installed in system profile. To search by name, run:
|
|
||||||
# $ nix-env -qaP | grep wget
|
|
||||||
environment.systemPackages =
|
|
||||||
[ pkgs.vim
|
|
||||||
];
|
|
||||||
|
|
||||||
# Auto upgrade nix package and the daemon service.
|
|
||||||
services.nix-daemon.enable = true;
|
|
||||||
nix.package = pkgs.nix;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Flakes
|
|
||||||
|
|
||||||
nix-darwin aims for both non-flake and flake configurations to be well supported despite flakes being an experimental feature in Nix.
|
|
||||||
|
|
||||||
### Step 1. Creating `flake.nix`
|
### Step 1. Creating `flake.nix`
|
||||||
|
|
||||||
|
@ -128,7 +78,7 @@ Make sure to set `nixpkgs.hostPlatform` in your `configuration.nix` to either `x
|
||||||
|
|
||||||
### Step 2. Installing `nix-darwin`
|
### Step 2. Installing `nix-darwin`
|
||||||
|
|
||||||
Instead of using `darwin-installer`, you can just run `darwin-rebuild switch` to install nix-darwin. As `darwin-rebuild` won't be installed in your `PATH` yet, you can use the following command:
|
Unlike NixOS, `nix-darwin` does not have an installer, you can just run `darwin-rebuild switch` to install nix-darwin. As `darwin-rebuild` won't be installed in your `PATH` yet, you can use the following command:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
nix run nix-darwin -- switch --flake ~/.config/nix-darwin
|
nix run nix-darwin -- switch --flake ~/.config/nix-darwin
|
||||||
|
@ -160,34 +110,67 @@ nix-darwin.lib.darwinSystem {
|
||||||
{ pkgs, lib, inputs }:
|
{ pkgs, lib, inputs }:
|
||||||
# inputs.self, inputs.nix-darwin, and inputs.nixpkgs can be accessed here
|
# inputs.self, inputs.nix-darwin, and inputs.nixpkgs can be accessed here
|
||||||
```
|
```
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Channels</summary>
|
||||||
|
|
||||||
|
### Step 1. Creating `configuration.nix`
|
||||||
|
|
||||||
|
Copy the [simple](./modules/examples/simple.nix) example to `~/.config/nix-darwin/configuration.nix`.
|
||||||
|
|
||||||
|
### Step 2. Adding `nix-darwin` channel
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nix-channel --add https://github.com/LnL7/nix-darwin/archive/master.tar.gz darwin
|
||||||
|
nix-channel --update
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 3. Installing `nix-darwin`
|
||||||
|
|
||||||
|
To install `nix-darwin`, you can just run `darwin-rebuild switch` to install nix-darwin. As `darwin-rebuild` won't be installed in your `PATH` yet, you can use the following command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nix-build https://github.com/LnL7/nix-darwin/archive/master.tar.gz -A darwin-rebuild
|
||||||
|
./result/bin/darwin-rebuild switch -I darwin-config=$HOME/.config/nix-darwin/configuration.nix
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 4. Using `nix-darwin`
|
||||||
|
|
||||||
|
After installing, you can run `darwin-rebuild` to apply changes to your system:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
darwin-rebuild switch
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 5. Updating `nix-darwin`
|
||||||
|
|
||||||
|
You can update `nix-darwin` using the following command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nix-channel --update darwin
|
||||||
|
```
|
||||||
|
</details>
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
Reference documentation of all the options is available [here](https://daiderd.com/nix-darwin/manual/index.html).
|
`darwin-help` will open up a local copy of the reference documentation, it can also be found online [here](https://daiderd.com/nix-darwin/manual/index.html).
|
||||||
This can also be accessed locally using `man 5 configuration.nix`.
|
|
||||||
|
|
||||||
`darwin-help` will open a HTML version of the manpage in the default browser.
|
The documentation is also available as manpages by running `man 5 configuration.nix`.
|
||||||
|
|
||||||
Furthermore there's `darwin-option` to introspect the settings of a system and its available options.
|
## Uninstalling
|
||||||
> NOTE: `darwin-option` is only available to non-flake installations.
|
|
||||||
|
To run the latest version of the uninstaller, you can run the following command:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ darwin-option services.activate-system.enable
|
nix --extra-experimental-features "nix-command flakes" run nix-darwin#darwin-uninstaller
|
||||||
Value:
|
|
||||||
true
|
|
||||||
|
|
||||||
Default:
|
|
||||||
false
|
|
||||||
|
|
||||||
Example:
|
|
||||||
no example
|
|
||||||
|
|
||||||
Description:
|
|
||||||
Whether to activate system at boot time.
|
|
||||||
```
|
```
|
||||||
|
|
||||||
There's also a small wiki https://github.com/LnL7/nix-darwin/wiki about
|
If that command doesn't work for you, you can try the locally installed uninstaller:
|
||||||
specific topics, like macOS upgrades.
|
|
||||||
|
```
|
||||||
|
darwin-uninstaller
|
||||||
|
```
|
||||||
|
|
||||||
## Tests
|
## Tests
|
||||||
|
|
||||||
|
|
21
default.nix
21
default.nix
|
@ -1,8 +1,8 @@
|
||||||
{ nixpkgs ? <nixpkgs>
|
{ nixpkgs ? <nixpkgs>
|
||||||
, configuration ? <darwin-config>
|
, configuration ? <darwin-config>
|
||||||
, lib ? pkgs.lib
|
|
||||||
, pkgs ? import nixpkgs { inherit system; }
|
|
||||||
, system ? builtins.currentSystem
|
, system ? builtins.currentSystem
|
||||||
|
, pkgs ? import nixpkgs { inherit system; }
|
||||||
|
, lib ? pkgs.lib
|
||||||
}:
|
}:
|
||||||
|
|
||||||
let
|
let
|
||||||
|
@ -15,20 +15,9 @@ let
|
||||||
nixpkgs.system = lib.mkDefault system;
|
nixpkgs.system = lib.mkDefault system;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# The source code of this repo needed by the installer.
|
|
||||||
nix-darwin = lib.cleanSource (
|
|
||||||
lib.cleanSourceWith {
|
|
||||||
# We explicitly specify a name here otherwise `cleanSource` will use the
|
|
||||||
# basename of ./. which might be different for different clones of this
|
|
||||||
# repo leading to non-reproducible outputs.
|
|
||||||
name = "nix-darwin";
|
|
||||||
src = ./.;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
in
|
in
|
||||||
|
|
||||||
eval // {
|
eval // {
|
||||||
installer = pkgs.callPackage ./pkgs/darwin-installer { inherit nix-darwin; };
|
darwin-uninstaller = pkgs.callPackage ./pkgs/darwin-uninstaller { };
|
||||||
uninstaller = pkgs.callPackage ./pkgs/darwin-uninstaller { };
|
|
||||||
|
inherit (pkgs.callPackage ./pkgs/nix-tools { }) darwin-option darwin-rebuild darwin-version;
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,11 +79,17 @@ in rec {
|
||||||
'@DARWIN_OPTIONS_JSON@' \
|
'@DARWIN_OPTIONS_JSON@' \
|
||||||
${optionsJSON}/share/doc/darwin/options.json
|
${optionsJSON}/share/doc/darwin/options.json
|
||||||
|
|
||||||
|
# Pass --redirects option if nixos-render-docs supports it
|
||||||
|
if nixos-render-docs manual html --help | grep --silent -E '^\s+--redirects\s'; then
|
||||||
|
redirects_opt="--redirects ${./redirects.json}"
|
||||||
|
fi
|
||||||
|
|
||||||
# TODO: --manpage-urls?
|
# TODO: --manpage-urls?
|
||||||
nixos-render-docs -j $NIX_BUILD_CORES manual html \
|
nixos-render-docs -j $NIX_BUILD_CORES manual html \
|
||||||
--manpage-urls ${pkgs.writeText "manpage-urls.json" "{}"} \
|
--manpage-urls ${pkgs.writeText "manpage-urls.json" "{}"} \
|
||||||
--revision ${lib.escapeShellArg revision} \
|
--revision ${lib.escapeShellArg revision} \
|
||||||
--generator "nixos-render-docs ${lib.version}" \
|
--generator "nixos-render-docs ${lib.version}" \
|
||||||
|
$redirects_opt \
|
||||||
--stylesheet style.css \
|
--stylesheet style.css \
|
||||||
--stylesheet highlightjs/mono-blue.css \
|
--stylesheet highlightjs/mono-blue.css \
|
||||||
--script ./highlightjs/highlight.pack.js \
|
--script ./highlightjs/highlight.pack.js \
|
||||||
|
@ -118,18 +124,18 @@ in rec {
|
||||||
|
|
||||||
# TODO: get these parameterized in upstream nixos-render-docs
|
# TODO: get these parameterized in upstream nixos-render-docs
|
||||||
sed -i -e '
|
sed -i -e '
|
||||||
/^\.TH / s|NixOS|Darwin|g
|
/^\.TH / s|NixOS|nix-darwin|g
|
||||||
|
|
||||||
/^\.SH "NAME"$/ {
|
/^\.SH "NAME"$/ {
|
||||||
N
|
N
|
||||||
s|NixOS|Darwin|g
|
s|NixOS|nix-darwin|g
|
||||||
}
|
}
|
||||||
|
|
||||||
/^\.SH "DESCRIPTION"$/ {
|
/^\.SH "DESCRIPTION"$/ {
|
||||||
N; N
|
N; N
|
||||||
s|/etc/nixos/configuration|configuration|g
|
s|/etc/nixos/configuration|configuration|g
|
||||||
s|NixOS|Darwin|g
|
s|NixOS|nix-darwin|g
|
||||||
s|nixos|darwin|g
|
s|nixos|nix-darwin|g
|
||||||
}
|
}
|
||||||
|
|
||||||
/\.SH "AUTHORS"$/ {
|
/\.SH "AUTHORS"$/ {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Darwin Configuration Options {#book-darwin-manual}
|
# nix-darwin Configuration Options {#book-darwin-manual}
|
||||||
## Version @DARWIN_VERSION@
|
## Version @DARWIN_VERSION@
|
||||||
|
|
||||||
```{=include=} options
|
```{=include=} options
|
||||||
|
|
5
doc/manual/redirects.json
Normal file
5
doc/manual/redirects.json
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"book-darwin-manual": [
|
||||||
|
"index.html#book-darwin-manual"
|
||||||
|
]
|
||||||
|
}
|
33
flake.nix
33
flake.nix
|
@ -1,9 +1,15 @@
|
||||||
{
|
{
|
||||||
# WARNING this is very much still experimental.
|
|
||||||
description = "A collection of darwin modules";
|
description = "A collection of darwin modules";
|
||||||
|
|
||||||
outputs = { self, nixpkgs }: let
|
outputs = { self, nixpkgs }: let
|
||||||
forAllSystems = nixpkgs.lib.genAttrs [ "aarch64-darwin" "x86_64-darwin" ];
|
forAllSystems = nixpkgs.lib.genAttrs [ "aarch64-darwin" "x86_64-darwin" "aarch64-linux" "x86_64-linux" ];
|
||||||
|
forDarwinSystems = nixpkgs.lib.genAttrs [ "aarch64-darwin" "x86_64-darwin" ];
|
||||||
|
|
||||||
|
jobs = forAllSystems (system: import ./release.nix {
|
||||||
|
inherit nixpkgs system;
|
||||||
|
|
||||||
|
nix-darwin = self;
|
||||||
|
});
|
||||||
in {
|
in {
|
||||||
lib = {
|
lib = {
|
||||||
evalConfig = import ./eval-config.nix;
|
evalConfig = import ./eval-config.nix;
|
||||||
|
@ -48,7 +54,6 @@
|
||||||
|
|
||||||
darwinModules.hydra = ./modules/examples/hydra.nix;
|
darwinModules.hydra = ./modules/examples/hydra.nix;
|
||||||
darwinModules.lnl = ./modules/examples/lnl.nix;
|
darwinModules.lnl = ./modules/examples/lnl.nix;
|
||||||
darwinModules.ofborg = ./modules/examples/ofborg.nix;
|
|
||||||
darwinModules.simple = ./modules/examples/simple.nix;
|
darwinModules.simple = ./modules/examples/simple.nix;
|
||||||
|
|
||||||
templates.default = {
|
templates.default = {
|
||||||
|
@ -56,23 +61,11 @@
|
||||||
description = "nix flake init -t nix-darwin";
|
description = "nix flake init -t nix-darwin";
|
||||||
};
|
};
|
||||||
|
|
||||||
checks = forAllSystems (system: let
|
checks = forDarwinSystems (system: jobs.${system}.tests // jobs.${system}.examples);
|
||||||
simple = self.lib.darwinSystem {
|
|
||||||
modules = [
|
|
||||||
self.darwinModules.simple
|
|
||||||
{ nixpkgs.hostPlatform = system; }
|
|
||||||
];
|
|
||||||
};
|
|
||||||
in {
|
|
||||||
simple = simple.system;
|
|
||||||
|
|
||||||
inherit (simple.config.system.build.manual)
|
packages = forAllSystems (system: {
|
||||||
optionsJSON
|
inherit (jobs.${system}.docs) manualHTML manpages optionsJSON;
|
||||||
manualHTML
|
} // (nixpkgs.lib.optionalAttrs (nixpkgs.lib.hasSuffix "darwin" system) (let
|
||||||
manpages;
|
|
||||||
});
|
|
||||||
|
|
||||||
packages = forAllSystems (system: let
|
|
||||||
pkgs = import nixpkgs {
|
pkgs = import nixpkgs {
|
||||||
inherit system;
|
inherit system;
|
||||||
overlays = [ self.overlays.default ];
|
overlays = [ self.overlays.default ];
|
||||||
|
@ -81,6 +74,6 @@
|
||||||
default = self.packages.${system}.darwin-rebuild;
|
default = self.packages.${system}.darwin-rebuild;
|
||||||
|
|
||||||
inherit (pkgs) darwin-option darwin-rebuild darwin-version darwin-uninstaller;
|
inherit (pkgs) darwin-option darwin-rebuild darwin-version darwin-uninstaller;
|
||||||
});
|
})));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,11 @@ in
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
(mkRenamedOptionModule ["environment" "postBuild"] ["environment" "extraSetup"])
|
(mkRenamedOptionModule ["environment" "postBuild"] ["environment" "extraSetup"])
|
||||||
|
(mkRemovedOptionModule [ "environment" "loginShell" ] ''
|
||||||
|
This option was only used to change the default command in tmux.
|
||||||
|
|
||||||
|
This has been removed in favour of changing the default command or default shell in tmux directly.
|
||||||
|
'')
|
||||||
];
|
];
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
|
@ -74,12 +79,6 @@ in
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
environment.loginShell = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "$SHELL -l";
|
|
||||||
description = "Configure default login shell.";
|
|
||||||
};
|
|
||||||
|
|
||||||
environment.variables = mkOption {
|
environment.variables = mkOption {
|
||||||
type = types.attrsOf (types.either types.str (types.listOf types.str));
|
type = types.attrsOf (types.either types.str (types.listOf types.str));
|
||||||
default = {};
|
default = {};
|
||||||
|
@ -198,6 +197,7 @@ in
|
||||||
name = "system-path";
|
name = "system-path";
|
||||||
paths = cfg.systemPackages;
|
paths = cfg.systemPackages;
|
||||||
postBuild = cfg.extraSetup;
|
postBuild = cfg.extraSetup;
|
||||||
|
ignoreCollisions = true;
|
||||||
inherit (cfg) pathsToLink extraOutputsToInstall;
|
inherit (cfg) pathsToLink extraOutputsToInstall;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
description = "Example Darwin system flake";
|
description = "Example nix-darwin system flake";
|
||||||
|
|
||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||||
|
@ -16,15 +16,10 @@
|
||||||
[ pkgs.vim
|
[ pkgs.vim
|
||||||
];
|
];
|
||||||
|
|
||||||
# Auto upgrade nix package and the daemon service.
|
|
||||||
services.nix-daemon.enable = true;
|
|
||||||
# nix.package = pkgs.nix;
|
|
||||||
|
|
||||||
# Necessary for using flakes on this system.
|
# Necessary for using flakes on this system.
|
||||||
nix.settings.experimental-features = "nix-command flakes";
|
nix.settings.experimental-features = "nix-command flakes";
|
||||||
|
|
||||||
# Create /etc/zshrc that loads the nix-darwin environment.
|
# Enable alternative shell support in nix-darwin.
|
||||||
programs.zsh.enable = true; # default shell on catalina
|
|
||||||
# programs.fish.enable = true;
|
# programs.fish.enable = true;
|
||||||
|
|
||||||
# Set Git commit hash for darwin-version.
|
# Set Git commit hash for darwin-version.
|
||||||
|
@ -35,7 +30,7 @@
|
||||||
system.stateVersion = 5;
|
system.stateVersion = 5;
|
||||||
|
|
||||||
# The platform the configuration will be used on.
|
# The platform the configuration will be used on.
|
||||||
nixpkgs.hostPlatform = "x86_64-darwin";
|
nixpkgs.hostPlatform = "aarch64-darwin";
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
@ -44,8 +39,5 @@
|
||||||
darwinConfigurations."simple" = nix-darwin.lib.darwinSystem {
|
darwinConfigurations."simple" = nix-darwin.lib.darwinSystem {
|
||||||
modules = [ configuration ];
|
modules = [ configuration ];
|
||||||
};
|
};
|
||||||
|
|
||||||
# Expose the package set, including overlays, for convenience.
|
|
||||||
darwinPackages = self.darwinConfigurations."simple".pkgs;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,25 +1,14 @@
|
||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
let
|
let
|
||||||
environment = concatStringsSep " "
|
environment = lib.concatStringsSep " "
|
||||||
[ "NIX_REMOTE=daemon"
|
[ "NIX_REMOTE=daemon"
|
||||||
"NIX_SSL_CERT_FILE=${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"
|
"NIX_SSL_CERT_FILE=${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"
|
||||||
];
|
];
|
||||||
in
|
in
|
||||||
|
|
||||||
{
|
{
|
||||||
# Create /etc/bashrc that loads the nix-darwin environment.
|
nix.settings.substituters = [ "http://cache1" ];
|
||||||
programs.bash.enable = true;
|
|
||||||
programs.bash.enableCompletion = false;
|
|
||||||
|
|
||||||
# Recreate /run/current-system symlink after boot.
|
|
||||||
services.activate-system.enable = true;
|
|
||||||
|
|
||||||
services.nix-daemon.enable = true;
|
|
||||||
|
|
||||||
nix.settings.substituters = [ http://cache1 ];
|
|
||||||
nix.settings.trusted-public-keys = [ "cache.daiderd.com-1:R8KOWZ8lDaLojqD+v9dzXAqGn29gEzPTTbr/GIpCTrI=" ];
|
nix.settings.trusted-public-keys = [ "cache.daiderd.com-1:R8KOWZ8lDaLojqD+v9dzXAqGn29gEzPTTbr/GIpCTrI=" ];
|
||||||
|
|
||||||
nix.settings.trusted-users = [ "@admin" "@hydra" ];
|
nix.settings.trusted-users = [ "@admin" "@hydra" ];
|
||||||
|
@ -31,7 +20,7 @@ in
|
||||||
nix.gc.automatic = true;
|
nix.gc.automatic = true;
|
||||||
nix.gc.options = "--max-freed $((25 * 1024**3 - 1024 * $(df -P -k /nix/store | tail -n 1 | awk '{ print $4 }')))";
|
nix.gc.options = "--max-freed $((25 * 1024**3 - 1024 * $(df -P -k /nix/store | tail -n 1 | awk '{ print $4 }')))";
|
||||||
|
|
||||||
environment.etc."per-user/hydra/ssh/authorized_keys".text = concatStringsSep "\n"
|
environment.etc."per-user/hydra/ssh/authorized_keys".text = lib.concatStringsSep "\n"
|
||||||
[ "command=\"${environment} ${config.nix.package}/bin/nix-store --serve --write\" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCVsc0pHGsskoayziMhA2e59bHPWe0bbKgusmqhuJFBGQ1BAk9UmPzKCWE3nCiV6CLD1+SygVkBjb06DYtc+94BnzviCa9qZtL0G4+2vhp6x8OvXh8xlf/eWw3k5MWlvu+kjJFpbW8wHWTiUqzH+uEeHklAosT0lFNjiIYd/Vs3JAezhUR62a6c7ZjWOd5F7ALGEKzOiwC4i37kSgGsIWNCbe0Ku7gyr718zhMGeyxax6saHhnkSpIB+7d6oHhKeiJSFMWctNmz1/qxXUPbxNaJvqgdKlVHhN+B7x/TIbkVr5pTC59Okx9LTcpflFIv79VT+Gf1K7VypZpSvJjG0xFRt8iDs1+ssWFBfvpo94vUbZ+ZwMDcBGR5iJeO41Gj5fYn5aaDl32RXfJ9Fkwael1L6pcXtkIc66jk+KQQpgoeNj8Y3Emntpqva/2AM41wDDvr5tKp5KhEKFLM95CoiWq+g88pZLcpqLK7wooDVqNkVUEbMaj9lBN0AzU9mcsIRGvTa6CmWAdBvwqS2fRZD97Oarqct9AWgb0X6mOUq9BJNi4i4xvjgnVkylLwtLUnibR/PeXMtkb9bv6BEZXNf5ACqxSjKXJyaIHI65I5TILCr5eEgaujgvmkREn6U3T1NZAUIeVe9aVYLqehYh79OHUBzggoHqidRrXBB/6zdg9UgQ=="
|
[ "command=\"${environment} ${config.nix.package}/bin/nix-store --serve --write\" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCVsc0pHGsskoayziMhA2e59bHPWe0bbKgusmqhuJFBGQ1BAk9UmPzKCWE3nCiV6CLD1+SygVkBjb06DYtc+94BnzviCa9qZtL0G4+2vhp6x8OvXh8xlf/eWw3k5MWlvu+kjJFpbW8wHWTiUqzH+uEeHklAosT0lFNjiIYd/Vs3JAezhUR62a6c7ZjWOd5F7ALGEKzOiwC4i37kSgGsIWNCbe0Ku7gyr718zhMGeyxax6saHhnkSpIB+7d6oHhKeiJSFMWctNmz1/qxXUPbxNaJvqgdKlVHhN+B7x/TIbkVr5pTC59Okx9LTcpflFIv79VT+Gf1K7VypZpSvJjG0xFRt8iDs1+ssWFBfvpo94vUbZ+ZwMDcBGR5iJeO41Gj5fYn5aaDl32RXfJ9Fkwael1L6pcXtkIc66jk+KQQpgoeNj8Y3Emntpqva/2AM41wDDvr5tKp5KhEKFLM95CoiWq+g88pZLcpqLK7wooDVqNkVUEbMaj9lBN0AzU9mcsIRGvTa6CmWAdBvwqS2fRZD97Oarqct9AWgb0X6mOUq9BJNi4i4xvjgnVkylLwtLUnibR/PeXMtkb9bv6BEZXNf5ACqxSjKXJyaIHI65I5TILCr5eEgaujgvmkREn6U3T1NZAUIeVe9aVYLqehYh79OHUBzggoHqidRrXBB/6zdg9UgQ=="
|
||||||
"command=\"${environment} ${config.nix.package}/bin/nix-store --serve --write\" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCnubA1pRqlpoAXkZ1q5nwhqi1RY2z840wFLFDj7vAMSups9E2U8PNIVtuVYApZpkBWIpzD4GGbQTF5Itnu5uBpJswc2Yat9yGWO/guuVyXIaRoBIM0Pg1WBWcWsz+k4rNludu9UQ74FHqEiqZIuIuOcgV+RIZn8xQlGt2kUqN9TWboHhZz8Zhx7EtGSJH6MJRLn3mA/pPjOF6k1jiiFG1pVDuqBTZPANkelWYCWAJ46jCyhxXltWE/jkBYGc/XbB8yT7DFE1XC6TVsSEp68R9PhVG3yqxqY06sniEyduSoGt/TDr6ycERd93bvLElXFATes85YiFszeaUgayYSKwQPe0q7YeHMhIXL0UYJYaKVVgT9saFDiHDzde7kKe+NA+J4+TbIk7Y/Ywn0jepsYV13M7TyEqgqbu9fvVGF3JI9+4g0m1gAzHTa7n6iiAedtz+Pi79uCEpRD2hWSSoLWroyPlep8j1p2tygtFsrieePEukesoToCTwqg1Ejnjh+yKdtUbc6xpyRvl3hKeO8QbCpfaaVd27e4vE4lP2JMW6nOo8b0wlVXQIFe5K2zh52q1MSwhLAq6Kg8oPmgj0lru4IivmPc+/NVwd3Qj3E9ZB8LRfTesfbcxHrC8lF5dL/QpLMeLwebrwCxL19gI0kxmDIaUQuHSyP3B2z+EmBKcN/Xw=="
|
"command=\"${environment} ${config.nix.package}/bin/nix-store --serve --write\" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCnubA1pRqlpoAXkZ1q5nwhqi1RY2z840wFLFDj7vAMSups9E2U8PNIVtuVYApZpkBWIpzD4GGbQTF5Itnu5uBpJswc2Yat9yGWO/guuVyXIaRoBIM0Pg1WBWcWsz+k4rNludu9UQ74FHqEiqZIuIuOcgV+RIZn8xQlGt2kUqN9TWboHhZz8Zhx7EtGSJH6MJRLn3mA/pPjOF6k1jiiFG1pVDuqBTZPANkelWYCWAJ46jCyhxXltWE/jkBYGc/XbB8yT7DFE1XC6TVsSEp68R9PhVG3yqxqY06sniEyduSoGt/TDr6ycERd93bvLElXFATes85YiFszeaUgayYSKwQPe0q7YeHMhIXL0UYJYaKVVgT9saFDiHDzde7kKe+NA+J4+TbIk7Y/Ywn0jepsYV13M7TyEqgqbu9fvVGF3JI9+4g0m1gAzHTa7n6iiAedtz+Pi79uCEpRD2hWSSoLWroyPlep8j1p2tygtFsrieePEukesoToCTwqg1Ejnjh+yKdtUbc6xpyRvl3hKeO8QbCpfaaVd27e4vE4lP2JMW6nOo8b0wlVXQIFe5K2zh52q1MSwhLAq6Kg8oPmgj0lru4IivmPc+/NVwd3Qj3E9ZB8LRfTesfbcxHrC8lF5dL/QpLMeLwebrwCxL19gI0kxmDIaUQuHSyP3B2z+EmBKcN/Xw=="
|
||||||
];
|
];
|
||||||
|
@ -53,4 +42,6 @@ in
|
||||||
chown hydra:hydra ~hydra ~hydra/.ssh ~hydra/.ssh/authorized_keys
|
chown hydra:hydra ~hydra ~hydra/.ssh ~hydra/.ssh/authorized_keys
|
||||||
echo "ok"
|
echo "ok"
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
system.stateVersion = 5;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
{ config, lib, inputs, pkgs, ... }:
|
{ config, lib, inputs, pkgs, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
# imports = [ ~/.config/nixpkgs/darwin/local-configuration.nix ];
|
|
||||||
|
|
||||||
# system.patches = [ ./pam.patch ];
|
|
||||||
|
|
||||||
system.defaults.NSGlobalDomain.AppleKeyboardUIMode = 3;
|
system.defaults.NSGlobalDomain.AppleKeyboardUIMode = 3;
|
||||||
system.defaults.NSGlobalDomain.ApplePressAndHoldEnabled = false;
|
system.defaults.NSGlobalDomain.ApplePressAndHoldEnabled = false;
|
||||||
system.defaults.NSGlobalDomain.InitialKeyRepeat = 10;
|
system.defaults.NSGlobalDomain.InitialKeyRepeat = 10;
|
||||||
|
@ -50,13 +46,10 @@
|
||||||
pkgs.gnupg
|
pkgs.gnupg
|
||||||
pkgs.htop
|
pkgs.htop
|
||||||
pkgs.jq
|
pkgs.jq
|
||||||
pkgs.mosh
|
|
||||||
pkgs.ripgrep
|
pkgs.ripgrep
|
||||||
pkgs.shellcheck
|
pkgs.shellcheck
|
||||||
pkgs.vault
|
|
||||||
|
|
||||||
pkgs.qes
|
pkgs.qes
|
||||||
pkgs.darwin-zsh-completions
|
|
||||||
];
|
];
|
||||||
|
|
||||||
services.yabai.enable = true;
|
services.yabai.enable = true;
|
||||||
|
@ -84,7 +77,6 @@
|
||||||
# serviceConfig.ProcessType = "Background";
|
# serviceConfig.ProcessType = "Background";
|
||||||
# };
|
# };
|
||||||
|
|
||||||
services.nix-daemon.enable = true;
|
|
||||||
# services.nix-daemon.enableSocketListener = true;
|
# services.nix-daemon.enableSocketListener = true;
|
||||||
|
|
||||||
nix.extraOptions = ''
|
nix.extraOptions = ''
|
||||||
|
@ -96,7 +88,7 @@
|
||||||
'';
|
'';
|
||||||
|
|
||||||
nix.settings.trusted-public-keys = [ "cache.daiderd.com-1:R8KOWZ8lDaLojqD+v9dzXAqGn29gEzPTTbr/GIpCTrI=" ];
|
nix.settings.trusted-public-keys = [ "cache.daiderd.com-1:R8KOWZ8lDaLojqD+v9dzXAqGn29gEzPTTbr/GIpCTrI=" ];
|
||||||
nix.settings.trusted-substituters = [ https://d3i7ezr9vxxsfy.cloudfront.net ];
|
nix.settings.trusted-substituters = [ "https://d3i7ezr9vxxsfy.cloudfront.net" ];
|
||||||
|
|
||||||
nix.settings.sandbox = true;
|
nix.settings.sandbox = true;
|
||||||
nix.settings.extra-sandbox-paths = [ "/private/tmp" "/private/var/tmp" "/usr/bin/env" ];
|
nix.settings.extra-sandbox-paths = [ "/private/tmp" "/private/var/tmp" "/usr/bin/env" ];
|
||||||
|
@ -199,7 +191,7 @@
|
||||||
# Dotfiles.
|
# Dotfiles.
|
||||||
# programs.vim.package = mkForce pkgs.lnl.vim;
|
# programs.vim.package = mkForce pkgs.lnl.vim;
|
||||||
|
|
||||||
programs.bash.enableCompletion = true;
|
programs.bash.completion.enable = true;
|
||||||
|
|
||||||
programs.zsh.enable = true;
|
programs.zsh.enable = true;
|
||||||
programs.zsh.enableBashCompletion = true;
|
programs.zsh.enableBashCompletion = true;
|
||||||
|
@ -277,7 +269,6 @@
|
||||||
zle -N up-line-or-beginning-search
|
zle -N up-line-or-beginning-search
|
||||||
'';
|
'';
|
||||||
|
|
||||||
environment.loginShell = "${pkgs.zsh}/bin/zsh -l";
|
|
||||||
environment.variables.SHELL = "${pkgs.zsh}/bin/zsh";
|
environment.variables.SHELL = "${pkgs.zsh}/bin/zsh";
|
||||||
|
|
||||||
environment.variables.LANG = "en_US.UTF-8";
|
environment.variables.LANG = "en_US.UTF-8";
|
||||||
|
@ -303,8 +294,6 @@
|
||||||
fi
|
fi
|
||||||
'';
|
'';
|
||||||
|
|
||||||
# environment.darwinConfig = "$HOME/.config/nixpkgs/darwin/configuration.nix";
|
|
||||||
|
|
||||||
nixpkgs.config.allowUnfree = true;
|
nixpkgs.config.allowUnfree = true;
|
||||||
|
|
||||||
nixpkgs.overlays = [
|
nixpkgs.overlays = [
|
||||||
|
@ -332,4 +321,6 @@
|
||||||
|
|
||||||
nix.configureBuildUsers = true;
|
nix.configureBuildUsers = true;
|
||||||
nix.nrBuildUsers = 32;
|
nix.nrBuildUsers = 32;
|
||||||
|
|
||||||
|
system.stateVersion = 5;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
{ config, lib, pkgs, ... }:
|
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
{
|
|
||||||
# Logs are enabled by default.
|
|
||||||
# $ tail -f /var/log/ofborg.log
|
|
||||||
services.ofborg.enable = true;
|
|
||||||
# services.ofborg.configFile = "/var/lib/ofborg/config.json";
|
|
||||||
|
|
||||||
# $ nix-channel --add https://github.com/NixOS/ofborg/archive/released.tar.gz ofborg
|
|
||||||
# $ nix-channel --update
|
|
||||||
services.ofborg.package = (import <ofborg> {}).ofborg.rs;
|
|
||||||
|
|
||||||
# Keep nix-daemon updated.
|
|
||||||
services.nix-daemon.enable = true;
|
|
||||||
|
|
||||||
nix.gc.automatic = true;
|
|
||||||
nix.gc.options = "--max-freed $((25 * 1024**3 - 1024 * $(df -P -k /nix/store | tail -n 1 | awk '{ print $4 }')))";
|
|
||||||
|
|
||||||
# Manage user for ofborg, this enables creating/deleting users
|
|
||||||
# depending on what modules are enabled.
|
|
||||||
users.knownGroups = [ "ofborg" ];
|
|
||||||
users.knownUsers = [ "ofborg" ];
|
|
||||||
|
|
||||||
# Used for backwards compatibility, please read the changelog before changing.
|
|
||||||
# $ darwin-rebuild changelog
|
|
||||||
system.stateVersion = 5;
|
|
||||||
}
|
|
|
@ -7,16 +7,10 @@
|
||||||
[ pkgs.vim
|
[ pkgs.vim
|
||||||
];
|
];
|
||||||
|
|
||||||
# Use a custom configuration.nix location.
|
# Use custom location for configuration.nix.
|
||||||
# $ darwin-rebuild switch -I darwin-config=$HOME/.config/nixpkgs/darwin/configuration.nix
|
environment.darwinConfig = "$HOME/.config/nix-darwin/configuration.nix";
|
||||||
# environment.darwinConfig = "$HOME/.config/nixpkgs/darwin/configuration.nix";
|
|
||||||
|
|
||||||
# Auto upgrade nix package and the daemon service.
|
# Enable alternative shell support in nix-darwin.
|
||||||
# services.nix-daemon.enable = true;
|
|
||||||
# nix.package = pkgs.nix;
|
|
||||||
|
|
||||||
# Create /etc/zshrc that loads the nix-darwin environment.
|
|
||||||
programs.zsh.enable = true; # default shell on catalina
|
|
||||||
# programs.fish.enable = true;
|
# programs.fish.enable = true;
|
||||||
|
|
||||||
# Used for backwards compatibility, please read the changelog before changing.
|
# Used for backwards compatibility, please read the changelog before changing.
|
||||||
|
|
|
@ -38,10 +38,12 @@ in
|
||||||
|
|
||||||
ids.uids = {
|
ids.uids = {
|
||||||
nixbld = lib.mkDefault 350;
|
nixbld = lib.mkDefault 350;
|
||||||
|
_prometheus-node-exporter = 534;
|
||||||
};
|
};
|
||||||
|
|
||||||
ids.gids = {
|
ids.gids = {
|
||||||
nixbld = lib.mkDefault (if config.system.stateVersion < 5 then 30000 else 350);
|
nixbld = lib.mkDefault (if config.system.stateVersion < 5 then 30000 else 350);
|
||||||
|
_prometheus-node-exporter = 534;
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
./system/activation-scripts.nix
|
./system/activation-scripts.nix
|
||||||
./system/applications.nix
|
./system/applications.nix
|
||||||
./system/defaults-write.nix
|
./system/defaults-write.nix
|
||||||
|
./system/defaults/controlcenter.nix
|
||||||
./system/defaults/LaunchServices.nix
|
./system/defaults/LaunchServices.nix
|
||||||
./system/defaults/NSGlobalDomain.nix
|
./system/defaults/NSGlobalDomain.nix
|
||||||
./system/defaults/GlobalPreferences.nix
|
./system/defaults/GlobalPreferences.nix
|
||||||
|
@ -21,6 +22,7 @@
|
||||||
./system/defaults/clock.nix
|
./system/defaults/clock.nix
|
||||||
./system/defaults/dock.nix
|
./system/defaults/dock.nix
|
||||||
./system/defaults/finder.nix
|
./system/defaults/finder.nix
|
||||||
|
./system/defaults/hitoolbox.nix
|
||||||
./system/defaults/screencapture.nix
|
./system/defaults/screencapture.nix
|
||||||
./system/defaults/screensaver.nix
|
./system/defaults/screensaver.nix
|
||||||
./system/defaults/alf.nix
|
./system/defaults/alf.nix
|
||||||
|
@ -52,7 +54,10 @@
|
||||||
./environment
|
./environment
|
||||||
./fonts
|
./fonts
|
||||||
./launchd
|
./launchd
|
||||||
|
./power
|
||||||
|
./power/sleep.nix
|
||||||
./services/activate-system
|
./services/activate-system
|
||||||
|
./services/aerospace
|
||||||
./services/autossh.nix
|
./services/autossh.nix
|
||||||
./services/buildkite-agents.nix
|
./services/buildkite-agents.nix
|
||||||
./services/chunkwm.nix
|
./services/chunkwm.nix
|
||||||
|
@ -72,6 +77,7 @@
|
||||||
./services/mopidy.nix
|
./services/mopidy.nix
|
||||||
./services/monitoring/telegraf.nix
|
./services/monitoring/telegraf.nix
|
||||||
./services/monitoring/netdata.nix
|
./services/monitoring/netdata.nix
|
||||||
|
./services/monitoring/prometheus-node-exporter.nix
|
||||||
./services/netbird.nix
|
./services/netbird.nix
|
||||||
./services/nix-daemon.nix
|
./services/nix-daemon.nix
|
||||||
./services/nix-gc
|
./services/nix-gc
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, ... }:
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
|
|
||||||
|
@ -8,15 +8,16 @@ let
|
||||||
hostnameRegEx = ''^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$'';
|
hostnameRegEx = ''^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$'';
|
||||||
|
|
||||||
emptyList = lst: if lst != [] then lst else ["empty"];
|
emptyList = lst: if lst != [] then lst else ["empty"];
|
||||||
quoteStrings = concatMapStringsSep " " (str: "'${str}'");
|
|
||||||
|
onOff = cond: if cond then "on" else "off";
|
||||||
|
|
||||||
setNetworkServices = optionalString (cfg.knownNetworkServices != []) ''
|
setNetworkServices = optionalString (cfg.knownNetworkServices != []) ''
|
||||||
networkservices=$(networksetup -listallnetworkservices)
|
networkservices=$(networksetup -listallnetworkservices)
|
||||||
${concatMapStringsSep "\n" (srv: ''
|
${concatMapStringsSep "\n" (srv: ''
|
||||||
case "$networkservices" in
|
case "$networkservices" in
|
||||||
*'${srv}'*)
|
*${lib.escapeShellArg srv}*)
|
||||||
networksetup -setdnsservers '${srv}' ${quoteStrings (emptyList cfg.dns)}
|
networksetup -setdnsservers ${lib.escapeShellArgs ([ srv ] ++ (emptyList cfg.dns))}
|
||||||
networksetup -setsearchdomains '${srv}' ${quoteStrings (emptyList cfg.search)}
|
networksetup -setsearchdomains ${lib.escapeShellArgs ([ srv ] ++ (emptyList cfg.search))}
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
'') cfg.knownNetworkServices}
|
'') cfg.knownNetworkServices}
|
||||||
|
@ -94,6 +95,16 @@ in
|
||||||
default = [];
|
default = [];
|
||||||
description = "The list of search paths used when resolving domain names.";
|
description = "The list of search paths used when resolving domain names.";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
networking.wakeOnLan.enable = mkOption {
|
||||||
|
type = types.nullOr types.bool;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Enable Wake-on-LAN for the device.
|
||||||
|
|
||||||
|
Battery powered devices may require being connected to power.
|
||||||
|
'';
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
|
@ -107,6 +118,7 @@ in
|
||||||
echo "configuring networking..." >&2
|
echo "configuring networking..." >&2
|
||||||
|
|
||||||
${optionalString (cfg.computerName != null) ''
|
${optionalString (cfg.computerName != null) ''
|
||||||
|
# shellcheck disable=SC1112
|
||||||
scutil --set ComputerName ${escapeShellArg cfg.computerName}
|
scutil --set ComputerName ${escapeShellArg cfg.computerName}
|
||||||
''}
|
''}
|
||||||
${optionalString (cfg.hostName != null) ''
|
${optionalString (cfg.hostName != null) ''
|
||||||
|
@ -117,6 +129,10 @@ in
|
||||||
''}
|
''}
|
||||||
|
|
||||||
${setNetworkServices}
|
${setNetworkServices}
|
||||||
|
|
||||||
|
${optionalString (cfg.wakeOnLan.enable != null) ''
|
||||||
|
systemsetup -setWakeOnNetworkAccess '${onOff cfg.wakeOnLan.enable}' &> /dev/null
|
||||||
|
''}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -191,9 +191,6 @@ in
|
||||||
description = ''
|
description = ''
|
||||||
Whether to distribute builds to the machines listed in
|
Whether to distribute builds to the machines listed in
|
||||||
{option}`nix.buildMachines`.
|
{option}`nix.buildMachines`.
|
||||||
|
|
||||||
NOTE: This requires services.nix-daemon.enable for a
|
|
||||||
multi-user install.
|
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -527,8 +524,10 @@ in
|
||||||
description = ''
|
description = ''
|
||||||
If set to true, Nix automatically detects files in the store that have
|
If set to true, Nix automatically detects files in the store that have
|
||||||
identical contents, and replaces them with hard links to a single copy.
|
identical contents, and replaces them with hard links to a single copy.
|
||||||
This saves disk space. If set to false (the default), you can still run
|
This saves disk space. If set to false (the default), you can enable
|
||||||
nix-store --optimise to get rid of duplicate files.
|
{option}`nix.optimise.automatic` to run {command}`nix-store --optimise`
|
||||||
|
periodically to get rid of duplicate files. You can also run
|
||||||
|
{command}`nix-store --optimise` manually.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -686,7 +685,7 @@ in
|
||||||
nixPackage
|
nixPackage
|
||||||
pkgs.nix-info
|
pkgs.nix-info
|
||||||
]
|
]
|
||||||
++ optional (config.programs.bash.enableCompletion) pkgs.nix-bash-completions;
|
++ optional (config.programs.bash.completion.enable) pkgs.nix-bash-completions;
|
||||||
|
|
||||||
environment.etc."nix/nix.conf".source = nixConf;
|
environment.etc."nix/nix.conf".source = nixConf;
|
||||||
|
|
||||||
|
@ -761,11 +760,17 @@ in
|
||||||
{ assertion = elem "nixbld" config.users.knownGroups -> elem "nixbld" createdGroups; message = "refusing to delete group nixbld in users.knownGroups, this would break nix"; }
|
{ assertion = elem "nixbld" config.users.knownGroups -> elem "nixbld" createdGroups; message = "refusing to delete group nixbld in users.knownGroups, this would break nix"; }
|
||||||
{ assertion = elem "_nixbld1" config.users.knownGroups -> elem "_nixbld1" createdUsers; message = "refusing to delete user _nixbld1 in users.knownUsers, this would break nix"; }
|
{ assertion = elem "_nixbld1" config.users.knownGroups -> elem "_nixbld1" createdUsers; message = "refusing to delete user _nixbld1 in users.knownUsers, this would break nix"; }
|
||||||
{ assertion = config.users.groups ? "nixbld" -> config.users.groups.nixbld.members != []; message = "refusing to remove all members from nixbld group, this would break nix"; }
|
{ assertion = config.users.groups ? "nixbld" -> config.users.groups.nixbld.members != []; message = "refusing to remove all members from nixbld group, this would break nix"; }
|
||||||
|
|
||||||
|
{
|
||||||
|
# Should be fixed in Lix by https://gerrit.lix.systems/c/lix/+/2100
|
||||||
|
# As `isNixAtLeast "2.92.0" "2.92.0-devpre20241107" == false`, we need to explicitly check if the user is running Lix 2.92.0
|
||||||
|
assertion = cfg.settings.auto-optimise-store -> (cfg.package.pname == "lix" && (isNixAtLeast "2.92.0-devpre20241107" || cfg.package.version == "2.92.0"));
|
||||||
|
message = "`nix.settings.auto-optimise-store` is known to corrupt the Nix Store, please use `nix.optimise.automatic` instead.";
|
||||||
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
# Not in NixOS module
|
# Not in NixOS module
|
||||||
warnings = [
|
warnings = [
|
||||||
(mkIf (!config.services.activate-system.enable && cfg.distributedBuilds) "services.activate-system is not enabled, a reboot could cause distributed builds to stop working.")
|
|
||||||
(mkIf (!cfg.distributedBuilds && cfg.buildMachines != []) "nix.distributedBuilds is not enabled, build machines won't be configured.")
|
(mkIf (!cfg.distributedBuilds && cfg.buildMachines != []) "nix.distributedBuilds is not enabled, build machines won't be configured.")
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
47
modules/power/default.nix
Normal file
47
modules/power/default.nix
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
{ config, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.power;
|
||||||
|
|
||||||
|
types = lib.types;
|
||||||
|
|
||||||
|
onOff = cond: if cond then "on" else "off";
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
power.restartAfterPowerFailure = lib.mkOption {
|
||||||
|
type = types.nullOr types.bool;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Whether to restart the computer after a power failure.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
power.restartAfterFreeze = lib.mkOption {
|
||||||
|
type = types.nullOr types.bool;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Whether to restart the computer after a system freeze.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
|
||||||
|
system.activationScripts.power.text = ''
|
||||||
|
echo "configuring power..." >&2
|
||||||
|
|
||||||
|
${lib.optionalString (cfg.restartAfterPowerFailure != null) ''
|
||||||
|
systemsetup -setRestartPowerFailure \
|
||||||
|
'${onOff cfg.restartAfterPowerFailure}' &> /dev/null
|
||||||
|
''}
|
||||||
|
|
||||||
|
${lib.optionalString (cfg.restartAfterFreeze != null) ''
|
||||||
|
systemsetup -setRestartFreeze \
|
||||||
|
'${onOff cfg.restartAfterFreeze}' &> /dev/null
|
||||||
|
''}
|
||||||
|
'';
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
80
modules/power/sleep.nix
Normal file
80
modules/power/sleep.nix
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
{ config, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.power.sleep;
|
||||||
|
|
||||||
|
types = lib.types;
|
||||||
|
|
||||||
|
onOff = cond: if cond then "on" else "off";
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
power.sleep.computer = lib.mkOption {
|
||||||
|
type = types.nullOr (types.either types.ints.positive (types.enum ["never"]));
|
||||||
|
default = null;
|
||||||
|
example = "never";
|
||||||
|
description = ''
|
||||||
|
Amount of idle time (in minutes) until the computer sleeps.
|
||||||
|
|
||||||
|
`"never"` disables computer sleeping.
|
||||||
|
|
||||||
|
The system might not be considered idle before connected displays sleep, as
|
||||||
|
per the `power.sleep.display` option.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
power.sleep.display = lib.mkOption {
|
||||||
|
type = types.nullOr (types.either types.ints.positive (types.enum ["never"]));
|
||||||
|
default = null;
|
||||||
|
example = "never";
|
||||||
|
description = ''
|
||||||
|
Amount of idle time (in minutes) until displays sleep.
|
||||||
|
|
||||||
|
`"never"` disables display sleeping.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
power.sleep.harddisk = lib.mkOption {
|
||||||
|
type = types.nullOr (types.either types.ints.positive (types.enum ["never"]));
|
||||||
|
default = null;
|
||||||
|
example = "never";
|
||||||
|
description = ''
|
||||||
|
Amount of idle time (in minutes) until hard disks sleep.
|
||||||
|
|
||||||
|
`"never"` disables hard disk sleeping.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
power.sleep.allowSleepByPowerButton = lib.mkOption {
|
||||||
|
type = types.nullOr types.bool;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Whether the power button can sleep the computer.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
|
||||||
|
system.activationScripts.power.text = lib.mkAfter ''
|
||||||
|
${lib.optionalString (cfg.computer != null) ''
|
||||||
|
systemsetup -setComputerSleep '${toString cfg.computer}' &> /dev/null
|
||||||
|
''}
|
||||||
|
|
||||||
|
${lib.optionalString (cfg.display != null) ''
|
||||||
|
systemsetup -setDisplaySleep '${toString cfg.display}' &> /dev/null
|
||||||
|
''}
|
||||||
|
|
||||||
|
${lib.optionalString (cfg.harddisk != null) ''
|
||||||
|
systemsetup -setHardDiskSleep '${toString cfg.harddisk}' &> /dev/null
|
||||||
|
''}
|
||||||
|
|
||||||
|
${lib.optionalString (cfg.allowSleepByPowerButton != null) ''
|
||||||
|
systemsetup -setAllowPowerButtonToSleepComputer \
|
||||||
|
'${onOff cfg.allowSleepByPowerButton}' &> /dev/null
|
||||||
|
''}
|
||||||
|
'';
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
|
@ -7,6 +7,10 @@ let
|
||||||
in
|
in
|
||||||
|
|
||||||
{
|
{
|
||||||
|
imports = [
|
||||||
|
(mkRenamedOptionModule [ "programs" "bash" "enableCompletion" ] [ "programs" "bash" "completion" "enable" ])
|
||||||
|
];
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
|
|
||||||
programs.bash.enable = mkOption {
|
programs.bash.enable = mkOption {
|
||||||
|
@ -21,16 +25,20 @@ in
|
||||||
type = types.lines;
|
type = types.lines;
|
||||||
};
|
};
|
||||||
|
|
||||||
programs.bash.enableCompletion = mkOption {
|
programs.bash.completion = {
|
||||||
|
enable = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = false;
|
default = false;
|
||||||
description = ''
|
description = ''
|
||||||
Enable bash completion for all interactive bash shells.
|
Enable bash completion for all interactive bash shells.
|
||||||
|
|
||||||
NOTE. This doesn't work with bash 3.2, which is the default on macOS.
|
NOTE: This doesn't work with bash 3.2, which is installed by default on macOS by Apple.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
package = mkPackageOption pkgs "bash-completion" { };
|
||||||
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
|
@ -38,9 +46,9 @@ in
|
||||||
environment.systemPackages =
|
environment.systemPackages =
|
||||||
[ # Include bash package
|
[ # Include bash package
|
||||||
pkgs.bashInteractive
|
pkgs.bashInteractive
|
||||||
] ++ optional cfg.enableCompletion pkgs.bash-completion;
|
] ++ optional cfg.completion.enable cfg.completion.package;
|
||||||
|
|
||||||
environment.pathsToLink =
|
environment.pathsToLink = optionals cfg.completion.enable
|
||||||
[ "/etc/bash_completion.d"
|
[ "/etc/bash_completion.d"
|
||||||
"/share/bash-completion/completions"
|
"/share/bash-completion/completions"
|
||||||
];
|
];
|
||||||
|
@ -70,9 +78,9 @@ in
|
||||||
${config.environment.interactiveShellInit}
|
${config.environment.interactiveShellInit}
|
||||||
${cfg.interactiveShellInit}
|
${cfg.interactiveShellInit}
|
||||||
|
|
||||||
${optionalString cfg.enableCompletion ''
|
${optionalString cfg.completion.enable ''
|
||||||
if [ "$TERM" != "dumb" ]; then
|
if [ "$TERM" != "dumb" ]; then
|
||||||
source "${pkgs.bash-completion}/etc/profile.d/bash_completion.sh"
|
source "${cfg.completion.package}/etc/profile.d/bash_completion.sh"
|
||||||
|
|
||||||
nullglobStatus=$(shopt -p nullglob)
|
nullglobStatus=$(shopt -p nullglob)
|
||||||
shopt -s nullglob
|
shopt -s nullglob
|
||||||
|
|
|
@ -41,6 +41,7 @@ in
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
(mkRenamedOptionModule [ "programs" "tmux" "tmuxConfig" ] [ "programs" "tmux" "extraConfig" ])
|
(mkRenamedOptionModule [ "programs" "tmux" "tmuxConfig" ] [ "programs" "tmux" "extraConfig" ])
|
||||||
|
(mkRemovedOptionModule [ "programs" "tmux" "defaultCommand" ] "Use `programs.tmux.extraConfig` to configure the default command instead. If unset, tmux will default to using your system configured login shell.")
|
||||||
];
|
];
|
||||||
options = {
|
options = {
|
||||||
programs.tmux.enable = mkOption {
|
programs.tmux.enable = mkOption {
|
||||||
|
@ -84,11 +85,6 @@ in
|
||||||
description = "Cater to iTerm2 and its tmux integration, as appropriate.";
|
description = "Cater to iTerm2 and its tmux integration, as appropriate.";
|
||||||
};
|
};
|
||||||
|
|
||||||
programs.tmux.defaultCommand = mkOption {
|
|
||||||
type = types.either types.str types.package;
|
|
||||||
description = "The default command to use for tmux panes.";
|
|
||||||
};
|
|
||||||
|
|
||||||
programs.tmux.tmuxOptions = mkOption {
|
programs.tmux.tmuxOptions = mkOption {
|
||||||
internal = true;
|
internal = true;
|
||||||
type = types.attrsOf (types.submodule text);
|
type = types.attrsOf (types.submodule text);
|
||||||
|
@ -120,12 +116,6 @@ in
|
||||||
source-file -q /etc/tmux.conf.local
|
source-file -q /etc/tmux.conf.local
|
||||||
'';
|
'';
|
||||||
|
|
||||||
programs.tmux.defaultCommand = mkDefault config.environment.loginShell;
|
|
||||||
|
|
||||||
programs.tmux.tmuxOptions.login-shell.text = ''
|
|
||||||
set -g default-command "${cfg.defaultCommand}"
|
|
||||||
'';
|
|
||||||
|
|
||||||
programs.tmux.tmuxOptions.sensible.text = mkIf cfg.enableSensible ''
|
programs.tmux.tmuxOptions.sensible.text = mkIf cfg.enableSensible ''
|
||||||
set -g default-terminal "screen-256color"
|
set -g default-terminal "screen-256color"
|
||||||
setw -g aggressive-resize on
|
setw -g aggressive-resize on
|
||||||
|
|
|
@ -18,7 +18,7 @@ in
|
||||||
options = {
|
options = {
|
||||||
programs.zsh.enable = mkOption {
|
programs.zsh.enable = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = false;
|
default = true;
|
||||||
description = "Whether to configure zsh as an interactive shell.";
|
description = "Whether to configure zsh as an interactive shell.";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -107,15 +107,24 @@ in
|
||||||
default = false;
|
default = false;
|
||||||
description = "Enable zsh-syntax-highlighting.";
|
description = "Enable zsh-syntax-highlighting.";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
programs.zsh.enableFastSyntaxHighlighting = mkEnableOption "zsh-fast-syntax-highlighting";
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
|
|
||||||
|
assertions = [
|
||||||
|
{
|
||||||
|
assertion = !(cfg.enableSyntaxHighlighting && cfg.enableFastSyntaxHighlighting);
|
||||||
|
message = "zsh-syntax-highlighting and zsh-fast-syntax-highlighting are mutually exclusive, please disable one of them.";
|
||||||
|
}
|
||||||
|
];
|
||||||
environment.systemPackages =
|
environment.systemPackages =
|
||||||
[ # Include zsh package
|
[ # Include zsh package
|
||||||
pkgs.zsh
|
pkgs.zsh
|
||||||
] ++ optional cfg.enableCompletion pkgs.nix-zsh-completions
|
] ++ optional cfg.enableCompletion pkgs.nix-zsh-completions
|
||||||
++ optional cfg.enableSyntaxHighlighting pkgs.zsh-syntax-highlighting;
|
++ optional cfg.enableSyntaxHighlighting pkgs.zsh-syntax-highlighting
|
||||||
|
++ optional cfg.enableFastSyntaxHighlighting pkgs.zsh-fast-syntax-highlighting;
|
||||||
|
|
||||||
environment.pathsToLink = [ "/share/zsh" ];
|
environment.pathsToLink = [ "/share/zsh" ];
|
||||||
|
|
||||||
|
@ -127,6 +136,7 @@ in
|
||||||
if [ -n "''${__ETC_ZSHENV_SOURCED-}" ]; then return; fi
|
if [ -n "''${__ETC_ZSHENV_SOURCED-}" ]; then return; fi
|
||||||
__ETC_ZSHENV_SOURCED=1
|
__ETC_ZSHENV_SOURCED=1
|
||||||
|
|
||||||
|
if [[ -o rcs ]]; then
|
||||||
if [ -z "''${__NIX_DARWIN_SET_ENVIRONMENT_DONE-}" ]; then
|
if [ -z "''${__NIX_DARWIN_SET_ENVIRONMENT_DONE-}" ]; then
|
||||||
. ${config.system.build.setEnvironment}
|
. ${config.system.build.setEnvironment}
|
||||||
fi
|
fi
|
||||||
|
@ -137,6 +147,7 @@ in
|
||||||
done
|
done
|
||||||
|
|
||||||
${cfg.shellInit}
|
${cfg.shellInit}
|
||||||
|
fi
|
||||||
|
|
||||||
# Read system-wide modifications.
|
# Read system-wide modifications.
|
||||||
if test -f /etc/zshenv.local; then
|
if test -f /etc/zshenv.local; then
|
||||||
|
@ -192,6 +203,10 @@ in
|
||||||
"source ${pkgs.zsh-syntax-highlighting}/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh"
|
"source ${pkgs.zsh-syntax-highlighting}/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
${optionalString cfg.enableFastSyntaxHighlighting
|
||||||
|
"source ${pkgs.zsh-fast-syntax-highlighting}/share/zsh-fast-syntax-highlighting/zsh-fast-syntax-highlighting.zsh"
|
||||||
|
}
|
||||||
|
|
||||||
${optionalString cfg.enableFzfCompletion "source ${fzfCompletion}"}
|
${optionalString cfg.enableFzfCompletion "source ${fzfCompletion}"}
|
||||||
${optionalString cfg.enableFzfGit "source ${fzfGit}"}
|
${optionalString cfg.enableFzfGit "source ${fzfGit}"}
|
||||||
${optionalString cfg.enableFzfHistory "source ${fzfHistory}"}
|
${optionalString cfg.enableFzfHistory "source ${fzfHistory}"}
|
||||||
|
|
|
@ -1,22 +1,11 @@
|
||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
let
|
|
||||||
cfg = config.services.activate-system;
|
|
||||||
in
|
|
||||||
|
|
||||||
{
|
{
|
||||||
options = {
|
imports = [
|
||||||
services.activate-system.enable = mkOption {
|
(lib.mkRemovedOptionModule [ "services" "activate-system" "enable" ] "The `activate-system` service is now always enabled as it is necessary for a working `nix-darwin` setup.")
|
||||||
type = types.bool;
|
];
|
||||||
default = true;
|
|
||||||
description = "Whether to activate system at boot time.";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
|
|
||||||
|
config = {
|
||||||
launchd.daemons.activate-system = {
|
launchd.daemons.activate-system = {
|
||||||
script = ''
|
script = ''
|
||||||
set -e
|
set -e
|
||||||
|
@ -41,6 +30,5 @@ in
|
||||||
serviceConfig.RunAtLoad = true;
|
serviceConfig.RunAtLoad = true;
|
||||||
serviceConfig.KeepAlive.SuccessfulExit = false;
|
serviceConfig.KeepAlive.SuccessfulExit = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
163
modules/services/aerospace/default.nix
Normal file
163
modules/services/aerospace/default.nix
Normal file
|
@ -0,0 +1,163 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.aerospace;
|
||||||
|
|
||||||
|
format = pkgs.formats.toml { };
|
||||||
|
configFile = format.generate "aerospace.toml" cfg.settings;
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
services.aerospace = with lib.types; {
|
||||||
|
enable = lib.mkEnableOption "AeroSpace window manager";
|
||||||
|
|
||||||
|
package = lib.mkPackageOption pkgs "aerospace" { };
|
||||||
|
|
||||||
|
settings = lib.mkOption {
|
||||||
|
type = submodule {
|
||||||
|
freeformType = format.type;
|
||||||
|
options = {
|
||||||
|
start-at-login = lib.mkOption {
|
||||||
|
type = bool;
|
||||||
|
default = false;
|
||||||
|
description = "Do not start AeroSpace at login. (Managed by launchd instead)";
|
||||||
|
};
|
||||||
|
after-login-command = lib.mkOption {
|
||||||
|
type = listOf str;
|
||||||
|
default = [ ];
|
||||||
|
description = "Do not use AeroSpace to run commands after login. (Managed by launchd instead)";
|
||||||
|
};
|
||||||
|
after-startup-command = lib.mkOption {
|
||||||
|
type = listOf str;
|
||||||
|
default = [ ];
|
||||||
|
description = "Do not use AeroSpace to run commands after startup. (Managed by launchd instead)";
|
||||||
|
};
|
||||||
|
enable-normalization-flatten-containers = lib.mkOption {
|
||||||
|
type = bool;
|
||||||
|
default = true;
|
||||||
|
description = "Containers that have only one child are \"flattened\".";
|
||||||
|
};
|
||||||
|
enable-normalization-opposite-orientation-for-nested-containers = lib.mkOption {
|
||||||
|
type = bool;
|
||||||
|
default = true;
|
||||||
|
description = "Containers that nest into each other must have opposite orientations.";
|
||||||
|
};
|
||||||
|
accordion-padding = lib.mkOption {
|
||||||
|
type = int;
|
||||||
|
default = 30;
|
||||||
|
description = "Padding between windows in an accordion container.";
|
||||||
|
};
|
||||||
|
default-root-container-layout = lib.mkOption {
|
||||||
|
type = enum [
|
||||||
|
"tiles"
|
||||||
|
"accordion"
|
||||||
|
];
|
||||||
|
default = "tiles";
|
||||||
|
description = "Default layout for the root container.";
|
||||||
|
};
|
||||||
|
default-root-container-orientation = lib.mkOption {
|
||||||
|
type = enum [
|
||||||
|
"horizontal"
|
||||||
|
"vertical"
|
||||||
|
"auto"
|
||||||
|
];
|
||||||
|
default = "auto";
|
||||||
|
description = "Default orientation for the root container.";
|
||||||
|
};
|
||||||
|
on-window-detected = lib.mkOption {
|
||||||
|
type = listOf str;
|
||||||
|
default = [ ];
|
||||||
|
description = "Commands to run every time a new window is detected.";
|
||||||
|
};
|
||||||
|
on-focus-changed = lib.mkOption {
|
||||||
|
type = listOf str;
|
||||||
|
default = [ ];
|
||||||
|
description = "Commands to run every time focused window or workspace changes.";
|
||||||
|
};
|
||||||
|
on-focused-monitor-changed = lib.mkOption {
|
||||||
|
type = listOf str;
|
||||||
|
default = [ "move-mouse monitor-lazy-center" ];
|
||||||
|
description = "Commands to run every time focused monitor changes.";
|
||||||
|
};
|
||||||
|
exec-on-workspace-change = lib.mkOption {
|
||||||
|
type = listOf str;
|
||||||
|
default = [ ];
|
||||||
|
example = [
|
||||||
|
"/bin/bash"
|
||||||
|
"-c"
|
||||||
|
"sketchybar --trigger aerospace_workspace_change FOCUSED=$AEROSPACE_FOCUSED_WORKSPACE"
|
||||||
|
];
|
||||||
|
description = "Commands to run every time workspace changes.";
|
||||||
|
};
|
||||||
|
key-mapping.preset = lib.mkOption {
|
||||||
|
type = enum [
|
||||||
|
"qwerty"
|
||||||
|
"dvorak"
|
||||||
|
];
|
||||||
|
default = "qwerty";
|
||||||
|
description = "Keymapping preset.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
default = { };
|
||||||
|
example = lib.literalExpression ''
|
||||||
|
{
|
||||||
|
gaps = {
|
||||||
|
outer.left = 8;
|
||||||
|
outer.bottom = 8;
|
||||||
|
outer.top = 8;
|
||||||
|
outer.right = 8;
|
||||||
|
};
|
||||||
|
mode.main.binding = {
|
||||||
|
alt-h = "focus left";
|
||||||
|
alt-j = "focus down";
|
||||||
|
alt-k = "focus up";
|
||||||
|
alt-l = "focus right";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
AeroSpace configuration, see
|
||||||
|
<link xlink:href="https://nikitabobko.github.io/AeroSpace/guide#configuring-aerospace"/>
|
||||||
|
for supported values.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = (
|
||||||
|
lib.mkIf (cfg.enable) {
|
||||||
|
assertions = [
|
||||||
|
{
|
||||||
|
assertion = !cfg.settings.start-at-login;
|
||||||
|
message = "AeroSpace started at login is managed by home-manager and launchd instead of itself via this option.";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
assertion = cfg.settings.after-login-command == [ ];
|
||||||
|
message = "AeroSpace will not run these commands as it does not start itself.";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
assertion = cfg.settings.after-startup-command == [ ];
|
||||||
|
message = "AeroSpace will not run these commands as it does not start itself.";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
environment.systemPackages = [ cfg.package ];
|
||||||
|
|
||||||
|
launchd.user.agents.aerospace = {
|
||||||
|
command =
|
||||||
|
"${cfg.package}/Applications/AeroSpace.app/Contents/MacOS/AeroSpace"
|
||||||
|
+ (lib.optionalString (cfg.settings != { }) " --config-path ${configFile}");
|
||||||
|
serviceConfig = {
|
||||||
|
KeepAlive = true;
|
||||||
|
RunAtLoad = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
|
@ -237,7 +237,7 @@ in
|
||||||
tagStr = lib.concatStringsSep "," (lib.mapAttrsToList (name: value: "${name}=${value}") cfg.tags);
|
tagStr = lib.concatStringsSep "," (lib.mapAttrsToList (name: value: "${name}=${value}") cfg.tags);
|
||||||
in
|
in
|
||||||
optionalString (cfg.privateSshKeyPath != null) ''
|
optionalString (cfg.privateSshKeyPath != null) ''
|
||||||
mkdir -m 0700 -p "${sshDir}"
|
mkdir -m 0700 "${sshDir}"
|
||||||
install -m600 "${toString cfg.privateSshKeyPath}" "${sshDir}/id_rsa"
|
install -m600 "${toString cfg.privateSshKeyPath}" "${sshDir}/id_rsa"
|
||||||
'' + ''
|
'' + ''
|
||||||
cat > "${cfg.dataDir}/buildkite-agent.cfg" <<EOF
|
cat > "${cfg.dataDir}/buildkite-agent.cfg" <<EOF
|
||||||
|
|
|
@ -44,9 +44,11 @@ in {
|
||||||
|
|
||||||
launchd.user.agents.emacs = {
|
launchd.user.agents.emacs = {
|
||||||
path = cfg.additionalPath ++ [ config.environment.systemPath ];
|
path = cfg.additionalPath ++ [ config.environment.systemPath ];
|
||||||
serviceConfig.ProgramArguments =
|
serviceConfig = {
|
||||||
[ "${cfg.package}/bin/${cfg.exec}" "--fg-daemon" ];
|
ProgramArguments = [ "${cfg.package}/bin/${cfg.exec}" "--fg-daemon" ];
|
||||||
serviceConfig.RunAtLoad = true;
|
RunAtLoad = true;
|
||||||
|
KeepAlive = true;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -48,14 +48,20 @@ in
|
||||||
text = mkBefore (''
|
text = mkBefore (''
|
||||||
echo >&2 "setting up GitHub Runner '${cfg.name}'..."
|
echo >&2 "setting up GitHub Runner '${cfg.name}'..."
|
||||||
|
|
||||||
${pkgs.coreutils}/bin/mkdir -p -m 0750 ${escapeShellArg (mkStateDir cfg)}
|
(
|
||||||
|
umask -S u=rwx,g=rx,o= > /dev/null
|
||||||
|
|
||||||
|
${pkgs.coreutils}/bin/mkdir -p ${escapeShellArg (mkStateDir cfg)}
|
||||||
${pkgs.coreutils}/bin/chown ${user}:${group} ${escapeShellArg (mkStateDir cfg)}
|
${pkgs.coreutils}/bin/chown ${user}:${group} ${escapeShellArg (mkStateDir cfg)}
|
||||||
|
|
||||||
${pkgs.coreutils}/bin/mkdir -p -m 0750 ${escapeShellArg (mkLogDir cfg)}
|
${pkgs.coreutils}/bin/mkdir -p ${escapeShellArg (mkLogDir cfg)}
|
||||||
${pkgs.coreutils}/bin/chown ${user}:${group} ${escapeShellArg (mkLogDir cfg)}
|
${pkgs.coreutils}/bin/chown ${user}:${group} ${escapeShellArg (mkLogDir cfg)}
|
||||||
'' + optionalString (cfg.workDir == null) ''
|
|
||||||
${pkgs.coreutils}/bin/mkdir -p -m 0750 ${escapeShellArg (mkWorkDir cfg)}
|
${optionalString (cfg.workDir == null) ''
|
||||||
|
${pkgs.coreutils}/bin/mkdir -p ${escapeShellArg (mkWorkDir cfg)}
|
||||||
${pkgs.coreutils}/bin/chown ${user}:${group} ${escapeShellArg (mkWorkDir cfg)}
|
${pkgs.coreutils}/bin/chown ${user}:${group} ${escapeShellArg (mkWorkDir cfg)}
|
||||||
|
''}
|
||||||
|
)
|
||||||
'');
|
'');
|
||||||
};
|
};
|
||||||
}));
|
}));
|
||||||
|
@ -88,6 +94,10 @@ in
|
||||||
|
|
||||||
script =
|
script =
|
||||||
let
|
let
|
||||||
|
# https://github.com/NixOS/nixpkgs/pull/333744 introduced an inconsistency with different
|
||||||
|
# versions of nixpkgs. Use the old version of escapeShellArg to make sure that labels
|
||||||
|
# are always escaped to avoid https://www.shellcheck.net/wiki/SC2054
|
||||||
|
escapeShellArgAlways = string: "'${replaceStrings ["'"] ["'\\''"] (toString string)}'";
|
||||||
configure = pkgs.writeShellApplication {
|
configure = pkgs.writeShellApplication {
|
||||||
name = "configure-github-runner-${name}";
|
name = "configure-github-runner-${name}";
|
||||||
text = /*bash*/''
|
text = /*bash*/''
|
||||||
|
@ -98,7 +108,7 @@ in
|
||||||
--disableupdate
|
--disableupdate
|
||||||
--work ${escapeShellArg workDir}
|
--work ${escapeShellArg workDir}
|
||||||
--url ${escapeShellArg cfg.url}
|
--url ${escapeShellArg cfg.url}
|
||||||
--labels "${escapeShellArg (concatStringsSep "," cfg.extraLabels)}"
|
--labels ${escapeShellArgAlways (concatStringsSep "," cfg.extraLabels)}
|
||||||
${optionalString (cfg.name != null ) "--name ${escapeShellArg cfg.name}"}
|
${optionalString (cfg.name != null ) "--name ${escapeShellArg cfg.name}"}
|
||||||
${optionalString cfg.replace "--replace"}
|
${optionalString cfg.replace "--replace"}
|
||||||
${optionalString (cfg.runnerGroup != null) "--runnergroup ${escapeShellArg cfg.runnerGroup}"}
|
${optionalString (cfg.runnerGroup != null) "--runnergroup ${escapeShellArg cfg.runnerGroup}"}
|
||||||
|
|
|
@ -9,18 +9,19 @@ let
|
||||||
in
|
in
|
||||||
|
|
||||||
{
|
{
|
||||||
options = {
|
options.services.karabiner-elements = {
|
||||||
services.karabiner-elements.enable = mkEnableOption "Karabiner-Elements";
|
enable = mkEnableOption "Karabiner-Elements";
|
||||||
|
package = mkPackageOption pkgs "karabiner-elements" { };
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
environment.systemPackages = [ pkgs.karabiner-elements ];
|
environment.systemPackages = [ cfg.package ];
|
||||||
|
|
||||||
system.activationScripts.preActivation.text = ''
|
system.activationScripts.preActivation.text = ''
|
||||||
rm -rf ${parentAppDir}
|
rm -rf ${parentAppDir}
|
||||||
mkdir -p ${parentAppDir}
|
mkdir -p ${parentAppDir}
|
||||||
# Kernel extensions must reside inside of /Applications, they cannot be symlinks
|
# Kernel extensions must reside inside of /Applications, they cannot be symlinks
|
||||||
cp -r ${pkgs.karabiner-elements.driver}/Applications/.Karabiner-VirtualHIDDevice-Manager.app ${parentAppDir}
|
cp -r ${cfg.package.driver}/Applications/.Karabiner-VirtualHIDDevice-Manager.app ${parentAppDir}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
system.activationScripts.postActivation.text = ''
|
system.activationScripts.postActivation.text = ''
|
||||||
|
@ -49,7 +50,7 @@ in
|
||||||
|
|
||||||
launchd.daemons.karabiner_grabber = {
|
launchd.daemons.karabiner_grabber = {
|
||||||
serviceConfig.ProgramArguments = [
|
serviceConfig.ProgramArguments = [
|
||||||
"${pkgs.karabiner-elements}/Library/Application Support/org.pqrs/Karabiner-Elements/bin/karabiner_grabber"
|
"${cfg.package}/Library/Application Support/org.pqrs/Karabiner-Elements/bin/karabiner_grabber"
|
||||||
];
|
];
|
||||||
serviceConfig.ProcessType = "Interactive";
|
serviceConfig.ProcessType = "Interactive";
|
||||||
serviceConfig.Label = "org.pqrs.karabiner.karabiner_grabber";
|
serviceConfig.Label = "org.pqrs.karabiner.karabiner_grabber";
|
||||||
|
@ -60,7 +61,7 @@ in
|
||||||
|
|
||||||
launchd.daemons.karabiner_observer = {
|
launchd.daemons.karabiner_observer = {
|
||||||
serviceConfig.ProgramArguments = [
|
serviceConfig.ProgramArguments = [
|
||||||
"${pkgs.karabiner-elements}/Library/Application Support/org.pqrs/Karabiner-Elements/bin/karabiner_observer"
|
"${cfg.package}/Library/Application Support/org.pqrs/Karabiner-Elements/bin/karabiner_observer"
|
||||||
];
|
];
|
||||||
|
|
||||||
serviceConfig.Label = "org.pqrs.karabiner.karabiner_observer";
|
serviceConfig.Label = "org.pqrs.karabiner.karabiner_observer";
|
||||||
|
@ -70,7 +71,7 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
launchd.daemons.Karabiner-DriverKit-VirtualHIDDeviceClient = {
|
launchd.daemons.Karabiner-DriverKit-VirtualHIDDeviceClient = {
|
||||||
command = "\"${pkgs.karabiner-elements.driver}/Library/Application Support/org.pqrs/Karabiner-DriverKit-VirtualHIDDevice/Applications/Karabiner-DriverKit-VirtualHIDDeviceClient.app/Contents/MacOS/Karabiner-DriverKit-VirtualHIDDeviceClient\"";
|
command = "\"${cfg.package.driver}/Library/Application Support/org.pqrs/Karabiner-DriverKit-VirtualHIDDevice/Applications/Karabiner-DriverKit-VirtualHIDDeviceClient.app/Contents/MacOS/Karabiner-DriverKit-VirtualHIDDeviceClient\"";
|
||||||
serviceConfig.ProcessType = "Interactive";
|
serviceConfig.ProcessType = "Interactive";
|
||||||
serviceConfig.Label = "org.pqrs.Karabiner-DriverKit-VirtualHIDDeviceClient";
|
serviceConfig.Label = "org.pqrs.Karabiner-DriverKit-VirtualHIDDeviceClient";
|
||||||
serviceConfig.KeepAlive = true;
|
serviceConfig.KeepAlive = true;
|
||||||
|
@ -91,7 +92,7 @@ in
|
||||||
script = ''
|
script = ''
|
||||||
rm -rf /run/wrappers
|
rm -rf /run/wrappers
|
||||||
mkdir -p /run/wrappers/bin
|
mkdir -p /run/wrappers/bin
|
||||||
install -m4555 "${pkgs.karabiner-elements}/Library/Application Support/org.pqrs/Karabiner-Elements/bin/karabiner_session_monitor" /run/wrappers/bin
|
install -m4555 "${cfg.package}/Library/Application Support/org.pqrs/Karabiner-Elements/bin/karabiner_session_monitor" /run/wrappers/bin
|
||||||
'';
|
'';
|
||||||
serviceConfig.RunAtLoad = true;
|
serviceConfig.RunAtLoad = true;
|
||||||
serviceConfig.KeepAlive.SuccessfulExit = false;
|
serviceConfig.KeepAlive.SuccessfulExit = false;
|
||||||
|
@ -106,8 +107,8 @@ in
|
||||||
serviceConfig.KeepAlive = true;
|
serviceConfig.KeepAlive = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
environment.userLaunchAgents."org.pqrs.karabiner.agent.karabiner_grabber.plist".source = "${pkgs.karabiner-elements}/Library/LaunchAgents/org.pqrs.karabiner.agent.karabiner_grabber.plist";
|
environment.userLaunchAgents."org.pqrs.karabiner.agent.karabiner_grabber.plist".source = "${cfg.package}/Library/LaunchAgents/org.pqrs.karabiner.agent.karabiner_grabber.plist";
|
||||||
environment.userLaunchAgents."org.pqrs.karabiner.agent.karabiner_observer.plist".source = "${pkgs.karabiner-elements}/Library/LaunchAgents/org.pqrs.karabiner.agent.karabiner_observer.plist";
|
environment.userLaunchAgents."org.pqrs.karabiner.agent.karabiner_observer.plist".source = "${cfg.package}/Library/LaunchAgents/org.pqrs.karabiner.agent.karabiner_observer.plist";
|
||||||
environment.userLaunchAgents."org.pqrs.karabiner.karabiner_console_user_server.plist".source = "${pkgs.karabiner-elements}/Library/LaunchAgents/org.pqrs.karabiner.karabiner_console_user_server.plist";
|
environment.userLaunchAgents."org.pqrs.karabiner.karabiner_console_user_server.plist".source = "${cfg.package}/Library/LaunchAgents/org.pqrs.karabiner.karabiner_console_user_server.plist";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
121
modules/services/monitoring/prometheus-node-exporter.nix
Normal file
121
modules/services/monitoring/prometheus-node-exporter.nix
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
|
||||||
|
let
|
||||||
|
inherit (lib)
|
||||||
|
concatStringsSep
|
||||||
|
escapeShellArgs
|
||||||
|
getExe
|
||||||
|
mkEnableOption
|
||||||
|
mkIf
|
||||||
|
mkOption
|
||||||
|
mkPackageOption
|
||||||
|
mkRemovedOptionModule
|
||||||
|
types
|
||||||
|
;
|
||||||
|
|
||||||
|
cfg = config.services.prometheus.exporters.node;
|
||||||
|
in {
|
||||||
|
imports = [
|
||||||
|
(mkRemovedOptionModule [ "services" "prometheus" "exporters" "node" "openFirewall" ] "No nix-darwin equivalent to this NixOS option.")
|
||||||
|
(mkRemovedOptionModule [ "services" "prometheus" "exporters" "node" "firewallFilter" ] "No nix-darwin equivalent to this NixOS option.")
|
||||||
|
(mkRemovedOptionModule [ "services" "prometheus" "exporters" "node" "firewallRules" ] "No nix-darwin equivalent to this NixOS option.")
|
||||||
|
];
|
||||||
|
|
||||||
|
options = {
|
||||||
|
services.prometheus.exporters.node = {
|
||||||
|
enable = mkEnableOption "Prometheus Node exporter";
|
||||||
|
|
||||||
|
package = mkPackageOption pkgs "prometheus-node-exporter" { };
|
||||||
|
|
||||||
|
listenAddress = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "";
|
||||||
|
example = "0.0.0.0";
|
||||||
|
description = ''
|
||||||
|
Address where Node exporter exposes its HTTP interface. Leave empty to bind to all addresses.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
port = mkOption {
|
||||||
|
type = types.port;
|
||||||
|
default = 9100;
|
||||||
|
description = ''
|
||||||
|
Port where the Node exporter exposes its HTTP interface.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
extraFlags = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [ ];
|
||||||
|
example = [ "--log.level=debug" ];
|
||||||
|
description = ''
|
||||||
|
Extra commandline options to pass to the Node exporter executable.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
enabledCollectors = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [ ];
|
||||||
|
description = ''
|
||||||
|
Collectors to enable in addition to the ones that are [enabled by default](https://github.com/prometheus/node_exporter#enabled-by-default).
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
disabledCollectors = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [ ];
|
||||||
|
example = [ "boottime" ];
|
||||||
|
description = ''
|
||||||
|
Collectors to disable from the list of collectors that are [enabled by default](https://github.com/prometheus/node_exporter#enabled-by-default).
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
users.users._prometheus-node-exporter = {
|
||||||
|
uid = config.ids.uids._prometheus-node-exporter;
|
||||||
|
gid = config.ids.gids._prometheus-node-exporter;
|
||||||
|
home = "/var/lib/prometheus-node-exporter";
|
||||||
|
createHome = true;
|
||||||
|
shell = "/usr/bin/false";
|
||||||
|
description = "System user for the Prometheus Node exporter";
|
||||||
|
};
|
||||||
|
|
||||||
|
users.groups._prometheus-node-exporter = {
|
||||||
|
gid = config.ids.gids._prometheus-node-exporter;
|
||||||
|
description = "System group for the Prometheus Node exporter";
|
||||||
|
};
|
||||||
|
|
||||||
|
users.knownGroups = [ "_prometheus-node-exporter" ];
|
||||||
|
users.knownUsers = [ "_prometheus-node-exporter" ];
|
||||||
|
|
||||||
|
launchd.daemons.prometheus-node-exporter = {
|
||||||
|
script = concatStringsSep " "
|
||||||
|
([
|
||||||
|
(getExe cfg.package)
|
||||||
|
"--web.listen-address"
|
||||||
|
"${cfg.listenAddress}:${toString cfg.port}"
|
||||||
|
]
|
||||||
|
++ (map (collector: "--collector.${collector}") cfg.enabledCollectors)
|
||||||
|
++ (map (collector: "--no-collector.${collector}") cfg.disabledCollectors)
|
||||||
|
) + escapeShellArgs cfg.extraFlags;
|
||||||
|
serviceConfig = let
|
||||||
|
logPath = config.users.users._prometheus-node-exporter.home
|
||||||
|
+ "/prometheus-node-exporter.log";
|
||||||
|
in {
|
||||||
|
KeepAlive = true;
|
||||||
|
RunAtLoad = true;
|
||||||
|
StandardErrorPath = logPath;
|
||||||
|
StandardOutPath = logPath;
|
||||||
|
GroupName = "_prometheus-node-exporter";
|
||||||
|
UserName = "_prometheus-node-exporter";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,16 +1,16 @@
|
||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, ... }:
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.services.nix-daemon;
|
cfg = config.services.nix-daemon;
|
||||||
|
|
||||||
|
inherit (lib) mkDefault mkIf mkMerge mkOption types;
|
||||||
in
|
in
|
||||||
|
|
||||||
{
|
{
|
||||||
options = {
|
options = {
|
||||||
services.nix-daemon.enable = mkOption {
|
services.nix-daemon.enable = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = false;
|
default = true;
|
||||||
description = "Whether to enable the nix-daemon service.";
|
description = "Whether to enable the nix-daemon service.";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -46,12 +46,6 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
|
|
||||||
assertions = [
|
|
||||||
{ assertion = elem "ofborg" config.users.knownGroups; message = "set users.knownGroups to enable ofborg group"; }
|
|
||||||
{ assertion = elem "ofborg" config.users.knownUsers; message = "set users.knownUsers to enable ofborg user"; }
|
|
||||||
];
|
|
||||||
|
|
||||||
warnings = mkIf (isDerivation cfg.configFile) [
|
warnings = mkIf (isDerivation cfg.configFile) [
|
||||||
"services.ofborg.configFile is a derivation, credentials will be world readable"
|
"services.ofborg.configFile is a derivation, credentials will be world readable"
|
||||||
];
|
];
|
||||||
|
@ -87,9 +81,13 @@ in
|
||||||
users.users.ofborg.shell = "/bin/bash";
|
users.users.ofborg.shell = "/bin/bash";
|
||||||
users.users.ofborg.description = "OfBorg service user";
|
users.users.ofborg.description = "OfBorg service user";
|
||||||
|
|
||||||
|
users.knownUsers = [ "ofborg" ];
|
||||||
|
|
||||||
users.groups.ofborg.gid = mkDefault 531;
|
users.groups.ofborg.gid = mkDefault 531;
|
||||||
users.groups.ofborg.description = "Nix group for OfBorg service";
|
users.groups.ofborg.description = "Nix group for OfBorg service";
|
||||||
|
|
||||||
|
users.knownGroups = [ "ofborg" ];
|
||||||
|
|
||||||
# FIXME: create logfiles automatically if defined.
|
# FIXME: create logfiles automatically if defined.
|
||||||
system.activationScripts.preActivation.text = ''
|
system.activationScripts.preActivation.text = ''
|
||||||
mkdir -p '${user.home}'
|
mkdir -p '${user.home}'
|
||||||
|
|
|
@ -355,11 +355,14 @@ in
|
||||||
"${cfg.dataDir}/recovery.conf"
|
"${cfg.dataDir}/recovery.conf"
|
||||||
''}
|
''}
|
||||||
|
|
||||||
exec ${postgresql}/bin/postgres -D ${cfg.dataDir}
|
exec ${postgresql}/bin/postgres
|
||||||
'';
|
'';
|
||||||
|
|
||||||
serviceConfig.KeepAlive = true;
|
serviceConfig.KeepAlive = true;
|
||||||
serviceConfig.RunAtLoad = true;
|
serviceConfig.RunAtLoad = true;
|
||||||
|
serviceConfig.EnvironmentVariables = {
|
||||||
|
PGDATA = cfg.dataDir;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -29,6 +29,7 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
|
environment.systemPackages = [ cfg.package ];
|
||||||
|
|
||||||
environment.etc."skhdrc".text = cfg.skhdConfig;
|
environment.etc."skhdrc".text = cfg.skhdConfig;
|
||||||
|
|
||||||
|
|
|
@ -67,6 +67,7 @@ in
|
||||||
${cfg.activationScripts.nix-daemon.text}
|
${cfg.activationScripts.nix-daemon.text}
|
||||||
${cfg.activationScripts.time.text}
|
${cfg.activationScripts.time.text}
|
||||||
${cfg.activationScripts.networking.text}
|
${cfg.activationScripts.networking.text}
|
||||||
|
${cfg.activationScripts.power.text}
|
||||||
${cfg.activationScripts.keyboard.text}
|
${cfg.activationScripts.keyboard.text}
|
||||||
${cfg.activationScripts.fonts.text}
|
${cfg.activationScripts.fonts.text}
|
||||||
${cfg.activationScripts.nvram.text}
|
${cfg.activationScripts.nvram.text}
|
||||||
|
@ -85,6 +86,7 @@ in
|
||||||
exit $_status
|
exit $_status
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
# FIXME: activationScripts.checks should be system level
|
||||||
system.activationScripts.userScript.text = ''
|
system.activationScripts.userScript.text = ''
|
||||||
#! ${stdenv.shell}
|
#! ${stdenv.shell}
|
||||||
set -e
|
set -e
|
||||||
|
|
|
@ -2,22 +2,49 @@
|
||||||
|
|
||||||
{
|
{
|
||||||
system.activationScripts.createRun.text = ''
|
system.activationScripts.createRun.text = ''
|
||||||
if ! test -L /run; then
|
IFS="." read -r -a macOSVersion <<< "$(sw_vers -productVersion)"
|
||||||
|
|
||||||
|
if [[ ''${macOSVersion[0]} -gt 10 || ( ''${macOSVersion[0]} -eq 10 && ''${macOSVersion[1]} -ge 15 ) ]]; then
|
||||||
if ! grep -q '^run\b' /etc/synthetic.conf 2>/dev/null; then
|
if ! grep -q '^run\b' /etc/synthetic.conf 2>/dev/null; then
|
||||||
echo "setting up /run via /etc/synthetic.conf..."
|
echo "setting up /run via /etc/synthetic.conf..."
|
||||||
echo -e "run\tprivate/var/run" | sudo tee -a /etc/synthetic.conf >/dev/null
|
printf 'run\tprivate/var/run\n' | sudo tee -a /etc/synthetic.conf >/dev/null
|
||||||
sudo /System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -B &>/dev/null || true
|
|
||||||
sudo /System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -t &>/dev/null || true
|
|
||||||
if ! test -L /run; then
|
|
||||||
echo "warning: apfs.util failed to symlink /run"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ ''${macOSVersion[0]} -gt 10 ]]; then
|
||||||
|
sudo /System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -t || true
|
||||||
|
else
|
||||||
|
sudo /System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -B || true
|
||||||
fi
|
fi
|
||||||
if ! test -L /run; then
|
|
||||||
|
if [[ ! -L /run ]]; then
|
||||||
|
printf >&2 '[1;31merror: apfs.util failed to symlink /run, aborting activation[0m\n'
|
||||||
|
printf >&2 'To create a symlink from /run to /var/run, please run:\n'
|
||||||
|
printf >&2 '\n'
|
||||||
|
printf >&2 "$ printf 'run\tprivate/var/run\n' | sudo tee -a /etc/synthetic.conf"
|
||||||
|
|
||||||
|
if [[ ''${macOSVersion[0]} -gt 10 ]]; then
|
||||||
|
printf >&2 '$ sudo /System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -t\n'
|
||||||
|
else
|
||||||
|
printf >&2 '$ sudo /System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -B\n'
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf >&2 '\n'
|
||||||
|
printf >&2 'The current contents of /etc/synthetic.conf is:\n'
|
||||||
|
printf >&2 '\n'
|
||||||
|
sudo sed 's/^/ /' /etc/synthetic.conf >&2
|
||||||
|
printf >&2 '\n'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
echo "setting up /run..."
|
echo "setting up /run..."
|
||||||
sudo ln -sfn private/var/run /run
|
sudo ln -sfn private/var/run /run
|
||||||
fi
|
|
||||||
if ! test -L /run; then
|
if [[ ! -L /run ]]; then
|
||||||
echo "warning: failed to symlink /run"
|
printf >&2 '[1;31merror: failed to symlink /run, aborting activation[0m\n'
|
||||||
|
printf >&2 'To create a symlink from /run to /var/run, please run:\n'
|
||||||
|
printf >&2 '\n'
|
||||||
|
printf >&2 '$ sudo ln -sfn private/var/link /run\n'
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
'';
|
'';
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
with lib;
|
with lib;
|
||||||
|
|
||||||
let
|
let
|
||||||
|
# Similar to lib.escapeShellArg but escapes "s instead of 's, to allow for parameter expansion in shells
|
||||||
|
escapeDoubleQuote = arg: ''"${replaceStrings ["\""] ["\"\\\"\""] (toString arg)}"'';
|
||||||
|
|
||||||
cfg = config.system.checks;
|
cfg = config.system.checks;
|
||||||
|
|
||||||
darwinChanges = ''
|
darwinChanges = ''
|
||||||
|
@ -22,28 +25,13 @@ let
|
||||||
'';
|
'';
|
||||||
|
|
||||||
runLink = ''
|
runLink = ''
|
||||||
if ! test -e /run; then
|
if [[ ! -e /run ]]; then
|
||||||
echo "[1;31merror: Directory /run does not exist, aborting activation[0m" >&2
|
printf >&2 '[1;31merror: directory /run does not exist, aborting activation[0m\n'
|
||||||
echo "Create a symlink to /var/run with:" >&2
|
exit 1
|
||||||
if test -e /etc/synthetic.conf; then
|
|
||||||
echo >&2
|
|
||||||
echo "$ printf 'run\tprivate/var/run\n' | sudo tee -a /etc/synthetic.conf" >&2
|
|
||||||
echo "$ sudo /System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -B # For Catalina" >&2
|
|
||||||
echo "$ sudo /System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -t # For Big Sur and later" >&2
|
|
||||||
echo >&2
|
|
||||||
echo "The current contents of /etc/synthetic.conf is:" >&2
|
|
||||||
echo >&2
|
|
||||||
sed 's/^/ /' /etc/synthetic.conf >&2
|
|
||||||
echo >&2
|
|
||||||
else
|
|
||||||
echo >&2
|
|
||||||
echo "$ sudo ln -s private/var/run /run" >&2
|
|
||||||
echo >&2
|
|
||||||
fi
|
|
||||||
exit 2
|
|
||||||
fi
|
fi
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
|
||||||
oldBuildUsers = ''
|
oldBuildUsers = ''
|
||||||
if dscl . -list /Users | grep -q '^nixbld'; then
|
if dscl . -list /Users | grep -q '^nixbld'; then
|
||||||
echo "[1;31merror: Detected old style nixbld users, aborting activation[0m" >&2
|
echo "[1;31merror: Detected old style nixbld users, aborting activation[0m" >&2
|
||||||
|
@ -104,7 +92,7 @@ let
|
||||||
|
|
||||||
buildUsers = ''
|
buildUsers = ''
|
||||||
buildUser=$(dscl . -read /Groups/nixbld GroupMembership 2>&1 | awk '/^GroupMembership: / {print $2}') || true
|
buildUser=$(dscl . -read /Groups/nixbld GroupMembership 2>&1 | awk '/^GroupMembership: / {print $2}') || true
|
||||||
if [ -z $buildUser ]; then
|
if [[ -z "$buildUser" ]]; then
|
||||||
echo "[1;31merror: Using the nix-daemon requires build users, aborting activation[0m" >&2
|
echo "[1;31merror: Using the nix-daemon requires build users, aborting activation[0m" >&2
|
||||||
echo "Create the build users or disable the daemon:" >&2
|
echo "Create the build users or disable the daemon:" >&2
|
||||||
echo "$ darwin-install" >&2
|
echo "$ darwin-install" >&2
|
||||||
|
@ -120,7 +108,7 @@ let
|
||||||
buildGroupID = ''
|
buildGroupID = ''
|
||||||
buildGroupID=$(dscl . -read /Groups/nixbld PrimaryGroupID | awk '{print $2}')
|
buildGroupID=$(dscl . -read /Groups/nixbld PrimaryGroupID | awk '{print $2}')
|
||||||
expectedBuildGroupID=${toString config.ids.gids.nixbld}
|
expectedBuildGroupID=${toString config.ids.gids.nixbld}
|
||||||
if [[ $buildGroupID != $expectedBuildGroupID ]]; then
|
if [[ $buildGroupID != "$expectedBuildGroupID" ]]; then
|
||||||
printf >&2 '\e[1;31merror: Build user group has mismatching GID, aborting activation\e[0m\n'
|
printf >&2 '\e[1;31merror: Build user group has mismatching GID, aborting activation\e[0m\n'
|
||||||
printf >&2 'The default Nix build user group ID was changed from 30000 to 350.\n'
|
printf >&2 'The default Nix build user group ID was changed from 30000 to 350.\n'
|
||||||
printf >&2 'You are currently managing Nix build users with nix-darwin, but your\n'
|
printf >&2 'You are currently managing Nix build users with nix-darwin, but your\n'
|
||||||
|
@ -130,6 +118,7 @@ let
|
||||||
printf >&2 'Possible causes include setting up a new Nix installation with an\n'
|
printf >&2 'Possible causes include setting up a new Nix installation with an\n'
|
||||||
printf >&2 'existing nix-darwin configuration, setting up a new nix-darwin\n'
|
printf >&2 'existing nix-darwin configuration, setting up a new nix-darwin\n'
|
||||||
printf >&2 'installation with an existing Nix installation, or manually increasing\n'
|
printf >&2 'installation with an existing Nix installation, or manually increasing\n'
|
||||||
|
# shellcheck disable=SC2016
|
||||||
printf >&2 'your `system.stateVersion` setting.\n'
|
printf >&2 'your `system.stateVersion` setting.\n'
|
||||||
printf >&2 '\n'
|
printf >&2 '\n'
|
||||||
printf >&2 'You can set the configured group ID to match the actual value:\n'
|
printf >&2 'You can set the configured group ID to match the actual value:\n'
|
||||||
|
@ -143,17 +132,25 @@ let
|
||||||
fi
|
fi
|
||||||
'';
|
'';
|
||||||
|
|
||||||
singleUser = ''
|
nixDaemon = if config.nix.useDaemon then ''
|
||||||
if grep -q 'build-users-group =' /etc/nix/nix.conf; then
|
if ! dscl . -read /Groups/nixbld PrimaryGroupID &> /dev/null; then
|
||||||
echo "[1;31merror: The daemon is not enabled but this is a multi-user install, aborting activation[0m" >&2
|
printf >&2 '[1;31merror: The daemon should not be enabled for single-user installs, aborting activation[0m\n'
|
||||||
echo "Enable the nix-daemon service:" >&2
|
printf >&2 'Disable the nix-daemon service:\n'
|
||||||
echo >&2
|
printf >&2 '\n'
|
||||||
echo " services.nix-daemon.enable = true;" >&2
|
printf >&2 ' services.nix-daemon.enable = false;\n'
|
||||||
echo >&2
|
printf >&2 '\n'
|
||||||
echo "or set" >&2
|
# shellcheck disable=SC2016
|
||||||
echo >&2
|
printf >&2 'and remove `nix.useDaemon` from your configuration if it is present.\n'
|
||||||
echo " nix.useDaemon = true;" >&2
|
printf >&2 '\n'
|
||||||
echo >&2
|
exit 2
|
||||||
|
fi
|
||||||
|
'' else ''
|
||||||
|
if dscl . -read /Groups/nixbld PrimaryGroupID &> /dev/null; then
|
||||||
|
printf >&2 '[1;31merror: The daemon should be enabled for multi-user installs, aborting activation[0m\n'
|
||||||
|
printf >&2 'Enable the nix-daemon service:\n'
|
||||||
|
printf >&2 '\n'
|
||||||
|
printf >&2 ' services.nix-daemon.enable = true;\n'
|
||||||
|
printf >&2 '\n'
|
||||||
exit 2
|
exit 2
|
||||||
fi
|
fi
|
||||||
'';
|
'';
|
||||||
|
@ -194,7 +191,7 @@ let
|
||||||
'';
|
'';
|
||||||
|
|
||||||
nixPath = ''
|
nixPath = ''
|
||||||
nixPath=${concatStringsSep ":" config.nix.nixPath}:$HOME/.nix-defexpr/channels
|
nixPath=${concatMapStringsSep ":" escapeDoubleQuote config.nix.nixPath}:$HOME/.nix-defexpr/channels
|
||||||
|
|
||||||
darwinConfig=$(NIX_PATH=$nixPath nix-instantiate --find-file darwin-config) || true
|
darwinConfig=$(NIX_PATH=$nixPath nix-instantiate --find-file darwin-config) || true
|
||||||
if ! test -e "$darwinConfig"; then
|
if ! test -e "$darwinConfig"; then
|
||||||
|
@ -282,6 +279,7 @@ let
|
||||||
if [[ -d /etc/ssh/authorized_keys.d ]]; then
|
if [[ -d /etc/ssh/authorized_keys.d ]]; then
|
||||||
printf >&2 '\e[1;31merror: /etc/ssh/authorized_keys.d exists, aborting activation\e[0m\n'
|
printf >&2 '\e[1;31merror: /etc/ssh/authorized_keys.d exists, aborting activation\e[0m\n'
|
||||||
printf >&2 'SECURITY NOTICE: The previous implementation of the\n'
|
printf >&2 'SECURITY NOTICE: The previous implementation of the\n'
|
||||||
|
# shellcheck disable=SC2016
|
||||||
printf >&2 '`users.users.<name>.openssh.authorizedKeys.*` options would not delete\n'
|
printf >&2 '`users.users.<name>.openssh.authorizedKeys.*` options would not delete\n'
|
||||||
printf >&2 'authorized keys files when the setting for a given user was removed.\n'
|
printf >&2 'authorized keys files when the setting for a given user was removed.\n'
|
||||||
printf >&2 '\n'
|
printf >&2 '\n'
|
||||||
|
@ -297,6 +295,19 @@ let
|
||||||
exit 2
|
exit 2
|
||||||
fi
|
fi
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
homebrewInstalled = ''
|
||||||
|
if [[ ! -f ${escapeShellArg config.homebrew.brewPrefix}/brew && -z "''${INSTALLING_HOMEBREW:-}" ]]; then
|
||||||
|
echo "[1;31merror: Using the homebrew module requires homebrew installed, aborting activation[0m" >&2
|
||||||
|
echo "Homebrew doesn't seem to be installed. Please install homebrew separately." >&2
|
||||||
|
echo "You can install homebrew using the following command:" >&2
|
||||||
|
echo >&2
|
||||||
|
# shellcheck disable=SC2016
|
||||||
|
echo ' /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"' >&2
|
||||||
|
echo >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
'';
|
||||||
in
|
in
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -337,7 +348,7 @@ in
|
||||||
(mkIf cfg.verifyBuildUsers buildUsers)
|
(mkIf cfg.verifyBuildUsers buildUsers)
|
||||||
(mkIf cfg.verifyBuildUsers preSequoiaBuildUsers)
|
(mkIf cfg.verifyBuildUsers preSequoiaBuildUsers)
|
||||||
(mkIf config.nix.configureBuildUsers buildGroupID)
|
(mkIf config.nix.configureBuildUsers buildGroupID)
|
||||||
(mkIf (!config.nix.useDaemon) singleUser)
|
nixDaemon
|
||||||
nixStore
|
nixStore
|
||||||
(mkIf (config.nix.gc.automatic && config.nix.gc.user == null) nixGarbageCollector)
|
(mkIf (config.nix.gc.automatic && config.nix.gc.user == null) nixGarbageCollector)
|
||||||
(mkIf (config.nix.optimise.automatic && config.nix.optimise.user == null) nixStoreOptimiser)
|
(mkIf (config.nix.optimise.automatic && config.nix.optimise.user == null) nixStoreOptimiser)
|
||||||
|
@ -345,12 +356,13 @@ in
|
||||||
nixInstaller
|
nixInstaller
|
||||||
(mkIf cfg.verifyNixPath nixPath)
|
(mkIf cfg.verifyNixPath nixPath)
|
||||||
oldSshAuthorizedKeysDirectory
|
oldSshAuthorizedKeysDirectory
|
||||||
|
(mkIf config.homebrew.enable homebrewInstalled)
|
||||||
];
|
];
|
||||||
|
|
||||||
system.activationScripts.checks.text = ''
|
system.activationScripts.checks.text = ''
|
||||||
${cfg.text}
|
${cfg.text}
|
||||||
|
|
||||||
if test ''${checkActivation:-0} -eq 1; then
|
if [[ "''${checkActivation:-0}" -eq 1 ]]; then
|
||||||
echo "ok" >&2
|
echo "ok" >&2
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -92,6 +92,8 @@ in
|
||||||
name = "darwin-system-${cfg.darwinLabel}";
|
name = "darwin-system-${cfg.darwinLabel}";
|
||||||
preferLocalBuild = true;
|
preferLocalBuild = true;
|
||||||
|
|
||||||
|
nativeBuildInputs = [ pkgs.shellcheck ];
|
||||||
|
|
||||||
activationScript = cfg.activationScripts.script.text;
|
activationScript = cfg.activationScripts.script.text;
|
||||||
activationUserScript = cfg.activationScripts.userScript.text;
|
activationUserScript = cfg.activationScripts.userScript.text;
|
||||||
inherit (cfg) darwinLabel;
|
inherit (cfg) darwinLabel;
|
||||||
|
@ -133,6 +135,8 @@ in
|
||||||
chmod u+x $out/activate-user
|
chmod u+x $out/activate-user
|
||||||
unset activationUserScript
|
unset activationUserScript
|
||||||
|
|
||||||
|
shellcheck $out/activate $out/activate-user
|
||||||
|
|
||||||
echo -n "$systemConfig" > $out/systemConfig
|
echo -n "$systemConfig" > $out/systemConfig
|
||||||
|
|
||||||
echo -n "$darwinLabel" > $out/darwin-version
|
echo -n "$darwinLabel" > $out/darwin-version
|
||||||
|
|
|
@ -14,7 +14,7 @@ let
|
||||||
alf = defaultsToList "/Library/Preferences/com.apple.alf" cfg.alf;
|
alf = defaultsToList "/Library/Preferences/com.apple.alf" cfg.alf;
|
||||||
loginwindow = defaultsToList "/Library/Preferences/com.apple.loginwindow" cfg.loginwindow;
|
loginwindow = defaultsToList "/Library/Preferences/com.apple.loginwindow" cfg.loginwindow;
|
||||||
smb = defaultsToList "/Library/Preferences/SystemConfiguration/com.apple.smb.server" cfg.smb;
|
smb = defaultsToList "/Library/Preferences/SystemConfiguration/com.apple.smb.server" cfg.smb;
|
||||||
SoftwareUpdate = defaultsToList "/Library/Preferences/SystemConfiguration/com.apple.SoftwareUpdate" cfg.SoftwareUpdate;
|
SoftwareUpdate = defaultsToList "/Library/Preferences/com.apple.SoftwareUpdate" cfg.SoftwareUpdate;
|
||||||
|
|
||||||
# userDefaults
|
# userDefaults
|
||||||
GlobalPreferences = defaultsToList ".GlobalPreferences" cfg.".GlobalPreferences";
|
GlobalPreferences = defaultsToList ".GlobalPreferences" cfg.".GlobalPreferences";
|
||||||
|
@ -23,6 +23,7 @@ let
|
||||||
menuExtraClock = defaultsToList "com.apple.menuextra.clock" cfg.menuExtraClock;
|
menuExtraClock = defaultsToList "com.apple.menuextra.clock" cfg.menuExtraClock;
|
||||||
dock = defaultsToList "com.apple.dock" cfg.dock;
|
dock = defaultsToList "com.apple.dock" cfg.dock;
|
||||||
finder = defaultsToList "com.apple.finder" cfg.finder;
|
finder = defaultsToList "com.apple.finder" cfg.finder;
|
||||||
|
hitoolbox = defaultsToList "com.apple.HIToolbox" cfg.hitoolbox;
|
||||||
magicmouse = defaultsToList "com.apple.AppleMultitouchMouse" cfg.magicmouse;
|
magicmouse = defaultsToList "com.apple.AppleMultitouchMouse" cfg.magicmouse;
|
||||||
magicmouseBluetooth = defaultsToList "com.apple.driver.AppleMultitouchMouse.mouse" cfg.magicmouse;
|
magicmouseBluetooth = defaultsToList "com.apple.driver.AppleMultitouchMouse.mouse" cfg.magicmouse;
|
||||||
screencapture = defaultsToList "com.apple.screencapture" cfg.screencapture;
|
screencapture = defaultsToList "com.apple.screencapture" cfg.screencapture;
|
||||||
|
@ -33,9 +34,11 @@ let
|
||||||
universalaccess = defaultsToList "com.apple.universalaccess" cfg.universalaccess;
|
universalaccess = defaultsToList "com.apple.universalaccess" cfg.universalaccess;
|
||||||
ActivityMonitor = defaultsToList "com.apple.ActivityMonitor" cfg.ActivityMonitor;
|
ActivityMonitor = defaultsToList "com.apple.ActivityMonitor" cfg.ActivityMonitor;
|
||||||
WindowManager = defaultsToList "com.apple.WindowManager" cfg.WindowManager;
|
WindowManager = defaultsToList "com.apple.WindowManager" cfg.WindowManager;
|
||||||
|
controlcenter = defaultsToList "~/Library/Preferences/ByHost/com.apple.controlcenter" cfg.controlcenter;
|
||||||
CustomUserPreferences = flatten (mapAttrsToList (name: value: defaultsToList name value) cfg.CustomUserPreferences);
|
CustomUserPreferences = flatten (mapAttrsToList (name: value: defaultsToList name value) cfg.CustomUserPreferences);
|
||||||
CustomSystemPreferences = flatten (mapAttrsToList (name: value: defaultsToList name value) cfg.CustomSystemPreferences);
|
CustomSystemPreferences = flatten (mapAttrsToList (name: value: defaultsToList name value) cfg.CustomSystemPreferences);
|
||||||
|
|
||||||
|
|
||||||
mkIfAttrs = list: mkIf (any (attrs: attrs != { }) list);
|
mkIfAttrs = list: mkIf (any (attrs: attrs != { }) list);
|
||||||
in
|
in
|
||||||
|
|
||||||
|
@ -76,6 +79,7 @@ in
|
||||||
menuExtraClock
|
menuExtraClock
|
||||||
dock
|
dock
|
||||||
finder
|
finder
|
||||||
|
hitoolbox
|
||||||
magicmouse
|
magicmouse
|
||||||
magicmouseBluetooth
|
magicmouseBluetooth
|
||||||
screencapture
|
screencapture
|
||||||
|
@ -87,6 +91,7 @@ in
|
||||||
ActivityMonitor
|
ActivityMonitor
|
||||||
CustomUserPreferences
|
CustomUserPreferences
|
||||||
WindowManager
|
WindowManager
|
||||||
|
controlcenter
|
||||||
]
|
]
|
||||||
''
|
''
|
||||||
# Set defaults
|
# Set defaults
|
||||||
|
@ -99,6 +104,7 @@ in
|
||||||
${concatStringsSep "\n" menuExtraClock}
|
${concatStringsSep "\n" menuExtraClock}
|
||||||
${concatStringsSep "\n" dock}
|
${concatStringsSep "\n" dock}
|
||||||
${concatStringsSep "\n" finder}
|
${concatStringsSep "\n" finder}
|
||||||
|
${concatStringsSep "\n" hitoolbox}
|
||||||
${concatStringsSep "\n" magicmouse}
|
${concatStringsSep "\n" magicmouse}
|
||||||
${concatStringsSep "\n" magicmouseBluetooth}
|
${concatStringsSep "\n" magicmouseBluetooth}
|
||||||
${concatStringsSep "\n" screencapture}
|
${concatStringsSep "\n" screencapture}
|
||||||
|
@ -110,10 +116,11 @@ in
|
||||||
${concatStringsSep "\n" ActivityMonitor}
|
${concatStringsSep "\n" ActivityMonitor}
|
||||||
${concatStringsSep "\n" CustomUserPreferences}
|
${concatStringsSep "\n" CustomUserPreferences}
|
||||||
${concatStringsSep "\n" WindowManager}
|
${concatStringsSep "\n" WindowManager}
|
||||||
|
${concatStringsSep "\n" controlcenter}
|
||||||
|
|
||||||
${optionalString (length dock > 0) ''
|
${optionalString (length dock > 0) ''
|
||||||
# Only restart Dock if current user is logged in
|
# Only restart Dock if current user is logged in
|
||||||
if pgrep -xu $UID Dock; then
|
if pgrep -xu $UID Dock >/dev/null; then
|
||||||
echo >&2 "restarting Dock..."
|
echo >&2 "restarting Dock..."
|
||||||
killall Dock || true
|
killall Dock || true
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -5,6 +5,14 @@ with lib;
|
||||||
{
|
{
|
||||||
options = {
|
options = {
|
||||||
|
|
||||||
|
system.defaults.menuExtraClock.FlashDateSeparators = mkOption {
|
||||||
|
type = types.nullOr types.bool;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
When enabled, the clock indicator (which by default is the colon) will flash on and off each second. Default is null.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
system.defaults.menuExtraClock.IsAnalog = mkOption {
|
system.defaults.menuExtraClock.IsAnalog = mkOption {
|
||||||
type = types.nullOr types.bool;
|
type = types.nullOr types.bool;
|
||||||
default = null;
|
default = null;
|
||||||
|
|
100
modules/system/defaults/controlcenter.nix
Normal file
100
modules/system/defaults/controlcenter.nix
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
{ config, lib, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
|
||||||
|
system.defaults.controlcenter.BatteryShowPercentage = lib.mkOption {
|
||||||
|
type = lib.types.nullOr lib.types.bool;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Apple menu > System Preferences > Control Center > Battery
|
||||||
|
|
||||||
|
Show a battery percentage in menu bar. Default is null.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
system.defaults.controlcenter.Sound = lib.mkOption {
|
||||||
|
type = lib.types.nullOr lib.types.bool;
|
||||||
|
apply = v: if v == null then null else if v == true then 18 else 24;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Apple menu > System Preferences > Control Center > Sound
|
||||||
|
|
||||||
|
Show a sound control in menu bar . Default is null.
|
||||||
|
|
||||||
|
18 = Display icon in menu bar
|
||||||
|
24 = Hide icon in menu bar
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
system.defaults.controlcenter.Bluetooth = lib.mkOption {
|
||||||
|
type = lib.types.nullOr lib.types.bool;
|
||||||
|
apply = v: if v == null then null else if v == true then 18 else 24;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Apple menu > System Preferences > Control Center > Bluetooth
|
||||||
|
|
||||||
|
Show a bluetooth control in menu bar. Default is null.
|
||||||
|
|
||||||
|
18 = Display icon in menu bar
|
||||||
|
24 = Hide icon in menu bar
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
system.defaults.controlcenter.AirDrop = lib.mkOption {
|
||||||
|
type = lib.types.nullOr lib.types.bool;
|
||||||
|
apply = v: if v == null then null else if v == true then 18 else 24;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Apple menu > System Preferences > Control Center > AirDrop
|
||||||
|
|
||||||
|
Show a AirDrop control in menu bar. Default is null.
|
||||||
|
|
||||||
|
18 = Display icon in menu bar
|
||||||
|
24 = Hide icon in menu bar
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
system.defaults.controlcenter.Display = lib.mkOption {
|
||||||
|
type = lib.types.nullOr lib.types.bool;
|
||||||
|
apply = v: if v == null then null else if v == true then 18 else 24;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Apple menu > System Preferences > Control Center > Display
|
||||||
|
|
||||||
|
Show a Screen Brightness control in menu bar. Default is null.
|
||||||
|
|
||||||
|
18 = Display icon in menu bar
|
||||||
|
24 = Hide icon in menu bar
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
system.defaults.controlcenter.FocusModes = lib.mkOption {
|
||||||
|
type = lib.types.nullOr lib.types.bool;
|
||||||
|
apply = v: if v == null then null else if v == true then 18 else 24;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Apple menu > System Preferences > Control Center > Focus
|
||||||
|
|
||||||
|
Show a Focus control in menu bar. Default is null.
|
||||||
|
|
||||||
|
18 = Display icon in menu bar
|
||||||
|
24 = Hide icon in menu bar
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
system.defaults.controlcenter.NowPlaying = lib.mkOption {
|
||||||
|
type = lib.types.nullOr lib.types.bool;
|
||||||
|
apply = v: if v == null then null else if v == true then 18 else 24;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Apple menu > System Preferences > Control Center > Now Playing
|
||||||
|
|
||||||
|
Show a Now Playing control in menu bar. Default is null.
|
||||||
|
|
||||||
|
18 = Display icon in menu bar
|
||||||
|
24 = Hide icon in menu bar
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -149,6 +149,14 @@ in {
|
||||||
else map (folder: { tile-data = { file-data = { _CFURLString = "file://" + folder; _CFURLStringType = 15; }; }; tile-type = if strings.hasInfix "." (last (splitString "/" folder)) then "file-tile" else "directory-tile"; }) value;
|
else map (folder: { tile-data = { file-data = { _CFURLString = "file://" + folder; _CFURLStringType = 15; }; }; tile-type = if strings.hasInfix "." (last (splitString "/" folder)) then "file-tile" else "directory-tile"; }) value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
system.defaults.dock.scroll-to-open = mkOption {
|
||||||
|
type = types.nullOr types.bool;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Scroll up on a Dock icon to show all Space's opened windows for an app, or open stack. The default is false.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
system.defaults.dock.show-process-indicators = mkOption {
|
system.defaults.dock.show-process-indicators = mkOption {
|
||||||
type = types.nullOr types.bool;
|
type = types.nullOr types.bool;
|
||||||
default = null;
|
default = null;
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
{ config, lib, ... }:
|
{ config, lib, ... }:
|
||||||
|
|
||||||
with lib;
|
let
|
||||||
|
inherit (lib) mkOption types;
|
||||||
|
|
||||||
|
cfg = config.system.defaults.finder;
|
||||||
|
in
|
||||||
{
|
{
|
||||||
options = {
|
options = {
|
||||||
|
|
||||||
|
@ -38,6 +41,15 @@ with lib;
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
system.defaults.finder.FXRemoveOldTrashItems = mkOption {
|
||||||
|
type = types.nullOr types.bool;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Remove items in the trash after 30 days.
|
||||||
|
The default is false.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
system.defaults.finder.FXPreferredViewStyle = mkOption {
|
system.defaults.finder.FXPreferredViewStyle = mkOption {
|
||||||
type = types.nullOr types.str;
|
type = types.nullOr types.str;
|
||||||
default = null;
|
default = null;
|
||||||
|
@ -72,6 +84,38 @@ with lib;
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
system.defaults.finder.ShowExternalHardDrivesOnDesktop = mkOption {
|
||||||
|
type = types.nullOr types.bool;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Whether to show external disks on desktop. The default is true.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
system.defaults.finder.ShowHardDrivesOnDesktop = mkOption {
|
||||||
|
type = types.nullOr types.bool;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Whether to show hard disks on desktop. The default is false.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
system.defaults.finder.ShowMountedServersOnDesktop = mkOption {
|
||||||
|
type = types.nullOr types.bool;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Whether to show connected servers on desktop. The default is false.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
system.defaults.finder.ShowRemovableMediaOnDesktop = mkOption {
|
||||||
|
type = types.nullOr types.bool;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Whether to show removable media (CDs, DVDs and iPods) on desktop. The default is true.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
system.defaults.finder._FXShowPosixPathInTitle = mkOption {
|
system.defaults.finder._FXShowPosixPathInTitle = mkOption {
|
||||||
type = types.nullOr types.bool;
|
type = types.nullOr types.bool;
|
||||||
default = null;
|
default = null;
|
||||||
|
@ -88,6 +132,14 @@ with lib;
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
system.defaults.finder._FXSortFoldersFirstOnDesktop = mkOption {
|
||||||
|
type = types.nullOr types.bool;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Keep folders on top when sorting by name on the desktop. The default is false.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
system.defaults.finder.FXEnableExtensionChangeWarning = mkOption {
|
system.defaults.finder.FXEnableExtensionChangeWarning = mkOption {
|
||||||
type = types.nullOr types.bool;
|
type = types.nullOr types.bool;
|
||||||
default = null;
|
default = null;
|
||||||
|
@ -96,5 +148,54 @@ with lib;
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
system.defaults.finder.NewWindowTarget = mkOption {
|
||||||
|
type = types.nullOr (types.enum [
|
||||||
|
"Computer"
|
||||||
|
"OS volume"
|
||||||
|
"Home"
|
||||||
|
"Desktop"
|
||||||
|
"Documents"
|
||||||
|
"Recents"
|
||||||
|
"iCloud Drive"
|
||||||
|
"Other"
|
||||||
|
]);
|
||||||
|
apply = key: if key == null then null else {
|
||||||
|
"Computer" = "PfCm";
|
||||||
|
"OS volume" = "PfVo";
|
||||||
|
"Home" = "PfHm";
|
||||||
|
"Desktop" = "PfDe";
|
||||||
|
"Documents" = "PfDo";
|
||||||
|
"Recents" = "PfAF";
|
||||||
|
"iCloud Drive" = "PfID";
|
||||||
|
"Other" = "PfLo";
|
||||||
|
}.${key};
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Change the default folder shown in Finder windows. "Other" corresponds to the value of
|
||||||
|
NewWindowTargetPath. The default is unset ("Recents").
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
system.defaults.finder.NewWindowTargetPath = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Sets the URI to open when NewWindowTarget is "Other". Spaces and similar characters must be
|
||||||
|
escaped. If the value is invalid, Finder will open your home directory.
|
||||||
|
Example: "file:///Users/foo/long%20cat%20pics".
|
||||||
|
The default is unset.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
assertions = [{
|
||||||
|
assertion = cfg.NewWindowTargetPath != null -> cfg.NewWindowTarget == "PfLo";
|
||||||
|
message = "`system.defaults.finder.NewWindowTarget` should be set to `Other` when `NewWindowTargetPath` is non-null.";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
assertion = cfg.NewWindowTarget == "PfLo" -> cfg.NewWindowTargetPath != null;
|
||||||
|
message = "`system.defaults.finder.NewWindowTargetPath` should be non-null when `NewWindowTarget` is set to `Other`.";
|
||||||
|
}];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
29
modules/system/defaults/hitoolbox.nix
Normal file
29
modules/system/defaults/hitoolbox.nix
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
{ lib, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
|
||||||
|
system.defaults.hitoolbox.AppleFnUsageType = lib.mkOption {
|
||||||
|
type = lib.types.nullOr (lib.types.enum [
|
||||||
|
"Do Nothing"
|
||||||
|
"Change Input Source"
|
||||||
|
"Show Emoji & Symbols"
|
||||||
|
"Start Dictation"
|
||||||
|
]);
|
||||||
|
apply = key: if key == null then null else {
|
||||||
|
"Do Nothing" = 0;
|
||||||
|
"Change Input Source" = 1;
|
||||||
|
"Show Emoji & Symbols" = 2;
|
||||||
|
"Start Dictation" = 3;
|
||||||
|
}.${key};
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Chooses what happens when you press the Fn key on the keyboard. A restart is required for
|
||||||
|
this setting to take effect.
|
||||||
|
|
||||||
|
The default is unset ("Show Emoji & Symbols").
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
|
@ -29,6 +29,18 @@ with lib;
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
system.defaults.screencapture.include-date = mkOption {
|
||||||
|
type = types.nullOr types.bool;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Include date and time in screenshot filenames. The default is true.
|
||||||
|
Screenshot 2024-01-09 at 13.27.20.png would be an example for true.
|
||||||
|
|
||||||
|
Screenshot.png
|
||||||
|
Screenshot 1.png would be an example for false.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
system.defaults.screencapture.show-thumbnail = mkOption {
|
system.defaults.screencapture.show-thumbnail = mkOption {
|
||||||
type = types.nullOr types.bool;
|
type = types.nullOr types.bool;
|
||||||
default = null;
|
default = null;
|
||||||
|
|
|
@ -105,19 +105,29 @@ in
|
||||||
${concatMapStringsSep "\n" (attr: launchdActivation "LaunchAgents" attr.target) launchAgents}
|
${concatMapStringsSep "\n" (attr: launchdActivation "LaunchAgents" attr.target) launchAgents}
|
||||||
${concatMapStringsSep "\n" (attr: launchdActivation "LaunchDaemons" attr.target) launchDaemons}
|
${concatMapStringsSep "\n" (attr: launchdActivation "LaunchDaemons" attr.target) launchDaemons}
|
||||||
|
|
||||||
for f in $(ls /run/current-system/Library/LaunchAgents 2> /dev/null); do
|
for f in /run/current-system/Library/LaunchAgents/*; do
|
||||||
if test ! -e "${cfg.build.launchd}/Library/LaunchAgents/$f"; then
|
[[ -e "$f" ]] || break # handle when directory is empty
|
||||||
echo "removing service $(basename $f .plist)" >&2
|
f=''${f#/run/current-system/Library/LaunchAgents/}
|
||||||
|
|
||||||
|
if [[ ! -e "${cfg.build.launchd}/Library/LaunchAgents/$f" ]]; then
|
||||||
|
echo "removing service $(basename "$f" .plist)" >&2
|
||||||
launchctl unload "/Library/LaunchAgents/$f" || true
|
launchctl unload "/Library/LaunchAgents/$f" || true
|
||||||
if test -e "/Library/LaunchAgents/$f"; then rm -f "/Library/LaunchAgents/$f"; fi
|
if [[ -e "/Library/LaunchAgents/$f" ]]; then
|
||||||
|
rm -f "/Library/LaunchAgents/$f"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
for f in $(ls /run/current-system/Library/LaunchDaemons 2> /dev/null); do
|
for f in /run/current-system/Library/LaunchDaemons/*; do
|
||||||
if test ! -e "${cfg.build.launchd}/Library/LaunchDaemons/$f"; then
|
[[ -e "$f" ]] || break # handle when directory is empty
|
||||||
echo "removing service $(basename $f .plist)" >&2
|
f=''${f#/run/current-system/Library/LaunchDaemons/}
|
||||||
|
|
||||||
|
if [[ ! -e "${cfg.build.launchd}/Library/LaunchDaemons/$f" ]]; then
|
||||||
|
echo "removing service $(basename "$f" .plist)" >&2
|
||||||
launchctl unload "/Library/LaunchDaemons/$f" || true
|
launchctl unload "/Library/LaunchDaemons/$f" || true
|
||||||
if test -e "/Library/LaunchDaemons/$f"; then rm -f "/Library/LaunchDaemons/$f"; fi
|
if [[ -e "/Library/LaunchDaemons/$f" ]]; then
|
||||||
|
rm -f "/Library/LaunchDaemons/$f"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
'';
|
'';
|
||||||
|
@ -133,11 +143,16 @@ in
|
||||||
''}
|
''}
|
||||||
${concatMapStringsSep "\n" (attr: userLaunchdActivation attr.target) userLaunchAgents}
|
${concatMapStringsSep "\n" (attr: userLaunchdActivation attr.target) userLaunchAgents}
|
||||||
|
|
||||||
for f in $(ls /run/current-system/user/Library/LaunchAgents 2> /dev/null); do
|
for f in /run/current-system/user/Library/LaunchAgents/*; do
|
||||||
if test ! -e "${cfg.build.launchd}/user/Library/LaunchAgents/$f"; then
|
[[ -e "$f" ]] || break # handle when directory is empty
|
||||||
echo "removing user service $(basename $f .plist)" >&2
|
f=''${f#/run/current-system/user/Library/LaunchAgents/}
|
||||||
launchctl unload ~/Library/LaunchAgents/$f || true
|
|
||||||
if test -e ~/Library/LaunchAgents/$f; then rm -f ~/Library/LaunchAgents/$f; fi
|
if [[ ! -e "${cfg.build.launchd}/user/Library/LaunchAgents/$f" ]]; then
|
||||||
|
echo "removing user service $(basename "$f" .plist)" >&2
|
||||||
|
launchctl unload ~/Library/LaunchAgents/"$f" || true
|
||||||
|
if [[ -e ~/Library/LaunchAgents/"$f" ]]; then
|
||||||
|
rm -f ~/Library/LaunchAgents/"$f"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
'';
|
'';
|
||||||
|
|
|
@ -56,8 +56,11 @@ in
|
||||||
# Applying patches to /.
|
# Applying patches to /.
|
||||||
echo "applying patches..." >&2
|
echo "applying patches..." >&2
|
||||||
|
|
||||||
for f in $(ls /run/current-system/patches 2> /dev/null); do
|
for f in /run/current-system/patches/*; do
|
||||||
if test ! -e "${config.system.build.patches}/patches/$f"; then
|
[[ -e "$f" ]] || break # handle when directory is empty
|
||||||
|
f=''${f#/run/current-system/patches/}
|
||||||
|
|
||||||
|
if [[ ! -e "${config.system.build.patches}/patches/$f" ]]; then
|
||||||
patch --force --reverse --backup -d / -p1 < "/run/current-system/patches/$f" || true
|
patch --force --reverse --backup -d / -p1 < "/run/current-system/patches/$f" || true
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
|
@ -14,9 +14,15 @@ in
|
||||||
example = literalExpression "[ pkgs.bashInteractive pkgs.zsh ]";
|
example = literalExpression "[ pkgs.bashInteractive pkgs.zsh ]";
|
||||||
description = ''
|
description = ''
|
||||||
A list of permissible login shells for user accounts.
|
A list of permissible login shells for user accounts.
|
||||||
No need to mention `/bin/sh`
|
|
||||||
and other shells that are available by default on
|
The default macOS shells will be automatically included:
|
||||||
macOS.
|
- /bin/bash
|
||||||
|
- /bin/csh
|
||||||
|
- /bin/dash
|
||||||
|
- /bin/ksh
|
||||||
|
- /bin/sh
|
||||||
|
- /bin/tcsh
|
||||||
|
- /bin/zsh
|
||||||
'';
|
'';
|
||||||
apply = map (v: if types.shellPackage.check v then "/run/current-system/sw${v.shellPath}" else v);
|
apply = map (v: if types.shellPackage.check v then "/run/current-system/sw${v.shellPath}" else v);
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,7 +7,7 @@ let
|
||||||
cfg = config.time;
|
cfg = config.time;
|
||||||
|
|
||||||
timeZone = optionalString (cfg.timeZone != null) ''
|
timeZone = optionalString (cfg.timeZone != null) ''
|
||||||
if [ -z $(systemsetup -listtimezones | grep "^ ${cfg.timeZone}$") ]; then
|
if ! systemsetup -listtimezones | grep -q "^ ${cfg.timeZone}$"; then
|
||||||
echo "${cfg.timeZone} is not a valid timezone. The command 'listtimezones' will show a list of valid time zones." >&2
|
echo "${cfg.timeZone} is not a valid timezone. The command 'listtimezones' will show a list of valid time zones." >&2
|
||||||
false
|
false
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
let
|
let
|
||||||
|
inherit (lib) concatStringsSep concatMapStringsSep elem escapeShellArg
|
||||||
|
escapeShellArgs filter filterAttrs flatten flip mapAttrs' mapAttrsToList
|
||||||
|
mkAfter mkIf mkMerge mkOption mkOrder mkRemovedOptionModule optionals
|
||||||
|
optionalString types;
|
||||||
|
|
||||||
cfg = config.users;
|
cfg = config.users;
|
||||||
|
|
||||||
group = import ./group.nix;
|
group = import ./group.nix;
|
||||||
user = import ./user.nix;
|
user = import ./user.nix;
|
||||||
|
|
||||||
toArguments = concatMapStringsSep " " (v: "'${v}'");
|
|
||||||
toGID = v: { "${toString v.gid}" = v.name; };
|
toGID = v: { "${toString v.gid}" = v.name; };
|
||||||
toUID = v: { "${toString v.uid}" = v.name; };
|
toUID = v: { "${toString v.uid}" = v.name; };
|
||||||
|
|
||||||
|
@ -32,9 +34,19 @@ let
|
||||||
then "/run/current-system/sw${v.shellPath}"
|
then "/run/current-system/sw${v.shellPath}"
|
||||||
else v;
|
else v;
|
||||||
|
|
||||||
|
systemShells =
|
||||||
|
let
|
||||||
|
shells = mapAttrsToList (_: u: u.shell) cfg.users;
|
||||||
|
in
|
||||||
|
filter types.shellPackage.check shells;
|
||||||
|
|
||||||
in
|
in
|
||||||
|
|
||||||
{
|
{
|
||||||
|
imports = [
|
||||||
|
(mkRemovedOptionModule [ "users" "forceRecreate" ] "")
|
||||||
|
];
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
users.knownGroups = mkOption {
|
users.knownGroups = mkOption {
|
||||||
type = types.listOf types.str;
|
type = types.listOf types.str;
|
||||||
|
@ -79,62 +91,185 @@ in
|
||||||
type = types.attrsOf types.str;
|
type = types.attrsOf types.str;
|
||||||
default = {};
|
default = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
users.forceRecreate = mkOption {
|
|
||||||
internal = true;
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = "Remove and recreate existing groups/users.";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
|
assertions = [
|
||||||
|
{
|
||||||
|
# We don't check `root` like the rest of the users as on some systems `root`'s
|
||||||
|
# home directory is set to `/var/root /private/var/root`
|
||||||
|
assertion = cfg.users ? root -> (cfg.users.root.home == null || cfg.users.root.home == "/var/root");
|
||||||
|
message = "`users.users.root.home` must be set to either `null` or `/var/root`.";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
assertion = !builtins.elem "root" deletedUsers;
|
||||||
|
message = "Remove `root` from `users.knownUsers` if you no longer want nix-darwin to manage it.";
|
||||||
|
}
|
||||||
|
] ++ flatten (flip mapAttrsToList cfg.users (name: user:
|
||||||
|
map (shell: {
|
||||||
|
assertion = let
|
||||||
|
s = user.shell.pname or null;
|
||||||
|
in
|
||||||
|
!user.ignoreShellProgramCheck -> (s == shell || (shell == "bash" && s == "bash-interactive")) -> (config.programs.${shell}.enable == true);
|
||||||
|
message = ''
|
||||||
|
users.users.${user.name}.shell is set to ${shell}, but
|
||||||
|
programs.${shell}.enable is not true. This will cause the ${shell}
|
||||||
|
shell to lack the basic Nix directories in its PATH and might make
|
||||||
|
logging in as that user impossible. You can fix it with:
|
||||||
|
programs.${shell}.enable = true;
|
||||||
|
|
||||||
|
If you know what you're doing and you are fine with the behavior,
|
||||||
|
set users.users.${user.name}.ignoreShellProgramCheck = true;
|
||||||
|
instead.
|
||||||
|
'';
|
||||||
|
}) [
|
||||||
|
"bash"
|
||||||
|
"fish"
|
||||||
|
"zsh"
|
||||||
|
]
|
||||||
|
));
|
||||||
|
|
||||||
|
warnings = flatten (flip mapAttrsToList cfg.users (name: user:
|
||||||
|
mkIf
|
||||||
|
(user.shell.pname or null == "bash")
|
||||||
|
"Set `users.users.${name}.shell = pkgs.bashInteractive;` instead of `pkgs.bash` as it does not include `readline`."
|
||||||
|
));
|
||||||
|
|
||||||
users.gids = mkMerge gids;
|
users.gids = mkMerge gids;
|
||||||
users.uids = mkMerge uids;
|
users.uids = mkMerge uids;
|
||||||
|
|
||||||
|
# NOTE: We put this in `system.checks` as we want this to run first to avoid partial activations
|
||||||
|
# however currently that runs at user level activation as that runs before system level activation
|
||||||
|
# TODO: replace `$USER` with `$SUDO_USER` when system.checks runs from system level
|
||||||
|
system.checks.text = mkIf (builtins.length (createdUsers ++ deletedUsers) > 0) (mkAfter ''
|
||||||
|
ensurePerms() {
|
||||||
|
homeDirectory=$(dscl . -read /Users/nobody NFSHomeDirectory)
|
||||||
|
homeDirectory=''${homeDirectory#NFSHomeDirectory: }
|
||||||
|
|
||||||
|
if ! sudo dscl . -change /Users/nobody NFSHomeDirectory "$homeDirectory" "$homeDirectory" &> /dev/null; then
|
||||||
|
if [[ -n "$SSH_CONNECTION" ]]; then
|
||||||
|
printf >&2 '\e[1;31merror: users cannot be %s over SSH without Full Disk Access, aborting activation\e[0m\n' "$2"
|
||||||
|
# shellcheck disable=SC2016
|
||||||
|
printf >&2 'The user %s could not be %s as `darwin-rebuild` was not executed with Full Disk Access over SSH.\n' "$1" "$2"
|
||||||
|
printf >&2 'You can either:\n'
|
||||||
|
printf >&2 '\n'
|
||||||
|
printf >&2 ' grant Full Disk Access to all programs run over SSH\n'
|
||||||
|
printf >&2 '\n'
|
||||||
|
printf >&2 'or\n'
|
||||||
|
printf >&2 '\n'
|
||||||
|
# shellcheck disable=SC2016
|
||||||
|
printf >&2 ' run `darwin-rebuild` in a graphical session.\n'
|
||||||
|
printf >&2 '\n'
|
||||||
|
printf >&2 'The option "Allow full disk access for remote users" can be found by\n'
|
||||||
|
printf >&2 'navigating to System Settings > General > Sharing > Remote Login\n'
|
||||||
|
printf >&2 'and then pressing on the i icon next to the switch.\n'
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
# The TCC service required to change home directories is `kTCCServiceSystemPolicySysAdminFiles`
|
||||||
|
# and we can reset it to ensure the user gets another prompt
|
||||||
|
tccutil reset SystemPolicySysAdminFiles > /dev/null
|
||||||
|
|
||||||
|
if ! sudo dscl . -change /Users/nobody NFSHomeDirectory "$homeDirectory" "$homeDirectory" &> /dev/null; then
|
||||||
|
printf >&2 '\e[1;31merror: permission denied when trying to %s user %s, aborting activation\e[0m\n' "$2" "$1"
|
||||||
|
# shellcheck disable=SC2016
|
||||||
|
printf >&2 '`darwin-rebuild` requires permissions to administrate your computer,\n'
|
||||||
|
printf >&2 'please accept the dialog that pops up.\n'
|
||||||
|
printf >&2 '\n'
|
||||||
|
# shellcheck disable=SC2016
|
||||||
|
printf >&2 'If you do not wish to be prompted every time `darwin-rebuild updates your users,\n'
|
||||||
|
printf >&2 'you can grant Full Disk Access to your terminal emulator in System Settings.\n'
|
||||||
|
printf >&2 '\n'
|
||||||
|
printf >&2 'This can be found in System Settings > Privacy & Security > Full Disk Access.\n'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
${concatMapStringsSep "\n" (v: let
|
||||||
|
name = escapeShellArg v.name;
|
||||||
|
dsclUser = escapeShellArg "/Users/${v.name}";
|
||||||
|
in ''
|
||||||
|
u=$(id -u ${name} 2> /dev/null) || true
|
||||||
|
if ! [[ -n "$u" && "$u" -ne "${toString v.uid}" ]]; then
|
||||||
|
if [ -z "$u" ]; then
|
||||||
|
ensurePerms ${name} create
|
||||||
|
|
||||||
|
${optionalString (v.home != null && v.name != "root") ''
|
||||||
|
else
|
||||||
|
homeDirectory=$(dscl . -read ${dsclUser} NFSHomeDirectory)
|
||||||
|
homeDirectory=''${homeDirectory#NFSHomeDirectory: }
|
||||||
|
if [[ ${escapeShellArg v.home} != "$homeDirectory" ]]; then
|
||||||
|
printf >&2 '\e[1;31merror: config contains the wrong home directory for %s, aborting activation\e[0m\n' ${name}
|
||||||
|
printf >&2 'nix-darwin does not support changing the home directory of existing users.\n'
|
||||||
|
printf >&2 '\n'
|
||||||
|
printf >&2 'Please set:\n'
|
||||||
|
printf >&2 '\n'
|
||||||
|
printf >&2 ' users.users.%s.home = "%s";\n' ${name} "$homeDirectory"
|
||||||
|
printf >&2 '\n'
|
||||||
|
printf >&2 'or remove it from your configuration.\n'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
''}
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
'') createdUsers}
|
||||||
|
|
||||||
|
${concatMapStringsSep "\n" (v: let
|
||||||
|
name = escapeShellArg v;
|
||||||
|
in ''
|
||||||
|
u=$(id -u ${name} 2> /dev/null) || true
|
||||||
|
if [ -n "$u" ]; then
|
||||||
|
if [ "$u" -gt 501 ]; then
|
||||||
|
# TODO: add `darwin.primaryUser` as well
|
||||||
|
if [[ ${name} == "$USER" ]]; then
|
||||||
|
# shellcheck disable=SC2016
|
||||||
|
printf >&2 '\e[1;31merror: refusing to delete the user calling `darwin-rebuild` (%s), aborting activation\e[0m\n', ${name}
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
ensurePerms ${name} delete
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
'') deletedUsers}
|
||||||
|
'');
|
||||||
|
|
||||||
system.activationScripts.groups.text = mkIf (cfg.knownGroups != []) ''
|
system.activationScripts.groups.text = mkIf (cfg.knownGroups != []) ''
|
||||||
echo "setting up groups..." >&2
|
echo "setting up groups..." >&2
|
||||||
|
|
||||||
${concatMapStringsSep "\n" (v: ''
|
${concatMapStringsSep "\n" (v: let
|
||||||
${optionalString cfg.forceRecreate ''
|
dsclGroup = escapeShellArg "/Groups/${v.name}";
|
||||||
g=$(dscl . -read '/Groups/${v.name}' PrimaryGroupID 2> /dev/null) || true
|
in ''
|
||||||
g=''${g#PrimaryGroupID: }
|
g=$(dscl . -read ${dsclGroup} PrimaryGroupID 2> /dev/null) || true
|
||||||
if [[ "$g" -eq ${toString v.gid} ]]; then
|
|
||||||
echo "deleting group ${v.name}..." >&2
|
|
||||||
dscl . -delete '/Groups/${v.name}' 2> /dev/null
|
|
||||||
else
|
|
||||||
echo "[1;31mwarning: existing group '${v.name}' has unexpected gid $g, skipping...[0m" >&2
|
|
||||||
fi
|
|
||||||
''}
|
|
||||||
|
|
||||||
g=$(dscl . -read '/Groups/${v.name}' PrimaryGroupID 2> /dev/null) || true
|
|
||||||
g=''${g#PrimaryGroupID: }
|
g=''${g#PrimaryGroupID: }
|
||||||
if [ -z "$g" ]; then
|
if [ -z "$g" ]; then
|
||||||
echo "creating group ${v.name}..." >&2
|
echo "creating group ${v.name}..." >&2
|
||||||
dscl . -create '/Groups/${v.name}' PrimaryGroupID ${toString v.gid}
|
dscl . -create ${dsclGroup} PrimaryGroupID ${toString v.gid}
|
||||||
dscl . -create '/Groups/${v.name}' RealName '${v.description}'
|
dscl . -create ${dsclGroup} RealName ${escapeShellArg v.description}
|
||||||
g=${toString v.gid}
|
g=${toString v.gid}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$g" -eq ${toString v.gid} ]; then
|
if [ "$g" -eq ${toString v.gid} ]; then
|
||||||
g=$(dscl . -read '/Groups/${v.name}' GroupMembership 2> /dev/null) || true
|
g=$(dscl . -read ${dsclGroup} GroupMembership 2> /dev/null) || true
|
||||||
if [ "$g" != 'GroupMembership: ${concatStringsSep " " v.members}' ]; then
|
if [ "$g" != 'GroupMembership: ${concatStringsSep " " v.members}' ]; then
|
||||||
echo "updating group members ${v.name}..." >&2
|
echo "updating group members ${v.name}..." >&2
|
||||||
dscl . -create '/Groups/${v.name}' GroupMembership ${toArguments v.members}
|
dscl . -create ${dsclGroup} GroupMembership ${escapeShellArgs v.members}
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
echo "[1;31mwarning: existing group '${v.name}' has unexpected gid $g, skipping...[0m" >&2
|
echo "[1;31mwarning: existing group '${v.name}' has unexpected gid $g, skipping...[0m" >&2
|
||||||
fi
|
fi
|
||||||
'') createdGroups}
|
'') createdGroups}
|
||||||
|
|
||||||
${concatMapStringsSep "\n" (name: ''
|
${concatMapStringsSep "\n" (name: let
|
||||||
g=$(dscl . -read '/Groups/${name}' PrimaryGroupID 2> /dev/null) || true
|
dsclGroup = escapeShellArg "/Groups/${name}";
|
||||||
|
in ''
|
||||||
|
g=$(dscl . -read ${dsclGroup} PrimaryGroupID 2> /dev/null) || true
|
||||||
g=''${g#PrimaryGroupID: }
|
g=''${g#PrimaryGroupID: }
|
||||||
if [ -n "$g" ]; then
|
if [ -n "$g" ]; then
|
||||||
if [ "$g" -gt 501 ]; then
|
if [ "$g" -gt 501 ]; then
|
||||||
echo "deleting group ${name}..." >&2
|
echo "deleting group ${name}..." >&2
|
||||||
dscl . -delete '/Groups/${name}' 2> /dev/null
|
dscl . -delete ${dsclGroup}
|
||||||
else
|
else
|
||||||
echo "[1;31mwarning: existing group '${name}' has unexpected gid $g, skipping...[0m" >&2
|
echo "[1;31mwarning: existing group '${name}' has unexpected gid $g, skipping...[0m" >&2
|
||||||
fi
|
fi
|
||||||
|
@ -145,44 +280,51 @@ in
|
||||||
system.activationScripts.users.text = mkIf (cfg.knownUsers != []) ''
|
system.activationScripts.users.text = mkIf (cfg.knownUsers != []) ''
|
||||||
echo "setting up users..." >&2
|
echo "setting up users..." >&2
|
||||||
|
|
||||||
${concatMapStringsSep "\n" (v: ''
|
${concatMapStringsSep "\n" (v: let
|
||||||
${optionalString cfg.forceRecreate ''
|
name = escapeShellArg v.name;
|
||||||
u=$(dscl . -read '/Users/${v.name}' UniqueID 2> /dev/null) || true
|
dsclUser = escapeShellArg "/Users/${v.name}";
|
||||||
u=''${u#UniqueID: }
|
in ''
|
||||||
if [[ "$u" -eq ${toString v.uid} ]]; then
|
u=$(id -u ${name} 2> /dev/null) || true
|
||||||
echo "deleting user ${v.name}..." >&2
|
|
||||||
dscl . -delete '/Users/${v.name}' 2> /dev/null
|
|
||||||
else
|
|
||||||
echo "[1;31mwarning: existing user '${v.name}' has unexpected uid $u, skipping...[0m" >&2
|
|
||||||
fi
|
|
||||||
''}
|
|
||||||
|
|
||||||
u=$(dscl . -read '/Users/${v.name}' UniqueID 2> /dev/null) || true
|
|
||||||
u=''${u#UniqueID: }
|
|
||||||
if [[ -n "$u" && "$u" -ne "${toString v.uid}" ]]; then
|
if [[ -n "$u" && "$u" -ne "${toString v.uid}" ]]; then
|
||||||
echo "[1;31mwarning: existing user '${v.name}' has unexpected uid $u, skipping...[0m" >&2
|
echo "[1;31mwarning: existing user '${v.name}' has unexpected uid $u, skipping...[0m" >&2
|
||||||
else
|
else
|
||||||
if [ -z "$u" ]; then
|
if [ -z "$u" ]; then
|
||||||
echo "creating user ${v.name}..." >&2
|
echo "creating user ${v.name}..." >&2
|
||||||
dscl . -create '/Users/${v.name}' UniqueID ${toString v.uid}
|
|
||||||
dscl . -create '/Users/${v.name}' PrimaryGroupID ${toString v.gid}
|
sysadminctl -addUser ${escapeShellArgs ([
|
||||||
dscl . -create '/Users/${v.name}' IsHidden ${if v.isHidden then "1" else "0"}
|
v.name
|
||||||
dscl . -create '/Users/${v.name}' RealName '${v.description}'
|
"-UID" v.uid
|
||||||
dscl . -create '/Users/${v.name}' NFSHomeDirectory '${v.home}'
|
"-GID" v.gid ]
|
||||||
${optionalString v.createHome "createhomedir -cu '${v.name}'"}
|
++ (optionals (v.description != null) [ "-fullName" v.description ])
|
||||||
|
++ [ "-home" (if v.home != null then v.home else "/var/empty") ]
|
||||||
|
++ [ "-shell" (if v.shell != null then shellPath v.shell else "/usr/bin/false") ])} 2> /dev/null
|
||||||
|
|
||||||
|
# We need to check as `sysadminctl -addUser` still exits with exit code 0 when there's an error
|
||||||
|
if ! id ${name} &> /dev/null; then
|
||||||
|
printf >&2 '\e[1;31merror: failed to create user %s, aborting activation\e[0m\n' ${name}
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
# Always set the shell path, in case it was updated
|
|
||||||
dscl . -create '/Users/${v.name}' UserShell ${lib.escapeShellArg (shellPath v.shell)}
|
dscl . -create ${dsclUser} IsHidden ${if v.isHidden then "1" else "0"}
|
||||||
|
|
||||||
|
# `sysadminctl -addUser` won't create the home directory if we use the `-home`
|
||||||
|
# flag so we need to do it ourselves
|
||||||
|
${optionalString (v.home != null && v.createHome) "createhomedir -cu ${name} > /dev/null"}
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Update properties on known users to keep them inline with configuration
|
||||||
|
dscl . -create ${dsclUser} PrimaryGroupID ${toString v.gid}
|
||||||
|
${optionalString (v.description != null) "dscl . -create ${dsclUser} RealName ${escapeShellArg v.description}"}
|
||||||
|
${optionalString (v.shell != null) "dscl . -create ${dsclUser} UserShell ${escapeShellArg (shellPath v.shell)}"}
|
||||||
fi
|
fi
|
||||||
'') createdUsers}
|
'') createdUsers}
|
||||||
|
|
||||||
${concatMapStringsSep "\n" (name: ''
|
${concatMapStringsSep "\n" (name: ''
|
||||||
u=$(dscl . -read '/Users/${name}' UniqueID 2> /dev/null) || true
|
u=$(id -u ${escapeShellArg name} 2> /dev/null) || true
|
||||||
u=''${u#UniqueID: }
|
|
||||||
if [ -n "$u" ]; then
|
if [ -n "$u" ]; then
|
||||||
if [ "$u" -gt 501 ]; then
|
if [ "$u" -gt 501 ]; then
|
||||||
echo "deleting user ${name}..." >&2
|
echo "deleting user ${name}..." >&2
|
||||||
dscl . -delete '/Users/${name}' 2> /dev/null
|
dscl . -delete ${escapeShellArg "/Users/${name}"}
|
||||||
else
|
else
|
||||||
echo "[1;31mwarning: existing user '${name}' has unexpected uid $u, skipping...[0m" >&2
|
echo "[1;31mwarning: existing user '${name}' has unexpected uid $u, skipping...[0m" >&2
|
||||||
fi
|
fi
|
||||||
|
@ -190,6 +332,9 @@ in
|
||||||
'') deletedUsers}
|
'') deletedUsers}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
# Install all the user shells
|
||||||
|
environment.systemPackages = systemShells;
|
||||||
|
|
||||||
environment.etc = mapAttrs' (name: { packages, ... }: {
|
environment.etc = mapAttrs' (name: { packages, ... }: {
|
||||||
name = "profiles/per-user/${name}";
|
name = "profiles/per-user/${name}";
|
||||||
value.source = pkgs.buildEnv {
|
value.source = pkgs.buildEnv {
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
{ name, lib, ... }:
|
{ name, lib, ... }:
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
options = {
|
options = let
|
||||||
|
inherit (lib) mkOption types;
|
||||||
|
in {
|
||||||
name = mkOption {
|
name = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
|
default = name;
|
||||||
description = ''
|
description = ''
|
||||||
The group's name. If undefined, the name of the attribute set
|
The group's name. If undefined, the name of the attribute set
|
||||||
will be used.
|
will be used.
|
||||||
|
@ -29,10 +30,4 @@ with lib;
|
||||||
description = "The group's description.";
|
description = "The group's description.";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = {
|
|
||||||
|
|
||||||
name = mkDefault name;
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
{ name, lib, ... }:
|
{ name, lib, ... }:
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
options = {
|
options = let
|
||||||
|
inherit (lib) literalExpression mkOption types;
|
||||||
|
in {
|
||||||
name = mkOption {
|
name = mkOption {
|
||||||
type = types.str;
|
type = types.nonEmptyStr;
|
||||||
|
default = name;
|
||||||
description = ''
|
description = ''
|
||||||
The name of the user account. If undefined, the name of the
|
The name of the user account. If undefined, the name of the
|
||||||
attribute set will be used.
|
attribute set will be used.
|
||||||
|
@ -13,12 +14,18 @@ with lib;
|
||||||
};
|
};
|
||||||
|
|
||||||
description = mkOption {
|
description = mkOption {
|
||||||
type = types.str;
|
type = types.nullOr types.nonEmptyStr;
|
||||||
default = "";
|
default = null;
|
||||||
example = "Alice Q. User";
|
example = "Alice Q. User";
|
||||||
description = ''
|
description = ''
|
||||||
A short description of the user account, typically the
|
A short description of the user account, typically the
|
||||||
user's full name.
|
user's full name.
|
||||||
|
|
||||||
|
This defaults to `null` which means, on creation, `sysadminctl`
|
||||||
|
will pick the description which is usually always {option}`name`.
|
||||||
|
|
||||||
|
Using an empty name is not supported and breaks macOS like
|
||||||
|
making the user not appear in Directory Utility.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -46,9 +53,15 @@ with lib;
|
||||||
# };
|
# };
|
||||||
|
|
||||||
home = mkOption {
|
home = mkOption {
|
||||||
type = types.path;
|
type = types.nullOr types.path;
|
||||||
default = "/var/empty";
|
default = null;
|
||||||
description = "The user's home directory.";
|
description = ''
|
||||||
|
The user's home directory. This defaults to `null`.
|
||||||
|
|
||||||
|
When this is set to `null`, if the user has not been created yet,
|
||||||
|
they will be created with the home directory `/var/empty` to match
|
||||||
|
the old default.
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
createHome = mkOption {
|
createHome = mkOption {
|
||||||
|
@ -58,10 +71,28 @@ with lib;
|
||||||
};
|
};
|
||||||
|
|
||||||
shell = mkOption {
|
shell = mkOption {
|
||||||
type = types.either types.shellPackage types.path;
|
type = types.nullOr (types.either types.shellPackage types.path);
|
||||||
default = "/sbin/nologin";
|
default = null;
|
||||||
example = literalExpression "pkgs.bashInteractive";
|
example = literalExpression "pkgs.bashInteractive";
|
||||||
description = "The user's shell.";
|
description = ''
|
||||||
|
The user's shell. This defaults to `null`.
|
||||||
|
|
||||||
|
When this is set to `null`, if the user has not been created yet,
|
||||||
|
they will be created with the shell `/usr/bin/false` to prevent
|
||||||
|
interactive login. If the user already exists, the value is
|
||||||
|
considered managed by macOS and `nix-darwin` will not change it.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
ignoreShellProgramCheck = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
By default, nix-darwin will check that programs.SHELL.enable is set to
|
||||||
|
true if the user has a custom shell specified. If that behavior isn't
|
||||||
|
required and there are custom overrides in place to make sure that the
|
||||||
|
shell is functional, set this to true.
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
packages = mkOption {
|
packages = mkOption {
|
||||||
|
@ -75,10 +106,4 @@ with lib;
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = {
|
|
||||||
|
|
||||||
name = mkDefault name;
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,147 +0,0 @@
|
||||||
{ stdenv, nix, pkgs, nix-darwin }:
|
|
||||||
|
|
||||||
let
|
|
||||||
nixPath = pkgs.lib.concatStringsSep ":" [
|
|
||||||
"darwin=${nix-darwin}"
|
|
||||||
"nixpkgs=${pkgs.path}"
|
|
||||||
"$HOME/.nix-defexpr/channels"
|
|
||||||
"/nix/var/nix/profiles/per-user/root/channels"
|
|
||||||
"$NIX_PATH"
|
|
||||||
];
|
|
||||||
in
|
|
||||||
|
|
||||||
stdenv.mkDerivation {
|
|
||||||
name = "darwin-installer";
|
|
||||||
preferLocalBuild = true;
|
|
||||||
|
|
||||||
unpackPhase = ":";
|
|
||||||
|
|
||||||
installPhase = ''
|
|
||||||
mkdir -p $out/bin
|
|
||||||
echo "$shellHook" > $out/bin/darwin-installer
|
|
||||||
chmod +x $out/bin/darwin-installer
|
|
||||||
'';
|
|
||||||
|
|
||||||
shellHook = ''
|
|
||||||
#!${stdenv.shell}
|
|
||||||
set -e
|
|
||||||
|
|
||||||
_PATH=$PATH
|
|
||||||
export PATH=/nix/var/nix/profiles/default/bin:${nix}/bin:${pkgs.gnused}/bin:${pkgs.openssh}/bin:/usr/bin:/bin:/usr/sbin:/sbin
|
|
||||||
|
|
||||||
action=switch
|
|
||||||
while [ "$#" -gt 0 ]; do
|
|
||||||
i="$1"; shift 1
|
|
||||||
case "$i" in
|
|
||||||
--help)
|
|
||||||
echo "darwin-installer: [--help] [--check]"
|
|
||||||
exit
|
|
||||||
;;
|
|
||||||
--check)
|
|
||||||
action=check
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
echo >&2
|
|
||||||
echo >&2 "Installing nix-darwin..."
|
|
||||||
echo >&2
|
|
||||||
|
|
||||||
config="$HOME/.nixpkgs/darwin-configuration.nix"
|
|
||||||
if ! test -f "$config"; then
|
|
||||||
echo "copying example configuration.nix" >&2
|
|
||||||
mkdir -p "$HOME/.nixpkgs"
|
|
||||||
cp "${../../modules/examples/simple.nix}" "$config"
|
|
||||||
chmod u+w "$config"
|
|
||||||
|
|
||||||
# Enable nix-daemon service for multi-user installs.
|
|
||||||
if [ ! -w /nix/var/nix/db ]; then
|
|
||||||
sed -i 's/# services.nix-daemon.enable/services.nix-daemon.enable/' "$config"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Skip when stdin is not a tty, eg.
|
|
||||||
# $ yes | darwin-installer
|
|
||||||
if test -t 0; then
|
|
||||||
read -p "Would you like to edit the default configuration.nix before starting? [y/N] " i
|
|
||||||
case "$i" in
|
|
||||||
y|Y)
|
|
||||||
PATH=$_PATH ''${EDITOR:-nano} "$config"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
|
|
||||||
i=y
|
|
||||||
darwinPath=$(NIX_PATH=$HOME/.nix-defexpr/channels nix-instantiate --eval -E '<darwin>' 2> /dev/null) || true
|
|
||||||
if ! test -e "$darwinPath"; then
|
|
||||||
if test -t 0; then
|
|
||||||
read -p "Would you like to manage <darwin> with nix-channel? [y/N] " i
|
|
||||||
fi
|
|
||||||
case "$i" in
|
|
||||||
y|Y)
|
|
||||||
nix-channel --add https://github.com/LnL7/nix-darwin/archive/master.tar.gz darwin
|
|
||||||
nix-channel --update
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
|
|
||||||
export NIX_PATH=${nixPath}
|
|
||||||
system=$(nix-build '<darwin>' -I "darwin-config=$config" -A system --no-out-link --show-trace)
|
|
||||||
|
|
||||||
export PATH=$system/sw/bin:$PATH
|
|
||||||
darwin-rebuild "$action" -I "darwin-config=$config"
|
|
||||||
|
|
||||||
echo >&2
|
|
||||||
echo >&2 " Open '$config' to get started."
|
|
||||||
echo >&2 " See the README for more information: [0;34mhttps://github.com/LnL7/nix-darwin/blob/master/README.md[0m"
|
|
||||||
echo >&2
|
|
||||||
echo >&2 " Don't forget to start a new shell or source /etc/static/bashrc."
|
|
||||||
echo >&2
|
|
||||||
exit
|
|
||||||
'';
|
|
||||||
|
|
||||||
passthru.check = stdenv.mkDerivation {
|
|
||||||
name = "run-darwin-test";
|
|
||||||
shellHook = ''
|
|
||||||
set -e
|
|
||||||
echo >&2 "running installer tests..."
|
|
||||||
echo >&2
|
|
||||||
|
|
||||||
echo >&2 "checking configuration.nix"
|
|
||||||
test -f ~/.nixpkgs/darwin-configuration.nix
|
|
||||||
test -w ~/.nixpkgs/darwin-configuration.nix
|
|
||||||
echo >&2 "checking darwin channel"
|
|
||||||
readlink ~/.nix-defexpr/channels/darwin
|
|
||||||
test -e ~/.nix-defexpr/channels/darwin
|
|
||||||
echo >&2 "checking /etc"
|
|
||||||
readlink /etc/static
|
|
||||||
test -e /etc/static
|
|
||||||
echo >&2 "checking profile"
|
|
||||||
cat /etc/profile
|
|
||||||
grep -v nix-daemon.sh /etc/profile
|
|
||||||
echo >&2 "checking /run/current-system"
|
|
||||||
readlink /run
|
|
||||||
test -e /run
|
|
||||||
readlink /run/current-system
|
|
||||||
test -e /run/current-system
|
|
||||||
echo >&2 "checking system profile"
|
|
||||||
readlink /nix/var/nix/profiles/system
|
|
||||||
test -e /nix/var/nix/profiles/system
|
|
||||||
|
|
||||||
echo >&2 "checking bash environment"
|
|
||||||
env -i USER=john HOME=/Users/john bash -li -c 'echo $PATH'
|
|
||||||
env -i USER=john HOME=/Users/john bash -li -c 'echo $PATH' | grep /Users/john/.nix-profile/bin:/run/current-system/sw/bin:/nix/var/nix/profiles/default/bin:/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin
|
|
||||||
env -i USER=john HOME=/Users/john bash -li -c 'echo $NIX_PATH'
|
|
||||||
env -i USER=john HOME=/Users/john bash -li -c 'echo $NIX_PATH' | grep darwin-config=/Users/john/.nixpkgs/darwin-configuration.nix:/nix/var/nix/profiles/per-user/root/channels
|
|
||||||
|
|
||||||
echo >&2 "checking zsh environment"
|
|
||||||
env -i USER=john HOME=/Users/john zsh -l -c 'echo $PATH'
|
|
||||||
env -i USER=john HOME=/Users/john zsh -l -c 'echo $PATH' | grep /Users/john/.nix-profile/bin:/run/current-system/sw/bin:/nix/var/nix/profiles/default/bin:/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin
|
|
||||||
env -i USER=john HOME=/Users/john zsh -l -c 'echo $NIX_PATH'
|
|
||||||
env -i USER=john HOME=/Users/john zsh -l -c 'echo $NIX_PATH' | grep darwin-config=/Users/john/.nixpkgs/darwin-configuration.nix:/nix/var/nix/profiles/per-user/root/channels
|
|
||||||
|
|
||||||
echo >&2 ok
|
|
||||||
exit
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
{ lib, ... }:
|
{ lib, pkgs, ... }:
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
|
|
||||||
|
@ -7,46 +7,49 @@ with lib;
|
||||||
assertions = mkForce [];
|
assertions = mkForce [];
|
||||||
system.activationScripts.checks.text = mkForce "";
|
system.activationScripts.checks.text = mkForce "";
|
||||||
|
|
||||||
# Disable etc, launchd, ...
|
|
||||||
environment.etc = mkForce {};
|
environment.etc = mkForce {};
|
||||||
launchd.agents = mkForce {};
|
launchd.agents = mkForce {};
|
||||||
launchd.daemons = mkForce {};
|
launchd.daemons = mkForce {};
|
||||||
launchd.user.agents = mkForce {};
|
launchd.user.agents = mkForce {};
|
||||||
|
|
||||||
|
# Don't try to reload `nix-daemon`
|
||||||
|
nix.useDaemon = mkForce false;
|
||||||
|
|
||||||
system.activationScripts.postUserActivation.text = mkAfter ''
|
system.activationScripts.postUserActivation.text = mkAfter ''
|
||||||
if test -L ~/.nix-defexpr/channels/darwin; then
|
if [[ -L ~/.nix-defexpr/channels/darwin ]]; then
|
||||||
nix-channel --remove darwin || true
|
nix-channel --remove darwin || true
|
||||||
fi
|
fi
|
||||||
'';
|
'';
|
||||||
|
|
||||||
system.activationScripts.postActivation.text = mkAfter ''
|
system.activationScripts.postActivation.text = mkAfter ''
|
||||||
if test -L /Applications/Nix\ Apps; then
|
if [[ -L /Applications/Nix\ Apps ]]; then
|
||||||
rm /Applications/Nix\ Apps
|
rm /Applications/Nix\ Apps
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test -L /etc/static; then
|
if [[ -L /etc/static ]]; then
|
||||||
rm /etc/static
|
rm /etc/static
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test -O /nix/store; then
|
# If the Nix Store is owned by root then we're on a multi-user system
|
||||||
if ! test -e /Library/LaunchDaemons/org.nixos.nix-daemon.plist; then
|
if [[ -O /nix/store ]]; then
|
||||||
sudo rm /Library/LaunchDaemons/org.nixos.nix-daemon.plist || true
|
if [[ -e /nix/var/nix/profiles/default/Library/LaunchDaemons/org.nixos.nix-daemon.plist ]]; then
|
||||||
sudo launchctl remove org.nixos.nix-daemon 2> /dev/null || true
|
|
||||||
sudo cp /nix/var/nix/profiles/default/Library/LaunchDaemons/org.nixos.nix-daemon.plist /Library/LaunchDaemons/org.nixos.nix-daemon.plist
|
sudo cp /nix/var/nix/profiles/default/Library/LaunchDaemons/org.nixos.nix-daemon.plist /Library/LaunchDaemons/org.nixos.nix-daemon.plist
|
||||||
sudo launchctl load -w /Library/LaunchDaemons/org.nixos.nix-daemon.plist
|
sudo launchctl load -w /Library/LaunchDaemons/org.nixos.nix-daemon.plist
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
if ! grep -q etc/profile.d/nix-daemon.sh /etc/bashrc; then
|
# grep will return 1 when no lines matched which makes this line fail with `set -eo pipefail`
|
||||||
echo >&2 "Found no nix-daemon.sh reference in /etc/bashrc"
|
dscl . -list /Users UserShell | { grep "\s/run/" || true; } | awk '{print $1}' | while read -r user; do
|
||||||
echo >&2 "add this snippet back to /etc/bashrc:"
|
shell=$(dscl . -read /Users/"$user" UserShell)
|
||||||
echo >&2
|
if [[ "$shell" != */bin/zsh ]]; then
|
||||||
echo >&2 " # Nix"
|
echo >&2 "warning: changing $user's shell from $shell to /bin/zsh"
|
||||||
echo >&2 " if [ -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' ]; then"
|
|
||||||
echo >&2 " . '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh'"
|
|
||||||
echo >&2 " fi"
|
|
||||||
echo >&2 " # End Nix"
|
|
||||||
echo >&2
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
dscl . -create /Users/"$user" UserShell /bin/zsh
|
||||||
|
done
|
||||||
|
|
||||||
|
while IFS= read -r -d "" file; do
|
||||||
|
mv "$file" "''${file%.*}"
|
||||||
|
done < <(find /etc -name '*.before-nix-darwin' -follow -print0)
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{ stdenv, lib, pkgs }:
|
{ lib, path, stdenv, writeShellApplication }:
|
||||||
|
|
||||||
let
|
let
|
||||||
uninstallSystem = import ../../eval-config.nix {
|
uninstallSystem = import ../../eval-config.nix {
|
||||||
|
@ -6,31 +6,15 @@ let
|
||||||
modules = [
|
modules = [
|
||||||
./configuration.nix
|
./configuration.nix
|
||||||
{
|
{
|
||||||
nixpkgs.source = pkgs.path;
|
nixpkgs.source = path;
|
||||||
nixpkgs.hostPlatform = pkgs.stdenv.hostPlatform.system;
|
nixpkgs.hostPlatform = stdenv.hostPlatform.system;
|
||||||
system.includeUninstaller = false;
|
system.includeUninstaller = false;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
in
|
in writeShellApplication {
|
||||||
|
|
||||||
stdenv.mkDerivation {
|
|
||||||
name = "darwin-uninstaller";
|
name = "darwin-uninstaller";
|
||||||
preferLocalBuild = true;
|
text = ''
|
||||||
|
|
||||||
unpackPhase = ":";
|
|
||||||
|
|
||||||
installPhase = ''
|
|
||||||
mkdir -p $out/bin
|
|
||||||
echo "$shellHook" > $out/bin/darwin-uninstaller
|
|
||||||
chmod +x $out/bin/darwin-uninstaller
|
|
||||||
'';
|
|
||||||
|
|
||||||
shellHook = ''
|
|
||||||
#!${stdenv.shell}
|
|
||||||
set -e
|
|
||||||
|
|
||||||
action=switch
|
|
||||||
while [ "$#" -gt 0 ]; do
|
while [ "$#" -gt 0 ]; do
|
||||||
i="$1"; shift 1
|
i="$1"; shift 1
|
||||||
case "$i" in
|
case "$i" in
|
||||||
|
@ -47,11 +31,13 @@ stdenv.mkDerivation {
|
||||||
echo >&2 " - remove /Applications/Nix Apps symlink"
|
echo >&2 " - remove /Applications/Nix Apps symlink"
|
||||||
echo >&2 " - cleanup static /etc files"
|
echo >&2 " - cleanup static /etc files"
|
||||||
echo >&2 " - disable and remove all launchd services managed by nix-darwin"
|
echo >&2 " - disable and remove all launchd services managed by nix-darwin"
|
||||||
echo >&2 " - restore daemon service from nix installer (only when this is a multi-user install)"
|
if [[ $(stat -f '%Su' /nix/store) == "root" ]]; then
|
||||||
|
echo >&2 " - restore nix-daemon service from nix installer as this is a multi-user install"
|
||||||
|
fi
|
||||||
echo >&2
|
echo >&2
|
||||||
|
|
||||||
if test -t 0; then
|
if [[ -t 0 ]]; then
|
||||||
read -p "Proceed? [y/n] " i
|
read -r -p "Proceed? [y/n] " i
|
||||||
case "$i" in
|
case "$i" in
|
||||||
y|Y)
|
y|Y)
|
||||||
;;
|
;;
|
||||||
|
@ -63,38 +49,49 @@ stdenv.mkDerivation {
|
||||||
|
|
||||||
${uninstallSystem.system}/sw/bin/darwin-rebuild activate
|
${uninstallSystem.system}/sw/bin/darwin-rebuild activate
|
||||||
|
|
||||||
if test -L /run/current-system; then
|
if [[ -L /run/current-system ]]; then
|
||||||
sudo rm /run/current-system
|
sudo rm /run/current-system
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ -L /run ]]; then
|
||||||
|
if [[ -e /etc/synthetic.conf ]]; then
|
||||||
|
sudo sed -i -E '/^run[[:space:]]/d' /etc/synthetic.conf
|
||||||
|
sudo /System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -B &>/dev/null || true
|
||||||
|
sudo /System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -t &>/dev/null || true
|
||||||
|
echo >&2 "NOTE: the /run symlink will be removed on reboot"
|
||||||
|
else
|
||||||
|
sudo rm /run
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
echo >&2
|
echo >&2
|
||||||
echo >&2 "NOTE: The /nix/var/nix/profiles/system* profiles still exist and won't be garbage collected."
|
echo >&2 "NOTE: The /nix/var/nix/profiles/system* profiles still exist and won't be garbage collected."
|
||||||
echo >&2
|
echo >&2
|
||||||
echo >&2 "Done!"
|
echo >&2 "Done!"
|
||||||
echo >&2
|
echo >&2
|
||||||
exit
|
|
||||||
'';
|
'';
|
||||||
|
|
||||||
passthru.check = stdenv.mkDerivation {
|
derivationArgs.passthru.tests.uninstaller = writeShellApplication {
|
||||||
name = "run-darwin-test";
|
name = "post-uninstall-test";
|
||||||
shellHook = ''
|
text = ''
|
||||||
set -e
|
|
||||||
echo >&2 "running uninstaller tests..."
|
echo >&2 "running uninstaller tests..."
|
||||||
echo >&2
|
echo >&2
|
||||||
|
|
||||||
echo >&2 "checking darwin channel"
|
echo >&2 "checking darwin channel"
|
||||||
! test -e ~/.nix-defexpr/channels/darwin
|
test -e ~/.nix-defexpr/channels/darwin && exit 1
|
||||||
echo >&2 "checking /etc"
|
echo >&2 "checking /etc"
|
||||||
! test -e /etc/static
|
test -e /etc/static && exit 1
|
||||||
echo >&2 "checking /run/current-system"
|
echo >&2 "checking /run/current-system"
|
||||||
! test -e /run/current-system
|
test -e /run/current-system && exit 1
|
||||||
echo >&2 "checking nix-daemon service (assuming a multi-user install)"
|
if [[ $(stat -f '%Su' /nix/store) == "root" ]]; then
|
||||||
sudo launchctl list | grep org.nixos.nix-daemon || echo "FIXME? sudo launchctl list | grep org.nixos.nix-daemon"
|
echo >&2 "checking nix-daemon service"
|
||||||
pgrep -l nix-daemon || echo "FIXME? pgrep -l nix-daemon"
|
launchctl print system/org.nixos.nix-daemon
|
||||||
readlink /Library/LaunchDaemons/org.nixos.nix-daemon.plist || echo "FIXME? readlink /Library/LaunchDaemons/org.nixos.nix-daemon.plist"
|
pgrep -l nix-daemon
|
||||||
grep /nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt /Library/LaunchDaemons/org.nixos.nix-daemon.plist || echo "FIXME? grep /nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt /Library/LaunchDaemons/org.nixos.nix-daemon.plist"
|
test -e /Library/LaunchDaemons/org.nixos.nix-daemon.plist
|
||||||
|
[[ "$(shasum -a 256 /Library/LaunchDaemons/org.nixos.nix-daemon.plist | awk '{print $1}')" == "$(shasum -a 256 /Library/LaunchDaemons/org.nixos.nix-daemon.plist | awk '{print $1}')" ]]
|
||||||
|
nix-store --store daemon -q --hash ${stdenv.shell}
|
||||||
|
fi
|
||||||
echo >&2 ok
|
echo >&2 ok
|
||||||
exit
|
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,17 +9,25 @@ showSyntax() {
|
||||||
echo " [--list-generations] [{--profile-name | -p} name] [--rollback]" >&2
|
echo " [--list-generations] [{--profile-name | -p} name] [--rollback]" >&2
|
||||||
echo " [{--switch-generation | -G} generation] [--verbose...] [-v...]" >&2
|
echo " [{--switch-generation | -G} generation] [--verbose...] [-v...]" >&2
|
||||||
echo " [-Q] [{--max-jobs | -j} number] [--cores number] [--dry-run]" >&2
|
echo " [-Q] [{--max-jobs | -j} number] [--cores number] [--dry-run]" >&2
|
||||||
echo " [--keep-going] [-k] [--keep-failed] [-K] [--fallback] [--show-trace]" >&2
|
echo " [--keep-going | -k] [--keep-failed | -K] [--fallback] [--show-trace]" >&2
|
||||||
echo " [-I path] [--option name value] [--arg name value] [--argstr name value]" >&2
|
echo " [--print-build-logs | -L] [--impure] [-I path]" >&2
|
||||||
echo " [--flake flake] [--no-flake] [--update-input input flake] [--impure]" >&2
|
echo " [--option name value] [--arg name value] [--argstr name value]" >&2
|
||||||
echo " [--recreate-lock-file] [--no-update-lock-file] [--refresh]" >&2
|
echo " [--no-flake | [--flake flake]" >&2
|
||||||
echo " [--offline] [--substituters substituters-list] ..." >&2
|
echo " [--commit-lock-file] [--recreate-lock-file]" >&2
|
||||||
|
echo " [--no-update-lock-file] [--no-write-lock-file]" >&2
|
||||||
|
echo " [--override-input input flake] [--update-input input]" >&2
|
||||||
|
echo " [--no-registries] [--offline] [--refresh]]" >&2
|
||||||
|
echo " [--substituters substituters-list] ..." >&2
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
sudo() {
|
sudo() {
|
||||||
|
# REMOVEME when support for macOS 10.13 is dropped
|
||||||
|
# macOS 10.13 does not support sudo --preserve-env so we make this conditional
|
||||||
if command sudo --help | grep -- --preserve-env= >/dev/null; then
|
if command sudo --help | grep -- --preserve-env= >/dev/null; then
|
||||||
command sudo -H --preserve-env=PATH env "$@"
|
# We use `env` before our command to ensure the preserved PATH gets checked
|
||||||
|
# when trying to resolve the command to execute
|
||||||
|
command sudo -H --preserve-env=PATH --preserve-env=SSH_CONNECTION env "$@"
|
||||||
else
|
else
|
||||||
command sudo -H "$@"
|
command sudo -H "$@"
|
||||||
fi
|
fi
|
||||||
|
@ -149,43 +157,17 @@ fi
|
||||||
|
|
||||||
# For convenience, use the hostname as the default configuration to
|
# For convenience, use the hostname as the default configuration to
|
||||||
# build from the flake.
|
# build from the flake.
|
||||||
if [ -n "$flake" ]; then
|
if [[ -n "$flake" ]]; then
|
||||||
# Offical regex from https://www.rfc-editor.org/rfc/rfc3986#appendix-B
|
if [[ $flake =~ ^(.*)\#([^\#\"]*)$ ]]; then
|
||||||
if [[ "${flake}" =~ ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))? ]]; then
|
flake="${BASH_REMATCH[1]}"
|
||||||
scheme=${BASH_REMATCH[1]} # eg. http:
|
flakeAttr="${BASH_REMATCH[2]}"
|
||||||
authority=${BASH_REMATCH[3]} # eg. //www.ics.uci.edu
|
|
||||||
path=${BASH_REMATCH[5]} # eg. /pub/ietf/uri/
|
|
||||||
queryWithQuestion=${BASH_REMATCH[6]}
|
|
||||||
fragment=${BASH_REMATCH[9]}
|
|
||||||
|
|
||||||
flake=${scheme}${authority}${path}${queryWithQuestion}
|
|
||||||
flakeAttr=${fragment}
|
|
||||||
fi
|
fi
|
||||||
if [ -z "$flakeAttr" ]; then
|
if [[ -z "$flakeAttr" ]]; then
|
||||||
flakeAttr=$(scutil --get LocalHostName)
|
flakeAttr=$(scutil --get LocalHostName)
|
||||||
fi
|
fi
|
||||||
flakeAttr=darwinConfigurations.${flakeAttr}
|
flakeAttr=darwinConfigurations.${flakeAttr}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -n "$flake" ]; then
|
|
||||||
if nix "${flakeFlags[@]}" flake metadata --version &>/dev/null; then
|
|
||||||
cmd=metadata
|
|
||||||
else
|
|
||||||
cmd=info
|
|
||||||
fi
|
|
||||||
|
|
||||||
metadata=$(nix "${flakeFlags[@]}" flake "$cmd" --json "${extraMetadataFlags[@]}" "${extraLockFlags[@]}" -- "$flake")
|
|
||||||
flake=$(jq -r .url <<<"${metadata}")
|
|
||||||
|
|
||||||
if [ "$(jq -r .resolved.submodules <<<"${metadata}")" = "true" ]; then
|
|
||||||
if [[ "$flake" == *'?'* ]]; then
|
|
||||||
flake="${flake}&submodules=1"
|
|
||||||
else
|
|
||||||
flake="${flake}?submodules=1"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$action" != build ]; then
|
if [ "$action" != build ]; then
|
||||||
if [ -n "$flake" ]; then
|
if [ -n "$flake" ]; then
|
||||||
extraBuildFlags+=("--no-link")
|
extraBuildFlags+=("--no-link")
|
||||||
|
|
|
@ -17,6 +17,7 @@ let
|
||||||
inherit name src;
|
inherit name src;
|
||||||
dir = "bin";
|
dir = "bin";
|
||||||
isExecutable = true;
|
isExecutable = true;
|
||||||
|
meta.mainProgram = name;
|
||||||
} // env);
|
} // env);
|
||||||
|
|
||||||
path = "${extraPath}:${systemPath}";
|
path = "${extraPath}:${systemPath}";
|
||||||
|
|
70
release.nix
70
release.nix
|
@ -1,21 +1,16 @@
|
||||||
{ nixpkgs ? <nixpkgs>
|
{ nixpkgs ? <nixpkgs>
|
||||||
, supportedSystems ? [ "x86_64-darwin" ]
|
# Adapted from https://github.com/NixOS/nixpkgs/blob/e818264fe227ad8861e0598166cf1417297fdf54/pkgs/top-level/release.nix#L11
|
||||||
|
, nix-darwin ? { }
|
||||||
|
, system ? builtins.currentSystem
|
||||||
|
, supportedSystems ? [ "x86_64-darwin" "aarch64-darwin" ]
|
||||||
, scrubJobs ? true
|
, scrubJobs ? true
|
||||||
}:
|
}:
|
||||||
|
|
||||||
let
|
let
|
||||||
inherit (release) mapTestOn packagePlatforms pkgs all linux darwin;
|
|
||||||
|
|
||||||
system = "x86_64-darwin";
|
|
||||||
|
|
||||||
mapPlatforms = systems: pkgs.lib.mapAttrs (n: v: systems);
|
|
||||||
|
|
||||||
buildFromConfig = configuration: sel: sel
|
buildFromConfig = configuration: sel: sel
|
||||||
(import ./. { inherit nixpkgs configuration system; }).config;
|
(import ./. { inherit nixpkgs configuration system; }).config;
|
||||||
|
|
||||||
makeSystem = configuration: pkgs.lib.genAttrs [ system ] (system:
|
makeSystem = configuration: buildFromConfig configuration (config: config.system.build.toplevel);
|
||||||
buildFromConfig configuration (config: config.system.build.toplevel)
|
|
||||||
);
|
|
||||||
|
|
||||||
makeTest = test:
|
makeTest = test:
|
||||||
let
|
let
|
||||||
|
@ -61,47 +56,24 @@ let
|
||||||
in
|
in
|
||||||
buildFromConfig configuration (config: config.system.build.run-test);
|
buildFromConfig configuration (config: config.system.build.run-test);
|
||||||
|
|
||||||
release = import <nixpkgs/pkgs/top-level/release-lib.nix> {
|
|
||||||
inherit supportedSystems scrubJobs;
|
|
||||||
packageSet = import nixpkgs;
|
|
||||||
};
|
|
||||||
|
|
||||||
packageSet = {
|
|
||||||
inherit (pkgs)
|
|
||||||
stdenv bash zsh nix
|
|
||||||
tmux reattach-to-user-namespace
|
|
||||||
nano emacs vim;
|
|
||||||
};
|
|
||||||
|
|
||||||
manual = buildFromConfig ({ lib, config, ... }: {
|
manual = buildFromConfig ({ lib, config, ... }: {
|
||||||
system.stateVersion = lib.mkDefault config.system.maxStateVersion;
|
system.stateVersion = lib.mkDefault config.system.maxStateVersion;
|
||||||
|
|
||||||
|
system.darwinVersionSuffix = let
|
||||||
|
shortRev = nix-darwin.shortRev or nix-darwin.dirtyShortRev or null;
|
||||||
|
in
|
||||||
|
lib.mkIf (shortRev != null) ".${shortRev}";
|
||||||
|
system.darwinRevision = let
|
||||||
|
rev = nix-darwin.rev or nix-darwin.dirtyRev or null;
|
||||||
|
in
|
||||||
|
lib.mkIf (rev != null) rev;
|
||||||
}) (config: config.system.build.manual);
|
}) (config: config.system.build.manual);
|
||||||
|
|
||||||
jobs = {
|
in {
|
||||||
|
docs = {
|
||||||
unstable = pkgs.releaseTools.aggregate {
|
inherit (manual) manualHTML manpages optionsJSON;
|
||||||
name = "darwin-${pkgs.lib.nixpkgsVersion}";
|
|
||||||
constituents =
|
|
||||||
[ jobs.stdenv.x86_64-darwin
|
|
||||||
jobs.bash.x86_64-darwin
|
|
||||||
jobs.zsh.x86_64-darwin
|
|
||||||
jobs.nix.x86_64-darwin
|
|
||||||
jobs.reattach-to-user-namespace.x86_64-darwin
|
|
||||||
jobs.tmux.x86_64-darwin
|
|
||||||
jobs.nano.x86_64-darwin
|
|
||||||
jobs.vim.x86_64-darwin
|
|
||||||
jobs.emacs.x86_64-darwin
|
|
||||||
jobs.examples.hydra.x86_64-darwin
|
|
||||||
jobs.examples.lnl.x86_64-darwin
|
|
||||||
jobs.examples.simple.x86_64-darwin
|
|
||||||
];
|
|
||||||
meta.description = "Release-critical builds for the darwin channel";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
manualHTML = manual.manualHTML;
|
|
||||||
manpages = manual.manpages;
|
|
||||||
options = manual.optionsJSON;
|
|
||||||
|
|
||||||
examples.hydra = makeSystem ./modules/examples/hydra.nix;
|
examples.hydra = makeSystem ./modules/examples/hydra.nix;
|
||||||
examples.lnl = makeSystem ./modules/examples/lnl.nix;
|
examples.lnl = makeSystem ./modules/examples/lnl.nix;
|
||||||
examples.simple = makeSystem ./modules/examples/simple.nix;
|
examples.simple = makeSystem ./modules/examples/simple.nix;
|
||||||
|
@ -129,6 +101,7 @@ let
|
||||||
tests.services-lorri = makeTest ./tests/services-lorri.nix;
|
tests.services-lorri = makeTest ./tests/services-lorri.nix;
|
||||||
tests.services-nix-daemon = makeTest ./tests/services-nix-daemon.nix;
|
tests.services-nix-daemon = makeTest ./tests/services-nix-daemon.nix;
|
||||||
tests.sockets-nix-daemon = makeTest ./tests/sockets-nix-daemon.nix;
|
tests.sockets-nix-daemon = makeTest ./tests/sockets-nix-daemon.nix;
|
||||||
|
tests.services-aerospace = makeTest ./tests/services-aerospace.nix;
|
||||||
tests.services-dnsmasq = makeTest ./tests/services-dnsmasq.nix;
|
tests.services-dnsmasq = makeTest ./tests/services-dnsmasq.nix;
|
||||||
tests.services-eternal-terminal = makeTest ./tests/services-eternal-terminal.nix;
|
tests.services-eternal-terminal = makeTest ./tests/services-eternal-terminal.nix;
|
||||||
tests.services-nix-gc = makeTest ./tests/services-nix-gc.nix;
|
tests.services-nix-gc = makeTest ./tests/services-nix-gc.nix;
|
||||||
|
@ -155,9 +128,4 @@ let
|
||||||
tests.users-groups = makeTest ./tests/users-groups.nix;
|
tests.users-groups = makeTest ./tests/users-groups.nix;
|
||||||
tests.users-packages = makeTest ./tests/users-packages.nix;
|
tests.users-packages = makeTest ./tests/users-packages.nix;
|
||||||
tests.fonts = makeTest ./tests/fonts.nix;
|
tests.fonts = makeTest ./tests/fonts.nix;
|
||||||
|
}
|
||||||
}
|
|
||||||
// (mapTestOn (packagePlatforms packageSet));
|
|
||||||
|
|
||||||
in
|
|
||||||
jobs
|
|
||||||
|
|
|
@ -205,6 +205,11 @@ defaults write .GlobalPreferences 'com.apple.sound.beep.sound' $'<?xml version="
|
||||||
<string>/System/Library/Sounds/Funk.aiff</string>
|
<string>/System/Library/Sounds/Funk.aiff</string>
|
||||||
</plist>'
|
</plist>'
|
||||||
|
|
||||||
|
defaults write com.apple.menuextra.clock 'FlashDateSeparators' $'<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<false/>
|
||||||
|
</plist>'
|
||||||
defaults write com.apple.menuextra.clock 'Show24Hour' $'<?xml version="1.0" encoding="UTF-8"?>
|
defaults write com.apple.menuextra.clock 'Show24Hour' $'<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
|
@ -299,6 +304,11 @@ defaults write com.apple.dock 'persistent-others' $'<?xml version="1.0" encoding
|
||||||
</dict>
|
</dict>
|
||||||
</array>
|
</array>
|
||||||
</plist>'
|
</plist>'
|
||||||
|
defaults write com.apple.dock 'scroll-to-open' $'<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<false/>
|
||||||
|
</plist>'
|
||||||
defaults write com.apple.finder 'AppleShowAllExtensions' $'<?xml version="1.0" encoding="UTF-8"?>
|
defaults write com.apple.finder 'AppleShowAllExtensions' $'<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
|
@ -329,16 +339,51 @@ defaults write com.apple.finder 'FXPreferredViewStyle' $'<?xml version="1.0" enc
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<string>Flwv</string>
|
<string>Flwv</string>
|
||||||
</plist>'
|
</plist>'
|
||||||
|
defaults write com.apple.finder 'FXRemoveOldTrashItems' $'<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<false/>
|
||||||
|
</plist>'
|
||||||
|
defaults write com.apple.finder 'NewWindowTarget' $'<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<string>PfLo</string>
|
||||||
|
</plist>'
|
||||||
|
defaults write com.apple.finder 'NewWindowTargetPath' $'<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<string>file:///Library/Apple</string>
|
||||||
|
</plist>'
|
||||||
defaults write com.apple.finder 'QuitMenuItem' $'<?xml version="1.0" encoding="UTF-8"?>
|
defaults write com.apple.finder 'QuitMenuItem' $'<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<true/>
|
<true/>
|
||||||
</plist>'
|
</plist>'
|
||||||
|
defaults write com.apple.finder 'ShowExternalHardDrivesOnDesktop' $'<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<false/>
|
||||||
|
</plist>'
|
||||||
|
defaults write com.apple.finder 'ShowHardDrivesOnDesktop' $'<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<false/>
|
||||||
|
</plist>'
|
||||||
|
defaults write com.apple.finder 'ShowMountedServersOnDesktop' $'<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<false/>
|
||||||
|
</plist>'
|
||||||
defaults write com.apple.finder 'ShowPathbar' $'<?xml version="1.0" encoding="UTF-8"?>
|
defaults write com.apple.finder 'ShowPathbar' $'<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<true/>
|
<true/>
|
||||||
</plist>'
|
</plist>'
|
||||||
|
defaults write com.apple.finder 'ShowRemovableMediaOnDesktop' $'<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<false/>
|
||||||
|
</plist>'
|
||||||
defaults write com.apple.finder 'ShowStatusBar' $'<?xml version="1.0" encoding="UTF-8"?>
|
defaults write com.apple.finder 'ShowStatusBar' $'<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
|
@ -354,8 +399,23 @@ defaults write com.apple.finder '_FXSortFoldersFirst' $'<?xml version="1.0" enco
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<true/>
|
<true/>
|
||||||
</plist>'
|
</plist>'
|
||||||
|
defaults write com.apple.finder '_FXSortFoldersFirstOnDesktop' $'<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<false/>
|
||||||
|
</plist>'
|
||||||
|
defaults write com.apple.HIToolbox 'AppleFnUsageType' $'<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<integer>2</integer>
|
||||||
|
</plist>'
|
||||||
|
|
||||||
|
|
||||||
|
defaults write com.apple.screencapture 'include-date' $'<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<true/>
|
||||||
|
</plist>'
|
||||||
defaults write com.apple.screencapture 'location' $'<?xml version="1.0" encoding="UTF-8"?>
|
defaults write com.apple.screencapture 'location' $'<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
|
@ -474,3 +534,38 @@ defaults write com.apple.WindowManager 'StandardHideWidgets' $'<?xml version="1.
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<true/>
|
<true/>
|
||||||
</plist>'
|
</plist>'
|
||||||
|
defaults write ~/Library/Preferences/ByHost/com.apple.controlcenter 'AirDrop' $'<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<integer>18</integer>
|
||||||
|
</plist>'
|
||||||
|
defaults write ~/Library/Preferences/ByHost/com.apple.controlcenter 'BatteryShowPercentage' $'<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<true/>
|
||||||
|
</plist>'
|
||||||
|
defaults write ~/Library/Preferences/ByHost/com.apple.controlcenter 'Bluetooth' $'<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<integer>18</integer>
|
||||||
|
</plist>'
|
||||||
|
defaults write ~/Library/Preferences/ByHost/com.apple.controlcenter 'Display' $'<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<integer>24</integer>
|
||||||
|
</plist>'
|
||||||
|
defaults write ~/Library/Preferences/ByHost/com.apple.controlcenter 'FocusModes' $'<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<integer>24</integer>
|
||||||
|
</plist>'
|
||||||
|
defaults write ~/Library/Preferences/ByHost/com.apple.controlcenter 'NowPlaying' $'<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<integer>18</integer>
|
||||||
|
</plist>'
|
||||||
|
defaults write ~/Library/Preferences/ByHost/com.apple.controlcenter 'Sound' $'<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<integer>24</integer>
|
||||||
|
</plist>'
|
|
@ -1,4 +1,4 @@
|
||||||
{ config, pkgs, ... }:
|
{ config, lib, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
networking.knownNetworkServices = [ "Wi-Fi" "Thunderbolt Ethernet" ];
|
networking.knownNetworkServices = [ "Wi-Fi" "Thunderbolt Ethernet" ];
|
||||||
|
@ -6,10 +6,10 @@
|
||||||
|
|
||||||
test = ''
|
test = ''
|
||||||
echo checking dns settings in /activate >&2
|
echo checking dns settings in /activate >&2
|
||||||
grep "networksetup -setdnsservers 'Wi-Fi' '8.8.8.8' '8.8.4.4'" ${config.out}/activate
|
grep "networksetup -setdnsservers ${lib.escapeShellArgs [ "Wi-Fi" "8.8.8.8" "8.8.4.4" ]}" ${config.out}/activate
|
||||||
grep "networksetup -setdnsservers 'Thunderbolt Ethernet' '8.8.8.8' '8.8.4.4'" ${config.out}/activate
|
grep "networksetup -setdnsservers ${lib.escapeShellArgs [ "Thunderbolt Ethernet" "8.8.8.8" "8.8.4.4" ]}" ${config.out}/activate
|
||||||
echo checking empty searchdomain settings in /activate >&2
|
echo checking empty searchdomain settings in /activate >&2
|
||||||
grep "networksetup -setsearchdomains 'Wi-Fi' 'empty'" ${config.out}/activate
|
grep "networksetup -setsearchdomains ${lib.escapeShellArgs [ "Wi-Fi" "empty" ]}" ${config.out}/activate
|
||||||
grep "networksetup -setsearchdomains 'Thunderbolt Ethernet' 'empty'" ${config.out}/activate
|
grep "networksetup -setsearchdomains ${lib.escapeShellArgs [ "Thunderbolt Ethernet" "empty" ]}" ${config.out}/activate
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
|
10
tests/networking-wakeonlan.nix
Normal file
10
tests/networking-wakeonlan.nix
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
{ config, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
networking.wakeOnLan.enable = true;
|
||||||
|
|
||||||
|
test = ''
|
||||||
|
echo checking wake on network access settings in /activate >&2
|
||||||
|
grep "systemsetup -setWakeOnNetworkAccess 'on'" ${config.out}/activate
|
||||||
|
'';
|
||||||
|
}
|
12
tests/power-restart.nix
Normal file
12
tests/power-restart.nix
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
{ config, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
power.restartAfterPowerFailure = true;
|
||||||
|
power.restartAfterFreeze = true;
|
||||||
|
|
||||||
|
test = ''
|
||||||
|
echo checking restart power settings in /activate >&2
|
||||||
|
grep "systemsetup -setRestartPowerFailure 'on'" ${config.out}/activate
|
||||||
|
grep "systemsetup -setRestartFreeze 'on'" ${config.out}/activate
|
||||||
|
'';
|
||||||
|
}
|
16
tests/power-sleep.nix
Normal file
16
tests/power-sleep.nix
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
{ config, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
power.sleep.computer = "never";
|
||||||
|
power.sleep.display = 15;
|
||||||
|
power.sleep.harddisk = 5;
|
||||||
|
power.sleep.allowSleepByPowerButton = false;
|
||||||
|
|
||||||
|
test = ''
|
||||||
|
echo checking power sleep settings in /activate >&2
|
||||||
|
grep "systemsetup -setComputerSleep 'never'" ${config.out}/activate
|
||||||
|
grep "systemsetup -setDisplaySleep '15'" ${config.out}/activate
|
||||||
|
grep "systemsetup -setHardDiskSleep '5'" ${config.out}/activate
|
||||||
|
grep "systemsetup -setAllowPowerButtonToSleepComputer 'off'" ${config.out}/activate
|
||||||
|
'';
|
||||||
|
}
|
|
@ -34,7 +34,7 @@
|
||||||
echo >&2 "checking compinit in /etc/zshrc"
|
echo >&2 "checking compinit in /etc/zshrc"
|
||||||
grep 'autoload -U compinit && compinit' ${config.out}/etc/zshrc
|
grep 'autoload -U compinit && compinit' ${config.out}/etc/zshrc
|
||||||
echo >&2 "checking bashcompinit in /etc/zshrc"
|
echo >&2 "checking bashcompinit in /etc/zshrc"
|
||||||
grep -vq 'bashcompinit' ${config.out}/etc/zshrc
|
(! grep 'bashcompinit' ${config.out}/etc/zshrc)
|
||||||
|
|
||||||
echo >&2 "checking zprofile.d in /etc/zprofile"
|
echo >&2 "checking zprofile.d in /etc/zprofile"
|
||||||
grep 'source /etc/zprofile.d/\*.conf' ${config.out}/etc/zprofile
|
grep 'source /etc/zprofile.d/\*.conf' ${config.out}/etc/zprofile
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
{ config, pkgs, ... }:
|
{ config, pkgs, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
services.activate-system.enable = true;
|
|
||||||
launchd.labelPrefix = "org.nix-darwin";
|
launchd.labelPrefix = "org.nix-darwin";
|
||||||
|
|
||||||
test = ''
|
test = ''
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
{ config, pkgs, ... }:
|
{ config, pkgs, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
services.activate-system.enable = true;
|
|
||||||
|
|
||||||
test = ''
|
test = ''
|
||||||
echo checking activation service in /Library/LaunchDaemons >&2
|
echo checking activation service in /Library/LaunchDaemons >&2
|
||||||
grep "org.nixos.activate-system" ${config.out}/Library/LaunchDaemons/org.nixos.activate-system.plist
|
grep "org.nixos.activate-system" ${config.out}/Library/LaunchDaemons/org.nixos.activate-system.plist
|
||||||
|
|
36
tests/services-aerospace.nix
Normal file
36
tests/services-aerospace.nix
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
{ config, pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
aerospace = pkgs.runCommand "aerospace-0.0.0" { } "mkdir $out";
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
services.aerospace.enable = true;
|
||||||
|
services.aerospace.package = aerospace;
|
||||||
|
services.aerospace.settings = {
|
||||||
|
gaps = {
|
||||||
|
outer.left = 8;
|
||||||
|
outer.bottom = 8;
|
||||||
|
outer.top = 8;
|
||||||
|
outer.right = 8;
|
||||||
|
};
|
||||||
|
mode.main.binding = {
|
||||||
|
alt-h = "focus left";
|
||||||
|
alt-j = "focus down";
|
||||||
|
alt-k = "focus up";
|
||||||
|
alt-l = "focus right";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
test = ''
|
||||||
|
echo >&2 "checking aerospace service in ~/Library/LaunchAgents"
|
||||||
|
grep "org.nixos.aerospace" ${config.out}/user/Library/LaunchAgents/org.nixos.aerospace.plist
|
||||||
|
grep "${aerospace}/Applications/AeroSpace.app/Contents/MacOS/AeroSpace" ${config.out}/user/Library/LaunchAgents/org.nixos.aerospace.plist
|
||||||
|
|
||||||
|
conf=`sed -En 's/^[[:space:]]*<string>.*--config-path (.*)<\/string>$/\1/p' \
|
||||||
|
${config.out}/user/Library/LaunchAgents/org.nixos.aerospace.plist`
|
||||||
|
|
||||||
|
echo >&2 "checking config in $conf"
|
||||||
|
if [ `cat $conf | wc -l` -eq "27" ]; then echo "aerospace.toml config correctly contains 27 lines"; else return 1; fi
|
||||||
|
'';
|
||||||
|
}
|
|
@ -42,6 +42,7 @@
|
||||||
system.defaults.NSGlobalDomain."com.apple.springing.delay" = 0.0;
|
system.defaults.NSGlobalDomain."com.apple.springing.delay" = 0.0;
|
||||||
system.defaults.NSGlobalDomain."com.apple.swipescrolldirection" = true;
|
system.defaults.NSGlobalDomain."com.apple.swipescrolldirection" = true;
|
||||||
system.defaults.".GlobalPreferences"."com.apple.sound.beep.sound" = "/System/Library/Sounds/Funk.aiff";
|
system.defaults.".GlobalPreferences"."com.apple.sound.beep.sound" = "/System/Library/Sounds/Funk.aiff";
|
||||||
|
system.defaults.menuExtraClock.FlashDateSeparators = false;
|
||||||
system.defaults.menuExtraClock.Show24Hour = false;
|
system.defaults.menuExtraClock.Show24Hour = false;
|
||||||
system.defaults.menuExtraClock.ShowDayOfWeek = true;
|
system.defaults.menuExtraClock.ShowDayOfWeek = true;
|
||||||
system.defaults.menuExtraClock.ShowDate = 2;
|
system.defaults.menuExtraClock.ShowDate = 2;
|
||||||
|
@ -50,18 +51,29 @@
|
||||||
system.defaults.dock.orientation = "left";
|
system.defaults.dock.orientation = "left";
|
||||||
system.defaults.dock.persistent-apps = ["MyApp.app" "Cool.app"];
|
system.defaults.dock.persistent-apps = ["MyApp.app" "Cool.app"];
|
||||||
system.defaults.dock.persistent-others = ["~/Documents" "~/Downloads/file.txt"];
|
system.defaults.dock.persistent-others = ["~/Documents" "~/Downloads/file.txt"];
|
||||||
|
system.defaults.dock.scroll-to-open = false;
|
||||||
system.defaults.finder.AppleShowAllFiles = true;
|
system.defaults.finder.AppleShowAllFiles = true;
|
||||||
system.defaults.finder.ShowStatusBar = true;
|
system.defaults.finder.ShowStatusBar = true;
|
||||||
system.defaults.finder.ShowPathbar = true;
|
system.defaults.finder.ShowPathbar = true;
|
||||||
system.defaults.finder.FXDefaultSearchScope = "SCcf";
|
system.defaults.finder.FXDefaultSearchScope = "SCcf";
|
||||||
system.defaults.finder.FXPreferredViewStyle = "Flwv";
|
system.defaults.finder.FXPreferredViewStyle = "Flwv";
|
||||||
|
system.defaults.finder.FXRemoveOldTrashItems = false;
|
||||||
system.defaults.finder.AppleShowAllExtensions = true;
|
system.defaults.finder.AppleShowAllExtensions = true;
|
||||||
system.defaults.finder.CreateDesktop = false;
|
system.defaults.finder.CreateDesktop = false;
|
||||||
|
system.defaults.finder.NewWindowTarget = "Other";
|
||||||
|
system.defaults.finder.NewWindowTargetPath = "file:///Library/Apple";
|
||||||
system.defaults.finder.QuitMenuItem = true;
|
system.defaults.finder.QuitMenuItem = true;
|
||||||
system.defaults.finder._FXShowPosixPathInTitle = true;
|
system.defaults.finder._FXShowPosixPathInTitle = true;
|
||||||
system.defaults.finder._FXSortFoldersFirst = true;
|
system.defaults.finder._FXSortFoldersFirst = true;
|
||||||
|
system.defaults.finder._FXSortFoldersFirstOnDesktop = false;
|
||||||
system.defaults.finder.FXEnableExtensionChangeWarning = false;
|
system.defaults.finder.FXEnableExtensionChangeWarning = false;
|
||||||
|
system.defaults.finder.ShowExternalHardDrivesOnDesktop = false;
|
||||||
|
system.defaults.finder.ShowHardDrivesOnDesktop = false;
|
||||||
|
system.defaults.finder.ShowMountedServersOnDesktop = false;
|
||||||
|
system.defaults.finder.ShowRemovableMediaOnDesktop = false;
|
||||||
|
system.defaults.hitoolbox.AppleFnUsageType = "Show Emoji & Symbols";
|
||||||
system.defaults.screencapture.location = "/tmp";
|
system.defaults.screencapture.location = "/tmp";
|
||||||
|
system.defaults.screencapture.include-date = true;
|
||||||
system.defaults.screensaver.askForPassword = true;
|
system.defaults.screensaver.askForPassword = true;
|
||||||
system.defaults.screensaver.askForPasswordDelay = 5;
|
system.defaults.screensaver.askForPasswordDelay = 5;
|
||||||
system.defaults.smb.NetBIOSName = "IMAC-000000";
|
system.defaults.smb.NetBIOSName = "IMAC-000000";
|
||||||
|
@ -91,6 +103,13 @@
|
||||||
true;
|
true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
system.defaults.controlcenter.BatteryShowPercentage = true;
|
||||||
|
system.defaults.controlcenter.Sound = false;
|
||||||
|
system.defaults.controlcenter.Bluetooth = true;
|
||||||
|
system.defaults.controlcenter.AirDrop = true;
|
||||||
|
system.defaults.controlcenter.Display = false;
|
||||||
|
system.defaults.controlcenter.FocusModes = false;
|
||||||
|
system.defaults.controlcenter.NowPlaying = true;
|
||||||
test = lib.strings.concatMapStringsSep "\n"
|
test = lib.strings.concatMapStringsSep "\n"
|
||||||
(x: ''
|
(x: ''
|
||||||
echo >&2 "checking defaults write in /${x}"
|
echo >&2 "checking defaults write in /${x}"
|
||||||
|
|
|
@ -19,45 +19,62 @@
|
||||||
users.users.foo.shell = pkgs.bashInteractive;
|
users.users.foo.shell = pkgs.bashInteractive;
|
||||||
|
|
||||||
users.users."created.user".uid = 42001;
|
users.users."created.user".uid = 42001;
|
||||||
|
users.users."created.user".description = null;
|
||||||
|
users.users."created.user".home = null;
|
||||||
|
users.users."created.user".shell = null;
|
||||||
|
|
||||||
users.users."unknown.user".uid = 42002;
|
users.users."unknown.user".uid = 42002;
|
||||||
|
|
||||||
test = ''
|
test = ''
|
||||||
echo "checking group creation in /activate" >&2
|
set -v
|
||||||
grep "dscl . -create '/Groups/foo' PrimaryGroupID 42000" ${config.out}/activate
|
|
||||||
grep "dscl . -create '/Groups/foo' RealName 'Foo group'" ${config.out}/activate
|
|
||||||
grep "dscl . -create '/Groups/created.group' PrimaryGroupID 42001" ${config.out}/activate
|
|
||||||
grep -qv "dscl . -delete '/Groups/created.group'" ${config.out}/activate
|
|
||||||
|
|
||||||
echo "checking group deletion in /activate" >&2
|
# checking group creation in /activate
|
||||||
grep "dscl . -delete '/Groups/deleted.group'" ${config.out}/activate
|
grep "dscl . -create ${lib.escapeShellArg "/Groups/foo"} PrimaryGroupID 42000" ${config.out}/activate
|
||||||
grep -qv "dscl . -create '/Groups/deleted.group'" ${config.out}/activate
|
grep "dscl . -create ${lib.escapeShellArg "/Groups/foo"} RealName ${lib.escapeShellArg "Foo group"}" ${config.out}/activate
|
||||||
|
grep "dscl . -create ${lib.escapeShellArg "/Groups/created.group"} PrimaryGroupID 42001" ${config.out}/activate
|
||||||
|
(! grep "dscl . -delete ${lib.escapeShellArg "/Groups/created.group"}" ${config.out}/activate)
|
||||||
|
|
||||||
|
# checking group deletion in /activate
|
||||||
|
grep "dscl . -delete ${lib.escapeShellArg "/Groups/deleted.group"}" ${config.out}/activate
|
||||||
|
(! grep "dscl . -create ${lib.escapeShellArg "/Groups/deleted.group"}" ${config.out}/activate)
|
||||||
|
|
||||||
echo "checking group membership in /activate" >&2
|
echo "checking group membership in /activate" >&2
|
||||||
grep "dscl . -create '/Groups/foo' GroupMembership 'admin' 'foo'" ${config.out}/activate
|
grep "dscl . -create ${lib.escapeShellArg "/Groups/foo"} GroupMembership ${lib.escapeShellArgs [ "admin" "foo" ]}" ${config.out}/activate
|
||||||
grep "dscl . -create '/Groups/created.group' GroupMembership" ${config.out}/activate
|
grep "dscl . -create ${lib.escapeShellArg "/Groups/created.group"} GroupMembership" ${config.out}/activate
|
||||||
|
|
||||||
echo "checking unknown group in /activate" >&2
|
# checking unknown group in /activate
|
||||||
grep -qv "dscl . -create '/Groups/unknown.group'" ${config.out}/activate
|
# checking groups not in knownGroups don't appear in /activate
|
||||||
grep -qv "dscl . -delete '/Groups/unknown.group'" ${config.out}/activate
|
(! grep "dscl . -create ${lib.escapeShellArg "/Groups/unknown.group"}" ${config.out}/activate)
|
||||||
|
(! grep "dscl . -delete ${lib.escapeShellArg "/Groups/unknown.group"}" ${config.out}/activate)
|
||||||
|
|
||||||
echo "checking user creation in /activate" >&2
|
# checking user creation in /activate
|
||||||
grep "dscl . -create '/Users/foo' UniqueID 42000" ${config.out}/activate
|
grep "sysadminctl -addUser ${lib.escapeShellArgs [ "foo" "-UID" 42000 "-GID" 42000 "-fullName" "Foo user" "-home" "/Users/foo" "-shell" "/run/current-system/sw/bin/bash" ]}" ${config.out}/activate
|
||||||
grep "dscl . -create '/Users/foo' PrimaryGroupID 42000" ${config.out}/activate
|
grep "createhomedir -cu ${lib.escapeShellArg "foo"}" ${config.out}/activate
|
||||||
grep "dscl . -create '/Users/foo' IsHidden 0" ${config.out}/activate
|
grep "sysadminctl -addUser ${lib.escapeShellArgs [ "created.user" "-UID" 42001 ]} .* ${lib.escapeShellArgs [ "-shell" "/usr/bin/false" ] }" ${config.out}/activate
|
||||||
grep "dscl . -create '/Users/foo' RealName 'Foo user'" ${config.out}/activate
|
grep "sysadminctl -addUser ${lib.escapeShellArg "created.user"} .* ${lib.escapeShellArgs [ "-home" "/var/empty" ]}" ${config.out}/activate
|
||||||
grep "dscl . -create '/Users/foo' NFSHomeDirectory '/Users/foo'" ${config.out}/activate
|
(! grep "dscl . -delete ${lib.escapeShellArg "/Users/created.user"}" ${config.out}/activate)
|
||||||
grep "dscl . -create '/Users/foo' UserShell ${lib.escapeShellArg "/run/current-system/sw/bin/bash"}" ${config.out}/activate
|
(! grep "dscl . -delete ${lib.escapeShellArg "/Groups/created.user"}" ${config.out}/activate)
|
||||||
grep "dscl . -create '/Users/created.user' UniqueID 42001" ${config.out}/activate
|
|
||||||
grep "dscl . -create '/Users/created.user' UserShell ${lib.escapeShellArg "/sbin/nologin"}" ${config.out}/activate
|
|
||||||
grep "createhomedir -cu 'foo'" ${config.out}/activate
|
|
||||||
grep -qv "dscl . -delete '/Groups/created.user'" ${config.out}/activate
|
|
||||||
|
|
||||||
echo "checking user deletion in /activate" >&2
|
# checking user properties always get updated in /activate
|
||||||
grep "dscl . -delete '/Users/deleted.user'" ${config.out}/activate
|
grep "dscl . -create ${lib.escapeShellArg "/Users/foo"} PrimaryGroupID 42000" ${config.out}/activate
|
||||||
grep -qv "dscl . -create '/Users/deleted.user'" ${config.out}/activate
|
grep "dscl . -create ${lib.escapeShellArg "/Users/foo"} RealName ${lib.escapeShellArg "Foo user"}" ${config.out}/activate
|
||||||
|
grep "createhomedir -cu ${lib.escapeShellArg "foo"}" ${config.out}/activate
|
||||||
|
grep "dscl . -create ${lib.escapeShellArg "/Users/foo"} UserShell ${lib.escapeShellArg "/run/current-system/sw/bin/bash"}" ${config.out}/activate
|
||||||
|
grep "dscl . -create ${lib.escapeShellArg "/Users/foo"} IsHidden 0" ${config.out}/activate
|
||||||
|
|
||||||
echo "checking unknown user in /activate" >&2
|
# checking user properties that are null don't get updated in /activate
|
||||||
grep -qv "dscl . -create '/Users/unknown.user'" ${config.out}/activate
|
(! grep "dscl . -create ${lib.escapeShellArg "/Users/created.user"} RealName" ${config.out}/activate)
|
||||||
grep -qv "dscl . -delete '/Users/unknown.user'" ${config.out}/activate
|
(! grep "dscl . -create ${lib.escapeShellArg "/Users/created.user"} UserShell" ${config.out}/activate)
|
||||||
|
|
||||||
|
# checking user deletion in /activate
|
||||||
|
grep "dscl . -delete ${lib.escapeShellArg "/Users/deleted.user"}" ${config.out}/activate
|
||||||
|
(! grep "sysadminctl -addUser ${lib.escapeShellArg "deleted.user"}" ${config.out}/activate)
|
||||||
|
|
||||||
|
# checking that users not specified in knownUsers doesn't get changed in /activate
|
||||||
|
(! grep "sysadminctl -addUser ${lib.escapeShellArg "unknown.user"}" ${config.out}/activate)
|
||||||
|
(! grep "dscl . -delete ${lib.escapeShellArg "/Users/unknown.user"}" ${config.out}/activate)
|
||||||
|
(! grep "dscl . -create ${lib.escapeShellArg "/Users/unknown.user"}" ${config.out}/activate)
|
||||||
|
|
||||||
|
set +v
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue