1
0
Fork 0
mirror of https://github.com/LnL7/nix-darwin.git synced 2025-03-31 04:04:45 +00:00

Merge branch 'LnL7:master' into dock-persistent-others

This commit is contained in:
clara 2025-03-11 11:17:35 +01:00 committed by GitHub
commit da640960dd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
75 changed files with 1532 additions and 800 deletions

2
.git-blame-ignore-revs Normal file
View file

@ -0,0 +1,2 @@
# nixpkgs: format with `nixfmt`
dc1c716ded39758062ed7e6bc410ad274119de9f

View file

@ -6,67 +6,73 @@ on:
- master
env:
CURRENT_STABLE_CHANNEL: nixpkgs-24.05-darwin
NIXPKGS_BRANCH: nixpkgs-unstable
NIX_VERSION: 2.24.11
jobs:
# The `test-stable` and `install-against-stable` job names are
# loadbearing, despite their inaccuracy on the unstable branch, as
# they are set as required checks in the repository configuration,
# which only repository admins can change.
#
# TODO: Change them once the repository configuration is updated.
test-stable:
runs-on: macos-13
steps:
- uses: actions/checkout@v4
- name: Install nix corresponding to latest stable channel
- name: Install Nix
uses: cachix/install-nix-action@v30
with:
install_url: https://releases.nixos.org/nix/nix-2.18.8/install
- run: nix flake check --override-input nixpkgs nixpkgs/${{ env.CURRENT_STABLE_CHANNEL }}
test-unstable:
runs-on: macos-13
steps:
- uses: actions/checkout@v4
- name: Install nix from current unstable channel
uses: cachix/install-nix-action@v30
with:
install_url: https://releases.nixos.org/nix/nix-2.24.9/install
- run: nix flake check --override-input nixpkgs nixpkgs/nixpkgs-unstable
install_url: https://releases.nixos.org/nix/nix-${{ env.NIX_VERSION }}/install
- run: nix flake check --override-input nixpkgs nixpkgs/${{ env.NIXPKGS_BRANCH }}
install-against-stable:
runs-on: macos-13
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- name: Install nix corresponding to latest stable channel
- name: Install Nix
uses: cachix/install-nix-action@v30
with:
install_url: https://releases.nixos.org/nix/nix-2.18.8/install
nix_path: nixpkgs=channel:${{ env.CURRENT_STABLE_CHANNEL }}
install_url: https://releases.nixos.org/nix/nix-${{ env.NIX_VERSION }}/install
nix_path: nixpkgs=channel:${{ env.NIXPKGS_BRANCH }}
- name: Install channels
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.NIXPKGS_BRANCH }} nixpkgs
nix-channel --update
- name: Install nix-darwin
run: |
export NIX_PATH=$HOME/.nix-defexpr/channels
mkdir -p ~/.config/nix-darwin
cp modules/examples/simple.nix ~/.config/nix-darwin/configuration.nix
sudo mkdir -p /etc/nix-darwin
sudo cp modules/examples/simple.nix /etc/nix-darwin/configuration.nix
nixConfHash=$(shasum -a 256 /etc/nix/nix.conf | cut -d ' ' -f 1)
/usr/bin/sed -i.bak \
"s/# programs.fish.enable = true;/nix.settings.access-tokens = [ \"github.com=\${{ secrets.GITHUB_TOKEN }}\" ]; environment.etc.\"nix\/nix.conf\".knownSha256Hashes = [ \"$nixConfHash\" ];/" \
~/.config/nix-darwin/configuration.nix
sudo /usr/bin/sed -i.bak \
"s/# programs.fish.enable = true;/ \
imports = [ \
({ options, ... }: { \
nix.settings.access-tokens = [ \"github.com=\${{ secrets.GITHUB_TOKEN }}\" ]; \
environment.etc.\"nix\/nix.conf\".knownSha256Hashes = [ \"$nixConfHash\" ]; \
nix.nixPath = \
[ { darwin = \"${PWD////\/}\"; } ] \
++ options.nix.nixPath.default; \
}) \
]; \
/" \
/etc/nix-darwin/configuration.nix
nix run .#darwin-rebuild \
-- switch \
-I darwin-config=$HOME/.config/nix-darwin/configuration.nix
nix run .#darwin-rebuild -- switch \
-I darwin=. \
-I darwin-config=/etc/nix-darwin/configuration.nix
- name: Switch to new configuration
run: |
. /etc/bashrc
/usr/bin/sed -i.bak \
sudo /usr/bin/sed -i.bak \
"s/pkgs.vim/pkgs.hello/" \
~/.config/nix-darwin/configuration.nix
/etc/nix-darwin/configuration.nix
darwin-rebuild switch -I darwin=.
darwin-rebuild switch
hello
- name: Test uninstallation of nix-darwin
@ -75,148 +81,54 @@ jobs:
# `cachix/install-nix-action` but not by our default config above
nix run .#darwin-uninstaller \
--extra-experimental-features "nix-command flakes" \
--override-input nixpkgs nixpkgs/${{ env.CURRENT_STABLE_CHANNEL }}
--override-input nixpkgs nixpkgs/${{ env.NIXPKGS_BRANCH }}
nix run .#darwin-uninstaller.tests.uninstaller \
--extra-experimental-features "nix-command flakes" \
--override-input nixpkgs nixpkgs/${{ env.CURRENT_STABLE_CHANNEL }}
--override-input nixpkgs nixpkgs/${{ env.NIXPKGS_BRANCH }}
install-against-unstable:
install-flake:
runs-on: macos-13
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- name: Install nix from current unstable channel
- name: Install Nix
uses: cachix/install-nix-action@v30
with:
install_url: https://releases.nixos.org/nix/nix-2.24.9/install
nix_path: nixpkgs=channel:nixpkgs-unstable
- name: Install channels
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 --update
install_url: https://releases.nixos.org/nix/nix-${{ env.NIX_VERSION }}/install
- name: Install nix-darwin
run: |
export NIX_PATH=$HOME/.nix-defexpr/channels
mkdir -p ~/.config/nix-darwin
cp modules/examples/simple.nix ~/.config/nix-darwin/configuration.nix
nixConfHash=$(shasum -a 256 /etc/nix/nix.conf | cut -d ' ' -f 1)
/usr/bin/sed -i.bak \
"s/# programs.fish.enable = true;/nix.settings.access-tokens = [ \"github.com=\${{ secrets.GITHUB_TOKEN }}\" ]; environment.etc.\"nix\/nix.conf\".knownSha256Hashes = [ \"$nixConfHash\" ];/" \
~/.config/nix-darwin/configuration.nix
nix run .#darwin-rebuild \
-- switch \
-I darwin-config=$HOME/.config/nix-darwin/configuration.nix
- name: Switch to new configuration
run: |
. /etc/bashrc
/usr/bin/sed -i.bak \
"s/pkgs.vim/pkgs.hello/" \
~/.config/nix-darwin/configuration.nix
darwin-rebuild switch -I darwin=.
hello
- name: Test uninstallation of nix-darwin
run: |
# We need to specify `--extra-experimental-features` because `experimental-features` is set by
# `cachix/install-nix-action` but not by our default config above
nix run .#darwin-uninstaller \
--extra-experimental-features "nix-command flakes" \
--override-input nixpkgs nixpkgs/nixpkgs-unstable
nix run .#darwin-uninstaller.tests.uninstaller \
--extra-experimental-features "nix-command flakes" \
--override-input nixpkgs nixpkgs/nixpkgs-unstable
install-flake-against-stable:
runs-on: macos-13
steps:
- uses: actions/checkout@v4
- name: Install nix version corresponding to latest stable channel
uses: cachix/install-nix-action@v30
with:
install_url: https://releases.nixos.org/nix/nix-2.18.8/install
- name: Install nix-darwin
run: |
mkdir -p ~/.config/nix-darwin
sudo mkdir -p /etc/nix-darwin
darwin=$(pwd)
pushd ~/.config/nix-darwin
nix flake init -t $darwin
pushd /etc/nix-darwin
sudo nix flake init -t $darwin
nixConfHash=$(shasum -a 256 /etc/nix/nix.conf | cut -d ' ' -f 1)
/usr/bin/sed -i.bak \
sudo /usr/bin/sed -i.bak \
"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 \
sudo /usr/bin/sed -i.bak \
's/darwinConfigurations."simple"/darwinConfigurations."'$(scutil --get LocalHostName)'"/g' \
flake.nix
sudo /usr/bin/sed -i.bak \
's/nixpkgs.hostPlatform = "aarch64-darwin";/nixpkgs.hostPlatform = "'$(nix eval --expr builtins.currentSystem --impure --raw)'";/' \
flake.nix
popd
nix run .#darwin-rebuild -- \
switch --flake ~/.config/nix-darwin#simple \
nix run .#darwin-rebuild -- switch \
--override-input nix-darwin . \
--override-input nixpkgs nixpkgs/${{ env.CURRENT_STABLE_CHANNEL }}
--override-input nixpkgs nixpkgs/${{ env.NIXPKGS_BRANCH }}
- name: Switch to new configuration
run: |
. /etc/bashrc
/usr/bin/sed -i.bak \
sudo /usr/bin/sed -i.bak \
"s/pkgs.vim/pkgs.hello/" \
~/.config/nix-darwin/flake.nix
/etc/nix-darwin/flake.nix
darwin-rebuild switch --flake ~/.config/nix-darwin#simple \
darwin-rebuild switch \
--override-input nix-darwin . \
--override-input nixpkgs nixpkgs/${{ env.CURRENT_STABLE_CHANNEL }}
--override-input nixpkgs nixpkgs/${{ env.NIXPKGS_BRANCH }}
hello
- name: Test uninstallation of nix-darwin
run: |
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 }}
install-flake-against-unstable:
runs-on: macos-13
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- name: Install nix from current unstable channel
uses: cachix/install-nix-action@v30
with:
install_url: https://releases.nixos.org/nix/nix-2.24.9/install
- name: Install nix-darwin
run: |
mkdir -p ~/.config/nix-darwin
darwin=$(pwd)
pushd ~/.config/nix-darwin
nix flake init -t $darwin
nixConfHash=$(shasum -a 256 /etc/nix/nix.conf | cut -d ' ' -f 1)
/usr/bin/sed -i.bak \
"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
popd
nix run .#darwin-rebuild -- \
switch --flake ~/.config/nix-darwin#simple \
--override-input nix-darwin . \
--override-input nixpkgs nixpkgs/nixpkgs-unstable
- name: Switch to new configuration
run: |
. /etc/bashrc
/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/nixpkgs-unstable
hello
- name: Test uninstallation of nix-darwin
run: |
nix run .#darwin-uninstaller --override-input nixpkgs nixpkgs/nixpkgs-unstable
nix run .#darwin-uninstaller.tests.uninstaller --override-input nixpkgs nixpkgs/nixpkgs-unstable
nix run .#darwin-uninstaller --override-input nixpkgs nixpkgs/${{ env.NIXPKGS_BRANCH }}
nix run .#darwin-uninstaller.tests.uninstaller --override-input nixpkgs nixpkgs/${{ env.NIXPKGS_BRANCH }}

View file

@ -1,3 +1,23 @@
2025-01-29
- There is now a `nix.enable` toggle to disable management of the Nix
installation. Nix installation management has been made more
opinionated as a consequence; nix-darwin now only supports managing a
multiuser daemon installation of Nix, and unconditionally takes
ownership of the nix-daemon launchd daemon and the `_nixbld*` build
users when Nix installation management is enabled.
If the new constraints do not work with your setup, you can disable
the `nix.enable` option to opt out of Nix installation management
entirely; see the option documentation for caveats.
2025-01-18
- The default configuration path for all new installations
is `/etc/nix-darwin`. This was already the undocumented
default for `darwin-rebuild switch` when using flakes. This
is implemented by setting `environment.darwinConfig` to
`"/etc/nix-darwin/configuration.nix"` by default when
`system.stateVersion` ≥ 6.
2024-09-10
- The default Nix build user group ID is now set to 350 when
`system.stateVersion` ≥ 5, to reflect the default for new Nix

View file

@ -11,11 +11,19 @@ nix-darwin is built up around [Nixpkgs](https://github.com/NixOS/nixpkgs), quite
## Prerequisites
The only prerequisite is a Nix implementation, both Nix and Lix are supported.
The only prerequisite is a Nix implementation; both Nix and Lix are supported.
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:
- 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.
* 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.
It can install one of two distributions of Nix:
* To install the **recommended** vanilla upstream [Nix](https://nixos.org), you will need to explicitly say `no` when prompted to install `Determinate Nix`.
* When run with the `--determinate` flag, it will install the [Determinate](https://docs.determinate.systems/) distribution.
As Determinate manages the Nix installation itself, you will need to set `nix.enable = false;` in your configuration to disable nix-darwins own Nix management.
Some nix-darwin functionality that relies on managing the Nix installation, like the `nix.*` options to adjust Nix settings or configure a Linux builder, will be unavailable.
* The [Lix installer](https://lix.systems/install/#on-any-other-linuxmacos-system) supports both flake-based and channel-based setups.
@ -33,12 +41,18 @@ Despite being an experimental feature in Nix currently, nix-darwin recommends th
<summary>Getting started from scratch</summary>
<p></p>
If you don't have an existing `configuration.nix`, you can run the following commands to generate a basic `flake.nix` inside `~/.config/nix-darwin`:
If you don't have an existing `configuration.nix`, you can run the following commands to generate a basic `flake.nix` inside `/etc/nix-darwin`:
```bash
mkdir -p ~/.config/nix-darwin
cd ~/.config/nix-darwin
nix flake init -t nix-darwin
sudo mkdir -p /etc/nix-darwin
sudo chown $(id -nu):$(id -ng) /etc/nix-darwin
cd /etc/nix-darwin
# To use Nixpkgs unstable:
nix flake init -t nix-darwin/master
# To use Nixpkgs 24.11:
nix flake init -t nix-darwin/nix-darwin-24.11
sed -i '' "s/simple/$(scutil --get LocalHostName)/" flake.nix
```
@ -57,8 +71,10 @@ Add the following to `flake.nix` in the same folder as `configuration.nix`:
description = "John's darwin system";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-24.05-darwin";
nix-darwin.url = "github:LnL7/nix-darwin";
# Use `github:NixOS/nixpkgs/nixpkgs-24.11-darwin` to use Nixpkgs 24.11.
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
# Use `github:LnL7/nix-darwin/nix-darwin-24.11` to use Nixpkgs 24.11.
nix-darwin.url = "github:LnL7/nix-darwin/master";
nix-darwin.inputs.nixpkgs.follows = "nixpkgs";
};
@ -81,7 +97,10 @@ Make sure to set `nixpkgs.hostPlatform` in your `configuration.nix` to either `x
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
nix run nix-darwin -- switch --flake ~/.config/nix-darwin
# To use Nixpkgs unstable:
nix run nix-darwin/master#darwin-rebuild -- switch
# To use Nixpkgs 24.11:
nix run nix-darwin/nix-darwin-24.11#darwin-rebuild -- switch
```
### Step 3. Using `nix-darwin`
@ -89,7 +108,7 @@ nix run nix-darwin -- switch --flake ~/.config/nix-darwin
After installing, you can run `darwin-rebuild` to apply changes to your system:
```bash
darwin-rebuild switch --flake ~/.config/nix-darwin
darwin-rebuild switch
```
#### Using flake inputs
@ -117,13 +136,17 @@ nix-darwin.lib.darwinSystem {
### Step 1. Creating `configuration.nix`
Copy the [simple](./modules/examples/simple.nix) example to `~/.config/nix-darwin/configuration.nix`.
Copy the [simple](./modules/examples/simple.nix) example to `/etc/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
# If you use Nixpkgs unstable (the default):
sudo nix-channel --add https://github.com/LnL7/nix-darwin/archive/master.tar.gz darwin
# If you use Nixpkgs 24.11:
sudo nix-channel --add https://github.com/LnL7/nix-darwin/archive/nix-darwin-24.11.tar.gz darwin
sudo nix-channel --update
```
### Step 3. Installing `nix-darwin`
@ -131,8 +154,8 @@ nix-channel --update
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
nix-build '<darwin>' -A darwin-rebuild
./result/bin/darwin-rebuild switch -I darwin-config=/etc/nix-darwin/configuration.nix
```
### Step 4. Using `nix-darwin`
@ -145,10 +168,10 @@ darwin-rebuild switch
### Step 5. Updating `nix-darwin`
You can update `nix-darwin` using the following command:
You can update Nixpkgs and `nix-darwin` using the following command:
```bash
nix-channel --update darwin
sudo nix-channel --update
```
</details>

View file

@ -0,0 +1,3 @@
# Written by https://github.com/DeterminateSystems/nix-installer.
# The contents below are based on options specified at installation time.

View file

@ -0,0 +1,14 @@
# Generated by https://github.com/DeterminateSystems/nix-installer.
# See `/nix/nix-installer --version` for the version details.
!include nix.custom.conf
experimental-features = nix-command flakes
always-allow-substitutes = true
extra-trusted-substituters = https://cache.flakehub.com
extra-trusted-public-keys = cache.flakehub.com-3:hJuILl5sVK4iKm86JzgdXW12Y2Hwd5G07qKtHTOcDCM= cache.flakehub.com-4:Asi8qIv291s0aYLyH6IOnr5Kf6+OF14WVjkE6t3xMio= cache.flakehub.com-5:zB96CRlL7tiPtzA9/WKyPkp3A2vqxqgdgyTVNGShPDU= cache.flakehub.com-6:W4EGFwAGgBj3he7c5fNh9NkOXw0PUVaxygCVKeuvaqU= cache.flakehub.com-7:mvxJ2DZVHn/kRxlIaxYNMuDG1OvMckZu32um1TadOR8= cache.flakehub.com-8:moO+OVS0mnTjBTcOUh2kYLQEd59ExzyoW1QgQ8XAARQ= cache.flakehub.com-9:wChaSeTI6TeCuV/Sg2513ZIM9i0qJaYsF+lZCXg0J6o= cache.flakehub.com-10:2GqeNlIp6AKp4EF2MVbE1kBOp9iBSyo0UPR9KoR0o1Y=
bash-prompt-prefix = (nix:$name)\040
max-jobs = auto
extra-nix-path = nixpkgs=flake:nixpkgs
upgrade-nix-store-path-url = https://install.determinate.systems/nix-upgrade/stable/universal

View file

@ -0,0 +1,4 @@
# Written by https://github.com/DeterminateSystems/nix-installer.
# The contents below are based on options specified at installation time.

View file

@ -0,0 +1,13 @@
# Generated by https://github.com/DeterminateSystems/nix-installer.
# See `/nix/nix-installer --version` for the version details.
extra-experimental-features = nix-command flakes
always-allow-substitutes = true
extra-trusted-substituters = https://cache.flakehub.com
extra-trusted-public-keys = cache.flakehub.com-3:hJuILl5sVK4iKm86JzgdXW12Y2Hwd5G07qKtHTOcDCM= cache.flakehub.com-4:Asi8qIv291s0aYLyH6IOnr5Kf6+OF14WVjkE6t3xMio= cache.flakehub.com-5:zB96CRlL7tiPtzA9/WKyPkp3A2vqxqgdgyTVNGShPDU= cache.flakehub.com-6:W4EGFwAGgBj3he7c5fNh9NkOXw0PUVaxygCVKeuvaqU= cache.flakehub.com-7:mvxJ2DZVHn/kRxlIaxYNMuDG1OvMckZu32um1TadOR8= cache.flakehub.com-8:moO+OVS0mnTjBTcOUh2kYLQEd59ExzyoW1QgQ8XAARQ= cache.flakehub.com-9:wChaSeTI6TeCuV/Sg2513ZIM9i0qJaYsF+lZCXg0J6o= cache.flakehub.com-10:2GqeNlIp6AKp4EF2MVbE1kBOp9iBSyo0UPR9KoR0o1Y=
bash-prompt-prefix = (nix:$name)\040
max-jobs = auto
extra-nix-path = nixpkgs=flake:nixpkgs
upgrade-nix-store-path-url = https://install.determinate.systems/nix-upgrade/stable/universal
!include nix.custom.conf

View file

@ -53,7 +53,7 @@ in rec {
substitute \
${optionsDoc.optionsJSON}/nix-support/hydra-build-products \
$out/nix-support/hydra-build-products \
--replace \
--replace-fail \
'${optionsDoc.optionsJSON}/share/doc/nixos' \
"$out/share/doc/darwin"
'';
@ -74,8 +74,8 @@ in rec {
cp -r ${pkgs.documentation-highlighter} $dst/highlightjs
substitute ${./manual.md} manual.md \
--replace '@DARWIN_VERSION@' "${version}" \
--replace \
--replace-fail '@DARWIN_VERSION@' "${version}" \
--replace-fail \
'@DARWIN_OPTIONS_JSON@' \
${optionsJSON}/share/doc/darwin/options.json

View file

@ -1,10 +1,72 @@
let
nixDarwinVersion = builtins.fromJSON (builtins.readFile ./version.json);
checkRelease = lib:
# Avoid breaking configurations when the unstable Nixpkgs version
# rolls over.
#
# TODO: Something more refined than this would be ideal, as this
# still means you could be using unstable nix-darwin 25.05 with
# Nixpkgs 26.05, which would be unfortunate.
if nixDarwinVersion.isReleaseBranch then
lib.trivial.release == nixDarwinVersion.release
else
lib.versionAtLeast lib.trivial.release nixDarwinVersion.release;
in
{ lib
, modules
, baseModules ? import ./modules/module-list.nix
, specialArgs ? { }
, check ? true
, enableNixpkgsReleaseCheck ? true
}@args:
assert enableNixpkgsReleaseCheck -> checkRelease lib || throw ''
nix-darwin now uses release branches that correspond to Nixpkgs releases.
The nix-darwin and Nixpkgs branches in use must match, but you are currently
using nix-darwin ${nixDarwinVersion.release} with Nixpkgs ${lib.trivial.release}.
On macOS, you should use either the `nixpkgs-unstable` or
`nixpkgs-YY.MM-darwin` branches of Nixpkgs. These correspond to the
`master` and `nix-darwin-YY.MM` branches of nix-darwin, respectively. Check
<https://status.nixos.org/> for the currently supported Nixpkgs releases.
If youre using flakes, make sure your inputs look like this:
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/NIXPKGS-BRANCH";
nix-darwin.url = "github:LnL7/nix-darwin/NIX-DARWIN-BRANCH";
nix-darwin.inputs.nixpkgs.follows = "nixpkgs";
# …
};
If youre using channels, you can check your current channels with:
$ sudo nix-channel --list
nixpkgs https://nixos.org/channels/NIXPKGS-BRANCH
darwin https://github.com/LnL7/nix-darwin/archive/NIX-DARWIN-BRANCH.tar.gz
$ nix-channel --list
If `darwin` or `nixpkgs` are present in `nix-channel --list` (without
`sudo`), you should delete them with `nix-channel --remove NAME`. These can
contribute to version mismatch problems.
You can then fix your channels like this:
$ sudo nix-channel --add https://nixos.org/channels/NIXPKGS-BRANCH nixpkgs
$ sudo nix-channel --add https://github.com/LnL7/nix-darwin/archive/NIX-DARWIN-BRANCH.tar.gz darwin
$ sudo nix-channel --update
After that, activating your system again should work correctly. If it
doesnt, please open an issue at
<https://github.com/LnL7/nix-darwin/issues/new> and include as much
information as possible.
'';
let
argsModule = {
_file = ./eval-config.nix;
@ -15,7 +77,7 @@ let
};
};
eval = lib.evalModules (builtins.removeAttrs args [ "lib" ] // {
eval = lib.evalModules (builtins.removeAttrs args [ "lib" "enableNixpkgsReleaseCheck" ] // {
class = "darwin";
modules = modules ++ [ argsModule ] ++ baseModules;
specialArgs = { modulesPath = builtins.toString ./modules; } // specialArgs;

12
flake.lock generated
View file

@ -2,16 +2,18 @@
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1718149104,
"narHash": "sha256-Ds1QpobBX2yoUDx9ZruqVGJ/uQPgcXoYuobBguyKEh8=",
"lastModified": 1736241350,
"narHash": "sha256-CHd7yhaDigUuJyDeX0SADbTM9FXfiWaeNyY34FL1wQU=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "e913ae340076bbb73d9f4d3d065c2bca7caafb16",
"rev": "8c9fd3e564728e90829ee7dbac6edc972971cd0f",
"type": "github"
},
"original": {
"id": "nixpkgs",
"type": "indirect"
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {

View file

@ -1,6 +1,10 @@
{
description = "A collection of darwin modules";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
};
outputs = { self, nixpkgs }: let
forAllSystems = nixpkgs.lib.genAttrs [ "aarch64-darwin" "x86_64-darwin" "aarch64-linux" "x86_64-linux" ];
forDarwinSystems = nixpkgs.lib.genAttrs [ "aarch64-darwin" "x86_64-darwin" ];

View file

@ -67,8 +67,24 @@ in
};
environment.darwinConfig = mkOption {
type = types.either types.path types.str;
default = "$HOME/.nixpkgs/darwin-configuration.nix";
type = types.nullOr (types.either types.path types.str);
default =
if config.nixpkgs.flake.setNixPath then
# Dont set this for flakebased systems.
null
else if config.system.stateVersion >= 6 then
"/etc/nix-darwin/configuration.nix"
else
"$HOME/.nixpkgs/darwin-configuration.nix";
defaultText = literalExpression ''
if config.nixpkgs.flake.setNixPath then
# Dont set this for flakebased systems.
null
else if config.system.stateVersion >= 6 then
"/etc/nix-darwin/configuration.nix"
else
"$HOME/.nixpkgs/darwin-configuration.nix"
'';
description = ''
The path of the darwin configuration.nix used to configure the system,
this updates the default darwin-config entry in NIX_PATH. Since this
@ -161,7 +177,7 @@ in
environment.systemPath = mkMerge [
[ (makeBinPath cfg.profiles) ]
(mkOrder 1200 [ "/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin" ])
(mkOrder 1200 [ "/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin" ])
];
# Use user, default and system profiles.

View file

@ -3,7 +3,7 @@
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
nix-darwin.url = "github:LnL7/nix-darwin";
nix-darwin.url = "github:LnL7/nix-darwin/master";
nix-darwin.inputs.nixpkgs.follows = "nixpkgs";
};
@ -27,7 +27,7 @@
# Used for backwards compatibility, please read the changelog before changing.
# $ darwin-rebuild changelog
system.stateVersion = 5;
system.stateVersion = 6;
# The platform the configuration will be used on.
nixpkgs.hostPlatform = "aarch64-darwin";

View file

@ -43,5 +43,5 @@ in
echo "ok"
'';
system.stateVersion = 5;
system.stateVersion = 6;
}

View file

@ -199,7 +199,7 @@
programs.zsh.enableFzfGit = true;
programs.zsh.enableFzfHistory = true;
programs.zsh.variables.cfg = "$HOME/.config/nixpkgs/darwin/configuration.nix";
programs.zsh.variables.cfg = "/etc/nix-darwin/configuration.nix";
programs.zsh.variables.darwin = "$HOME/.nix-defexpr/darwin";
programs.zsh.variables.nixpkgs = "$HOME/.nix-defexpr/nixpkgs";
@ -319,8 +319,7 @@
# path = /etc/per-user/lnl/gitconfig
# environment.etc."per-user/lnl/gitconfig".text = builtins.readFile "${inputs.dotfiles}/git/gitconfig";
nix.configureBuildUsers = true;
nix.nrBuildUsers = 32;
system.stateVersion = 5;
system.stateVersion = 6;
}

View file

@ -7,13 +7,10 @@
[ pkgs.vim
];
# Use custom location for configuration.nix.
environment.darwinConfig = "$HOME/.config/nix-darwin/configuration.nix";
# Enable alternative shell support in nix-darwin.
# programs.fish.enable = true;
# Used for backwards compatibility, please read the changelog before changing.
# $ darwin-rebuild changelog
system.stateVersion = 5;
system.stateVersion = 6;
}

View file

@ -137,7 +137,7 @@ let
config = {
brewBundleCmd = concatStringsSep " " (
optional (!config.autoUpdate) "HOMEBREW_NO_AUTO_UPDATE=1"
++ [ "brew bundle --file='${brewfileFile}' --no-lock" ]
++ [ "brew bundle --file='${brewfileFile}'" ]
++ optional (!config.upgrade) "--no-upgrade"
++ optional (config.cleanup == "uninstall") "--cleanup"
++ optional (config.cleanup == "zap") "--cleanup --zap"
@ -396,6 +396,9 @@ let
no_binaries = mkNullOrBoolOption {
description = "Whether to disable linking of helper executables.";
};
ignore_dependencies = mkNullOrBoolOption {
description = "Ignore casks dependencies in case you manage them extrenally";
};
brewfileLine = mkInternalOption { type = types.nullOr types.str; };
};
@ -705,9 +708,6 @@ in
description = ''
Applications to install from Mac App Store using {command}`mas`.
When this option is used, `"mas"` is automatically added to
[](#opt-homebrew.brews).
Note that you need to be signed into the Mac App Store for {command}`mas` to
successfully install and upgrade applications, and that unfortunately apps removed from this
option will not be uninstalled automatically even if
@ -765,8 +765,7 @@ in
];
homebrew.brews =
optional (cfg.masApps != { }) "mas"
++ optional (cfg.whalebrews != [ ]) "whalebrew";
optional (cfg.whalebrews != [ ]) "whalebrew";
homebrew.brewfile =
"# Created by `nix-darwin`'s `homebrew` module\n\n"
@ -786,7 +785,8 @@ in
# Homebrew Bundle
echo >&2 "Homebrew bundle..."
if [ -f "${cfg.brewPrefix}/brew" ]; then
PATH="${cfg.brewPrefix}":$PATH ${cfg.onActivation.brewBundleCmd}
PATH="${cfg.brewPrefix}:${lib.makeBinPath [ pkgs.mas ]}:$PATH" \
${cfg.onActivation.brewBundleCmd}
else
echo -e "\e[1;31merror: Homebrew is not installed, skipping...\e[0m" >&2
fi

View file

@ -39,11 +39,13 @@ in
ids.uids = {
nixbld = lib.mkDefault 350;
_prometheus-node-exporter = 534;
_dnscrypt-proxy = 535;
};
ids.gids = {
nixbld = lib.mkDefault (if config.system.stateVersion < 5 then 30000 else 350);
_prometheus-node-exporter = 534;
_dnscrypt-proxy = 535;
};
};

View file

@ -62,6 +62,7 @@
./services/chunkwm.nix
./services/cachix-agent.nix
./services/dnsmasq.nix
./services/dnscrypt-proxy.nix
./services/emacs.nix
./services/eternal-terminal.nix
./services/github-runner
@ -82,6 +83,7 @@
./services/nix-gc
./services/nix-optimise
./services/ofborg
./services/openssh.nix
./services/postgresql
./services/privoxy
./services/redis

View file

@ -118,7 +118,6 @@ in
echo "configuring networking..." >&2
${optionalString (cfg.computerName != null) ''
# shellcheck disable=SC1112
scutil --set ComputerName ${escapeShellArg cfg.computerName}
''}
${optionalString (cfg.hostName != null) ''
@ -133,6 +132,11 @@ in
${optionalString (cfg.wakeOnLan.enable != null) ''
systemsetup -setWakeOnNetworkAccess '${onOff cfg.wakeOnLan.enable}' &> /dev/null
''}
if [ -e /etc/hosts.before-nix-darwin ]; then
echo "restoring /etc/hosts..." >&2
sudo mv /etc/hosts{.before-nix-darwin,}
fi
'';
};

View file

@ -12,6 +12,8 @@ let
isNixAtLeast = versionAtLeast (getVersion nixPackage);
configureBuildUsers = !(config.nix.settings.auto-allocate-uids or false);
makeNixBuildUser = nr: {
name = "_nixbld${toString nr}";
value = {
@ -49,13 +51,16 @@ let
mkKeyValuePairs = attrs: concatStringsSep "\n" (mapAttrsToList mkKeyValue attrs);
isExtra = key: hasPrefix "extra-" key;
in
pkgs.writeTextFile {
name = "nix.conf";
text = ''
# WARNING: this file is generated from the nix.* options in
# your nix-darwin configuration. Do not edit it!
${mkKeyValuePairs cfg.settings}
${mkKeyValuePairs (filterAttrs (key: value: !(isExtra key)) cfg.settings)}
${mkKeyValuePairs (filterAttrs (key: value: isExtra key) cfg.settings)}
${cfg.extraOptions}
'';
checkPhase =
@ -134,6 +139,34 @@ let
namedPaths ++ searchPaths;
};
handleUnmanaged = managedConfig: mkMerge [
(mkIf cfg.enable managedConfig)
(mkIf (!cfg.enable) {
system.activationScripts.nix-daemon.text = ''
# Restore unmanaged Nix daemon if present
unmanagedNixProfile=/nix/var/nix/profiles/default
if [[
-e /run/current-system/Library/LaunchDaemons/org.nixos.nix-daemon.plist
&& -e $unmanagedNixProfile/Library/LaunchDaemons/org.nixos.nix-daemon.plist
]]; then
printf >&2 'restoring unmanaged Nix daemon...\n'
cp \
"$unmanagedNixProfile/Library/LaunchDaemons/org.nixos.nix-daemon.plist" \
/Library/LaunchDaemons
launchctl load -w /Library/LaunchDaemons/org.nixos.nix-daemon.plist
fi
'';
})
];
managedDefault = name: default: {
default = if cfg.enable then default else throw ''
${name}: accessed when `nix.enable` is off; this is a bug in
nix-darwin or a thirdparty module
'';
defaultText = default;
};
in
{
@ -144,7 +177,6 @@ in
in
[
# Only ever in NixOS
(mkRemovedOptionModule [ "nix" "enable" ] "No `nix-darwin` equivalent to this NixOS option.")
(mkRemovedOptionModule [ "nix" "daemonCPUSchedPolicy" ] (altOption "nix.daemonProcessType"))
(mkRemovedOptionModule [ "nix" "daemonIOSchedClass" ] (altOption "nix.daemonProcessType"))
(mkRemovedOptionModule [ "nix" "daemonIOSchedPriority" ] (altOption "nix.daemonIOLowPriority"))
@ -157,6 +189,14 @@ in
(mkRenamedOptionModule [ "users" "nix" "nrBuildUsers" ] [ "nix" "nrBuildUsers" ])
(mkRenamedOptionModule [ "nix" "daemonIONice" ] [ "nix" "daemonIOLowPriority" ])
(mkRemovedOptionModule [ "nix" "daemonNiceLevel" ] (consider "nix.daemonProcessType"))
(mkRemovedOptionModule [ "nix" "useDaemon" ] ''
nix-darwin now only supports managing multiuser daemon
installations of Nix.
'')
(mkRemovedOptionModule [ "nix" "configureBuildUsers" ] ''
nix-darwin now manages build users unconditionally when
`nix.enable` is on.
'')
] ++ mapAttrsToList (oldConf: newConf: mkRenamedOptionModule [ "nix" oldConf ] [ "nix" "settings" newConf ]) legacyConfMappings;
###### interface
@ -165,29 +205,43 @@ in
nix = {
enable = lib.mkOption {
type = lib.types.bool;
default = true;
description = ''
Whether to enable Nix.
Disabling this will stop nix-darwin from managing the
installed version of Nix, the nix-daemon launchd daemon, and
the settings in {file}`/etc/nix/nix.conf`.
This allows you to use nix-darwin without it taking over your
system installation of Nix. Some nix-darwin functionality
that relies on managing the Nix installation, like the
`nix.*` options to adjust Nix settings or configure a Linux
builder, will be unavailable. You will also have to upgrade
Nix yourself, as nix-darwin will no longer do so.
::: {.warning}
If you have already removed your global system installation
of Nix, this will break nix-darwin and you will have to
reinstall Nix to fix it.
:::
'';
};
package = mkOption {
type = types.package;
default = pkgs.nix;
inherit (managedDefault "nix.package" pkgs.nix) default;
defaultText = literalExpression "pkgs.nix";
description = ''
This option specifies the Nix package instance to use throughout the system.
'';
};
# Not in NixOS module
useDaemon = mkOption {
type = types.bool;
default = false;
description = ''
If set, Nix will use the daemon to perform operations.
Use this instead of services.nix-daemon.enable if you don't want the
daemon service to be managed for you.
'';
};
distributedBuilds = mkOption {
type = types.bool;
default = false;
inherit (managedDefault "nix.distributedBuilds" false) default defaultText;
description = ''
Whether to distribute builds to the machines listed in
{option}`nix.buildMachines`.
@ -197,7 +251,7 @@ in
# Not in NixOS module
daemonProcessType = mkOption {
type = types.enum [ "Background" "Standard" "Adaptive" "Interactive" ];
default = "Standard";
inherit (managedDefault "nix.daemonProcessType" "Standard") default defaultText;
description = ''
Nix daemon process resource limits class. These limits propagate to
build processes. `Standard` is the default process type
@ -212,7 +266,7 @@ in
# Not in NixOS module
daemonIOLowPriority = mkOption {
type = types.bool;
default = false;
inherit (managedDefault "nix.daemonIOLowPriority" false) default defaultText;
description = ''
Whether the Nix daemon process should considered to be low priority when
doing file system I/O.
@ -340,7 +394,7 @@ in
};
};
});
default = [ ];
inherit (managedDefault "nix.buildMachines" [ ]) default defaultText;
description = ''
This option lists the machines to be used if distributed builds are
enabled (see {option}`nix.distributedBuilds`).
@ -354,21 +408,13 @@ in
envVars = mkOption {
type = types.attrs;
internal = true;
default = { };
inherit (managedDefault "nix.envVars" { }) default defaultText;
description = "Environment variables used by Nix.";
};
# Not in NixOS module
configureBuildUsers = mkOption {
type = types.bool;
default = false;
description = ''
Enable configuration for nixbld group and users.
'';
};
nrBuildUsers = mkOption {
type = types.int;
inherit (managedDefault "nix.nrBuildUsers" 0) default defaultText;
description = ''
Number of `nixbld` user accounts created to
perform secure concurrent builds. If you receive an error
@ -396,11 +442,13 @@ in
# Definition differs substantially from NixOS module
nixPath = mkOption {
type = nixPathType;
default = lib.optionals cfg.channel.enable [
# Include default path <darwin-config>.
{ darwin-config = "${config.environment.darwinConfig}"; }
"/nix/var/nix/profiles/per-user/root/channels"
];
inherit (managedDefault "nix.nixPath" (
lib.optionals cfg.channel.enable [
# Include default path <darwin-config>.
{ darwin-config = "${config.environment.darwinConfig}"; }
"/nix/var/nix/profiles/per-user/root/channels"
]
)) default;
defaultText = lib.literalExpression ''
lib.optionals cfg.channel.enable [
@ -422,7 +470,7 @@ in
checkConfig = mkOption {
type = types.bool;
default = true;
inherit (managedDefault "nix.checkConfig" true) default defaultText;
description = ''
If enabled (the default), checks for data type mismatches and that Nix
can parse the generated nix.conf.
@ -483,7 +531,7 @@ in
};
}
));
default = { };
inherit (managedDefault "nix.registry" { }) default defaultText;
description = ''
A system-wide flake registry.
'';
@ -491,7 +539,7 @@ in
extraOptions = mkOption {
type = types.lines;
default = "";
inherit (managedDefault "nix.extraOptions" "") default defaultText;
example = ''
keep-outputs = true
keep-derivations = true
@ -617,7 +665,6 @@ in
trusted-users = mkOption {
type = types.listOf types.str;
default = [ "root" ];
example = [ "root" "alice" "@admin" ];
description = ''
A list of names of users that have additional rights when
@ -661,7 +708,7 @@ in
};
};
};
default = { };
inherit (managedDefault "nix.settings" { }) default defaultText;
description = ''
Configuration for Nix, see
<https://nixos.org/manual/nix/stable/#sec-conf-file>
@ -679,7 +726,7 @@ in
###### implementation
config = {
config = handleUnmanaged {
environment.systemPackages =
[
nixPackage
@ -703,6 +750,8 @@ in
"5d23e6d7015756c6f300f8cd558ec4d9234ca61deefd4f2478e91a49760b0747" # DeterminateSystems Nix installer 0.16.0
"e4974acb79c56148cb8e92137fa4f2de9b7356e897b332fc4e6769e8c0b83e18" # DeterminateSystems Nix installer 0.20.0
"966d22ef5bb9b56d481e8e0d5f7ca2deaf4d24c0f0fc969b2eeaa7ae0aa42907" # DeterminateSystems Nix installer 0.22.0
"53712b4335030e2dbfb46bb235f8cffcac83fea404bd32dc99417ac89e2dd7c5" # DeterminateSystems Nix installer 0.33.0
"6bb8d6b0dd16b44ee793a9b8382dac76c926e4c16ffb8ddd2bb4884d1ca3f811" # DeterminateSystems Nix installer 0.34.0
"24797ac05542ff8b52910efc77870faa5f9e3275097227ea4e50c430a5f72916" # lix-installer 0.17.1 with flakes
"b027b5cad320b5b8123d9d0db9f815c3f3921596c26dc3c471457098e4d3cc40" # lix-installer 0.17.1 without flakes
];
@ -758,13 +807,13 @@ in
# Not in NixOS module
{ 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.knownUsers -> 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"; }
{
# 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"));
# Lix 2.92.0 will set `VERSION_SUFFIX` to `""`; `lib.versionAtLeast "" "pre20241107"` will return `true`.
assertion = cfg.settings.auto-optimise-store -> (cfg.package.pname == "lix" && (isNixAtLeast "2.92.0" && versionAtLeast (strings.removePrefix "-" cfg.package.VERSION_SUFFIX) "pre20241107"));
message = "`nix.settings.auto-optimise-store` is known to corrupt the Nix Store, please use `nix.optimise.automatic` instead.";
}
];
@ -784,21 +833,11 @@ in
# Set up the environment variables for running Nix.
environment.variables = cfg.envVars // { NIX_PATH = cfg.nixPath; };
environment.extraInit = mkMerge [
(mkIf cfg.channel.enable ''
if [ -e "$HOME/.nix-defexpr/channels" ]; then
export NIX_PATH="$HOME/.nix-defexpr/channels''${NIX_PATH:+:$NIX_PATH}"
fi
'')
# Not in NixOS module
''
# Set up secure multi-user builds: non-root users build through the
# Nix daemon.
if [ ! -w /nix/var/nix/db ]; then
export NIX_REMOTE=daemon
fi
''
];
environment.extraInit = mkIf cfg.channel.enable ''
if [ -e "$HOME/.nix-defexpr/channels" ]; then
export NIX_PATH="$HOME/.nix-defexpr/channels''${NIX_PATH:+:$NIX_PATH}"
fi
'';
environment.extraSetup = mkIf (!cfg.channel.enable) ''
rm --force $out/bin/nix-channel
@ -806,10 +845,10 @@ in
nix.nrBuildUsers = mkDefault (max 32 (if cfg.settings.max-jobs == "auto" then 0 else cfg.settings.max-jobs));
users.users = mkIf cfg.configureBuildUsers nixbldUsers;
users.users = mkIf configureBuildUsers nixbldUsers;
# Not in NixOS module
users.groups.nixbld = mkIf cfg.configureBuildUsers {
users.groups.nixbld = mkIf configureBuildUsers {
description = "Nix build group for nix-daemon";
gid = config.ids.gids.nixbld;
members = attrNames nixbldUsers;
@ -817,14 +856,62 @@ in
users.knownUsers =
let nixbldUserNames = attrNames nixbldUsers;
in
mkIf cfg.configureBuildUsers (mkMerge [
mkMerge [
nixbldUserNames
(map (removePrefix "_") nixbldUserNames) # delete old style nixbld users
]);
users.knownGroups = mkIf cfg.configureBuildUsers [ "nixbld" ];
];
users.knownGroups = [ "nixbld" ];
# The Determinate Systems installer puts userspecified settings in
# `/etc/nix/nix.custom.conf` since v0.33.0. Supplement the
# `/etc/nix/nix.conf` hash check so that we dont accidentally
# clobber user configuration.
#
# TODO: Maybe this could use a more general file placement mechanism
# to express that we want it deleted and know only one hash?
system.activationScripts.etcChecks.text = mkAfter ''
nixCustomConfKnownSha256Hashes=(
# v0.33.0
6787fade1cf934f82db554e78e1fc788705c2c5257fddf9b59bdd963ca6fec63
# v0.34.0
3bd68ef979a42070a44f8d82c205cfd8e8cca425d91253ec2c10a88179bb34aa
)
if [[ -e /etc/nix/nix.custom.conf ]]; then
nixCustomConfSha256Output=$(shasum -a 256 /etc/nix/nix.custom.conf)
nixCustomConfSha256Hash=''${nixCustomConfSha256Output%% *}
nixCustomConfIsKnown=
for nixCustomConfKnownSha256Hash
in "''${nixCustomConfKnownSha256Hashes[@]}"
do
if
[[ $nixCustomConfSha256Hash == "$nixCustomConfKnownSha256Hash" ]]
then
nixCustomConfIsKnown=1
break
fi
done
if [[ ! $nixCustomConfIsKnown ]]; then
printf >&2 '\e[1;31merror: custom settings in `/etc/nix/nix.custom.conf`, aborting activation\e[0m\n'
printf >&2 'You will need to migrate these to nix-darwin `nix.*` settings if you\n'
printf >&2 'wish to keep them. Check the manual for the appropriate settings and\n'
printf >&2 'add them to your system configuration, then run:\n'
printf >&2 '\n'
printf >&2 ' $ sudo mv /etc/nix/nix.custom.conf{,.before-nix-darwin}\n'
printf >&2 '\n'
printf >&2 'and activate your system again.\n'
exit 2
fi
fi
'';
# Unrelated to use in NixOS module
system.activationScripts.nix-daemon.text = mkIf cfg.useDaemon ''
system.activationScripts.nix-daemon.text = ''
# Follow up on the `/etc/nix/nix.custom.conf` check.
# TODO: Use a more generalized file placement mechanism for this.
if [[ -e /etc/nix/nix.custom.conf ]]; then
mv /etc/nix/nix.custom.conf{,.before-nix-darwin}
fi
if ! diff /etc/nix/nix.conf /run/current-system/etc/nix/nix.conf &> /dev/null || ! diff /etc/nix/machines /run/current-system/etc/nix/machines &> /dev/null; then
echo "reloading nix-daemon..." >&2
launchctl kill HUP system/org.nixos.nix-daemon
@ -835,12 +922,15 @@ in
done
'';
# Legacy configuration conversion.
nix.settings = mkMerge [
{
trusted-public-keys = [ "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" ];
trusted-users = [ "root" ];
substituters = mkAfter [ "https://cache.nixos.org/" ];
# Not in NixOS module
build-users-group = "nixbld";
# Not implemented yet
# system-features = mkDefault (
# [ "nixos-test" "benchmark" "big-parallel" "kvm" ] ++
@ -856,8 +946,6 @@ in
(mkIf (isNixAtLeast "2.3pre") { sandbox-fallback = false; })
# Not in NixOS module
(mkIf cfg.useDaemon { build-users-group = "nixbld"; })
];
};

View file

@ -61,9 +61,16 @@ in
maxJobs = mkOption {
type = types.ints.positive;
default = 1;
example = 4;
default = cfg.package.nixosConfig.virtualisation.cores;
defaultText = ''
The `virtualisation.cores` of the build machine's final NixOS configuration.
'';
example = 2;
description = ''
Instead of setting this directly, you should set
{option}`nix.linux-builder.config.virtualisation.cores` to configure
the amount of cores the Linux builder should have.
The number of concurrent jobs the Linux builder machine supports. The
build machine will enforce its own limits, but this allows hydra
to schedule better since there is no work-stealing between build
@ -153,6 +160,13 @@ in
};
config = mkIf cfg.enable {
assertions = [
{
assertion = config.nix.enable;
message = ''`nix.linux-builder.enable` requires `nix.enable`'';
}
];
system.activationScripts.preActivation.text = ''
mkdir -p ${cfg.workingDirectory}
'';

View file

@ -4,7 +4,7 @@ let
nix-tools = pkgs.callPackage ../../pkgs/nix-tools {
inherit (config.system) profile;
inherit (config.environment) systemPath;
nixPackage = config.nix.package;
nixPath = lib.optionalString config.nix.enable (lib.concatStringsSep ":" config.nix.nixPath);
};
darwin-uninstaller = pkgs.callPackage ../../pkgs/darwin-uninstaller { };

View file

@ -37,8 +37,8 @@ in
setNixPath = mkOption {
type = types.bool;
default = cfg.source != null;
defaultText = "config.nixpkgs.flake.source != null";
default = config.nix.enable && cfg.source != null;
defaultText = literalExpression ''config.nix.enable && nixpkgs.flake.source != null'';
description = ''
Whether to set {env}`NIX_PATH` to include `nixpkgs=flake:nixpkgs` such that `<nixpkgs>`
@ -57,8 +57,8 @@ in
setFlakeRegistry = mkOption {
type = types.bool;
default = cfg.source != null;
defaultText = "config.nixpkgs.flake.source != null";
default = config.nix.enable && cfg.source != null;
defaultText = literalExpression ''config.nix.enable && config.nixpkgs.flake.source != null'';
description = ''
Whether to pin nixpkgs in the system-wide flake registry (`/etc/nix/registry.json`) to the
@ -85,6 +85,18 @@ in
be set, since it is implemented in terms of indirection through the flake registry.
'';
}
# TODO: Upstream these to NixOS.
{
assertion = cfg.setNixPath -> config.nix.enable;
message = ''`nixpkgs.flake.setNixPath` requires `nix.enable`'';
}
{
assertion = cfg.setFlakeRegistry -> config.nix.enable;
message = ''`nixpkgs.flake.setFlakeRegistry` requires `nix.enable`'';
}
];
}
(mkIf cfg.setFlakeRegistry {

View file

@ -1,89 +1,96 @@
{ config, options, lib, pkgs, ... }:
with lib;
{
config,
options,
lib,
pkgs,
...
}:
let
cfg = config.nixpkgs;
opt = options.nixpkgs;
isConfig = x:
builtins.isAttrs x || lib.isFunction x;
isConfig = x: builtins.isAttrs x || lib.isFunction x;
optCall = f: x:
if lib.isFunction f
then f x
else f;
optCall = f: x: if lib.isFunction f then f x else f;
mergeConfig = lhs_: rhs_:
mergeConfig =
lhs_: rhs_:
let
lhs = optCall lhs_ { inherit pkgs; };
rhs = optCall rhs_ { inherit pkgs; };
in
recursiveUpdate lhs rhs //
optionalAttrs (lhs ? packageOverrides) {
packageOverrides = pkgs:
optCall lhs.packageOverrides pkgs //
optCall (attrByPath [ "packageOverrides" ] { } rhs) pkgs;
} //
optionalAttrs (lhs ? perlPackageOverrides) {
perlPackageOverrides = pkgs:
optCall lhs.perlPackageOverrides pkgs //
optCall (attrByPath [ "perlPackageOverrides" ] { } rhs) pkgs;
lib.recursiveUpdate lhs rhs
// lib.optionalAttrs (lhs ? packageOverrides) {
packageOverrides =
pkgs:
optCall lhs.packageOverrides pkgs // optCall (lib.attrByPath [ "packageOverrides" ] { } rhs) pkgs;
}
// lib.optionalAttrs (lhs ? perlPackageOverrides) {
perlPackageOverrides =
pkgs:
optCall lhs.perlPackageOverrides pkgs
// optCall (lib.attrByPath [ "perlPackageOverrides" ] { } rhs) pkgs;
};
configType = mkOptionType {
configType = lib.mkOptionType {
name = "nixpkgs-config";
description = "nixpkgs config";
check = x:
let traceXIfNot = c:
if c x then true
else lib.traceSeqN 1 x false;
in traceXIfNot isConfig;
merge = args: foldr (def: mergeConfig def.value) {};
check =
x:
let
traceXIfNot = c: if c x then true else lib.traceSeqN 1 x false;
in
traceXIfNot isConfig;
merge = args: lib.foldr (def: mergeConfig def.value) { };
};
overlayType = mkOptionType {
overlayType = lib.mkOptionType {
name = "nixpkgs-overlay";
description = "nixpkgs overlay";
check = lib.isFunction;
merge = lib.mergeOneOption;
};
pkgsType = types.pkgs // {
pkgsType = lib.types.pkgs // {
# This type is only used by itself, so let's elaborate the description a bit
# for the purpose of documentation.
description = "An evaluation of Nixpkgs; the top level attribute set of packages";
};
hasBuildPlatform = opt.buildPlatform.highestPrio < (mkOptionDefault {}).priority;
hasBuildPlatform = opt.buildPlatform.highestPrio < (lib.mkOptionDefault { }).priority;
hasHostPlatform = opt.hostPlatform.isDefined;
hasPlatform = hasHostPlatform || hasBuildPlatform;
# Context for messages
hostPlatformLine = optionalString hasHostPlatform "${showOptionWithDefLocs opt.hostPlatform}";
buildPlatformLine = optionalString hasBuildPlatform "${showOptionWithDefLocs opt.buildPlatform}";
hostPlatformLine = lib.optionalString hasHostPlatform "${lib.showOptionWithDefLocs opt.hostPlatform}";
buildPlatformLine = lib.optionalString hasBuildPlatform "${lib.showOptionWithDefLocs opt.buildPlatform}";
legacyOptionsDefined =
optional (opt.system.highestPrio < (mkDefault {}).priority) opt.system
;
legacyOptionsDefined = lib.optional (
opt.system.highestPrio < (lib.mkDefault { }).priority
) opt.system;
defaultPkgs =
if opt.hostPlatform.isDefined
then
let isCross = cfg.buildPlatform != cfg.hostPlatform;
systemArgs =
if isCross
then {
if opt.hostPlatform.isDefined then
let
isCross = cfg.buildPlatform != cfg.hostPlatform;
systemArgs =
if isCross then
{
localSystem = cfg.buildPlatform;
crossSystem = cfg.hostPlatform;
}
else {
else
{
localSystem = cfg.hostPlatform;
};
in
import cfg.source ({
inherit (cfg) config overlays;
} // systemArgs)
import cfg.source (
{
inherit (cfg) config overlays;
}
// systemArgs
)
else
import cfg.source {
inherit (cfg) config overlays;
@ -96,9 +103,9 @@ in
{
options.nixpkgs = {
pkgs = mkOption {
pkgs = lib.mkOption {
type = pkgsType;
example = literalExpression "import <nixpkgs> {}";
example = lib.literalExpression "import <nixpkgs> {}";
description = ''
If set, the pkgs argument to all nix-darwin modules is the value of
this option, extended with `nixpkgs.overlays`, if
@ -120,53 +127,48 @@ in
'';
};
config = mkOption {
default = {};
example = literalExpression
''
{ allowBroken = true; allowUnfree = true; }
'';
config = lib.mkOption {
default = { };
example = lib.literalExpression ''
{ allowBroken = true; allowUnfree = true; }
'';
type = configType;
description = ''
The configuration of the Nix Packages collection. (For
details, see the Nixpkgs documentation.) It allows you to set
package configuration options.
Global configuration for Nixpkgs.
The complete list of [Nixpkgs configuration options](https://nixos.org/manual/nixpkgs/unstable/#sec-config-options-reference) is in the [Nixpkgs manual section on global configuration](https://nixos.org/manual/nixpkgs/unstable/#chap-packageconfig).
Ignored when `nixpkgs.pkgs` is set.
Ignored when {option}`nixpkgs.pkgs` is set.
'';
};
overlays = mkOption {
default = [];
example = literalExpression
''
[
(self: super: {
openssh = super.openssh.override {
hpnSupport = true;
kerberos = self.libkrb5;
};
})
]
'';
type = types.listOf overlayType;
overlays = lib.mkOption {
default = [ ];
example = lib.literalExpression ''
[
(self: super: {
openssh = super.openssh.override {
hpnSupport = true;
kerberos = self.libkrb5;
};
})
]
'';
type = lib.types.listOf overlayType;
description = ''
List of overlays to use with the Nix Packages collection.
(For details, see the Nixpkgs documentation.) It allows
you to override packages globally. Each function in the list
takes as an argument the *original* Nixpkgs.
The first argument should be used for finding dependencies, and
the second should be used for overriding recipes.
List of overlays to apply to Nixpkgs.
This option allows modifying the Nixpkgs package set accessed through the `pkgs` module argument.
If `nixpkgs.pkgs` is set, overlays specified here
will be applied after the overlays that were already present
in `nixpkgs.pkgs`.
For details, see the [Overlays chapter in the Nixpkgs manual](https://nixos.org/manual/nixpkgs/stable/#chap-overlays).
If the {option}`nixpkgs.pkgs` option is set, overlays specified using `nixpkgs.overlays` will be applied after the overlays that were already included in `nixpkgs.pkgs`.
'';
};
hostPlatform = mkOption {
type = types.either types.str types.attrs; # TODO utilize lib.systems.parsedPlatform
example = { system = "aarch64-darwin"; config = "aarch64-apple-darwin"; };
hostPlatform = lib.mkOption {
type = lib.types.either lib.types.str lib.types.attrs; # TODO utilize lib.systems.parsedPlatform
example = {
system = "aarch64-darwin";
};
# Make sure that the final value has all fields for sake of other modules
# referring to this. TODO make `lib.systems` itself use the module system.
apply = lib.systems.elaborate;
@ -179,15 +181,24 @@ in
'';
};
buildPlatform = mkOption {
type = types.either types.str types.attrs; # TODO utilize lib.systems.parsedPlatform
buildPlatform = lib.mkOption {
type = lib.types.either lib.types.str lib.types.attrs; # TODO utilize lib.systems.parsedPlatform
default = cfg.hostPlatform;
example = { system = "x86_64-darwin"; config = "x86_64-apple-darwin"; };
example = {
system = "x86_64-darwin";
};
# Make sure that the final value has all fields for sake of other modules
# referring to this.
apply = lib.systems.elaborate;
defaultText = literalExpression
''config.nixpkgs.hostPlatform'';
apply =
inputBuildPlatform:
let
elaborated = lib.systems.elaborate inputBuildPlatform;
in
if lib.systems.equals elaborated cfg.hostPlatform then
cfg.hostPlatform # make identical, so that `==` equality works; see https://github.com/NixOS/nixpkgs/issues/278001
else
elaborated;
defaultText = lib.literalExpression ''config.nixpkgs.hostPlatform'';
description = ''
Specifies the platform on which nix-darwin should be built.
By default, nix-darwin is built on the system where it runs, but you can
@ -202,12 +213,11 @@ in
'';
};
system = mkOption {
type = types.str;
system = lib.mkOption {
type = lib.types.str;
example = "x86_64-darwin";
default =
if opt.hostPlatform.isDefined
then
if opt.hostPlatform.isDefined then
throw ''
Neither ${opt.system} nor any other option in nixpkgs.* is meant
to be read by modules and configurations.
@ -232,9 +242,9 @@ in
# nix-darwin only
source = mkOption {
type = types.path;
defaultText = literalMD ''
source = lib.mkOption {
type = lib.types.path;
defaultText = lib.literalMD ''
`<nixpkgs>` or nix-darwin's `nixpkgs` flake input
'';
description = ''
@ -247,8 +257,8 @@ in
'';
};
constructedByUs = mkOption {
type = types.bool;
constructedByUs = lib.mkOption {
type = lib.types.bool;
internal = true;
description = ''
Whether `pkgs` was constructed by this module. This is false when any of
@ -266,40 +276,51 @@ in
# which is somewhat costly for Nixpkgs. With an explicit priority, we only
# evaluate the wrapper to find out that the priority is lower, and then we
# don't need to evaluate `finalPkgs`.
lib.mkOverride lib.modules.defaultOverridePriority
finalPkgs.__splicedPackages;
lib.mkOverride lib.modules.defaultOverridePriority finalPkgs.__splicedPackages;
};
nixpkgs.constructedByUs =
# We set it with default priority and it can not be merged, so if the
# pkgs module argument has that priority, it's from us.
(lib.modules.mergeAttrDefinitionsWithPrio options._module.args).pkgs.highestPrio
== lib.modules.defaultOverridePriority
== lib.modules.defaultOverridePriority
# Although, if nixpkgs.pkgs is set, we did forward it, but we did not construct it.
&& !opt.pkgs.isDefined;
&& !opt.pkgs.isDefined;
assertions = [
(
let
pkgsSystem = finalPkgs.stdenv.targetPlatform.system;
in {
in
{
assertion = cfg.constructedByUs -> !hasPlatform -> cfg.system == pkgsSystem;
message = "The nix-darwin nixpkgs.pkgs option was set to a Nixpkgs invocation that compiles to target system ${pkgsSystem} but nix-darwin was configured for system ${darwinExpectedSystem} via nix-darwin option nixpkgs.system. The nix-darwin system settings must match the Nixpkgs target system.";
message = "The nix-darwin nixpkgs.pkgs option was set to a Nixpkgs invocation that compiles to target system ${pkgsSystem} but nix-darwin was configured for system ${config.nixpkgs.system} via nix-darwin option nixpkgs.system. The nix-darwin system settings must match the Nixpkgs target system.";
}
)
{
assertion = cfg.constructedByUs -> hasPlatform -> legacyOptionsDefined == [];
assertion = cfg.constructedByUs -> hasPlatform -> legacyOptionsDefined == [ ];
message = ''
Your system configures nixpkgs with the platform parameter${optionalString hasBuildPlatform "s"}:
${hostPlatformLine
}${buildPlatformLine
}
Your system configures nixpkgs with the platform parameter${lib.optionalString hasBuildPlatform "s"}:
${hostPlatformLine}${buildPlatformLine}
However, it also defines the legacy options:
${concatMapStrings showOptionWithDefLocs legacyOptionsDefined}
${lib.concatMapStrings lib.showOptionWithDefLocs legacyOptionsDefined}
For a future proof system configuration, we recommend to remove
the legacy definitions.
'';
}
{
assertion = opt.pkgs.isDefined -> cfg.config == { };
message = ''
Your system configures nixpkgs with an externally created instance.
`nixpkgs.config` options should be passed when creating the instance instead.
Current value:
${lib.generators.toPretty { multiline = true; } cfg.config}
Defined in:
${lib.concatMapStringsSep "\n" (file: " - ${file}") opt.config.files}
'';
}
];
};
}

View file

@ -15,6 +15,8 @@ in
default = null;
description = ''
Whether to restart the computer after a power failure.
Option is not supported on all devices.
'';
};

View file

@ -57,6 +57,8 @@ in
type = types.bool;
};
package = lib.mkPackageOption pkgs "fish" { };
useBabelfish = mkOption {
type = types.bool;
default = false;
@ -238,7 +240,7 @@ in
++ optional cfg.vendor.functions.enable "/share/fish/vendor_functions.d";
}
{ systemPackages = [ pkgs.fish ]; }
{ systemPackages = [ cfg.package ]; }
];
};

View file

@ -114,6 +114,15 @@ in
type = with types; attrsOf (submodule userOptions);
};
programs.ssh.extraConfig = lib.mkOption {
type = lib.types.lines;
default = "";
description = ''
Extra configuration text loaded in {file}`ssh_config`.
See {manpage}`ssh_config(5)` for help.
'';
};
programs.ssh.knownHosts = mkOption {
default = {};
type = types.attrsOf (types.submodule host);
@ -151,6 +160,7 @@ in
+ (if h.publicKey != null then h.publicKey else readFile h.publicKeyFile)
)) + "\n";
};
"ssh/ssh_config.d/100-nix-darwin.conf".text = config.programs.ssh.extraConfig;
"ssh/sshd_config.d/101-authorized-keys.conf" = {
text = ''
# sshd doesn't like reading from symbolic links, so we cat

View file

@ -204,7 +204,7 @@ in
}
${optionalString cfg.enableFastSyntaxHighlighting
"source ${pkgs.zsh-fast-syntax-highlighting}/share/zsh-fast-syntax-highlighting/zsh-fast-syntax-highlighting.zsh"
"source ${pkgs.zsh-fast-syntax-highlighting}/share/zsh/site-functions/fast-syntax-highlighting.plugin.zsh"
}
${optionalString cfg.enableFzfCompletion "source ${fzfCompletion}"}

View file

@ -1,69 +1,106 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.security.pam;
# Implementation Notes
#
# We don't use `environment.etc` because this would require that the user manually delete
# `/etc/pam.d/sudo` which seems unwise given that applying the nix-darwin configuration requires
# sudo. We also can't use `system.patchs` since it only runs once, and so won't patch in the
# changes again after OS updates (which remove modifications to this file).
#
# As such, we resort to line addition/deletion in place using `sed`. We add a comment to the
# added line that includes the name of the option, to make it easier to identify the line that
# should be deleted when the option is disabled.
mkSudoTouchIdAuthScript = isEnabled:
let
file = "/etc/pam.d/sudo";
option = "security.pam.enableSudoTouchIdAuth";
sed = "${pkgs.gnused}/bin/sed";
in ''
${if isEnabled then ''
# Enable sudo Touch ID authentication, if not already enabled
if ! grep 'pam_tid.so' ${file} > /dev/null; then
${sed} -i '2i\
auth sufficient pam_tid.so # nix-darwin: ${option}
' ${file}
fi
'' else ''
# Disable sudo Touch ID authentication, if added by nix-darwin
if grep '${option}' ${file} > /dev/null; then
${sed} -i '/${option}/d' ${file}
fi
''}
'';
cfg = config.security.pam.services.sudo_local;
in
{
imports = [
(lib.mkRemovedOptionModule [ "security" "pam" "enableSudoTouchIdAuth" ] ''
This option has been renamed to `security.pam.services.sudo_local.touchIdAuth` for consistency with NixOS.
'')
];
options = {
security.pam.enableSudoTouchIdAuth = mkEnableOption "" // {
description = ''
Enable sudo authentication with Touch ID.
security.pam.services.sudo_local = {
enable = lib.mkEnableOption "managing {file}`/etc/pam.d/sudo_local` with nix-darwin" // {
default = true;
example = false;
};
When enabled, this option adds the following line to
{file}`/etc/pam.d/sudo`:
text = lib.mkOption {
type = lib.types.lines;
default = "";
description = ''
Contents of {file}`/etc/pam.d/sudo_local`
'';
};
```
auth sufficient pam_tid.so
```
touchIdAuth = lib.mkEnableOption "" // {
description = ''
Whether to enable Touch ID with sudo.
::: {.note}
macOS resets this file when doing a system update. As such, sudo
authentication with Touch ID won't work after a system update
until the nix-darwin configuration is reapplied.
:::
'';
This will also allow your Apple Watch to be used for sudo. If this doesn't work,
you can go into `System Settings > Touch ID & Password` and toggle the switch for
your Apple Watch.
'';
};
watchIdAuth = lib.mkEnableOption "" // {
description = ''
Use Apple Watch for sudo authentication, for devices without Touch ID or
laptops with lids closed, consider using this.
When enabled, you can use your Apple Watch to authenticate sudo commands.
If this doesn't work, you can go into `System Settings > Touch ID & Password`
and toggle the switch for your Apple Watch.
'';
};
reattach = lib.mkEnableOption "" // {
description = ''
Whether to enable reattaching a program to the user's bootstrap session.
This fixes Touch ID for sudo not working inside tmux and screen.
This allows programs like tmux and screen that run in the background to
survive across user sessions to work with PAM services that are tied to the
bootstrap session.
'';
};
};
};
config = {
system.activationScripts.pam.text = ''
security.pam.services.sudo_local.text = lib.concatLines (
(lib.optional cfg.reattach "auth optional ${pkgs.pam-reattach}/lib/pam/pam_reattach.so")
++ (lib.optional cfg.touchIdAuth "auth sufficient pam_tid.so")
++ (lib.optional cfg.watchIdAuth "auth sufficient ${pkgs.pam-watchid}/lib/pam_watchid.so")
);
environment.etc."pam.d/sudo_local" = {
inherit (cfg) enable text;
};
system.activationScripts.pam.text =
let
file = "/etc/pam.d/sudo";
marker = "security.pam.services.sudo_local";
deprecatedOption = "security.pam.enableSudoTouchIdAuth";
sed = lib.getExe pkgs.gnused;
in
''
# PAM settings
echo >&2 "setting up pam..."
${mkSudoTouchIdAuthScript cfg.enableSudoTouchIdAuth}
# REMOVEME when macOS 13 no longer supported as macOS automatically
# nukes this file on system upgrade
# Always clear out older implementation if it is present
if grep '${deprecatedOption}' ${file} > /dev/null; then
${sed} -i '/${deprecatedOption}/d' ${file}
fi
${if cfg.enable then ''
# REMOVEME when macOS 13 no longer supported
# `sudo_local` is automatically included after macOS 14
if ! grep 'sudo_local' ${file} > /dev/null; then
${sed} -i '2iauth include sudo_local # nix-darwin: ${marker}' ${file}
fi
'' else ''
# Remove include line if we added it
if grep '${marker}' ${file} > /dev/null; then
${sed} -i '/${marker}/d' ${file}
fi
''}
'';
};
}

View file

@ -21,14 +21,15 @@
ln -sfn $(cat ${config.system.profile}/systemConfig) /run/current-system
# Prevent the current configuration from being garbage-collected.
ln -sfn /run/current-system /nix/var/nix/gcroots/current-system
if [[ -d /nix/var/nix/gcroots ]]; then
ln -sfn /run/current-system /nix/var/nix/gcroots/current-system
fi
${config.system.activationScripts.etcChecks.text}
${config.system.activationScripts.etc.text}
${config.system.activationScripts.keyboard.text}
'';
serviceConfig.RunAtLoad = true;
serviceConfig.KeepAlive.SuccessfulExit = false;
};
};
}

View file

@ -9,7 +9,31 @@ let
cfg = config.services.aerospace;
format = pkgs.formats.toml { };
configFile = format.generate "aerospace.toml" cfg.settings;
filterAttrsRecursive = pred: set:
lib.listToAttrs (
lib.concatMap (
name: let
v = set.${name};
in
if pred v
then [
(lib.nameValuePair name (
if lib.isAttrs v
then filterAttrsRecursive pred v
else if lib.isList v
then
(map (i:
if lib.isAttrs i
then filterAttrsRecursive pred i
else i) (lib.filter pred v))
else v
))
]
else []
) (lib.attrNames set)
);
filterNulls = filterAttrsRecursive (v: v != null);
configFile = format.generate "aerospace.toml" (filterNulls cfg.settings);
in
{
@ -36,7 +60,8 @@ in
after-startup-command = lib.mkOption {
type = listOf str;
default = [ ];
description = "Do not use AeroSpace to run commands after startup. (Managed by launchd instead)";
description = "Add commands that run after AeroSpace startup";
example = [ "layout tiles" ];
};
enable-normalization-flatten-containers = lib.mkOption {
type = bool;
@ -71,9 +96,84 @@ in
description = "Default orientation for the root container.";
};
on-window-detected = lib.mkOption {
type = listOf str;
type = listOf (submodule {
options = {
"if" = lib.mkOption {
type = submodule {
options = {
app-id = lib.mkOption {
type = nullOr str;
default = null;
description = "The application ID to match (optional).";
};
workspace = lib.mkOption {
type = nullOr str;
default = null;
description = "The workspace name to match (optional).";
};
window-title-regex-substring = lib.mkOption {
type = nullOr str;
default = null;
description = "Substring to match in the window title (optional).";
};
app-name-regex-substring = lib.mkOption {
type = nullOr str;
default = null;
description = "Regex substring to match the app name (optional).";
};
during-aerospace-startup = lib.mkOption {
type = nullOr bool;
default = null;
description = "Whether to match during aerospace startup (optional).";
};
};
};
default = { };
description = "Conditions for detecting a window.";
};
check-further-callbacks = lib.mkOption {
type = nullOr bool;
default = null;
description = "Whether to check further callbacks after this rule (optional).";
};
run = lib.mkOption {
type = oneOf [str (listOf str)];
example = ["move-node-to-workspace m" "resize-node"];
description = "Commands to execute when the conditions match (required).";
};
};
});
default = [ ];
description = "Commands to run every time a new window is detected.";
example = [
{
"if" = {
app-id = "Another.Cool.App";
workspace = "cool-workspace";
window-title-regex-substring = "Title";
app-name-regex-substring = "CoolApp";
during-aerospace-startup = false;
};
check-further-callbacks = false;
run = ["move-node-to-workspace m" "resize-node"];
}
];
description = "Commands to run every time a new window is detected with optional conditions.";
};
workspace-to-monitor-force-assignment = lib.mkOption {
type = attrsOf (oneOf [int str (listOf str)]);
default = { };
description = ''
Map workspaces to specific monitors.
Left-hand side is the workspace name, and right-hand side is the monitor pattern.
'';
example = {
"1" = 1; # First monitor from left to right.
"2" = "main"; # Main monitor.
"3" = "secondary"; # Secondary monitor (non-main).
"4" = "built-in"; # Built-in display.
"5" = "^built-in retina display$"; # Regex for the built-in retina display.
"6" = ["secondary" "dell"]; # Match first pattern in the list.
};
};
on-focus-changed = lib.mkOption {
type = listOf str;
@ -142,10 +242,6 @@ in
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 ];

View file

@ -227,8 +227,9 @@ in
{ path = cfg.runtimePackages ++ [ cfg.package pkgs.coreutils pkgs.darwin.DarwinTools ];
environment = {
HOME = cfg.dataDir;
NIX_REMOTE = "daemon";
inherit (config.environment.variables) NIX_SSL_CERT_FILE;
} // (if config.nix.useDaemon then { NIX_REMOTE = "daemon"; } else {});
};
## NB: maximum care is taken so that secrets (ssh keys and the CI token)
## don't end up in the Nix store.

View file

@ -51,6 +51,14 @@ in {
};
config = mkIf cfg.enable {
# TODO: Upstream this to NixOS.
assertions = [
{
assertion = config.nix.enable;
message = ''`services.cachix-agent.enable` requires `nix.enable`'';
}
];
launchd.daemons.cachix-agent = {
script = ''
. ${cfg.credentialsFile}

View file

@ -0,0 +1,81 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.services.dnscrypt-proxy;
format = pkgs.formats.toml { };
configFile = format.generate "dnscrypt-proxy.toml" cfg.settings;
in
{
options.services.dnscrypt-proxy = {
enable = lib.mkEnableOption "the dnscrypt-proxy service.";
package = lib.mkPackageOption pkgs "dnscrypt-proxy" { };
settings = lib.mkOption {
description = ''
Attrset that is converted and passed as TOML config file.
For available params, see: <https://github.com/DNSCrypt/dnscrypt-proxy/blob/${pkgs.dnscrypt-proxy.version}/dnscrypt-proxy/example-dnscrypt-proxy.toml>
'';
example = lib.literalExpression ''
{
sources.public-resolvers = {
urls = [ "https://download.dnscrypt.info/resolvers-list/v2/public-resolvers.md" ];
cache_file = "public-resolvers.md";
minisign_key = "RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3";
refresh_delay = 72;
};
}
'';
type = format.type;
default = { };
};
};
config = lib.mkIf cfg.enable {
users.users._dnscrypt-proxy = {
uid = config.ids.uids._dnscrypt-proxy;
gid = config.ids.gids._dnscrypt-proxy;
home = "/var/lib/dnscrypt-proxy";
createHome = true;
shell = "/usr/bin/false";
description = "System user for dnscrypt-proxy";
};
users.groups._dnscrypt-proxy = {
gid = config.ids.gids._dnscrypt-proxy;
description = "System group for dnscrypt-proxy";
};
users.knownUsers = [ "_dnscrypt-proxy" ];
users.knownGroups = [ "_dnscrypt-proxy" ];
launchd.daemons.dnscrypt-proxy = {
script = ''
${lib.getExe' cfg.package "dnscrypt-proxy"} -config ${configFile}
'';
serviceConfig =
let
logPath = config.users.users._dnscrypt-proxy.home + "/dnscrypt-proxy.log";
in
{
RunAtLoad = true;
KeepAlive = true;
StandardOutPath = logPath;
StandardErrorPath = logPath;
GroupName = "_dnscrypt-proxy";
UserName = "_dnscrypt-proxy";
};
};
};
}

View file

@ -3,7 +3,9 @@
, ...
}:
with lib;
let
inherit (lib) literalExpression mkOption mkPackageOption types;
in
{
options.services.github-runners = mkOption {
description = ''
@ -88,6 +90,9 @@ with lib;
Changing this option or the `tokenFile`s content triggers a new runner registration.
You can also manually trigger a new runner registration by deleting
{file}`/var/lib/github-runners/<name>/.runner` and restarting the service.
We suggest using the fine-grained PATs. A runner registration token is valid
only for 1 hour after creation, so the next time the runner configuration changes
this will give you hard-to-debug HTTP 404 errors in the configure step.

View file

@ -1,6 +1,10 @@
{ config, lib, pkgs, ... }:
with lib;
let
inherit (lib) any attrValues boolToString concatStringsSep escapeShellArg
flatten flip getExe getExe' hasAttr hasPrefix mapAttrsToList mapAttrs' mkBefore
mkDefault mkIf mkMerge nameValuePair optionalAttrs optionalString replaceStrings;
mkSvcName = name: "github-runner-${name}";
mkStateDir = cfg: "/var/lib/github-runners/${cfg.name}";
mkLogDir = cfg: "/var/log/github-runners/${cfg.name}";
@ -9,6 +13,11 @@ in
{
config.assertions = flatten (
flip mapAttrsToList config.services.github-runners (name: cfg: map (mkIf cfg.enable) [
# TODO: Upstream this to NixOS.
{
assertion = config.nix.enable;
message = ''`services.github-runners.${name}.enable` requires `nix.enable`'';
}
{
assertion = (cfg.user == null && cfg.group == null) || (cfg.user != null);
message = "`services.github-runners.${name}`: Either set `user` and `group` to `null` to have nix-darwin manage them or set at least `user` explicitly";
@ -51,15 +60,17 @@ in
(
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)}
${getExe' pkgs.coreutils "mkdir"} -p ${escapeShellArg (mkStateDir cfg)}
${getExe' pkgs.coreutils "chown"} ${user}:${group} ${escapeShellArg (mkStateDir cfg)}
${pkgs.coreutils}/bin/mkdir -p ${escapeShellArg (mkLogDir cfg)}
${pkgs.coreutils}/bin/chown ${user}:${group} ${escapeShellArg (mkLogDir cfg)}
${getExe' pkgs.coreutils "mkdir"} -p ${escapeShellArg (mkLogDir cfg)}
# launchd will fail to start the service if the outer direction doesn't have sufficient permissions
${getExe' pkgs.coreutils "chmod"} o+rx ${escapeShellArg (mkLogDir { name = ""; })}
${getExe' pkgs.coreutils "chown"} ${user}:${group} ${escapeShellArg (mkLogDir cfg)}
${optionalString (cfg.workDir == null) ''
${pkgs.coreutils}/bin/mkdir -p ${escapeShellArg (mkWorkDir cfg)}
${pkgs.coreutils}/bin/chown ${user}:${group} ${escapeShellArg (mkWorkDir cfg)}
${getExe' pkgs.coreutils "mkdir"} -p ${escapeShellArg (mkWorkDir cfg)}
${getExe' pkgs.coreutils "chown"} ${user}:${group} ${escapeShellArg (mkWorkDir cfg)}
''}
)
'');
@ -123,7 +134,7 @@ in
else
args+=(--token "$token")
fi
${package}/bin/config.sh "''${args[@]}"
${getExe' package "config.sh"} "''${args[@]}"
'';
};
in
@ -131,12 +142,12 @@ in
echo "Configuring GitHub Actions Runner"
# Always clean the working directory
${pkgs.findutils}/bin/find ${escapeShellArg workDir} -mindepth 1 -delete
${getExe pkgs.findutils} ${escapeShellArg workDir} -mindepth 1 -delete
# Clean the $RUNNER_ROOT if we are in ephemeral mode
if ${boolToString cfg.ephemeral}; then
echo "Cleaning $RUNNER_ROOT"
${pkgs.findutils}/bin/find "$RUNNER_ROOT" -mindepth 1 -delete
${getExe pkgs.findutils} "$RUNNER_ROOT" -mindepth 1 -delete
fi
# If the `.runner` file does not exist, we assume the runner is not configured
@ -145,7 +156,7 @@ in
fi
# Start the service
${package}/bin/Runner.Listener run --startuptype service
${getExe' package "Runner.Listener"} run --startuptype service
'';
serviceConfig = mkMerge [

View file

@ -551,8 +551,9 @@ in
launchd.daemons.gitlab-runner = {
environment = { #config.networking.proxy.envVars // {
HOME = "${config.users.users.gitlab-runner.home}";
NIX_REMOTE = "daemon";
NIX_SSL_CERT_FILE = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt";
} // (if config.nix.useDaemon then { NIX_REMOTE = "daemon"; } else {});
};
path = with pkgs; [
bash
gawk

View file

@ -22,6 +22,14 @@ in
};
config = mkIf cfg.enable {
# TODO: Upstream this to NixOS.
assertions = [
{
assertion = config.nix.enable;
message = ''`services.hercules-ci-agent.enable` requires `nix.enable`'';
}
];
launchd.daemons.hercules-ci-agent = {
script = "exec ${cfg.package}/bin/hercules-ci-agent --config ${cfg.tomlFile}";
@ -74,7 +82,7 @@ in
darwin.label = config.system.darwinLabel;
darwin.revision = config.system.darwinRevision;
darwin.version = config.system.darwinVersion;
darwin.nix.daemon = config.nix.useDaemon;
darwin.nix.daemon = true;
darwin.nix.sandbox = config.nix.settings.sandbox;
};
};

View file

@ -29,6 +29,14 @@ in
};
config = mkIf cfg.enable {
# TODO: Upstream this to NixOS.
assertions = [
{
assertion = config.nix.enable;
message = ''`services.lorri.enable` requires `nix.enable`'';
}
];
environment.systemPackages = [ pkgs.lorri ];
launchd.user.agents.lorri = {
command = with pkgs; "${lorri}/bin/lorri daemon";
@ -43,4 +51,4 @@ in
};
};
};
}
}

View file

@ -3,17 +3,18 @@
let
cfg = config.services.nix-daemon;
inherit (lib) mkDefault mkIf mkMerge mkOption types;
inherit (lib) mkRemovedOptionModule mkDefault mkIf mkMerge mkOption types;
in
{
options = {
services.nix-daemon.enable = mkOption {
type = types.bool;
default = true;
description = "Whether to enable the nix-daemon service.";
};
imports = [
(mkRemovedOptionModule [ "services" "nix-daemon" "enable" ] ''
nix-darwin now manages nix-daemon unconditionally when
`nix.enable` is on.
'')
];
options = {
services.nix-daemon.enableSocketListener = mkOption {
type = types.bool;
default = false;
@ -39,9 +40,7 @@ in
};
};
config = mkIf cfg.enable {
nix.useDaemon = true;
config = mkIf config.nix.enable {
launchd.daemons.nix-daemon = {
command = lib.getExe' config.nix.package "nix-daemon";

View file

@ -14,6 +14,7 @@ in
(mkRemovedOptionModule [ "nix" "gc" "dates" ] "Use `nix.gc.interval` instead.")
(mkRemovedOptionModule [ "nix" "gc" "randomizedDelaySec" ] "No `nix-darwin` equivalent to this NixOS option.")
(mkRemovedOptionModule [ "nix" "gc" "persistent" ] "No `nix-darwin` equivalent to this NixOS option.")
(mkRemovedOptionModule [ "nix" "gc" "user" ] "The garbage collection service now always runs as `root`.")
];
###### interface
@ -28,13 +29,6 @@ in
description = "Automatically run the garbage collector at a specific time.";
};
# Not in NixOS module
user = mkOption {
type = types.nullOr types.str;
default = null;
description = "User that runs the garbage collector.";
};
interval = mkOption {
type = launchdTypes.StartCalendarInterval;
default = [{ Weekday = 7; Hour = 3; Minute = 15; }];
@ -62,15 +56,18 @@ in
###### implementation
config = mkIf cfg.automatic {
config = {
assertions = [
{
assertion = cfg.automatic -> config.nix.enable;
message = ''nix.gc.automatic requires nix.enable'';
}
];
launchd.daemons.nix-gc = {
launchd.daemons.nix-gc = mkIf cfg.automatic {
command = "${config.nix.package}/bin/nix-collect-garbage ${cfg.options}";
environment.NIX_REMOTE = optionalString config.nix.useDaemon "daemon";
serviceConfig.RunAtLoad = false;
serviceConfig.StartCalendarInterval = cfg.interval;
serviceConfig.UserName = cfg.user;
};
};
}

View file

@ -20,6 +20,7 @@ in
{
imports = [
(mkRemovedOptionModule [ "nix" "optimise" "dates" ] "Use `nix.optimise.interval` instead.")
(mkRemovedOptionModule [ "nix" "optimise" "user" ] "The store optimisation service now always runs as `root`.")
];
###### interface
@ -34,13 +35,6 @@ in
description = "Automatically run the nix store optimiser at a specific time.";
};
# Not in NixOS module
user = mkOption {
type = types.nullOr types.str;
default = null;
description = "User that runs the store optimisation.";
};
interval = mkOption {
type = launchdTypes.StartCalendarInterval;
default = [{ Weekday = 7; Hour = 4; Minute = 15; }];
@ -58,17 +52,20 @@ in
###### implementation
config = mkIf cfg.automatic {
config = {
assertions = [
{
assertion = cfg.automatic -> config.nix.enable;
message = ''nix.optimise.automatic requires nix.enable'';
}
];
launchd.daemons.nix-optimise = {
environment.NIX_REMOTE = optionalString config.nix.useDaemon "daemon";
launchd.daemons.nix-optimise = mkIf cfg.automatic {
command = "${lib.getExe' config.nix.package "nix-store"} --optimise";
serviceConfig = {
RunAtLoad = false;
StartCalendarInterval = cfg.interval;
UserName = cfg.user;
};
};
};
}

View file

@ -46,6 +46,13 @@ in
};
config = mkIf cfg.enable {
assertions = [
{
assertion = config.nix.enable;
message = ''`services.ofborg.enable` requires `nix.enable`'';
}
];
warnings = mkIf (isDerivation cfg.configFile) [
"services.ofborg.configFile is a derivation, credentials will be world readable"
];

View file

@ -0,0 +1,33 @@
{ config, lib, ... }:
let
cfg = config.services.openssh;
in
{
options = {
services.openssh.enable = lib.mkOption {
type = lib.types.nullOr lib.types.bool;
default = null;
description = ''
Whether to enable Apple's built-in OpenSSH server.
The default is null which means let macOS manage the OpenSSH server.
'';
};
};
config = {
# We don't use `systemsetup -setremotelogin` as it requires Full Disk Access
system.activationScripts.launchd.text = lib.mkIf (cfg.enable != null) (if cfg.enable then ''
if [[ "$(systemsetup -getremotelogin | sed 's/Remote Login: //')" == "Off" ]]; then
launchctl enable system/com.openssh.sshd
launchctl bootstrap system /System/Library/LaunchDaemons/ssh.plist
fi
'' else ''
if [[ "$(systemsetup -getremotelogin | sed 's/Remote Login: //')" == "On" ]]; then
launchctl bootout system/com.openssh.sshd
launchctl disable system/com.openssh.sshd
fi
'');
};
}

View file

@ -13,6 +13,32 @@ let
mkTextDerivation = name: text: pkgs.writeScript "activate-${name}" text;
};
activationPath =
lib.makeBinPath [
pkgs.gnugrep
pkgs.coreutils
]
+ lib.optionalString (!config.nix.enable) ''
$(
# If `nix.enable` is off, there might be an unmanaged Nix
# installation (say in `/nix/var/nix/profiles/default`) that
# activation scripts (such as Home Manager) want to find on the
# `$PATH`. Search for it directly to avoid polluting the
# activation script environment with everything on the
# `environment.systemPath`.
if nixEnvPath=$(
PATH="${config.environment.systemPath}" command -v nix-env
); then
printf ':'
${lib.getExe' pkgs.coreutils "dirname"} -- "$(
${lib.getExe' pkgs.coreutils "readlink"} \
--canonicalize-missing \
-- "$nixEnvPath"
)"
fi
)''
+ ":@out@/sw/bin:/usr/bin:/bin:/usr/sbin:/sbin";
in
{
@ -40,13 +66,12 @@ in
#! ${stdenv.shell}
set -e
set -o pipefail
export PATH="${pkgs.gnugrep}/bin:${pkgs.coreutils}/bin:@out@/sw/bin:/usr/bin:/bin:/usr/sbin:/sbin"
PATH="${activationPath}"
export PATH
systemConfig=@out@
_status=0
trap "_status=1" ERR
# Ensure a consistent umask.
umask 0022
@ -81,9 +106,9 @@ in
ln -sfn "$(readlink -f "$systemConfig")" /run/current-system
# Prevent the current configuration from being garbage-collected.
ln -sfn /run/current-system /nix/var/nix/gcroots/current-system
exit $_status
if [[ -d /nix/var/nix/gcroots ]]; then
ln -sfn /run/current-system /nix/var/nix/gcroots/current-system
fi
'';
# FIXME: activationScripts.checks should be system level
@ -91,7 +116,9 @@ in
#! ${stdenv.shell}
set -e
set -o pipefail
export PATH="${pkgs.gnugrep}/bin:${pkgs.coreutils}/bin:@out@/sw/bin:/usr/bin:/bin"
PATH="${activationPath}"
export PATH
systemConfig=@out@

View file

@ -2,50 +2,35 @@
{
system.activationScripts.createRun.text = ''
IFS="." read -r -a macOSVersion <<< "$(sw_vers -productVersion)"
if [[ $(stat -c '%a' /etc/synthetic.conf) != "644" ]]; then
echo "fixing permissions on /etc/synthetic.conf..."
sudo chmod 644 /etc/synthetic.conf
fi
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
echo "setting up /run via /etc/synthetic.conf..."
printf 'run\tprivate/var/run\n' | sudo tee -a /etc/synthetic.conf >/dev/null
fi
if [[ $(grep -c '^run\b' /etc/synthetic.conf) -gt 1 ]]; then
echo "found duplicate run entries in /etc/synthetic.conf, removing..."
sudo sed -i "" -e '/^run\tprivate\/var\/run$/d' /etc/synthetic.conf
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
if ! grep -q '^run\b' /etc/synthetic.conf 2>/dev/null; then
echo "setting up /run via /etc/synthetic.conf..."
printf 'run\tprivate/var/run\n' | sudo tee -a /etc/synthetic.conf >/dev/null
fi
if [[ ! -L /run ]]; then
printf >&2 'error: apfs.util failed to symlink /run, aborting activation\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"
sudo /System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -t || true
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..."
sudo ln -sfn private/var/run /run
if [[ ! -L /run ]]; then
printf >&2 'error: failed to symlink /run, aborting activation\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
if [[ ! -L /run ]]; then
printf >&2 'error: apfs.util failed to symlink /run, aborting activation\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\n"
printf >&2 '$ sudo /System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -t\n'
printf >&2 '\n'
printf >&2 'The current contents of /etc/synthetic.conf is:\n'
printf >&2 '\n'
sed 's/^/ /' /etc/synthetic.conf >&2
printf >&2 '\n'
exit 1
fi
'';
}

View file

@ -8,53 +8,54 @@ let
cfg = config.system.checks;
darwinChanges = ''
darwinChanges=/dev/null
if test -e /run/current-system/darwin-changes; then
darwinChanges=/run/current-system/darwin-changes
fi
darwinChanges=$(diff --changed-group-format='%>' --unchanged-group-format= /run/current-system/darwin-changes $systemConfig/darwin-changes 2> /dev/null) || true
if test -n "$darwinChanges"; then
echo >&2
echo "CHANGELOG" >&2
echo >&2
echo "$darwinChanges" >&2
echo >&2
macOSVersion = ''
IFS=. read -ra osVersion <<<"$(sw_vers -productVersion)"
if (( osVersion[0] < 11 || (osVersion[0] == 11 && osVersion[1] < 3) )); then
printf >&2 '\e[1;31merror: macOS version is less than 11.3, aborting activation\e[0m\n'
printf >&2 'Nixpkgs 25.05 requires macOS Big Sur 11.3 or newer, and 25.11 will\n'
printf >&2 'require macOS Sonoma 14.\n'
printf >&2 '\n'
printf >&2 'For more information on your options going forward, see the 25.05\n'
printf >&2 'release notes:\n'
printf >&2 '<https://nixos.org/manual/nixos/unstable/release-notes#sec-release-25.05>\n'
printf >&2 '\n'
printf >&2 'Nixpkgs 24.11 and nix-darwin 24.11 continue to support down to macOS\n'
printf >&2 'Sierra 10.12, and will be supported through June 2025.\n'
printf >&2 '\n'
printf >&2 'You can override this check by setting:\n'
printf >&2 '\n'
printf >&2 ' system.checks.verifyMacOSVersion = false;\n'
printf >&2 '\n'
printf >&2 'However, we are unable to provide support if you do so.\n'
exit 2
fi
'';
runLink = ''
if [[ ! -e /run ]]; then
printf >&2 'error: directory /run does not exist, aborting activation\n'
exit 1
determinate = ''
if [[ -e /usr/local/bin/determinate-nixd ]]; then
printf >&2 '\e[1;31merror: Determinate detected, aborting activation\e[0m\n'
printf >&2 'Determinate uses its own daemon to manage the Nix installation that\n'
printf >&2 'conflicts with nix-darwins native Nix management.\n'
printf >&2 '\n'
printf >&2 'To turn off nix-darwins management of the Nix installation, set:\n'
printf >&2 '\n'
printf >&2 ' nix.enable = false;\n'
printf >&2 '\n'
printf >&2 'This will allow you to use nix-darwin with Determinate. Some nix-darwin\n'
printf >&2 'functionality that relies on managing the Nix installation, like the\n'
printf >&2 '`nix.*` options to adjust Nix settings or configure a Linux builder,\n'
printf >&2 'will be unavailable.\n'
exit 2
fi
'';
oldBuildUsers = ''
if dscl . -list /Users | grep -q '^nixbld'; then
echo "error: Detected old style nixbld users, aborting activation" >&2
echo "These can cause migration problems when upgrading to certain macOS versions" >&2
echo "You can enable the following option to migrate to new style nixbld users" >&2
echo >&2
echo " nix.configureBuildUsers = true;" >&2
echo >&2
echo "or disable this check with" >&2
echo >&2
echo " system.checks.verifyBuildUsers = false;" >&2
echo >&2
exit 2
fi
'';
preSequoiaBuildUsers = ''
${lib.optionalString config.nix.configureBuildUsers ''
# Dont complain when were about to migrate oldstyle build users…
if ! dscl . -list /Users | grep -q '^nixbld'; then
''}
firstBuildUserID=$(dscl . -read /Users/_nixbld1 UniqueID | awk '{print $2}')
if [[ $firstBuildUserID != ${toString (config.ids.uids.nixbld + 1)} ]]; then
if
# Dont complain when were about to migrate oldstyle build users…
[[ $firstBuildUserID != ${toString (config.ids.uids.nixbld + 1)} ]] \
&& ! dscl . -list /Users | grep -q '^nixbld'
then
printf >&2 '\e[1;31merror: Build users have unexpected UIDs, aborting activation\e[0m\n'
printf >&2 'The default Nix build user ID range has been adjusted for\n'
printf >&2 'compatibility with macOS Sequoia 15. Your _nixbld1 user currently has\n'
@ -87,22 +88,6 @@ let
printf >&2 '\n'
exit 2
fi
${lib.optionalString config.nix.configureBuildUsers "fi"}
'';
buildUsers = ''
buildUser=$(dscl . -read /Groups/nixbld GroupMembership 2>&1 | awk '/^GroupMembership: / {print $2}') || true
if [[ -z "$buildUser" ]]; then
echo "error: Using the nix-daemon requires build users, aborting activation" >&2
echo "Create the build users or disable the daemon:" >&2
echo "$ darwin-install" >&2
echo >&2
echo "or set (this requires some manual intervention to restore permissions)" >&2
echo >&2
echo " services.nix-daemon.enable = false;" >&2
echo >&2
exit 2
fi
'';
buildGroupID = ''
@ -118,7 +103,6 @@ let
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 'installation with an existing Nix installation, or manually increasing\n'
# shellcheck disable=SC2016
printf >&2 'your `system.stateVersion` setting.\n'
printf >&2 '\n'
printf >&2 'You can set the configured group ID to match the actual value:\n'
@ -132,46 +116,21 @@ let
fi
'';
nixDaemon = if config.nix.useDaemon then ''
if ! dscl . -read /Groups/nixbld PrimaryGroupID &> /dev/null; then
printf >&2 'error: The daemon should not be enabled for single-user installs, aborting activation\n'
printf >&2 'Disable the nix-daemon service:\n'
nixDaemon = ''
if [[ "$(stat --format='%u' /nix)" != 0 ]]; then
printf >&2 'error: singleuser install detected, aborting activation\n'
printf >&2 'nix-darwin now only supports managing multiuser daemon installations\n'
printf >&2 'of Nix. You can uninstall nix-darwin and Nix and then reinstall both to\n'
printf >&2 'fix this.\n'
printf >&2 '\n'
printf >&2 ' services.nix-daemon.enable = false;\n'
printf >&2 'If you dont want to do that, you can disable management of the Nix\n'
printf >&2 'installation with:\n'
printf >&2 '\n'
# shellcheck disable=SC2016
printf >&2 'and remove `nix.useDaemon` from your configuration if it is present.\n'
printf >&2 ' nix.enable = false;\n'
printf >&2 '\n'
printf >&2 'See the `nix.enable` option documentation for caveats.\n'
exit 2
fi
'' else ''
if dscl . -read /Groups/nixbld PrimaryGroupID &> /dev/null; then
printf >&2 'error: The daemon should be enabled for multi-user installs, aborting activation\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
fi
'';
nixChannels = ''
channelsLink=$(readlink "$HOME/.nix-defexpr/channels") || true
case "$channelsLink" in
*"$USER"*)
;;
"")
;;
*)
echo "error: The ~/.nix-defexpr/channels symlink does not point your users channels, aborting activation" >&2
echo "Running nix-channel will regenerate it" >&2
echo >&2
echo " rm ~/.nix-defexpr/channels" >&2
echo " nix-channel --update" >&2
echo >&2
exit 2
;;
esac
'';
nixInstaller = ''
@ -196,7 +155,7 @@ let
darwinConfig=$(NIX_PATH=$nixPath nix-instantiate --find-file darwin-config) || true
if ! test -e "$darwinConfig"; then
echo "error: Changed <darwin-config> but target does not exist, aborting activation" >&2
echo "Create ''${darwinConfig:-~/.nixpkgs/darwin-configuration.nix} or set environment.darwinConfig:" >&2
echo "Create ''${darwinConfig:-/etc/nix-darwin/configuration.nix} or set environment.darwinConfig:" >&2
echo >&2
echo " environment.darwinConfig = \"$(nix-instantiate --find-file darwin-config 2> /dev/null || echo '***')\";" >&2
echo >&2
@ -211,8 +170,8 @@ let
if ! test -e "$darwinPath"; then
echo "error: Changed <darwin> but target does not exist, aborting activation" >&2
echo "Add the darwin repo as a channel or set nix.nixPath:" >&2
echo "$ nix-channel --add https://github.com/LnL7/nix-darwin/archive/master.tar.gz darwin" >&2
echo "$ nix-channel --update" >&2
echo "$ sudo nix-channel --add https://github.com/LnL7/nix-darwin/archive/master.tar.gz darwin" >&2
echo "$ sudo nix-channel --update" >&2
echo >&2
echo "or set" >&2
echo >&2
@ -225,8 +184,8 @@ let
if ! test -e "$nixpkgsPath"; then
echo "error: Changed <nixpkgs> but target does not exist, aborting activation" >&2
echo "Add a nixpkgs channel or set nix.nixPath:" >&2
echo "$ nix-channel --add http://nixos.org/channels/nixpkgs-unstable nixpkgs" >&2
echo "$ nix-channel --update" >&2
echo "$ sudo nix-channel --add http://nixos.org/channels/nixpkgs-unstable nixpkgs" >&2
echo "$ sudo nix-channel --update" >&2
echo >&2
echo "or set" >&2
echo >&2
@ -236,50 +195,12 @@ let
fi
'';
nixStore = ''
if test -w /nix/var/nix/db -a ! -O /nix/store; then
echo >&2 "error: the store is not owned by this user, but /nix/var/nix/db is writable"
echo >&2 "If you are using the daemon:"
echo >&2
echo >&2 " sudo chown -R root:wheel /nix/var/nix/db"
echo >&2
echo >&2 "Otherwise:"
echo >&2
echo >&2 " sudo chown -R $USER:staff /nix/store"
echo >&2
exit 2
fi
'';
nixGarbageCollector = ''
if test -O /nix/store; then
echo "error: A single-user install can't run gc as root, aborting activation" >&2
echo "Configure the garbage collector to run as the current user:" >&2
echo >&2
echo " nix.gc.user = \"$USER\";" >&2
echo >&2
exit 2
fi
'';
nixStoreOptimiser = ''
if test -O /nix/store; then
echo "error: A single-user install can't run optimiser as root, aborting activation" >&2
echo "Configure the optimiser to run as the current user:" >&2
echo >&2
echo " nix.optimise.user = \"$USER\";" >&2
echo >&2
exit 2
fi
'';
# TODO: Remove this a couple years down the line when we can assume
# that anyone who cares about security has upgraded.
oldSshAuthorizedKeysDirectory = ''
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 '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 'authorized keys files when the setting for a given user was removed.\n'
printf >&2 '\n'
@ -302,36 +223,47 @@ let
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
'';
# some mac devices, notably notebook do not support restartAfterPowerFailure option
restartAfterPowerFailureIsSupported = ''
if sudo /usr/sbin/systemsetup -getRestartPowerFailure | grep -q "Not supported"; then
printf >&2 "\e[1;31merror: restarting after power failure is not supported on your machine\e[0m\n" >&2
printf >&2 "Please ensure that \`power.restartAfterPowerFailure\` is not set.\n" >&2
exit 2
fi
'';
in
{
imports = [
(mkRemovedOptionModule [ "system" "checks" "verifyNixChannels" ] "This check has been removed.")
];
options = {
system.checks.verifyNixPath = mkOption {
type = types.bool;
default = true;
default = config.nix.enable;
description = "Whether to run the NIX_PATH validation checks.";
};
system.checks.verifyNixChannels = mkOption {
type = types.bool;
default = config.nix.channel.enable;
description = "Whether to run the nix-channels validation checks.";
};
system.checks.verifyBuildUsers = mkOption {
type = types.bool;
default =
(config.nix.useDaemon && !(config.nix.settings.auto-allocate-uids or false))
|| config.nix.configureBuildUsers;
config.nix.enable && !(config.nix.settings.auto-allocate-uids or false);
description = "Whether to run the Nix build users validation checks.";
};
system.checks.verifyMacOSVersion = mkOption {
type = types.bool;
default = true;
description = "Whether to run the macOS version check.";
};
system.checks.text = mkOption {
internal = true;
type = types.lines;
@ -342,21 +274,16 @@ in
config = {
system.checks.text = mkMerge [
darwinChanges
runLink
(mkIf (cfg.verifyBuildUsers && !config.nix.configureBuildUsers) oldBuildUsers)
(mkIf cfg.verifyBuildUsers buildUsers)
(mkIf cfg.verifyMacOSVersion macOSVersion)
(mkIf config.nix.enable determinate)
(mkIf cfg.verifyBuildUsers preSequoiaBuildUsers)
(mkIf config.nix.configureBuildUsers buildGroupID)
nixDaemon
nixStore
(mkIf (config.nix.gc.automatic && config.nix.gc.user == null) nixGarbageCollector)
(mkIf (config.nix.optimise.automatic && config.nix.optimise.user == null) nixStoreOptimiser)
(mkIf cfg.verifyNixChannels nixChannels)
(mkIf cfg.verifyBuildUsers buildGroupID)
(mkIf config.nix.enable nixDaemon)
nixInstaller
(mkIf cfg.verifyNixPath nixPath)
oldSshAuthorizedKeysDirectory
(mkIf config.homebrew.enable homebrewInstalled)
(mkIf (config.power.restartAfterPowerFailure != null) restartAfterPowerFailureIsSupported)
];
system.activationScripts.checks.text = ''

View file

@ -135,7 +135,10 @@ in
chmod u+x $out/activate-user
unset activationUserScript
shellcheck $out/activate $out/activate-user
# We exclude the warnings for `…` in singlequote strings and
# nonASCII quotation marks as they are noisy and lead to a lot
# of false positives in our userfacing output:
shellcheck --exclude=SC2016,SC1112 $out/activate $out/activate-user
echo -n "$systemConfig" > $out/systemConfig

View file

@ -9,6 +9,9 @@ let
"defaults write ${domain} '${key}' $'${strings.escape [ "'" ] (generators.toPlist { } value)}'";
defaultsToList = domain: attrs: mapAttrsToList (writeDefault domain) (filterAttrs (n: v: v != null) attrs);
# Filter out options to not pass through
# dock has alias options that we need to ignore
dockFiltered = (builtins.removeAttrs cfg.dock ["expose-group-by-app"]);
# defaults
alf = defaultsToList "/Library/Preferences/com.apple.alf" cfg.alf;
@ -21,7 +24,7 @@ let
LaunchServices = defaultsToList "com.apple.LaunchServices" cfg.LaunchServices;
NSGlobalDomain = defaultsToList "-g" cfg.NSGlobalDomain;
menuExtraClock = defaultsToList "com.apple.menuextra.clock" cfg.menuExtraClock;
dock = defaultsToList "com.apple.dock" cfg.dock;
dock = defaultsToList "com.apple.dock" dockFiltered;
finder = defaultsToList "com.apple.finder" cfg.finder;
hitoolbox = defaultsToList "com.apple.HIToolbox" cfg.hitoolbox;
magicmouse = defaultsToList "com.apple.AppleMultitouchMouse" cfg.magicmouse;
@ -39,7 +42,7 @@ let
CustomSystemPreferences = flatten (mapAttrsToList (name: value: defaultsToList name value) cfg.CustomSystemPreferences);
mkIfAttrs = list: mkIf (any (attrs: attrs != { }) list);
mkIfLists = list: mkIf (any (attrs: attrs != [ ]) list);
in
{
@ -54,7 +57,7 @@ in
else types.float.check x;
};
system.activationScripts.defaults.text = mkIfAttrs [
system.activationScripts.defaults.text = mkIfLists [
alf
loginwindow
smb
@ -71,7 +74,7 @@ in
${concatStringsSep "\n" CustomSystemPreferences}
'';
system.activationScripts.userDefaults.text = mkIfAttrs
system.activationScripts.userDefaults.text = mkIfLists
[
GlobalPreferences
LaunchServices

View file

@ -57,6 +57,38 @@ with lib;
'';
};
system.defaults.WindowManager.EnableTilingByEdgeDrag = mkOption {
type = types.nullOr types.bool;
default = null;
description = ''
Enable dragging windows to screen edges to tile them. The default is true.
'';
};
system.defaults.WindowManager.EnableTopTilingByEdgeDrag = mkOption {
type = types.nullOr types.bool;
default = null;
description = ''
Enable dragging windows to the menu bar to fill the screen. The default is true.
'';
};
system.defaults.WindowManager.EnableTilingOptionAccelerator = mkOption {
type = types.nullOr types.bool;
default = null;
description = ''
Enable holding alt to tile windows. The default is true.
'';
};
system.defaults.WindowManager.EnableTiledWindowMargins = mkOption {
type = types.nullOr types.bool;
default = null;
description = ''
Enable window margins when tiling windows. The default is true.
'';
};
system.defaults.WindowManager.StandardHideWidgets = mkOption {
type = types.nullOr types.bool;
default = null;

View file

@ -6,6 +6,10 @@ let
# Should only be used with options that previously used floats defined as strings.
inherit (config.lib.defaults.types) floatWithDeprecationError;
in {
imports = [
(mkRenamedOptionModule [ "system" "defaults" "dock" "expose-group-by-app" ] [ "system" "defaults" "dock" "expose-group-apps" ])
];
options = {
system.defaults.dock.appswitcher-all-displays = mkOption {
@ -67,11 +71,11 @@ in {
'';
};
system.defaults.dock.expose-group-by-app = mkOption {
system.defaults.dock.expose-group-apps = mkOption {
type = types.nullOr types.bool;
default = null;
description = ''
Whether to group windows by application in Mission Control's Exposé. The default is true.
Whether to group windows by application in Mission Control's Exposé. The default is false.
'';
};
@ -124,16 +128,72 @@ in {
};
system.defaults.dock.persistent-apps = mkOption {
type = types.nullOr (types.listOf (types.either types.path types.str));
type = let
taggedType = types.attrTag {
app = mkOption {
description = "An application to be added to the dock.";
type = types.str;
};
file = mkOption {
description = "A file to be added to the dock.";
type = types.str;
};
folder = mkOption {
description = "A folder to be added to the dock.";
type = types.str;
};
spacer = mkOption {
description = "A spacer to be added to the dock. Can be small or regular size.";
type = types.submodule {
options.small = mkOption {
description = "Whether the spacer is small.";
type = types.bool;
default = false;
};
};
};
};
simpleType = types.either types.str types.path;
toTagged = path: { app = path; };
in
types.nullOr (types.listOf (types.coercedTo simpleType toTagged taggedType));
default = null;
example = [ "/Applications/Safari.app" "/System/Applications/Utilities/Terminal.app" ];
example = [
{ app = "/Applications/Safari.app"; }
{ spacer = { small = false; }; }
{ spacer = { small = true; }; }
{ folder = "/System/Applications/Utilities"; }
{ file = "/User/example/Downloads/test.csv"; }
];
description = ''
Persistent applications in the dock.
Persistent applications, spacers, files, and folders in the dock.
'';
apply = value:
if !(isList value)
then value
else map (app: { tile-data = { file-data = { _CFURLString = app; _CFURLStringType = 0; }; }; }) value;
apply =
let
toTile = item: if item ? app then {
tile-data.file-data = {
_CFURLString = item.app;
_CFURLStringType = 0;
};
} else if item ? spacer then {
tile-data = { };
tile-type = if item.spacer.small then "small-spacer-tile" else "spacer-tile";
} else if item ? folder then {
tile-data.file-data = {
_CFURLString = "file://" + item.folder;
_CFURLStringType = 15;
};
tile-type = "directory-tile";
} else if item ? file then {
tile-data.file-data = {
_CFURLString = "file://" + item.file;
_CFURLStringType = 15;
};
tile-type = "file-tile";
} else item;
in
value: if value == null then null else map toTile value;
};
system.defaults.dock.persistent-others = mkOption {
@ -230,7 +290,6 @@ in {
Magnified icon size on hover. The default is 16.
'';
};
system.defaults.dock.wvous-tl-corner = mkOption {
type = types.nullOr types.ints.positive;

View file

@ -48,5 +48,20 @@ with lib;
Show thumbnail after screencapture before writing to file. The default is true.
'';
};
system.defaults.screencapture.target = mkOption {
type = types.nullOr (types.enum [ "file" "clipboard" "preview" "mail" "messages" ]);
default = null;
description = ''
Target to which screencapture should save screenshot to. The default is "file".
Valid values include:
* `file`: Saves as a file in location specified by `system.defaults.screencapture.location`
* `clipboard`: Saves screenshot to clipboard
* `preview`: Opens screenshot in Preview app
* `mail`
* `messages`
'';
};
};
}

View file

@ -28,7 +28,6 @@ with lib;
default = null;
description = ''
Disable transparency in the menu bar and elsewhere.
Requires macOS Yosemite or later.
The default is false.
'';
};

View file

@ -51,7 +51,7 @@ in
system.maxStateVersion = mkOption {
internal = true;
type = types.int;
default = 5;
default = 6;
};
system.darwinLabel = mkOption {
@ -59,11 +59,18 @@ in
description = "Label to be used in the names of generated outputs.";
};
system.darwinRelease = mkOption {
readOnly = true;
type = types.str;
default = (lib.importJSON ../../version.json).release;
description = "The nix-darwin release (e.g. `24.11`).";
};
system.darwinVersion = mkOption {
internal = true;
type = types.str;
default = "darwin${toString cfg.stateVersion}${cfg.darwinVersionSuffix}";
description = "The full darwin version (e.g. `darwin4.2abdb5a`).";
default = cfg.darwinRelease + cfg.darwinVersionSuffix;
description = "The full nix-darwin version (e.g. `24.11.2abdb5a`).";
};
system.darwinVersionSuffix = mkOption {
@ -72,7 +79,7 @@ in
default = if cfg.darwinRevision != null
then ".${substring 0 7 cfg.darwinRevision}"
else "";
description = "The short darwin version suffix (e.g. `.2abdb5a`).";
description = "The short nix-darwin version suffix (e.g. `.2abdb5a`).";
};
system.darwinRevision = mkOption {
@ -86,14 +93,15 @@ in
readOnly = true;
type = types.str;
default = lib.trivial.release;
description = "The nixpkgs release (e.g. `16.03`).";
description = "The nixpkgs release (e.g. `24.11`).";
};
# TODO: Shouldnt mismatch the Darwin release, rethink all this…
system.nixpkgsVersion = mkOption {
internal = true;
type = types.str;
default = cfg.nixpkgsRelease + cfg.nixpkgsVersionSuffix;
description = "The full nixpkgs version (e.g. `16.03.1160.f2d4ee1`).";
description = "The full nixpkgs version (e.g. `24.11.1160.f2d4ee1`).";
};
system.nixpkgsVersionSuffix = mkOption {
@ -124,7 +132,7 @@ in
config = {
# This default is set here rather than up there so that the options
# documentation is not reprocessed on every commit
system.darwinLabel = mkDefault "${cfg.nixpkgsVersion}+${cfg.darwinVersion}";
system.darwinLabel = mkDefault cfg.darwinVersion;
assertions = [
{

View file

@ -147,9 +147,8 @@ in
homeDirectory=''${homeDirectory#NFSHomeDirectory: }
if ! sudo dscl . -change /Users/nobody NFSHomeDirectory "$homeDirectory" "$homeDirectory" &> /dev/null; then
if [[ -n "$SSH_CONNECTION" ]]; then
if [[ "$(launchctl managername)" != Aqua ]]; 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'
@ -157,7 +156,6 @@ in
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'
@ -171,12 +169,10 @@ in
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 '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'
@ -224,7 +220,6 @@ in
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

View file

@ -12,16 +12,16 @@ with lib;
launchd.daemons = mkForce {};
launchd.user.agents = mkForce {};
# Don't try to reload `nix-daemon`
nix.useDaemon = mkForce false;
# Restore any unmanaged `nix-daemon`.
nix.enable = false;
system.activationScripts.postUserActivation.text = mkAfter ''
if [[ -L ~/.nix-defexpr/channels/darwin ]]; then
nix-channel --remove darwin || true
fi
nix-channel --remove darwin || true
'';
system.activationScripts.postActivation.text = mkAfter ''
nix-channel --remove darwin || true
if [[ -L /Applications/Nix\ Apps ]]; then
rm /Applications/Nix\ Apps
fi
@ -30,14 +30,6 @@ with lib;
rm /etc/static
fi
# If the Nix Store is owned by root then we're on a multi-user system
if [[ -O /nix/store ]]; then
if [[ -e /nix/var/nix/profiles/default/Library/LaunchDaemons/org.nixos.nix-daemon.plist ]]; then
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
fi
fi
# grep will return 1 when no lines matched which makes this line fail with `set -eo pipefail`
dscl . -list /Users UserShell | { grep "\s/run/" || true; } | awk '{print $1}' | while read -r user; do
shell=$(dscl . -read /Users/"$user" UserShell)

View file

@ -31,8 +31,11 @@ in writeShellApplication {
echo >&2 " - remove /Applications/Nix Apps symlink"
echo >&2 " - cleanup static /etc files"
echo >&2 " - disable and remove all launchd services managed by nix-darwin"
if [[ $(stat -f '%Su' /nix/store) == "root" ]]; then
echo >&2 " - restore nix-daemon service from nix installer as this is a multi-user install"
if [[
-e /run/current-system/Library/LaunchDaemons/org.nixos.nix-daemon.plist
&& -e /nix/var/nix/profiles/default/Library/LaunchDaemons/org.nixos.nix-daemon.plist
]]; then
echo >&2 " - restore nix-daemon service from the Nix installer"
fi
echo >&2
@ -56,7 +59,6 @@ in writeShellApplication {
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
@ -78,7 +80,7 @@ in writeShellApplication {
echo >&2
echo >&2 "checking darwin channel"
test -e ~/.nix-defexpr/channels/darwin && exit 1
nix-instantiate --find-file darwin && exit 1
echo >&2 "checking /etc"
test -e /etc/static && exit 1
echo >&2 "checking /run/current-system"
@ -88,7 +90,7 @@ in writeShellApplication {
launchctl print system/org.nixos.nix-daemon
pgrep -l nix-daemon
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}')" ]]
[[ "$(shasum -a 256 /Library/LaunchDaemons/org.nixos.nix-daemon.plist | awk '{print $1}')" == "$(shasum -a 256 /nix/var/nix/profiles/default/Library/LaunchDaemons/org.nixos.nix-daemon.plist | awk '{print $1}')" ]]
nix-store --store daemon -q --hash ${stdenv.shell}
fi
echo >&2 ok

View file

@ -1,7 +1,9 @@
#! @shell@
set -e
set -o pipefail
export PATH=@path@:$PATH
export PATH=@path@
export NIX_PATH=${NIX_PATH:-@nixPath@}
evalNix() {
nix-instantiate --eval --strict "${extraEvalFlags[@]}" -E "with import <darwin> {}; $*" 2>/dev/null

View file

@ -1,8 +1,9 @@
#! @shell@
set -e
set -o pipefail
export PATH=@path@:$PATH
export PATH=@path@
export NIX_PATH=${NIX_PATH:-@nixPath@}
showSyntax() {
echo "darwin-rebuild [--help] {edit | switch | activate | build | check | changelog}" >&2
@ -22,15 +23,9 @@ showSyntax() {
}
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
# 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
command sudo -H "$@"
fi
# 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 "$@"
}
# Parse the command line.
@ -177,8 +172,8 @@ if [ "$action" != build ]; then
fi
if [ "$action" = edit ]; then
darwinConfig=$(nix-instantiate --find-file darwin-config)
if [ -z "$flake" ]; then
darwinConfig=$(nix-instantiate "${extraBuildFlags[@]}" --find-file darwin-config)
exec "${EDITOR:-vi}" "$darwinConfig"
else
exec nix "${flakeFlags[@]}" edit "${extraLockFlags[@]}" -- "$flake#$flakeAttr"

View file

@ -5,12 +5,31 @@
, substituteAll
, stdenv
, profile ? "/nix/var/nix/profiles/system"
, nixPackage ? "/nix/var/nix/profiles/default"
, systemPath ? "$HOME/.nix-profile/bin:/etc/profiles/per-user/$USER/bin:/run/current-system/sw/bin:/nix/var/nix/profiles/default/bin:/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin"
, # This should be kept in sync with the default
# `environment.systemPath`. We err on side of including conditional
# things like the profile directories, since theyre more likely to
# help than hurt, and this default is mostly used for fresh
# installations anyway.
systemPath ? lib.concatStringsSep ":" [
"$HOME/.nix-profile/bin"
"/etc/profiles/per-user/$USER/bin"
"/run/current-system/sw/bin"
"/nix/var/nix/profiles/default/bin"
"/usr/local/bin"
"/usr/bin"
"/bin"
"/usr/sbin"
"/sbin"
]
, # This should be kept in sync with the default `nix.nixPath`.
nixPath ? lib.concatStringsSep ":" [
"darwin-config=/etc/nix-darwin/configuration.nix"
"/nix/var/nix/profiles/per-user/root/channels"
]
}:
let
extraPath = lib.makeBinPath [ nixPackage coreutils jq git ];
extraPath = lib.makeBinPath [ coreutils jq git ];
writeProgram = name: env: src:
substituteAll ({
@ -25,14 +44,14 @@ in
{
darwin-option = writeProgram "darwin-option"
{
inherit path;
inherit path nixPath;
inherit (stdenv) shell;
}
./darwin-option.sh;
darwin-rebuild = writeProgram "darwin-rebuild"
{
inherit path profile;
inherit path nixPath profile;
inherit (stdenv) shell;
postInstall = ''
mkdir -p $out/share/zsh/site-functions

View file

@ -80,7 +80,6 @@ in {
tests.activation-scripts = makeTest ./tests/activation-scripts.nix;
tests.autossh = makeTest ./tests/autossh.nix;
tests.checks-nix-gc = makeTest ./tests/checks-nix-gc.nix;
tests.environment-path = makeTest ./tests/environment-path.nix;
tests.environment-terminfo = makeTest ./tests/environment-terminfo.nix;
tests.homebrew = makeTest ./tests/homebrew.nix;
@ -88,6 +87,7 @@ in {
tests.launchd-setenv = makeTest ./tests/launchd-setenv.nix;
tests.networking-hostname = makeTest ./tests/networking-hostname.nix;
tests.networking-networkservices = makeTest ./tests/networking-networkservices.nix;
tests.nix-enable = makeTest ./tests/nix-enable.nix;
tests.nixpkgs-overlays = makeTest ./tests/nixpkgs-overlays.nix;
tests.programs-ssh = makeTest ./tests/programs-ssh.nix;
tests.programs-tmux = makeTest ./tests/programs-tmux.nix;
@ -103,6 +103,7 @@ in {
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-dnscrypt-proxy = makeTest ./tests/services-dnscrypt-proxy.nix;
tests.services-eternal-terminal = makeTest ./tests/services-eternal-terminal.nix;
tests.services-nix-gc = makeTest ./tests/services-nix-gc.nix;
tests.services-nix-optimise = makeTest ./tests/services-nix-optimise.nix;

View file

@ -1,19 +0,0 @@
{ config, pkgs, ... }:
let
nix = pkgs.runCommand "nix-2.2" {} "mkdir -p $out";
in
{
nix.gc.automatic = true;
nix.package = nix;
test = ''
echo checking nix-gc validation >&2
grep "nix.gc.user = " ${config.out}/activate-user
echo checking nix-gc service in /Library/LaunchDaemons >&2
grep "<string>org.nixos.nix-gc</string>" ${config.out}/Library/LaunchDaemons/org.nixos.nix-gc.plist
(! grep "<key>UserName</key>" ${config.out}/Library/LaunchDaemons/org.nixos.nix-gc.plist)
'';
}

View file

@ -30,8 +30,8 @@ with lib;
"afterProfile/bin"
"/usr/local/bin"
"/usr/bin"
"/usr/sbin"
"/bin"
"/usr/sbin"
"/sbin"
"afterPath"
]}"

View file

@ -235,6 +235,11 @@ defaults write com.apple.dock 'autohide-delay' $'<?xml version="1.0" encoding="U
<plist version="1.0">
<real>0.240000</real>
</plist>'
defaults write com.apple.dock 'expose-group-apps' $'<?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.dock 'orientation' $'<?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">
@ -250,7 +255,7 @@ defaults write com.apple.dock 'persistent-apps' $'<?xml version="1.0" encoding="
<key>file-data</key>
<dict>
<key>_CFURLString</key>
<string>MyApp.app</string>
<string>/Applications/MyApp.app</string>
<key>_CFURLStringType</key>
<integer>0</integer>
</dict>
@ -262,12 +267,56 @@ defaults write com.apple.dock 'persistent-apps' $'<?xml version="1.0" encoding="
<key>file-data</key>
<dict>
<key>_CFURLString</key>
<string>Cool.app</string>
<string>/Applications/Cool.app</string>
<key>_CFURLStringType</key>
<integer>0</integer>
</dict>
</dict>
</dict>
<dict>
<key>tile-data</key>
<dict>
</dict>
<key>tile-type</key>
<string>small-spacer-tile</string>
</dict>
<dict>
<key>tile-data</key>
<dict>
</dict>
<key>tile-type</key>
<string>spacer-tile</string>
</dict>
<dict>
<key>tile-data</key>
<dict>
<key>file-data</key>
<dict>
<key>_CFURLString</key>
<string>file:///Applications/Utilities</string>
<key>_CFURLStringType</key>
<integer>15</integer>
</dict>
</dict>
<key>tile-type</key>
<string>directory-tile</string>
</dict>
<dict>
<key>tile-data</key>
<dict>
<key>file-data</key>
<dict>
<key>_CFURLString</key>
<string>file:///Users/example/Downloads/test.csv</string>
<key>_CFURLStringType</key>
<integer>15</integer>
</dict>
</dict>
<key>tile-type</key>
<string>file-tile</string>
</dict>
</array>
</plist>'
defaults write com.apple.dock 'persistent-others' $'<?xml version="1.0" encoding="UTF-8"?>
@ -421,6 +470,11 @@ defaults write com.apple.screencapture 'location' $'<?xml version="1.0" encoding
<plist version="1.0">
<string>/tmp</string>
</plist>'
defaults write com.apple.screencapture 'target' $'<?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</string>
</plist>'
defaults write com.apple.screensaver 'askForPassword' $'<?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">
@ -509,6 +563,26 @@ defaults write com.apple.WindowManager 'EnableStandardClickToShowDesktop' $'<?xm
<plist version="1.0">
<false/>
</plist>'
defaults write com.apple.WindowManager 'EnableTiledWindowMargins' $'<?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.WindowManager 'EnableTilingByEdgeDrag' $'<?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.WindowManager 'EnableTilingOptionAccelerator' $'<?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.WindowManager 'EnableTopTilingByEdgeDrag' $'<?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.WindowManager 'GloballyEnabled' $'<?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">
@ -568,4 +642,4 @@ defaults write ~/Library/Preferences/ByHost/com.apple.controlcenter 'Sound' $'<?
<!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>'
</plist>'

16
tests/nix-enable.nix Normal file
View file

@ -0,0 +1,16 @@
{ config, ... }:
{
nix.enable = false;
test = ''
printf >&2 'checking for unexpected Nix binary in /sw/bin\n'
[[ -e ${config.out}/sw/bin/nix-env ]] && exit 1
printf >&2 'checking for unexpected nix-daemon plist in /Library/LaunchDaemons\n'
[[ -e ${config.out}/Library/LaunchDaemons/org.nixos.nix-daemon.plist ]] && exit 1
printf >&2 'checking for latebound Nix lookup in /activate\n'
grep nixEnvPath= ${config.out}/activate
'';
}

View file

@ -8,6 +8,7 @@ in
services.aerospace.enable = true;
services.aerospace.package = aerospace;
services.aerospace.settings = {
after-startup-command = [ "layout tiles" ];
gaps = {
outer.left = 8;
outer.bottom = 8;
@ -20,6 +21,32 @@ in
alt-k = "focus up";
alt-l = "focus right";
};
on-window-detected = [
{
"if" = {
app-id = "Another.Cool.App";
during-aerospace-startup = false;
};
check-further-callbacks = false;
run = "move-node-to-workspace m";
}
{
"if".app-name-regex-substring = "finder|calendar";
run = "layout floating";
}
{
"if".workspace = "1";
run = "layout h_accordion";
}
];
workspace-to-monitor-force-assignment = {
"1" = 1;
"2" = "main";
"3" = "secondary";
"4" = "built-in";
"5" = "^built-in retina display$";
"6" = [ "secondary" "dell" ];
};
};
test = ''
@ -31,6 +58,35 @@ in
${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
grep 'after-startup-command = \["layout tiles"\]' $conf
grep 'bottom = 8' $conf
grep 'left = 8' $conf
grep 'right = 8' $conf
grep 'top = 8' $conf
grep 'alt-h = "focus left"' $conf
grep 'alt-j = "focus down"' $conf
grep 'alt-k = "focus up"' $conf
grep 'alt-l = "focus right"' $conf
grep 'check-further-callbacks = false' $conf
grep 'run = "move-node-to-workspace m"' $conf
grep 'app-id = "Another.Cool.App"' $conf
grep 'during-aerospace-startup = false' $conf
grep 'run = "layout floating"' $conf
grep 'app-name-regex-substring = "finder|calendar"' $conf
(! grep 'window-title-regex-substring' $conf)
grep 'workspace = "1"' $conf
grep 'run = "layout h_accordion"' $conf
grep '1 = 1' $conf
grep '2 = "main"' $conf
grep '3 = "secondary"' $conf
grep '4 = "built-in"' $conf
grep '5 = "^built-in retina display$"' $conf
grep '6 = \["secondary", "dell"\]' $conf
'';
}

View file

@ -0,0 +1,23 @@
{
config,
pkgs,
...
}:
let
dnscrypt-proxy = pkgs.runCommand "dnscrypt-proxy-0.0.0" { } "mkdir $out";
in
{
services.dnscrypt-proxy.enable = true;
services.dnscrypt-proxy.package = dnscrypt-proxy;
test = ''
echo >&2 "checking dnscrypt-proxy service in /Library/LaunchDaemons"
grep -q "org.nixos.dnscrypt-proxy" -- ${config.out}/Library/LaunchDaemons/org.nixos.dnscrypt-proxy.plist
grep -q "dnscrypt-proxy-start" -- ${config.out}/Library/LaunchDaemons/org.nixos.dnscrypt-proxy.plist
echo >&2 "checking dnscrypt-proxy system user in /Library/LaunchDaemons"
grep -q "_dnscrypt-proxy" -- ${config.out}/Library/LaunchDaemons/org.nixos.dnscrypt-proxy.plist
'';
}

View file

@ -6,7 +6,6 @@ let
in
{
services.nix-daemon.enable = true;
nix.package = nix;
launchd.labelPrefix = "org.nix-darwin"; # should not have an effect on nix-daemon
@ -27,8 +26,5 @@ in
echo checking nix-daemon reload in /activate >&2
grep "launchctl kill HUP system/org.nixos.nix-daemon" ${config.out}/activate
echo checking NIX_REMOTE=daemon in setEnvironment >&2
grep "NIX_REMOTE=daemon" ${config.system.build.setEnvironment}
'';
}

View file

@ -7,19 +7,13 @@ in
{
nix.gc.automatic = true;
nix.gc.options = "--delete-older-than 30d";
nix.gc.user = "nixuser";
nix.package = nix;
test = ''
echo checking nix-gc service in /Library/LaunchDaemons >&2
grep "<string>org.nixos.nix-gc</string>" ${config.out}/Library/LaunchDaemons/org.nixos.nix-gc.plist
grep "<string>/bin/wait4path /nix/store &amp;&amp; exec ${nix}/bin/nix-collect-garbage --delete-older-than 30d</string>" ${config.out}/Library/LaunchDaemons/org.nixos.nix-gc.plist
grep "<key>UserName</key>" ${config.out}/Library/LaunchDaemons/org.nixos.nix-gc.plist
grep "<string>nixuser</string>" ${config.out}/Library/LaunchDaemons/org.nixos.nix-gc.plist
(! grep "<key>KeepAlive</key>" ${config.out}/Library/LaunchDaemons/org.nixos.nix-gc.plist)
echo checking nix-gc validation >&2
(! grep "nix.gc.user = " ${config.out}/activate-user)
'';
}

View file

@ -6,7 +6,6 @@ in
{
nix.optimise.automatic = true;
nix.optimise.user = "nixuser";
nix.package = nix;
test = ''
@ -15,11 +14,6 @@ in
${config.out}/Library/LaunchDaemons/org.nixos.nix-optimise.plist
grep "<string>/bin/wait4path /nix/store &amp;&amp; exec ${nix}/bin/nix-store --optimise</string>" \
${config.out}/Library/LaunchDaemons/org.nixos.nix-optimise.plist
grep "<key>UserName</key>" ${config.out}/Library/LaunchDaemons/org.nixos.nix-optimise.plist
grep "<string>nixuser</string>" ${config.out}/Library/LaunchDaemons/org.nixos.nix-optimise.plist
(! grep "<key>KeepAlive</key>" ${config.out}/Library/LaunchDaemons/org.nixos.nix-optimise.plist)
echo checking nix-optimise validation >&2
(! grep "nix.optimise.user = " ${config.out}/activate-user)
'';
}

View file

@ -5,7 +5,6 @@ let
in
{
services.nix-daemon.enable = true;
services.nix-daemon.enableSocketListener = true;
nix.package = nix;
launchd.labelPrefix = "org.nix-darwin"; # should not have an effect on nix-daemon

View file

@ -46,10 +46,18 @@
system.defaults.menuExtraClock.Show24Hour = false;
system.defaults.menuExtraClock.ShowDayOfWeek = true;
system.defaults.menuExtraClock.ShowDate = 2;
system.defaults.dock.expose-group-apps = true;
system.defaults.dock.appswitcher-all-displays = false;
system.defaults.dock.autohide-delay = 0.24;
system.defaults.dock.orientation = "left";
system.defaults.dock.persistent-apps = ["MyApp.app" "Cool.app"];
system.defaults.dock.persistent-apps = [
"/Applications/MyApp.app"
{ app = "/Applications/Cool.app"; }
{ spacer = { small = true; }; }
{ spacer = { small = false; }; }
{ folder = "/Applications/Utilities"; }
{ file = "/Users/example/Downloads/test.csv"; }
];
system.defaults.dock.persistent-others = ["~/Documents" "~/Downloads/file.txt"];
system.defaults.dock.scroll-to-open = false;
system.defaults.finder.AppleShowAllFiles = true;
@ -73,6 +81,7 @@
system.defaults.finder.ShowRemovableMediaOnDesktop = false;
system.defaults.hitoolbox.AppleFnUsageType = "Show Emoji & Symbols";
system.defaults.screencapture.location = "/tmp";
system.defaults.screencapture.target = "file";
system.defaults.screencapture.include-date = true;
system.defaults.screensaver.askForPassword = true;
system.defaults.screensaver.askForPasswordDelay = 5;
@ -94,6 +103,10 @@
system.defaults.WindowManager.AppWindowGroupingBehavior = true;
system.defaults.WindowManager.StandardHideDesktopIcons = false;
system.defaults.WindowManager.HideDesktop = false;
system.defaults.WindowManager.EnableTilingByEdgeDrag = true;
system.defaults.WindowManager.EnableTopTilingByEdgeDrag = true;
system.defaults.WindowManager.EnableTilingOptionAccelerator = true;
system.defaults.WindowManager.EnableTiledWindowMargins = true;
system.defaults.WindowManager.StandardHideWidgets = true;
system.defaults.WindowManager.StageManagerHideWidgets = true;
system.defaults.CustomUserPreferences = {

4
version.json Normal file
View file

@ -0,0 +1,4 @@
{
"release": "25.05",
"isReleaseBranch": false
}