diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 866fd9920..a494fd651 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -4,7 +4,7 @@ on: push: env: - CURRENT_STABLE_CHANNEL: nixpkgs-23.05-darwin + CURRENT_STABLE_CHANNEL: nixpkgs-23.11-darwin jobs: test-stable: @@ -13,9 +13,9 @@ jobs: steps: - uses: actions/checkout@v3 - name: Install nix corresponding to latest stable channel - uses: cachix/install-nix-action@v22 + uses: cachix/install-nix-action@v23 with: - install_url: https://github.com/nix-community/nix-unstable-installer/releases/download/nix-2.10.0pre20220822_7c3ab57/install + install_url: https://releases.nixos.org/nix/nix-2.13.6/install - run: nix-build ./release.nix -I nixpkgs=channel:${{ env.CURRENT_STABLE_CHANNEL }} -I darwin=. -A tests - run: nix-build ./release.nix -I nixpkgs=channel:${{ env.CURRENT_STABLE_CHANNEL }} -I darwin=. -A manpages - run: nix-build ./release.nix -I nixpkgs=channel:${{ env.CURRENT_STABLE_CHANNEL }} -I darwin=. -A examples.simple @@ -26,7 +26,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: Install nix from current unstable channel - uses: cachix/install-nix-action@v22 + uses: cachix/install-nix-action@v23 - run: nix-build ./release.nix -I nixpkgs=channel:nixpkgs-unstable -I darwin=. -A tests - run: nix-build ./release.nix -I nixpkgs=channel:nixpkgs-unstable -I darwin=. -A manpages - run: nix-build ./release.nix -I nixpkgs=channel:nixpkgs-unstable -I darwin=. -A examples.simple @@ -37,9 +37,9 @@ jobs: steps: - uses: actions/checkout@v3 - name: Install nix corresponding to latest stable channel - uses: cachix/install-nix-action@v22 + uses: cachix/install-nix-action@v23 with: - install_url: https://github.com/nix-community/nix-unstable-installer/releases/download/nix-2.10.0pre20220822_7c3ab57/install + install_url: https://releases.nixos.org/nix/nix-2.13.6/install nix_path: nixpkgs=channel:${{ env.CURRENT_STABLE_CHANNEL }} - name: Install ${{ env.CURRENT_STABLE_CHANNEL }} channel run: | @@ -82,7 +82,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: Install nix from current unstable channel - uses: cachix/install-nix-action@v22 + uses: cachix/install-nix-action@v23 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Install nixpkgs-unstable channel @@ -126,9 +126,9 @@ jobs: steps: - uses: actions/checkout@v3 - name: Install nix version corresponding to latest stable channel - uses: cachix/install-nix-action@v22 + uses: cachix/install-nix-action@v23 with: - install_url: https://github.com/nix-community/nix-unstable-installer/releases/download/nix-2.10.0pre20220822_7c3ab57/install + install_url: https://releases.nixos.org/nix/nix-2.13.6/install - name: Install nix-darwin run: | mkdir -p ~/.config/nix-darwin @@ -209,7 +209,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: Install nix from current unstable channel - uses: cachix/install-nix-action@v22 + uses: cachix/install-nix-action@v23 - name: Install nix-darwin run: | mkdir -p ~/.config/nix-darwin diff --git a/.github/workflows/update-manual.yml b/.github/workflows/update-manual.yml index 60cb36299..ef9d52f45 100644 --- a/.github/workflows/update-manual.yml +++ b/.github/workflows/update-manual.yml @@ -21,7 +21,7 @@ jobs: - name: Build manual run: | - nix-build ./release.nix -I nixpkgs=channel:nixpkgs-23.05-darwin -I darwin=. -A manualHTML + nix-build ./release.nix -I nixpkgs=channel:nixpkgs-23.11-darwin -I darwin=. -A manualHTML - name: Push update to manual run: | diff --git a/README.md b/README.md index b3b00280e..e1f06094a 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ nix-darwin is built up around [Nixpkgs](https://github.com/NixOS/nixpkgs), quite To install nix-darwin, a working installation of [Nix](https://github.com/NixOS/nix#installation) is required. -> NOTE: Using `darwin-installer` is no longer necessary on flake based systems. +If you wish to use nix-darwin with flakes, please refer to the [flakes](#flakes) section. ```bash nix-build https://github.com/LnL7/nix-darwin/archive/master.tar.gz -A installer @@ -69,10 +69,9 @@ Configuration lives in `~/.nixpkgs/darwin-configuration.nix`. Check out } ``` -## Flakes (experimental) +## Flakes -There is also preliminary support for building your configuration using a [flake](https://nixos.wiki/wiki/Flakes). This -is mostly based on the flake support that was added to NixOS. +nix-darwin aims for both non-flake and flake configurations to be well supported despite flakes being an experimental feature in Nix. ### Step 1. Creating `flake.nix` @@ -86,11 +85,10 @@ If you don't have an existing `configuration.nix`, you can run the following com mkdir -p ~/.config/nix-darwin cd ~/.config/nix-darwin nix flake init -t nix-darwin +sed -i '' "s/simple/$(scutil --get LocalHostName)/" flake.nix ``` -Make sure to replace all occurrences of `simple` with your short hostname which you can find by running `hostname -s`. - -> NOTE: Make sure to change `nixpkgs.hostPlatform` to `aarch64-darwin` if you are using Apple Silicon. +Make sure to change `nixpkgs.hostPlatform` to `aarch64-darwin` if you are using Apple Silicon. @@ -105,8 +103,8 @@ 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-23.05-darwin"; - nix-darwin.url = "github:LnL7/nix-darwin/master"; + nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-23.11-darwin"; + nix-darwin.url = "github:LnL7/nix-darwin"; nix-darwin.inputs.nixpkgs.follows = "nixpkgs"; }; @@ -118,9 +116,9 @@ Add the following to `flake.nix` in the same folder as `configuration.nix`: } ``` -Make sure to replace `Johns-MacBook` with your short hostname which you can find by running `hostname -s`. +Make sure to replace `Johns-MacBook` with your hostname which you can find by running `scutil --get LocalHostName`. -> NOTE: Make sure to set `nixpkgs.hostPlatform` in your `configuration.nix` to either `x86_64-darwin` (Intel) or `aarch64-darwin` (Apple Silicon). +Make sure to set `nixpkgs.hostPlatform` in your `configuration.nix` to either `x86_64-darwin` (Intel) or `aarch64-darwin` (Apple Silicon). @@ -174,7 +172,7 @@ export NIX_PATH=darwin=$HOME/.nix-defexpr/darwin:darwin-config=$HOME/.nixpkgs/da cp ~/.nix-defexpr/darwin/modules/examples/simple.nix ~/.nixpkgs/darwin-configuration.nix # you can also use this to rebootstrap nix-darwin in case -# darwin-rebuild is to old to activate the system. +# darwin-rebuild is too old to activate the system. $(nix-build '' -A system --no-out-link)/sw/bin/darwin-rebuild build $(nix-build '' -A system --no-out-link)/sw/bin/darwin-rebuild switch diff --git a/default.nix b/default.nix index 7c7e06b2b..c93b47833 100644 --- a/default.nix +++ b/default.nix @@ -16,7 +16,7 @@ let }; }; - # The source code of this repo needed by the [un]installers. + # The source code of this repo needed by the installer. nix-darwin = lib.cleanSource ( lib.cleanSourceWith { # We explicitly specify a name here otherwise `cleanSource` will use the @@ -30,5 +30,5 @@ in eval // { installer = pkgs.callPackage ./pkgs/darwin-installer { inherit nix-darwin; }; - uninstaller = pkgs.callPackage ./pkgs/darwin-uninstaller { inherit nix-darwin; }; + uninstaller = pkgs.callPackage ./pkgs/darwin-uninstaller { }; } diff --git a/doc/known-files/5d23e6d7015756c6f300f8cd558ec4d9234ca61deefd4f2478e91a49760b0747 b/doc/known-files/5d23e6d7015756c6f300f8cd558ec4d9234ca61deefd4f2478e91a49760b0747 new file mode 100644 index 000000000..55a2da166 --- /dev/null +++ b/doc/known-files/5d23e6d7015756c6f300f8cd558ec4d9234ca61deefd4f2478e91a49760b0747 @@ -0,0 +1,9 @@ +# Generated by https://github.com/DeterminateSystems/nix-installer. +# See `/nix/nix-installer --version` for the version details. + +build-users-group = nixbld +experimental-features = nix-command flakes repl-flake +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 diff --git a/doc/known-files/97f4135d262ca22d65c9554aad795c10a4491fa61b67d9c2430f4d82bbfec9a2 b/doc/known-files/97f4135d262ca22d65c9554aad795c10a4491fa61b67d9c2430f4d82bbfec9a2 new file mode 100644 index 000000000..63529267a --- /dev/null +++ b/doc/known-files/97f4135d262ca22d65c9554aad795c10a4491fa61b67d9c2430f4d82bbfec9a2 @@ -0,0 +1,8 @@ +# Generated by https://github.com/DeterminateSystems/nix-installer. +# See `/nix/nix-installer --version` for the version details. + +build-users-group = nixbld +experimental-features = nix-command flakes repl-flake +bash-prompt-prefix = (nix:$name)\040 +max-jobs = auto +extra-nix-path = nixpkgs=flake:nixpkgs diff --git a/doc/known-files/9d5aa72f807091b481820d12e693093293ba33c73854909ad7b0fb192c2db193 b/doc/known-files/9d5aa72f807091b481820d12e693093293ba33c73854909ad7b0fb192c2db193 new file mode 100644 index 000000000..c3977df97 --- /dev/null +++ b/doc/known-files/9d5aa72f807091b481820d12e693093293ba33c73854909ad7b0fb192c2db193 @@ -0,0 +1,11 @@ +# List of acceptable shells for chpass(1). +# Ftpd will not allow users to connect who are not using +# one of these shells. + +/bin/bash +/bin/csh +/bin/dash +/bin/ksh +/bin/sh +/bin/tcsh +/bin/zsh diff --git a/doc/known-files/c6080216f2a170611e339c3f46e4e1d61aaf0d8b417ad93ade8d647da1382c11 b/doc/known-files/c6080216f2a170611e339c3f46e4e1d61aaf0d8b417ad93ade8d647da1382c11 new file mode 100644 index 000000000..f2dc63647 --- /dev/null +++ b/doc/known-files/c6080216f2a170611e339c3f46e4e1d61aaf0d8b417ad93ade8d647da1382c11 @@ -0,0 +1,6 @@ +# Generated by https://github.com/DeterminateSystems/nix-installer, version 0.14.0. +build-users-group = nixbld +experimental-features = nix-command flakes repl-flake +bash-prompt-prefix = (nix:$name)\040 +max-jobs = auto +extra-nix-path = nixpkgs=flake:nixpkgs diff --git a/doc/known-files/d07015be6875f134976fce84c6c7a77b512079c1c5f9594dfa65c70b7968b65f b/doc/known-files/d07015be6875f134976fce84c6c7a77b512079c1c5f9594dfa65c70b7968b65f new file mode 100644 index 000000000..7a676da99 --- /dev/null +++ b/doc/known-files/d07015be6875f134976fce84c6c7a77b512079c1c5f9594dfa65c70b7968b65f @@ -0,0 +1,7 @@ + +# Set up Nix only on SSH connections +# See: https://github.com/DeterminateSystems/nix-installer/pull/714 +if [ -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' ] && [ -n "${SSH_CONNECTION}" ] && [ "${SHLVL}" -eq 1 ]; then + . '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' +fi +# End Nix diff --git a/doc/manual/default.nix b/doc/manual/default.nix index 5a0072a92..abe126b73 100644 --- a/doc/manual/default.nix +++ b/doc/manual/default.nix @@ -71,7 +71,6 @@ in rec { mkdir -p $dst cp $styles/style.css $dst - cp $styles/overrides.css $dst cp -r ${pkgs.documentation-highlighter} $dst/highlightjs substitute ${./manual.md} manual.md \ @@ -86,7 +85,6 @@ in rec { --revision ${lib.escapeShellArg revision} \ --generator "nixos-render-docs ${lib.version}" \ --stylesheet style.css \ - --stylesheet overrides.css \ --stylesheet highlightjs/mono-blue.css \ --script ./highlightjs/highlight.pack.js \ --script ./highlightjs/loader.js \ diff --git a/eval-config.nix b/eval-config.nix index 9663849a5..d2567a419 100644 --- a/eval-config.nix +++ b/eval-config.nix @@ -24,6 +24,7 @@ in { inherit (eval._module.args) pkgs; inherit (eval) options config; + inherit (eval) _module; system = eval.config.system.build.toplevel; } diff --git a/flake.nix b/flake.nix index d09f4d6c5..e25fe6a6f 100644 --- a/flake.nix +++ b/flake.nix @@ -42,7 +42,7 @@ overlays.default = final: prev: { inherit (prev.callPackage ./pkgs/nix-tools { }) darwin-rebuild darwin-option darwin-version; - darwin-uninstaller = prev.callPackage ./pkgs/darwin-uninstaller { nix-darwin = self; }; + darwin-uninstaller = prev.callPackage ./pkgs/darwin-uninstaller { }; }; darwinModules.hydra = ./modules/examples/hydra.nix; diff --git a/modules/documentation/default.nix b/modules/documentation/default.nix index 2f3bb9a4d..10bcbd334 100644 --- a/modules/documentation/default.nix +++ b/modules/documentation/default.nix @@ -88,7 +88,7 @@ in documentation.enable = mkOption { type = types.bool; default = true; - description = lib.mdDoc '' + description = '' Whether to install documentation of packages from {option}`environment.systemPackages` into the generated system path. @@ -100,7 +100,7 @@ in documentation.man.enable = mkOption { type = types.bool; default = true; - description = lib.mdDoc '' + description = '' Whether to install manual pages and the {command}`man` command. This also includes "man" outputs. ''; @@ -109,7 +109,7 @@ in documentation.info.enable = mkOption { type = types.bool; default = true; - description = lib.mdDoc '' + description = '' Whether to install info pages and the {command}`info` command. This also includes "info" outputs. ''; @@ -118,7 +118,7 @@ in documentation.doc.enable = mkOption { type = types.bool; default = true; - description = lib.mdDoc '' + description = '' Whether to install documentation distributed in packages' `/share/doc`. Usually plain text and/or HTML. This also includes "doc" outputs. diff --git a/modules/environment/default.nix b/modules/environment/default.nix index c4883c395..753ee311f 100644 --- a/modules/environment/default.nix +++ b/modules/environment/default.nix @@ -21,7 +21,7 @@ in type = types.listOf types.package; default = []; example = literalExpression "[ pkgs.curl pkgs.vim ]"; - description = lib.mdDoc '' + description = '' The set of packages that appear in /run/current-system/sw. These packages are automatically available to all users, and are @@ -34,39 +34,39 @@ in environment.systemPath = mkOption { type = types.listOf (types.either types.path types.str); - description = lib.mdDoc "The set of paths that are added to PATH."; + description = "The set of paths that are added to PATH."; apply = x: if isList x then makeDrvBinPath x else x; }; environment.profiles = mkOption { type = types.listOf types.str; - description = lib.mdDoc "A list of profiles used to setup the global environment."; + description = "A list of profiles used to setup the global environment."; }; environment.postBuild = mkOption { type = types.lines; default = ""; - description = lib.mdDoc "Commands to execute when building the global environment."; + description = "Commands to execute when building the global environment."; }; environment.extraOutputsToInstall = mkOption { type = types.listOf types.str; default = []; example = [ "doc" "info" "devdoc" ]; - description = lib.mdDoc "List of additional package outputs to be symlinked into {file}`/run/current-system/sw`."; + description = "List of additional package outputs to be symlinked into {file}`/run/current-system/sw`."; }; environment.pathsToLink = mkOption { type = types.listOf types.str; default = []; example = [ "/share/doc" ]; - description = lib.mdDoc "List of directories to be symlinked in {file}`/run/current-system/sw`."; + description = "List of directories to be symlinked in {file}`/run/current-system/sw`."; }; environment.darwinConfig = mkOption { type = types.either types.path types.str; default = "$HOME/.nixpkgs/darwin-configuration.nix"; - description = lib.mdDoc '' + 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 changes an environment variable it will only apply to new shells. @@ -79,14 +79,14 @@ in environment.loginShell = mkOption { type = types.str; default = "$SHELL -l"; - description = lib.mdDoc "Configure default login shell."; + description = "Configure default login shell."; }; environment.variables = mkOption { type = types.attrsOf (types.either types.str (types.listOf types.str)); default = {}; example = { EDITOR = "vim"; LANG = "nl_NL.UTF-8"; }; - description = lib.mdDoc '' + description = '' A set of environment variables used in the global environment. These variables will be set on shell initialisation. The value of each variable can be either a string or a list of @@ -100,7 +100,7 @@ in type = types.attrsOf types.str; default = {}; example = { ll = "ls -l"; }; - description = lib.mdDoc '' + description = '' An attribute set that maps aliases (the top level attribute names in this option) to command strings or directly to build outputs. The alises are added to all users' shells. @@ -110,7 +110,7 @@ in environment.extraInit = mkOption { type = types.lines; default = ""; - description = lib.mdDoc '' + description = '' Shell script code called during global environment initialisation after all variables and profileVariables have been set. This code is asumed to be shell-independent, which means you should @@ -120,7 +120,7 @@ in environment.shellInit = mkOption { default = ""; - description = lib.mdDoc '' + description = '' Shell script code called during shell initialisation. This code is asumed to be shell-independent, which means you should stick to pure sh without sh word split. @@ -130,7 +130,7 @@ in environment.loginShellInit = mkOption { default = ""; - description = lib.mdDoc '' + description = '' Shell script code called during login shell initialisation. This code is asumed to be shell-independent, which means you should stick to pure sh without sh word split. @@ -140,7 +140,7 @@ in environment.interactiveShellInit = mkOption { default = ""; - description = lib.mdDoc '' + description = '' Shell script code called during interactive shell initialisation. This code is asumed to be shell-independent, which means you should stick to pure sh without sh word split. diff --git a/modules/examples/lnl.nix b/modules/examples/lnl.nix index 264bd1a1f..2edf6cb9f 100644 --- a/modules/examples/lnl.nix +++ b/modules/examples/lnl.nix @@ -308,40 +308,6 @@ nixpkgs.overlays = [ (self: super: { - darwin-zsh-completions = super.runCommand "darwin-zsh-completions-0.0.0" - { preferLocalBuild = true; } - '' - mkdir -p $out/share/zsh/site-functions - - cat <<-'EOF' > $out/share/zsh/site-functions/_darwin-rebuild - #compdef darwin-rebuild - #autoload - - _nix-common-options - - local -a _1st_arguments - _1st_arguments=( - 'switch:Build, activate, and update the current generation'\ - 'build:Build without activating or updating the current generation'\ - 'check:Build and run the activation sanity checks'\ - 'changelog:Show most recent entries in the changelog'\ - ) - - _arguments \ - '--list-generations[Print a list of all generations in the active profile]'\ - '--rollback[Roll back to the previous configuration]'\ - {--switch-generation,-G}'[Activate specified generation]'\ - '(--profile-name -p)'{--profile-name,-p}'[Profile to use to track current and previous system configurations]:Profile:_nix_profiles'\ - '1:: :->subcmds' && return 0 - - case $state in - subcmds) - _describe -t commands 'darwin-rebuild subcommands' _1st_arguments - ;; - esac - EOF - ''; - vim_configurable = super.vim_configurable.override { guiSupport = "no"; }; diff --git a/modules/fonts/default.nix b/modules/fonts/default.nix index b39df76a7..714063996 100644 --- a/modules/fonts/default.nix +++ b/modules/fonts/default.nix @@ -13,8 +13,9 @@ in options = { fonts.fontDir.enable = mkOption { + type = types.bool; default = false; - description = lib.mdDoc '' + description = '' Whether to enable font management and install configured fonts to {file}`/Library/Fonts`. @@ -26,7 +27,7 @@ in type = types.listOf types.path; default = [ ]; example = literalExpression "[ pkgs.dejavu_fonts ]"; - description = lib.mdDoc '' + description = '' List of fonts to install. Fonts present in later entries override those with the same filenames @@ -41,7 +42,7 @@ in { preferLocalBuild = true; } '' mkdir -p $out/Library/Fonts - font_regexp='.*\.\(ttf\|ttc\|otf\)' + font_regexp='.*\.\(ttf\|ttc\|otf\|dfont\)' find -L ${toString cfg.fonts} -regex "$font_regexp" -type f -print0 | while IFS= read -rd "" f; do ln -sf "$f" $out/Library/Fonts done diff --git a/modules/homebrew.nix b/modules/homebrew.nix index 8665565f8..7aee9e130 100644 --- a/modules/homebrew.nix +++ b/modules/homebrew.nix @@ -65,7 +65,7 @@ let type = types.enum [ "none" "uninstall" "zap" ]; default = "none"; example = "uninstall"; - description = lib.mdDoc '' + description = '' This option manages what happens to formulae installed by Homebrew, that aren't present in the Brewfile generated by this module, during {command}`nix-darwin` system activation. @@ -92,7 +92,7 @@ let autoUpdate = mkOption { type = types.bool; default = false; - description = lib.mdDoc '' + description = '' Whether to enable Homebrew to auto-update itself and all formulae during {command}`nix-darwin` system activation. The default is `false` so that repeated invocations of {command}`darwin-rebuild switch` are idempotent. @@ -102,15 +102,32 @@ let Although auto-updating is disabled by default during system activation, note that Homebrew will auto-update when you manually invoke certain Homebrew commands. To modify this behavior see [](#opt-homebrew.global.autoUpdate). + + Implementation note: when disabled, this option sets the `HOMEBREW_NO_AUTO_UPDATE` + environment variable when {command}`nix-darwin` invokes {command}`brew bundle [install]` + during system activation. ''; }; upgrade = mkOption { type = types.bool; default = false; - description = lib.mdDoc '' + description = '' Whether to enable Homebrew to upgrade outdated formulae and Mac App Store apps during {command}`nix-darwin` system activation. The default is `false` so that repeated invocations of {command}`darwin-rebuild switch` are idempotent. + + Implementation note: when disabled, {command}`nix-darwin` invokes + {command}`brew bundle [install]` with the {command}`--no-upgrade` flag during system + activation. + ''; + }; + extraFlags = mkOption { + type = types.listOf types.str; + default = [ ]; + example = [ "--verbose" ]; + description = '' + Extra flags to pass to {command}`brew bundle [install]` during {command}`nix-darwin` + system activation. ''; }; @@ -120,10 +137,11 @@ let config = { brewBundleCmd = concatStringsSep " " ( optional (!config.autoUpdate) "HOMEBREW_NO_AUTO_UPDATE=1" - ++ [ "brew bundle --verbose --file='${brewfileFile}' --no-lock" ] + ++ [ "brew bundle --file='${brewfileFile}' --no-lock" ] ++ optional (!config.upgrade) "--no-upgrade" ++ optional (config.cleanup == "uninstall") "--cleanup" ++ optional (config.cleanup == "zap") "--cleanup --zap" + ++ config.extraFlags ); }; }; @@ -133,7 +151,7 @@ let brewfile = mkOption { type = types.bool; default = false; - description = lib.mdDoc '' + description = '' Whether to enable Homebrew to automatically use the Brewfile that this module generates in the Nix store, when you manually invoke {command}`brew bundle`. @@ -154,7 +172,7 @@ let autoUpdate = mkOption { type = types.bool; default = true; - description = lib.mdDoc '' + description = '' Whether to enable Homebrew to auto-update itself and all formulae when you manually invoke commands like {command}`brew install`, {command}`brew upgrade`, {command}`brew tap`, and {command}`brew bundle [install]`. @@ -177,7 +195,7 @@ let type = types.bool; default = !config.brewfile; defaultText = literalExpression "!config.homebrew.global.brewfile"; - description = lib.mdDoc '' + description = '' Whether to enable Homebrew to generate lockfiles when you manually invoke {command}`brew bundle [install]`. @@ -217,14 +235,14 @@ let name = mkOption { type = types.str; example = "homebrew/cask-fonts"; - description = lib.mdDoc '' + description = '' When {option}`clone_target` is unspecified, this is the name of a formula repository to tap from GitHub using HTTPS. For example, `"user/repo"` will tap https://github.com/user/homebrew-repo. ''; }; clone_target = mkNullOrStrOption { - description = lib.mdDoc '' + description = '' Use this option to tap a formula repository from anywhere, using any transport protocol that {command}`git` handles. When {option}`clone_target` is specified, taps can be cloned from places other than GitHub and using protocols other than HTTPS, e.g., @@ -232,7 +250,7 @@ let ''; }; force_auto_update = mkNullOrBoolOption { - description = lib.mdDoc '' + description = '' Whether to auto-update the tap even if it is not hosted on GitHub. By default, only taps hosted on GitHub are auto-updated (for performance reasons). ''; @@ -259,77 +277,77 @@ let caskArgsOptions = { config, ... }: { options = { appdir = mkNullOrStrOption { - description = lib.mdDoc '' + description = '' Target location for Applications. Homebrew's default is {file}`/Applications`. ''; }; colorpickerdir = mkNullOrStrOption { - description = lib.mdDoc '' + description = '' Target location for Color Pickers. Homebrew's default is {file}`~/Library/ColorPickers`. ''; }; prefpanedir = mkNullOrStrOption { - description = lib.mdDoc '' + description = '' Target location for Preference Panes. Homebrew's default is {file}`~/Library/PreferencePanes`. ''; }; qlplugindir = mkNullOrStrOption { - description = lib.mdDoc '' + description = '' Target location for QuickLook Plugins. Homebrew's default is {file}`~/Library/QuickLook`. ''; }; mdimporterdir = mkNullOrStrOption { - description = lib.mdDoc '' + description = '' Target location for Spotlight Plugins. Homebrew's default is {file}`~/Library/Spotlight`. ''; }; dictionarydir = mkNullOrStrOption { - description = lib.mdDoc '' + description = '' Target location for Dictionaries. Homebrew's default is {file}`~/Library/Dictionaries`. ''; }; fontdir = mkNullOrStrOption { - description = lib.mdDoc '' + description = '' Target location for Fonts. Homebrew's default is {file}`~/Library/Fonts`. ''; }; servicedir = mkNullOrStrOption { - description = lib.mdDoc '' + description = '' Target location for Services. Homebrew's default is {file}`~/Library/Services`. ''; }; input_methoddir = mkNullOrStrOption { - description = lib.mdDoc '' + description = '' Target location for Input Methods. Homebrew's default is {file}`~/Library/Input Methods`. ''; }; internet_plugindir = mkNullOrStrOption { - description = lib.mdDoc '' + description = '' Target location for Internet Plugins. Homebrew's default is {file}`~/Library/Internet Plug-Ins`. ''; }; audio_unit_plugindir = mkNullOrStrOption { - description = lib.mdDoc '' + description = '' Target location for Audio Unit Plugins. Homebrew's default is @@ -337,28 +355,28 @@ let ''; }; vst_plugindir = mkNullOrStrOption { - description = lib.mdDoc '' + description = '' Target location for VST Plugins. Homebrew's default is {file}`~/Library/Audio/Plug-Ins/VST`. ''; }; vst3_plugindir = mkNullOrStrOption { - description = lib.mdDoc '' + description = '' Target location for VST3 Plugins. Homebrew's default is {file}`~/Library/Audio/Plug-Ins/VST3`. ''; }; screen_saverdir = mkNullOrStrOption { - description = lib.mdDoc '' + description = '' Target location for Screen Savers. Homebrew's default is {file}`~/Library/Screen Savers`. ''; }; language = mkNullOrStrOption { - description = lib.mdDoc '' + description = '' Comma-separated list of language codes to prefer for cask installation. The first matching language is used, otherwise it reverts to the cask’s default language. The default value is the language of your system. @@ -366,17 +384,17 @@ let example = "zh-TW"; }; require_sha = mkNullOrBoolOption { - description = lib.mdDoc '' + description = '' Whether to require cask(s) to have a checksum. Homebrew's default is `false`. ''; }; no_quarantine = mkNullOrBoolOption { - description = lib.mdDoc "Whether to disable quarantining of downloads."; + description = "Whether to disable quarantining of downloads."; }; no_binaries = mkNullOrBoolOption { - description = lib.mdDoc "Whether to disable linking of helper executables."; + description = "Whether to disable linking of helper executables."; }; brewfileLine = mkInternalOption { type = types.nullOr types.str; }; @@ -397,12 +415,12 @@ let options = { name = mkOption { type = types.str; - description = lib.mdDoc "The name of the formula to install."; + description = "The name of the formula to install."; }; args = mkOption { type = with types; nullOr (listOf str); default = null; - description = lib.mdDoc '' + description = '' Arguments flags to pass to {command}`brew install`. Values should not include the leading `"--"`. ''; @@ -410,7 +428,7 @@ let conflicts_with = mkOption { type = with types; nullOr (listOf str); default = null; - description = lib.mdDoc '' + description = '' List of formulae that should be unlinked and their services stopped (if they are installed). ''; @@ -418,7 +436,7 @@ let restart_service = mkOption { type = with types; nullOr (either bool (enum [ "changed" ])); default = null; - description = lib.mdDoc '' + description = '' Whether to run {command}`brew services restart` for the formula and register it to launch at login (or boot). If set to `"changed"`, the service will only be restarted on version changes. @@ -427,7 +445,7 @@ let ''; }; start_service = mkNullOrBoolOption { - description = lib.mdDoc '' + description = '' Whether to run {command}`brew services start` for the formula and register it to launch at login (or boot). @@ -435,7 +453,7 @@ let ''; }; link = mkNullOrBoolOption { - description = lib.mdDoc '' + description = '' Whether to link the formula to the Homebrew prefix. When this option is `null`, Homebrew will use it's default behavior which is to link the formula if it's currently unlinked and not keg-only, and to unlink the formula if it's @@ -470,19 +488,19 @@ let options = { name = mkOption { type = types.str; - description = lib.mdDoc "The name of the cask to install."; + description = "The name of the cask to install."; }; args = mkOption { type = types.nullOr (types.submodule caskArgsOptions); default = null; visible = "shallow"; # so that options from `homebrew.caskArgs` aren't repeated. - description = lib.mdDoc '' + description = '' Arguments passed to {command}`brew install --cask` when installing this cask. See [](#opt-homebrew.caskArgs) for the available options. ''; }; greedy = mkNullOrBoolOption { - description = lib.mdDoc '' + description = '' Whether to always upgrade this cask regardless of whether it's unversioned or it updates itself. ''; @@ -513,7 +531,7 @@ in ]; options.homebrew = { - enable = mkEnableOption (lib.mdDoc '' + enable = mkEnableOption '' {command}`nix-darwin` to manage installing/updating/upgrading Homebrew taps, formulae, and casks, as well as Mac App Store apps and Docker containers, using Homebrew Bundle. @@ -536,7 +554,7 @@ in [](#opt-homebrew.onActivation). This module also provides a few options for modifying how Homebrew commands behave when - you manually invoke them, under [](#opt-homebrew.global)''); + you manually invoke them, under [](#opt-homebrew.global)''; brewPrefix = mkOption { type = types.str; @@ -545,7 +563,7 @@ in if pkgs.stdenv.hostPlatform.isAarch64 then "/opt/homebrew/bin" else "/usr/local/bin" ''; - description = lib.mdDoc '' + description = '' The path prefix where the {command}`brew` executable is located. This will be set to the correct value based on your system's platform, and should only need to be changed if you manually installed Homebrew in a non-standard location. @@ -555,7 +573,7 @@ in onActivation = mkOption { type = types.submodule onActivationOptions; default = { }; - description = lib.mdDoc '' + description = '' Options for configuring the behavior of the {command}`brew bundle` command that {command}`nix-darwin` runs during system activation. ''; @@ -564,7 +582,7 @@ in global = mkOption { type = types.submodule globalOptions; default = { }; - description = lib.mdDoc '' + description = '' Options for configuring the behavior of Homebrew commands when you manually invoke them. ''; }; @@ -586,7 +604,7 @@ in } ] ''; - description = lib.mdDoc '' + description = '' List of Homebrew formula repositories to tap. Taps defined as strings, e.g., `"user/repo"`, are a shorthand for: @@ -604,7 +622,7 @@ in require_sha = true; } ''; - description = lib.mdDoc '' + description = '' Arguments passed to {command}`brew install --cask` for all casks listed in [](#opt-homebrew.casks). ''; @@ -635,7 +653,7 @@ in } ] ''; - description = lib.mdDoc '' + description = '' List of Homebrew formulae to install. Formulae defined as strings, e.g., `"imagemagick"`, are a shorthand for: @@ -666,7 +684,7 @@ in } ] ''; - description = lib.mdDoc '' + description = '' List of Homebrew casks to install. Casks defined as strings, e.g., `"google-chrome"`, are a shorthand for: @@ -684,7 +702,7 @@ in Xcode = 497799835; } ''; - description = lib.mdDoc '' + description = '' Applications to install from Mac App Store using {command}`mas`. When this option is used, `"mas"` is automatically added to @@ -705,7 +723,7 @@ in type = with types; listOf str; default = [ ]; example = [ "whalebrew/wget" ]; - description = lib.mdDoc '' + description = '' List of Docker images to install using {command}`whalebrew`. When this option is used, `"whalebrew"` is automatically added to @@ -723,12 +741,12 @@ in # 'brew cask install' only if '/usr/libexec/java_home --failfast' fails cask "java" unless system "/usr/libexec/java_home --failfast" ''; - description = lib.mdDoc "Extra lines to be added verbatim to the bottom of the generated Brewfile."; + description = "Extra lines to be added verbatim to the bottom of the generated Brewfile."; }; brewfile = mkInternalOption { type = types.str; - description = lib.mdDoc "String reprensentation of the generated Brewfile useful for debugging."; + description = "String reprensentation of the generated Brewfile useful for debugging."; }; }; diff --git a/modules/launchd/default.nix b/modules/launchd/default.nix index d1b2b50aa..ccb6cc696 100644 --- a/modules/launchd/default.nix +++ b/modules/launchd/default.nix @@ -1,6 +1,5 @@ { config, lib, pkgs, ... }: -with import ./lib.nix { inherit lib; }; with lib; let @@ -10,7 +9,7 @@ let toEnvironmentText = name: value: { name = "${value.serviceConfig.Label}.plist"; - value.text = toPLIST value.serviceConfig; + value.text = generators.toPlist { } value.serviceConfig; }; launchdConfig = import ./launchd.nix; @@ -31,14 +30,14 @@ let type = types.attrsOf (types.either types.str (types.listOf types.str)); default = {}; example = { PATH = "/foo/bar/bin"; LANG = "nl_NL.UTF-8"; }; - description = lib.mdDoc "Environment variables passed to the service's processes."; + description = "Environment variables passed to the service's processes."; apply = mapAttrs (n: v: if isList v then concatStringsSep ":" v else v); }; path = mkOption { type = types.listOf (types.either types.path types.str); default = []; - description = lib.mdDoc '' + description = '' Packages added to the service's {env}`PATH` environment variable. Only the {file}`bin` and subdirectories of each package is added. @@ -49,13 +48,13 @@ let command = mkOption { type = types.either types.str types.path; default = ""; - description = lib.mdDoc "Command executed as the service's main process."; + description = "Command executed as the service's main process."; }; script = mkOption { type = types.lines; default = ""; - description = lib.mdDoc "Shell commands executed as the service's main process."; + description = "Shell commands executed as the service's main process."; }; # preStart = mkOption { @@ -74,7 +73,7 @@ let KeepAlive = true; }; default = {}; - description = lib.mdDoc '' + description = '' Each attribute in this set specifies an option for a key in the plist. ''; @@ -100,7 +99,7 @@ in launchd.labelPrefix = mkOption { type = types.str; default = "org.nixos"; - description = lib.mdDoc '' + description = '' The default prefix of the service label. Individual services can override this by setting the Label attribute. ''; @@ -110,7 +109,7 @@ in type = types.attrsOf (types.either types.str (types.listOf types.str)); default = {}; example = { LANG = "nl_NL.UTF-8"; }; - description = lib.mdDoc '' + description = '' A set of environment variables to be set on all future processes launched by launchd in the caller's context. The value of each variable can be either a string or a list of @@ -124,7 +123,7 @@ in type = types.attrsOf (types.either types.str (types.listOf types.str)); default = {}; example = { LANG = "nl_NL.UTF-8"; }; - description = lib.mdDoc '' + description = '' A set of environment variables to be set on all future processes launched by launchd in the caller's context. The value of each variable can be either a string or a list of @@ -137,7 +136,7 @@ in launchd.agents = mkOption { default = {}; type = types.attrsOf (types.submodule serviceOptions); - description = lib.mdDoc '' + description = '' Definition of per-user launchd agents. When a user logs in, a per-user launchd is started. @@ -153,7 +152,7 @@ in launchd.daemons = mkOption { default = {}; type = types.attrsOf (types.submodule serviceOptions); - description = lib.mdDoc '' + description = '' Definition of launchd daemons. After the system is booted and the kernel is running, launchd is run to finish the system initialization. @@ -169,7 +168,7 @@ in launchd.user.agents = mkOption { default = {}; type = types.attrsOf (types.submodule serviceOptions); - description = lib.mdDoc '' + description = '' Definition of per-user launchd agents. When a user logs in, a per-user launchd is started. diff --git a/modules/launchd/launchd.nix b/modules/launchd/launchd.nix index 63bb3c665..9fecde667 100644 --- a/modules/launchd/launchd.nix +++ b/modules/launchd/launchd.nix @@ -6,13 +6,13 @@ with lib; options = { Label = mkOption { type = types.str; - description = lib.mdDoc "This required key uniquely identifies the job to launchd."; + description = "This required key uniquely identifies the job to launchd."; }; Disabled = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' This optional key is used as a hint to `launchctl(1)` that it should not submit this job to launchd when loading a job or jobs. The value of this key does NOT reflect the current state of the job on the running system. If you wish to know whether a job is loaded in launchd, reading this key from a configuration @@ -35,7 +35,7 @@ with lib; UserName = mkOption { type = types.nullOr types.str; default = null; - description = lib.mdDoc '' + description = '' This optional key specifies the user to run the job as. This key is only applicable when launchd is running as root. ''; @@ -44,7 +44,7 @@ with lib; GroupName = mkOption { type = types.nullOr types.str; default = null; - description = lib.mdDoc '' + description = '' This optional key specifies the group to run the job as. This key is only applicable when launchd is running as root. If UserName is set and GroupName is not, the the group will be set to the default group of the user. @@ -54,7 +54,7 @@ with lib; inetdCompatibility = mkOption { default = null; example = { Wait = true; }; - description = lib.mdDoc '' + description = '' The presence of this key specifies that the daemon expects to be run as if it were launched from inetd. ''; type = types.nullOr (types.submodule { @@ -62,7 +62,7 @@ with lib; Wait = mkOption { type = types.nullOr (types.either types.bool types.str); default = null; - description = lib.mdDoc '' + description = '' This flag corresponds to the "wait" or "nowait" option of inetd. If true, then the listening socket is passed via the standard in/out/error file descriptors. If false, then `accept(2)` is called on behalf of the job, and the result is passed via the standard in/out/error descriptors. @@ -75,7 +75,7 @@ with lib; LimitLoadToHosts = mkOption { type = types.nullOr (types.listOf types.str); default = null; - description = lib.mdDoc '' + description = '' This configuration file only applies to the hosts listed with this key. Note: One should set kern.hostname in `sysctl.conf(5)` for this feature to work reliably. ''; @@ -84,16 +84,16 @@ with lib; LimitLoadFromHosts = mkOption { type = types.nullOr (types.listOf types.str); default = null; - description = lib.mdDoc '' + description = '' This configuration file only applies to hosts NOT listed with this key. Note: One should set kern.hostname in `sysctl.conf(5)` for this feature to work reliably. ''; }; LimitLoadToSessionType = mkOption { - type = types.nullOr types.str; + type = types.nullOr (types.oneOf [types.str (types.listOf types.str)]); default = null; - description = lib.mdDoc '' + description = '' This configuration file only applies to sessions of the type specified. This key is used in concert with the -S flag to {command}`launchctl`. ''; @@ -102,7 +102,7 @@ with lib; Program = mkOption { type = types.nullOr types.path; default = null; - description = lib.mdDoc '' + description = '' This key maps to the first argument of `execvp(3)`. If this key is missing, then the first element of the array of strings provided to the ProgramArguments will be used instead. This key is required in the absence of the ProgramArguments key. @@ -112,7 +112,7 @@ with lib; ProgramArguments = mkOption { type = types.nullOr (types.listOf types.str); default = null; - description = lib.mdDoc '' + description = '' This key maps to the second argument of `execvp(3)`. This key is required in the absence of the Program key. Please note: many people are confused by this key. Please read `execvp(3)` very carefully! ''; @@ -121,7 +121,7 @@ with lib; EnableGlobbing = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' This flag causes launchd to use the `glob(3)` mechanism to update the program arguments before invocation. ''; }; @@ -129,7 +129,7 @@ with lib; EnableTransactions = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' This flag instructs launchd that the job promises to use `vproc_transaction_begin(3)` and `vproc_transaction_end(3)` to track outstanding transactions that need to be reconciled before the process can safely terminate. If no outstanding transactions are in progress, then launchd is free to @@ -140,7 +140,7 @@ with lib; OnDemand = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' This key was used in Mac OS X 10.4 to control whether a job was kept alive or not. The default was true. This key has been deprecated and replaced in Mac OS X 10.5 and later with the more powerful KeepAlive option. @@ -154,7 +154,7 @@ with lib; SuccessfulExit = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' If true, the job will be restarted as long as the program exits and with an exit status of zero. If false, the job will be restarted in the inverse condition. This key implies that "RunAtLoad" is set to true, since the job needs to run at least once before we can get an exit status. @@ -164,7 +164,7 @@ with lib; NetworkState = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' If true, the job will be kept alive as long as the network is up, where up is defined as at least one non-loopback interface being up and having IPv4 or IPv6 addresses assigned to them. If false, the job will be kept alive in the inverse condition. @@ -174,7 +174,7 @@ with lib; PathState = mkOption { type = types.nullOr (types.attrsOf types.bool); default = null; - description = lib.mdDoc '' + description = '' Each key in this dictionary is a file-system path. If the value of the key is true, then the job will be kept alive as long as the path exists. If false, the job will be kept alive in the inverse condition. The intent of this feature is that two or more jobs may create semaphores in @@ -185,7 +185,7 @@ with lib; OtherJobEnabled = mkOption { type = types.nullOr (types.attrsOf types.bool); default = null; - description = lib.mdDoc '' + description = '' Each key in this dictionary is the label of another job. If the value of the key is true, then this job is kept alive as long as that other job is enabled. Otherwise, if the value is false, then this job is kept alive as long as the other job is disabled. This feature should not be @@ -196,7 +196,7 @@ with lib; Crashed = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' If true, the the job will be restarted as long as it exited due to a signal which is typically associated with a crash (SIGILL, SIGSEGV, etc.). If false, the job will be restarted in the inverse condition. @@ -211,7 +211,7 @@ with lib; }; })); default = null; - description = lib.mdDoc '' + description = '' This optional key is used to control whether your job is to be kept continuously running or to let demand and conditions control the invocation. The default is false and therefore only demand will start the job. The value may be set to true to unconditionally keep the job alive. Alternatively, a dictionary @@ -226,7 +226,7 @@ with lib; RunAtLoad = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' This optional key is used to control whether your job is launched once at the time the job is loaded. The default is false. ''; @@ -235,7 +235,7 @@ with lib; RootDirectory = mkOption { type = types.nullOr types.str; default = null; - description = lib.mdDoc '' + description = '' This optional key is used to specify a directory to `chroot(2)` to before running the job. ''; }; @@ -243,7 +243,7 @@ with lib; WorkingDirectory = mkOption { type = types.nullOr types.str; default = null; - description = lib.mdDoc '' + description = '' This optional key is used to specify a directory to `chdir(2)` to before running the job. ''; }; @@ -251,7 +251,7 @@ with lib; EnvironmentVariables = mkOption { type = types.nullOr (types.attrsOf types.str); default = null; - description = lib.mdDoc '' + description = '' This optional key is used to specify additional environment variables to be set before running the job. ''; @@ -260,7 +260,7 @@ with lib; Umask = mkOption { type = types.nullOr types.int; default = null; - description = lib.mdDoc '' + description = '' This optional key specifies what value should be passed to `umask(2)` before running the job. Known bug: Property lists don't support octal, so please convert the value to decimal. ''; @@ -269,7 +269,7 @@ with lib; TimeOut = mkOption { type = types.nullOr types.int; default = null; - description = lib.mdDoc '' + description = '' The recommended idle time out (in seconds) to pass to the job. If no value is specified, a default time out will be supplied by launchd for use by the job at check in time. ''; @@ -278,7 +278,7 @@ with lib; ExitTimeOut = mkOption { type = types.nullOr types.int; default = null; - description = lib.mdDoc '' + description = '' The amount of time launchd waits before sending a SIGKILL signal. The default value is 20 seconds. The value zero is interpreted as infinity. ''; @@ -287,7 +287,7 @@ with lib; ThrottleInterval = mkOption { type = types.nullOr types.int; default = null; - description = lib.mdDoc '' + description = '' This key lets one override the default throttling policy imposed on jobs by launchd. The value is in seconds, and by default, jobs will not be spawned more than once every 10 seconds. The principle behind this is that jobs should linger around just in case they are needed again in the near future. @@ -299,7 +299,7 @@ with lib; InitGroups = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' This optional key specifies whether `initgroups(3)` should be called before running the job. The default is true in 10.5 and false in 10.4. This key will be ignored if the UserName key is not set. ''; @@ -308,7 +308,7 @@ with lib; WatchPaths = mkOption { type = types.nullOr (types.listOf types.path); default = null; - description = lib.mdDoc '' + description = '' This optional key causes the job to be started if any one of the listed paths are modified. ''; }; @@ -316,7 +316,7 @@ with lib; QueueDirectories = mkOption { type = types.nullOr (types.listOf types.str); default = null; - description = lib.mdDoc '' + description = '' Much like the WatchPaths option, this key will watch the paths for modifications. The difference being that the job will only be started if the path is a directory and the directory is not empty. ''; @@ -325,7 +325,7 @@ with lib; StartOnMount = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' This optional key causes the job to be started every time a filesystem is mounted. ''; }; @@ -333,7 +333,7 @@ with lib; StartInterval = mkOption { type = types.nullOr types.int; default = null; - description = lib.mdDoc '' + description = '' This optional key causes the job to be started every N seconds. If the system is asleep, the job will be started the next time the computer wakes up. If multiple intervals transpire before the computer is woken, those events will be coalesced into one event upon wake from sleep. @@ -342,66 +342,63 @@ with lib; StartCalendarInterval = mkOption { default = null; - example = { Hour = 2; Minute = 30; }; - description = lib.mdDoc '' + example = [{ Hour = 2; Minute = 30; }]; + description = '' This optional key causes the job to be started every calendar interval as specified. Missing arguments are considered to be wildcard. The semantics are much like `crontab(5)`. Unlike cron which skips job invocations when the computer is asleep, launchd will start the job the next time the computer wakes up. If multiple intervals transpire before the computer is woken, those events will be coalesced into one event upon wake from sleep. ''; - type = let - submod = types.submodule { - options = { - Minute = mkOption { - type = types.nullOr (types.ints.between 0 59); - default = null; - description = lib.mdDoc '' - The minute on which this job will be run. - ''; - }; - - Hour = mkOption { - type = types.nullOr (types.ints.between 0 23); - default = null; - description = lib.mdDoc '' - The hour on which this job will be run. - ''; - }; - - Day = mkOption { - type = types.nullOr (types.ints.between 1 31); - default = null; - description = lib.mdDoc '' - The day on which this job will be run. - ''; - }; - - Weekday = mkOption { - type = types.nullOr (types.ints.between 0 7); - default = null; - description = lib.mdDoc '' - The weekday on which this job will be run (0 and 7 are Sunday). - ''; - }; - - Month = mkOption { - type = types.nullOr (types.ints.between 1 12); - default = null; - description = lib.mdDoc '' - The month on which this job will be run. - ''; - }; + type = types.nullOr (types.listOf (types.submodule { + options = { + Minute = mkOption { + type = types.nullOr types.int; + default = null; + description = '' + The minute on which this job will be run. + ''; + }; + + Hour = mkOption { + type = types.nullOr types.int; + default = null; + description = '' + The hour on which this job will be run. + ''; + }; + + Day = mkOption { + type = types.nullOr types.int; + default = null; + description = '' + The day on which this job will be run. + ''; + }; + + Weekday = mkOption { + type = types.nullOr types.int; + default = null; + description = '' + The weekday on which this job will be run (0 and 7 are Sunday). + ''; + }; + + Month = mkOption { + type = types.nullOr types.int; + default = null; + description = '' + The month on which this job will be run. + ''; }; }; - in - types.nullOr (types.either submod (types.addCheck (types.listOf submod) (x: x != []))); + })); }; StandardInPath = mkOption { type = types.nullOr types.path; default = null; - description = lib.mdDoc '' + description = '' This optional key specifies what file should be used for data being supplied to stdin when using `stdio(3)`. ''; @@ -410,7 +407,7 @@ with lib; StandardOutPath = mkOption { type = types.nullOr types.path; default = null; - description = lib.mdDoc '' + description = '' This optional key specifies what file should be used for data being sent to stdout when using `stdio(3)`. ''; }; @@ -418,7 +415,7 @@ with lib; StandardErrorPath = mkOption { type = types.nullOr types.path; default = null; - description = lib.mdDoc '' + description = '' This optional key specifies what file should be used for data being sent to stderr when using `stdio(3)`. ''; }; @@ -426,7 +423,7 @@ with lib; Debug = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' This optional key specifies that launchd should adjust its log mask temporarily to LOG_DEBUG while dealing with this job. ''; @@ -435,7 +432,7 @@ with lib; WaitForDebugger = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' This optional key specifies that launchd should instruct the kernel to have the job wait for a debugger to attach before any code in the job is executed. ''; @@ -443,7 +440,7 @@ with lib; SoftResourceLimits = mkOption { default = null; - description = lib.mdDoc '' + description = '' Resource limits to be imposed on the job. These adjust variables set with `setrlimit(2)`. The following keys apply: ''; @@ -452,7 +449,7 @@ with lib; Core = mkOption { type = types.nullOr types.int; default = null; - description = lib.mdDoc '' + description = '' The largest size (in bytes) core file that may be created. ''; }; @@ -460,7 +457,7 @@ with lib; CPU = mkOption { type = types.nullOr types.int; default = null; - description = lib.mdDoc '' + description = '' The maximum amount of cpu time (in seconds) to be used by each process. ''; }; @@ -468,7 +465,7 @@ with lib; Data = mkOption { type = types.nullOr types.int; default = null; - description = lib.mdDoc '' + description = '' The maximum size (in bytes) of the data segment for a process; this defines how far a program may extend its break with the `sbrk(2)` system call. ''; @@ -477,7 +474,7 @@ with lib; FileSize = mkOption { type = types.nullOr types.int; default = null; - description = lib.mdDoc '' + description = '' The largest size (in bytes) file that may be created. ''; }; @@ -485,7 +482,7 @@ with lib; MemoryLock = mkOption { type = types.nullOr types.int; default = null; - description = lib.mdDoc '' + description = '' The maximum size (in bytes) which a process may lock into memory using the mlock(2) function. ''; }; @@ -493,7 +490,7 @@ with lib; NumberOfFiles = mkOption { type = types.nullOr types.int; default = null; - description = lib.mdDoc '' + description = '' The maximum number of open files for this process. Setting this value in a system wide daemon will set the `sysctl(3)` kern.maxfiles (SoftResourceLimits) or kern.maxfilesperproc (HardResourceLimits) value in addition to the `setrlimit(2)` values. @@ -503,7 +500,7 @@ with lib; NumberOfProcesses = mkOption { type = types.nullOr types.int; default = null; - description = lib.mdDoc '' + description = '' The maximum number of simultaneous processes for this user id. Setting this value in a system wide daemon will set the `sysctl(3)` kern.maxproc (SoftResourceLimits) or kern.maxprocperuid (HardResourceLimits) value in addition to the `setrlimit(2)` values. @@ -513,7 +510,7 @@ with lib; ResidentSetSize = mkOption { type = types.nullOr types.int; default = null; - description = lib.mdDoc '' + description = '' The maximum size (in bytes) to which a process's resident set size may grow. This imposes a limit on the amount of physical memory to be given to a process; if memory is tight, the system will prefer to take memory from processes that are exceeding their declared resident set size. @@ -523,7 +520,7 @@ with lib; Stack = mkOption { type = types.nullOr types.int; default = null; - description = lib.mdDoc '' + description = '' The maximum size (in bytes) of the stack segment for a process; this defines how far a program's stack segment may be extended. Stack extension is performed automatically by the system. ''; @@ -535,7 +532,7 @@ with lib; HardResourceLimits = mkOption { default = null; example = { NumberOfFiles = 4096; }; - description = lib.mdDoc '' + description = '' Resource limits to be imposed on the job. These adjust variables set with `setrlimit(2)`. The following keys apply: ''; @@ -544,7 +541,7 @@ with lib; Core = mkOption { type = types.nullOr types.int; default = null; - description = lib.mdDoc '' + description = '' The largest size (in bytes) core file that may be created. ''; }; @@ -552,7 +549,7 @@ with lib; CPU = mkOption { type = types.nullOr types.int; default = null; - description = lib.mdDoc '' + description = '' The maximum amount of cpu time (in seconds) to be used by each process. ''; }; @@ -560,7 +557,7 @@ with lib; Data = mkOption { type = types.nullOr types.int; default = null; - description = lib.mdDoc '' + description = '' The maximum size (in bytes) of the data segment for a process; this defines how far a program may extend its break with the `sbrk(2)` system call. ''; @@ -569,7 +566,7 @@ with lib; FileSize = mkOption { type = types.nullOr types.int; default = null; - description = lib.mdDoc '' + description = '' The largest size (in bytes) file that may be created. ''; }; @@ -577,7 +574,7 @@ with lib; MemoryLock = mkOption { type = types.nullOr types.int; default = null; - description = lib.mdDoc '' + description = '' The maximum size (in bytes) which a process may lock into memory using the `mlock(2)` function. ''; }; @@ -585,7 +582,7 @@ with lib; NumberOfFiles = mkOption { type = types.nullOr types.int; default = null; - description = lib.mdDoc '' + description = '' The maximum number of open files for this process. Setting this value in a system wide daemon will set the `sysctl(3)` kern.maxfiles (SoftResourceLimits) or kern.maxfilesperproc (HardResourceLimits) value in addition to the `setrlimit(2)` values. @@ -595,7 +592,7 @@ with lib; NumberOfProcesses = mkOption { type = types.nullOr types.int; default = null; - description = lib.mdDoc '' + description = '' The maximum number of simultaneous processes for this user id. Setting this value in a system wide daemon will set the `sysctl(3)` kern.maxproc (SoftResourceLimits) or kern.maxprocperuid (HardResourceLimits) value in addition to the `setrlimit(2)` values. @@ -605,7 +602,7 @@ with lib; ResidentSetSize = mkOption { type = types.nullOr types.int; default = null; - description = lib.mdDoc '' + description = '' The maximum size (in bytes) to which a process's resident set size may grow. This imposes a limit on the amount of physical memory to be given to a process; if memory is tight, the system will prefer to take memory from processes that are exceeding their declared resident set size. @@ -615,7 +612,7 @@ with lib; Stack = mkOption { type = types.nullOr types.int; default = null; - description = lib.mdDoc '' + description = '' The maximum size (in bytes) of the stack segment for a process; this defines how far a program's stack segment may be extended. Stack extension is performed automatically by the system. ''; @@ -627,7 +624,7 @@ with lib; Nice = mkOption { type = types.nullOr types.int; default = null; - description = lib.mdDoc '' + description = '' This optional key specifies what nice(3) value should be applied to the daemon. ''; }; @@ -636,7 +633,7 @@ with lib; type = types.nullOr (types.enum [ "Background" "Standard" "Adaptive" "Interactive" ]); default = null; example = "Background"; - description = lib.mdDoc '' + description = '' This optional key describes, at a high level, the intended purpose of the job. The system will apply resource limits based on what kind of job it is. If left unspecified, the system will apply light resource limits to the job, throttling its CPU usage and I/O bandwidth. The following are valid values: @@ -663,7 +660,7 @@ with lib; AbandonProcessGroup = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' When a job dies, launchd kills any remaining processes with the same process group ID as the job. Setting this key to true disables that behavior. ''; @@ -672,7 +669,7 @@ with lib; LowPriorityIO = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' This optional key specifies whether the kernel should consider this daemon to be low priority when doing file system I/O. ''; @@ -681,7 +678,7 @@ with lib; LaunchOnlyOnce = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' This optional key specifies whether the job can only be run once and only once. In other words, if the job cannot be safely respawned without a full machine reboot, then set this key to be true. ''; @@ -690,7 +687,7 @@ with lib; MachServices = mkOption { default = null; example = { "org.nixos.service" = { ResetAtClose = true; }; }; - description = lib.mdDoc '' + description = '' This optional key is used to specify Mach services to be registered with the Mach bootstrap sub-system. Each key in this dictionary should be the name of service to be advertised. The value of the key must be a boolean and set to true. Alternatively, a dictionary can be used instead of a simple true value. @@ -703,7 +700,7 @@ with lib; ResetAtClose = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' If this boolean is false, the port is recycled, thus leaving clients to remain oblivious to the demand nature of job. If the value is set to true, clients receive port death notifications when the job lets go of the receive right. The port will be recreated atomically with respect to bootstrap_look_up() @@ -716,7 +713,7 @@ with lib; HideUntilCheckIn = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Reserve the name in the namespace, but cause bootstrap_look_up() to fail until the job has checked in with launchd. ''; @@ -728,7 +725,7 @@ with lib; LaunchEvents = mkOption { type = types.nullOr (types.attrs); default = null; - description = lib.mdDoc '' + description = '' Specifies higher-level event types to be used as launch-on-demand event sources. Each sub-dictionary defines events for a particular event subsystem, such as "com.apple.iokit.matching", which can be used to @@ -753,7 +750,7 @@ with lib; ServiceIPC = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' This optional key specifies whether the job participates in advanced communication with launchd. The default is false. This flag is incompatible with the inetdCompatibility key. @@ -763,7 +760,7 @@ with lib; SessionCreate = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' This key specifies that the job should be spawned into a new security audit session rather than the default session for the context is belongs to. See auditon(2) for details. @@ -772,7 +769,7 @@ with lib; Sockets = mkOption { default = null; - description = lib.mdDoc '' + description = '' This optional key is used to specify launch on demand sockets that can be used to let launchd know when to run the job. The job must check-in to get a copy of the file descriptors using APIs outlined in launch(3). The keys of the top level Sockets dictionary can be anything. They are meant for the application @@ -789,7 +786,7 @@ with lib; SockType = mkOption { type = types.nullOr (types.enum [ "stream" "dgram" "seqpacket" ]); default = null; - description = lib.mdDoc '' + description = '' This optional key tells launchctl what type of socket to create. The default is "stream" and other valid values for this key are "dgram" and "seqpacket" respectively. ''; @@ -798,7 +795,7 @@ with lib; SockPassive = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' This optional key specifies whether `listen(2)` or `connect(2)` should be called on the created file descriptor. The default is true ("to listen"). ''; @@ -807,7 +804,7 @@ with lib; SockNodeName = mkOption { type = types.nullOr types.str; default = null; - description = lib.mdDoc '' + description = '' This optional key specifies the node to `connect(2)` or `bind(2)` to. ''; }; @@ -815,7 +812,7 @@ with lib; SockServiceName = mkOption { type = types.nullOr types.str; default = null; - description = lib.mdDoc '' + description = '' This optional key specifies the service on the node to `connect(2)` or `bind(2)` to. ''; }; @@ -823,7 +820,7 @@ with lib; SockFamily = mkOption { type = types.nullOr (types.enum [ "IPv4" "IPv6" ]); default = null; - description = lib.mdDoc '' + description = '' This optional key can be used to specifically request that "IPv4" or "IPv6" socket(s) be created. ''; }; @@ -831,7 +828,7 @@ with lib; SockProtocol = mkOption { type = types.nullOr (types.enum [ "TCP" ]); default = null; - description = lib.mdDoc '' + description = '' This optional key specifies the protocol to be passed to `socket(2)`. The only value understood by this key at the moment is "TCP". ''; @@ -840,7 +837,7 @@ with lib; SockPathName = mkOption { type = types.nullOr types.path; default = null; - description = lib.mdDoc '' + description = '' This optional key implies SockFamily is set to "Unix". It specifies the path to `connect(2)` or `bind(2)` to. ''; @@ -849,7 +846,7 @@ with lib; SecureSocketWithKey = mkOption { type = types.nullOr types.str; default = null; - description = lib.mdDoc '' + description = '' This optional key is a variant of SockPathName. Instead of binding to a known path, a securely generated socket is created and the path is assigned to the environment variable that is inherited by all jobs spawned by launchd. @@ -859,7 +856,7 @@ with lib; SockPathMode = mkOption { type = types.nullOr types.int; default = null; - description = lib.mdDoc '' + description = '' This optional key specifies the mode of the socket. Known bug: Property lists don't support octal, so please convert the value to decimal. ''; @@ -868,7 +865,7 @@ with lib; Bonjour = mkOption { type = types.nullOr (types.either types.bool (types.listOf types.str)); default = null; - description = lib.mdDoc '' + description = '' This optional key can be used to request that the service be registered with the `mDNSResponder(8)`. If the value is boolean, the service name is inferred from the SockServiceName. ''; @@ -877,7 +874,7 @@ with lib; MulticastGroup = mkOption { type = types.nullOr types.str; default = null; - description = lib.mdDoc '' + description = '' This optional key can be used to request that the datagram socket join a multicast group. If the value is a hostname, then `getaddrinfo(3)` will be used to join the correct multicast address for a given socket family. If an explicit IPv4 or IPv6 address is given, it is required that the SockFamily diff --git a/modules/launchd/lib.nix b/modules/launchd/lib.nix deleted file mode 100644 index 65fc03639..000000000 --- a/modules/launchd/lib.nix +++ /dev/null @@ -1,57 +0,0 @@ -{ lib }: - -with lib; - -let - - attrFilter = name: value: name != "_module" && value != null; - -in - -rec { - - toPLIST = x: '' - - - - '' + pprExpr "" x - + "\n"; - - pprExpr = ind: x: - if isNull x then "" else - if isBool x then pprBool ind x else - if isInt x then pprInt ind x else - if isString x then pprStr ind x else - if isList x then pprList ind x else - if isAttrs x then pprAttrs ind x else - throw "invalid plist type"; - - pprLiteral = ind: x: ind + x; - - pprBool = ind: x: pprLiteral ind (if x then "" else ""); - pprInt = ind: x: pprLiteral ind "${toString x}"; - pprStr = ind: x: pprLiteral ind "${x}"; - pprKey = ind: x: pprLiteral ind "${x}"; - - pprIndent = ind: (pprExpr "\t${ind}"); - - pprItem = ind: concatMapStringsSep "\n" (pprIndent ind); - - pprList = ind: x: concatStringsSep "\n" [ - (pprLiteral ind "") - (pprItem ind x) - (pprLiteral ind "") - ]; - - pprAttrs = ind: x: concatStringsSep "\n" [ - (pprLiteral ind "") - (pprAttr ind x) - (pprLiteral ind "") - ]; - - pprAttr = ind: x: concatStringsSep "\n" (flatten (mapAttrsToList (name: value: optional (attrFilter name value) [ - (pprKey "\t${ind}" name) - (pprExpr "\t${ind}" value) - ]) x)); - -} diff --git a/modules/lib/write-text.nix b/modules/lib/write-text.nix index b8f2ad55a..2fe02aff7 100644 --- a/modules/lib/write-text.nix +++ b/modules/lib/write-text.nix @@ -16,7 +16,7 @@ in enable = mkOption { type = types.bool; default = true; - description = lib.mdDoc '' + description = '' Whether this file should be generated. This option allows specific files to be disabled. ''; @@ -25,7 +25,7 @@ in text = mkOption { type = types.lines; default = ""; - description = lib.mdDoc '' + description = '' Text of the file. ''; }; @@ -33,14 +33,14 @@ in target = mkOption { type = types.str; default = name; - description = lib.mdDoc '' + description = '' Name of symlink. Defaults to the attribute name. ''; }; source = mkOption { type = types.path; - description = lib.mdDoc '' + description = '' Path of the source file. ''; }; @@ -48,7 +48,7 @@ in copy = mkOption { type = types.bool; default = false; - description = lib.mdDoc '' + description = '' Whether this file should be copied instead of symlinking. ''; }; diff --git a/modules/meta.nix b/modules/meta.nix index 0adc3fb0b..f259469cf 100644 --- a/modules/meta.nix +++ b/modules/meta.nix @@ -34,8 +34,8 @@ in type = listOfMaintainers; internal = true; default = []; - example = [ lib.maintainers.all ]; - description = lib.mdDoc '' + example = [ lib.maintainers.lnl7 ]; + description = '' List of maintainers of each module. This option should be defined at most once per module. diff --git a/modules/misc/ids.nix b/modules/misc/ids.nix index 0bccdbc06..07f1240b0 100644 --- a/modules/misc/ids.nix +++ b/modules/misc/ids.nix @@ -18,7 +18,7 @@ in ids.uids = lib.mkOption { internal = true; - description = lib.mdDoc '' + description = '' The user IDs used in NixOS. ''; type = types.attrsOf types.int; @@ -26,7 +26,7 @@ in ids.gids = lib.mkOption { internal = true; - description = lib.mdDoc '' + description = '' The group IDs used in NixOS. ''; type = types.attrsOf types.int; diff --git a/modules/misc/lib.nix b/modules/misc/lib.nix index 3599661f6..e50794ccc 100644 --- a/modules/misc/lib.nix +++ b/modules/misc/lib.nix @@ -7,7 +7,7 @@ type = lib.types.attrsOf lib.types.attrs; - description = lib.mdDoc '' + description = '' This option allows modules to define helper functions, constants, etc. ''; }; diff --git a/modules/module-list.nix b/modules/module-list.nix index 93c63bf81..e87f696ca 100644 --- a/modules/module-list.nix +++ b/modules/module-list.nix @@ -7,6 +7,7 @@ ./security/pam.nix ./security/pki ./security/sandbox + ./security/sudo.nix ./system ./system/base.nix ./system/checks.nix @@ -34,8 +35,10 @@ ./system/etc.nix ./system/keyboard.nix ./system/launchd.nix + ./system/nvram.nix ./system/patches.nix ./system/shells.nix + ./system/startup.nix ./system/version.nix ./time ./networking @@ -54,6 +57,7 @@ ./services/dnsmasq.nix ./services/emacs.nix ./services/eternal-terminal.nix + ./services/github-runner ./services/gitlab-runner.nix ./services/hercules-ci-agent ./services/ipfs.nix @@ -67,6 +71,7 @@ ./services/netbird.nix ./services/nix-daemon.nix ./services/nix-gc + ./services/nix-optimise ./services/ofborg ./services/postgresql ./services/privoxy @@ -78,10 +83,12 @@ ./services/synapse-bt.nix ./services/synergy ./services/tailscale.nix + ./services/trezord.nix ./services/wg-quick.nix ./services/yabai ./services/nextdns ./programs/bash + ./programs/direnv.nix ./programs/fish.nix ./programs/gnupg.nix ./programs/man.nix diff --git a/modules/networking/default.nix b/modules/networking/default.nix index af82c39bd..1065c2688 100644 --- a/modules/networking/default.nix +++ b/modules/networking/default.nix @@ -29,7 +29,7 @@ in type = types.nullOr types.str; default = null; example = "John’s MacBook Pro"; - description = lib.mdDoc '' + description = '' The user-friendly name for the system, set in System Preferences > Sharing > Computer Name. Setting this option is equivalent to running `scutil --set ComputerName`. @@ -42,7 +42,7 @@ in type = types.nullOr (types.strMatching hostnameRegEx); default = null; example = "Johns-MacBook-Pro"; - description = lib.mdDoc '' + description = '' The hostname of your system, as visible from the command line and used by local and remote networks when connecting through SSH and Remote Login. @@ -56,7 +56,7 @@ in type = types.nullOr (types.strMatching hostnameRegEx); default = cfg.hostName; example = "Johns-MacBook-Pro"; - description = lib.mdDoc '' + description = '' The local hostname, or local network name, is displayed beneath the computer's name at the top of the Sharing preferences pane. It identifies your Mac to Bonjour-compatible services. @@ -74,7 +74,7 @@ in type = types.listOf types.str; default = []; example = [ "Wi-Fi" "Ethernet Adaptor" "Thunderbolt Ethernet" ]; - description = lib.mdDoc '' + description = '' List of networkservices that should be configured. To display a list of all the network services on the server's @@ -86,13 +86,13 @@ in type = types.listOf types.str; default = []; example = [ "8.8.8.8" "8.8.4.4" "2001:4860:4860::8888" "2001:4860:4860::8844" ]; - description = lib.mdDoc "The list of dns servers used when resolving domain names."; + description = "The list of dns servers used when resolving domain names."; }; networking.search = mkOption { type = types.listOf types.str; default = []; - description = lib.mdDoc "The list of search paths used when resolving domain names."; + description = "The list of search paths used when resolving domain names."; }; }; @@ -107,13 +107,13 @@ in echo "configuring networking..." >&2 ${optionalString (cfg.computerName != null) '' - scutil --set ComputerName '${cfg.computerName}' + scutil --set ComputerName ${escapeShellArg cfg.computerName} ''} ${optionalString (cfg.hostName != null) '' - scutil --set HostName '${cfg.hostName}' + scutil --set HostName ${escapeShellArg cfg.hostName} ''} ${optionalString (cfg.localHostName != null) '' - scutil --set LocalHostName '${cfg.localHostName}' + scutil --set LocalHostName ${escapeShellArg cfg.localHostName} ''} ${setNetworkServices} diff --git a/modules/nix/default.nix b/modules/nix/default.nix index ace3fddd4..2213a38f2 100644 --- a/modules/nix/default.nix +++ b/modules/nix/default.nix @@ -62,13 +62,17 @@ let if pkgs.stdenv.hostPlatform != pkgs.stdenv.buildPlatform then '' echo "Ignoring validation for cross-compilation" '' - else '' + else + let + showCommand = if isNixAtLeast "2.20pre" then "config show" else "show-config"; + in + '' echo "Validating generated nix.conf" ln -s $out ./nix.conf set -e set +o pipefail NIX_CONF_DIR=$PWD \ - ${cfg.package}/bin/nix show-config ${optionalString (isNixAtLeast "2.3pre") "--no-net"} \ + ${cfg.package}/bin/nix ${showCommand} ${optionalString (isNixAtLeast "2.3pre") "--no-net"} \ ${optionalString (isNixAtLeast "2.4pre") "--option experimental-features nix-command"} \ |& sed -e 's/^warning:/error:/' \ | (! grep '${if cfg.checkConfig then "^error:" else "^error: unknown setting"}') @@ -165,7 +169,7 @@ in type = types.package; default = pkgs.nix; defaultText = literalExpression "pkgs.nix"; - description = lib.mdDoc '' + description = '' This option specifies the Nix package instance to use throughout the system. ''; }; @@ -174,7 +178,7 @@ in useDaemon = mkOption { type = types.bool; default = false; - description = lib.mdDoc '' + 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. @@ -184,7 +188,7 @@ in distributedBuilds = mkOption { type = types.bool; default = false; - description = lib.mdDoc '' + description = '' Whether to distribute builds to the machines listed in {option}`nix.buildMachines`. @@ -197,7 +201,7 @@ in daemonProcessType = mkOption { type = types.enum [ "Background" "Standard" "Adaptive" "Interactive" ]; default = "Standard"; - description = lib.mdDoc '' + description = '' Nix daemon process resource limits class. These limits propagate to build processes. `Standard` is the default process type and will apply light resource limits, throttling its CPU usage and I/O @@ -212,7 +216,7 @@ in daemonIOLowPriority = mkOption { type = types.bool; default = false; - description = lib.mdDoc '' + description = '' Whether the Nix daemon process should considered to be low priority when doing file system I/O. ''; @@ -224,7 +228,7 @@ in hostName = mkOption { type = types.str; example = "nixbuilder.example.org"; - description = lib.mdDoc '' + description = '' The hostname of the build machine. ''; }; @@ -232,7 +236,7 @@ in type = types.enum [ null "ssh" "ssh-ng" ]; default = "ssh"; example = "ssh-ng"; - description = lib.mdDoc '' + description = '' The protocol used for communicating with the build machine. Use `ssh-ng` if your remote builder and your local Nix version support that improved protocol. @@ -245,7 +249,7 @@ in type = types.nullOr types.str; default = null; example = "x86_64-linux"; - description = lib.mdDoc '' + description = '' The system type the build machine can execute derivations on. Either this attribute or {var}`systems` must be present, where {var}`system` takes precedence if @@ -256,7 +260,7 @@ in type = types.listOf types.str; default = [ ]; example = [ "x86_64-linux" "aarch64-linux" ]; - description = lib.mdDoc '' + description = '' The system types the build machine can execute derivations on. Either this attribute or {var}`system` must be present, where {var}`system` takes precedence if @@ -267,7 +271,7 @@ in type = types.nullOr types.str; default = null; example = "builder"; - description = lib.mdDoc '' + description = '' The username to log in as on the remote host. This user must be able to log in and run nix commands non-interactively. It must also be privileged to build derivations, so must be included in @@ -278,7 +282,7 @@ in type = types.nullOr types.str; default = null; example = "/root/.ssh/id_buildhost_builduser"; - description = lib.mdDoc '' + description = '' The path to the SSH private key with which to authenticate on the build machine. The private key must not have a passphrase. If null, the building user (root on NixOS machines) must have an @@ -291,7 +295,7 @@ in maxJobs = mkOption { type = types.int; default = 1; - description = lib.mdDoc '' + description = '' The number of concurrent jobs the build 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 @@ -301,7 +305,7 @@ in speedFactor = mkOption { type = types.int; default = 1; - description = lib.mdDoc '' + description = '' The relative speed of this builder. This is an arbitrary integer that indicates the speed of this builder, relative to other builders. Higher is faster. @@ -311,7 +315,7 @@ in type = types.listOf types.str; default = [ ]; example = [ "big-parallel" ]; - description = lib.mdDoc '' + description = '' A list of features mandatory for this builder. The builder will be ignored for derivations that don't require all features in this list. All mandatory features are automatically included in @@ -322,7 +326,7 @@ in type = types.listOf types.str; default = [ ]; example = [ "kvm" "big-parallel" ]; - description = lib.mdDoc '' + description = '' A list of features supported by this builder. The builder will be ignored for derivations that require features not in this list. @@ -331,7 +335,7 @@ in publicHostKey = mkOption { type = types.nullOr types.str; default = null; - description = lib.mdDoc '' + description = '' The (base64-encoded) public host key of this builder. The field is calculated via {command}`base64 -w0 /etc/ssh/ssh_host_type_key.pub`. If null, SSH will use its regular known-hosts file when connecting. @@ -340,7 +344,7 @@ in }; }); default = [ ]; - description = lib.mdDoc '' + description = '' This option lists the machines to be used if distributed builds are enabled (see {option}`nix.distributedBuilds`). Nix will perform derivations on those machines via SSH by copying the @@ -354,21 +358,21 @@ in type = types.attrs; internal = true; default = { }; - description = lib.mdDoc "Environment variables used by Nix."; + description = "Environment variables used by Nix."; }; # Not in NixOS module configureBuildUsers = mkOption { type = types.bool; default = false; - description = lib.mdDoc '' + description = '' Enable configuration for nixbld group and users. ''; }; nrBuildUsers = mkOption { type = types.int; - description = lib.mdDoc '' + description = '' Number of `nixbld` user accounts created to perform secure concurrent builds. If you receive an error message saying that “all build users are currently in use”, @@ -384,7 +388,7 @@ in { darwin-config = "${config.environment.darwinConfig}"; } "/nix/var/nix/profiles/per-user/root/channels" ]; - description = lib.mdDoc '' + description = '' The default Nix expression search path, used by the Nix evaluator to look up paths enclosed in angle brackets (e.g. ``). @@ -398,7 +402,7 @@ in checkConfig = mkOption { type = types.bool; default = true; - description = lib.mdDoc '' + description = '' If enabled (the default), checks for data type mismatches and that Nix can parse the generated nix.conf. ''; @@ -420,25 +424,25 @@ in from = mkOption { type = referenceAttrs; example = { type = "indirect"; id = "nixpkgs"; }; - description = lib.mdDoc "The flake reference to be rewritten."; + description = "The flake reference to be rewritten."; }; to = mkOption { type = referenceAttrs; example = { type = "github"; owner = "my-org"; repo = "my-nixpkgs"; }; - description = lib.mdDoc "The flake reference {option}`from` is rewritten to."; + description = "The flake reference {option}`from` is rewritten to."; }; flake = mkOption { type = types.nullOr types.attrs; default = null; example = literalExpression "nixpkgs"; - description = lib.mdDoc '' + description = '' The flake input {option}`from` is rewritten to. ''; }; exact = mkOption { type = types.bool; default = true; - description = lib.mdDoc '' + description = '' Whether the {option}`from` reference needs to match exactly. If set, a {option}`from` reference like `nixpkgs` does not match with a reference like `nixpkgs/nixos-20.03`. @@ -459,7 +463,7 @@ in } )); default = { }; - description = lib.mdDoc '' + description = '' A system-wide flake registry. ''; }; @@ -471,7 +475,7 @@ in keep-outputs = true keep-derivations = true ''; - description = lib.mdDoc "Additional text appended to {file}`nix.conf`."; + description = "Additional text appended to {file}`nix.conf`."; }; settings = mkOption { @@ -483,7 +487,7 @@ in type = types.either types.int (types.enum [ "auto" ]); default = "auto"; example = 64; - description = lib.mdDoc '' + description = '' This option defines the maximum number of jobs that Nix will try to build in parallel. The default is auto, which means it will use all available logical cores. It is recommend to set it to the total @@ -496,7 +500,7 @@ in type = types.bool; default = false; example = true; - description = lib.mdDoc '' + description = '' If set to true, Nix automatically detects files in the store that have identical contents, and replaces them with hard links to a single copy. This saves disk space. If set to false (the default), you can still run @@ -508,7 +512,7 @@ in type = types.int; default = 0; example = 64; - description = lib.mdDoc '' + description = '' This option defines the maximum number of concurrent tasks during one build. It affects, e.g., -j option for make. The special value 0 means that the builder should use all @@ -521,7 +525,7 @@ in sandbox = mkOption { type = types.either types.bool (types.enum [ "relaxed" ]); default = false; - description = lib.mdDoc '' + description = '' If set, Nix will perform builds in a sandboxed environment that it will set up automatically for each build. This prevents impurities in builds by disallowing access to dependencies outside of the Nix @@ -535,7 +539,7 @@ in type = types.listOf types.str; default = [ ]; example = [ "/dev" "/proc" ]; - description = lib.mdDoc '' + description = '' Directories from the host filesystem to be included in the sandbox. ''; @@ -543,7 +547,7 @@ in substituters = mkOption { type = types.listOf types.str; - description = lib.mdDoc '' + description = '' List of binary cache URLs used to obtain pre-built binaries of Nix packages. @@ -555,7 +559,7 @@ in type = types.listOf types.str; default = [ ]; example = [ "https://hydra.nixos.org/" ]; - description = lib.mdDoc '' + description = '' List of binary cache URLs that non-root users can use (in addition to those specified using {option}`nix.settings.substituters`) by passing @@ -566,7 +570,7 @@ in require-sigs = mkOption { type = types.bool; default = true; - description = lib.mdDoc '' + description = '' If enabled (the default), Nix will only download binaries from binary caches if they are cryptographically signed with any of the keys listed in {option}`nix.settings.trusted-public-keys`. If disabled, signatures are neither @@ -578,7 +582,7 @@ in trusted-public-keys = mkOption { type = types.listOf types.str; example = [ "hydra.nixos.org-1:CNHJZBh9K4tP3EKF6FkkgeVYsS3ohTl+oS0Qa8bezVs=" ]; - description = lib.mdDoc '' + description = '' List of public keys used to sign binary caches. If {option}`nix.settings.trusted-public-keys` is enabled, then Nix will use a binary from a binary cache if and only @@ -592,7 +596,7 @@ in type = types.listOf types.str; default = [ "root" ]; example = [ "root" "alice" "@admin" ]; - description = lib.mdDoc '' + description = '' A list of names of users that have additional rights when connecting to the Nix daemon, such as the ability to specify additional binary caches, or to import unsigned NARs. You @@ -622,7 +626,7 @@ in type = types.listOf types.str; default = [ "*" ]; example = [ "@admin" "@builders" "alice" "bob" ]; - description = lib.mdDoc '' + description = '' A list of names of users (separated by whitespace) that are allowed to connect to the Nix daemon. As with {option}`nix.settings.trusted-users`, you can specify groups by @@ -635,7 +639,7 @@ in }; }; default = { }; - description = lib.mdDoc '' + description = '' Configuration for Nix, see for avalaible options. @@ -671,6 +675,9 @@ in "c06b0c6080dd1d62e61a30cfad100c0cfed2d3bcd378e296632dc3b28b31dc69" # official Nix installer as of 2.0.1 "ff08c12813680da98c4240328f828647b67a65ba7aa89c022bd8072cba862cf1" # official Nix installer as of 2.4 "f3e03d851c240c1aa7daccd144ee929f0f5971982424c868c434eb6030e961d4" # DeterminateSystems Nix installer 0.10.0 + "c6080216f2a170611e339c3f46e4e1d61aaf0d8b417ad93ade8d647da1382c11" # DeterminateSystems Nix installer 0.14.0 + "97f4135d262ca22d65c9554aad795c10a4491fa61b67d9c2430f4d82bbfec9a2" # DeterminateSystems Nix installer 0.15.1 + "5d23e6d7015756c6f300f8cd558ec4d9234ca61deefd4f2478e91a49760b0747" # DeterminateSystems Nix installer 0.16.0+ ]; environment.etc."nix/registry.json".text = builtins.toJSON { diff --git a/modules/nix/linux-builder.nix b/modules/nix/linux-builder.nix index 0d473d33c..176d69eb9 100644 --- a/modules/nix/linux-builder.nix +++ b/modules/nix/linux-builder.nix @@ -8,38 +8,70 @@ let cfg = config.nix.linux-builder; builderWithOverrides = cfg.package.override { - inherit (cfg) modules; + modules = [ cfg.config ]; }; + + # create-builder uses TMPDIR to share files with the builder, notably certs. + # macOS will clean up files in /tmp automatically that haven't been accessed in 3+ days. + # If we let it use /tmp, leaving the computer asleep for 3 days makes the certs vanish. + # So we'll use /run/org.nixos.linux-builder instead and clean it up ourselves. + script = pkgs.writeShellScript "linux-builder-start" '' + export TMPDIR=/run/org.nixos.linux-builder USE_TMPDIR=1 + rm -rf $TMPDIR + mkdir -p $TMPDIR + trap "rm -rf $TMPDIR" EXIT + ${lib.optionalString cfg.ephemeral '' + rm -f ${cfg.workingDirectory}/${builderWithOverrides.nixosConfig.networking.hostName}.qcow2 + ''} + ${builderWithOverrides}/bin/create-builder + ''; in { + imports = [ + (mkRemovedOptionModule [ "nix" "linux-builder" "modules" ] "This option has been replaced with `nix.linux-builder.config` which allows setting options directly like `nix.linux-builder.config.networking.hostName = \"banana\";.") + ]; + options.nix.linux-builder = { - enable = mkEnableOption (lib.mdDoc "Linux builder"); + enable = mkEnableOption "Linux builder"; package = mkOption { type = types.package; default = pkgs.darwin.linux-builder; defaultText = "pkgs.darwin.linux-builder"; - description = lib.mdDoc '' + description = '' This option specifies the Linux builder to use. ''; }; - modules = mkOption { - type = types.listOf types.anything; - default = [ ]; + config = mkOption { + type = types.deferredModule; + default = { }; example = literalExpression '' - [ - ({ config, ... }: + ({ pkgs, ... }: - { - virtualisation.darwin-builder.hostPort = 22; - }) - ] + { + environment.systemPackages = [ pkgs.neovim ]; + }) ''; - description = lib.mdDoc '' - This option specifies extra NixOS modules and configuration for the builder. You should first run the Linux builder - without changing this option otherwise you may not be able to build the Linux builder. + description = '' + This option specifies extra NixOS configuration for the builder. You should first use the Linux builder + without changing the builder configuration otherwise you may not be able to build the Linux builder. + ''; + }; + + mandatoryFeatures = mkOption { + type = types.listOf types.str; + default = []; + defaultText = literalExpression ''[]''; + example = literalExpression ''[ "big-parallel" ]''; + description = '' + A list of features mandatory for the Linux builder. The builder will + be ignored for derivations that don't require all features in + this list. All mandatory features are automatically included in + {var}`supportedFeatures`. + + This sets the corresponding `nix.buildMachines.*.mandatoryFeatures` option. ''; }; @@ -47,12 +79,91 @@ in type = types.ints.positive; default = 1; example = 4; - description = lib.mdDoc '' - This option specifies the maximum number of jobs to run on the Linux builder at once. + description = '' + 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 + machines. This sets the corresponding `nix.buildMachines.*.maxJobs` option. ''; }; + + protocol = mkOption { + type = types.str; + default = "ssh-ng"; + defaultText = literalExpression ''"ssh-ng"''; + example = literalExpression ''"ssh"''; + description = '' + The protocol used for communicating with the build machine. Use + `ssh-ng` if your remote builder and your local Nix version support that + improved protocol. + + Use `null` when trying to change the special localhost builder without a + protocol which is for example used by hydra. + ''; + }; + + speedFactor = mkOption { + type = types.ints.positive; + default = 1; + defaultText = literalExpression ''1''; + description = '' + The relative speed of the Linux builder. This is an arbitrary integer + that indicates the speed of this builder, relative to other + builders. Higher is faster. + + This sets the corresponding `nix.buildMachines.*.speedFactor` option. + ''; + }; + + supportedFeatures = mkOption { + type = types.listOf types.str; + default = [ "kvm" "benchmark" "big-parallel" ]; + defaultText = literalExpression ''[ "kvm" "benchmark" "big-parallel" ]''; + example = literalExpression ''[ "kvm" "big-parallel" ]''; + description = '' + A list of features supported by the Linux builder. The builder will + be ignored for derivations that require features not in this + list. + + This sets the corresponding `nix.buildMachines.*.supportedFeatures` option. + ''; + }; + + systems = mkOption { + type = types.listOf types.str; + default = [ "${stdenv.hostPlatform.uname.processor}-linux" ]; + defaultText = literalExpression ''[ "''${stdenv.hostPlatform.uname.processor}-linux" ]''; + example = literalExpression '' + [ + "x86_64-linux" + "aarch64-linux" + ] + ''; + description = '' + This option specifies system types the build machine can execute derivations on. + + This sets the corresponding `nix.buildMachines.*.systems` option. + ''; + }; + + + workingDirectory = mkOption { + type = types.str; + default = "/var/lib/darwin-builder"; + description = '' + The working directory of the Linux builder daemon process. + ''; + }; + + ephemeral = mkEnableOption '' + wipe the builder's filesystem on every restart. + + This is disabled by default as maintaining the builder's Nix Store reduces + rebuilds. You can enable this if you don't want your builder to accumulate + state. + ''; }; config = mkIf cfg.enable { @@ -65,7 +176,7 @@ in } ]; system.activationScripts.preActivation.text = '' - mkdir -p /var/lib/darwin-builder + mkdir -p ${cfg.workingDirectory} ''; launchd.daemons.linux-builder = { @@ -75,11 +186,11 @@ in serviceConfig = { ProgramArguments = [ "/bin/sh" "-c" - "/bin/wait4path /nix/store && exec ${builderWithOverrides}/bin/create-builder" + "/bin/wait4path /nix/store && exec ${script}" ]; KeepAlive = true; RunAtLoad = true; - WorkingDirectory = "/var/lib/darwin-builder"; + WorkingDirectory = cfg.workingDirectory; }; }; @@ -96,10 +207,8 @@ in hostName = "linux-builder"; sshUser = "builder"; sshKey = "/etc/nix/builder_ed25519"; - system = "${stdenv.hostPlatform.uname.processor}-linux"; - supportedFeatures = [ "kvm" "benchmark" "big-parallel" ]; publicHostKey = "c3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSUpCV2N4Yi9CbGFxdDFhdU90RStGOFFVV3JVb3RpQzVxQkorVXVFV2RWQ2Igcm9vdEBuaXhvcwo="; - inherit (cfg) maxJobs; + inherit (cfg) mandatoryFeatures maxJobs protocol speedFactor supportedFeatures systems; }]; nix.settings.builders-use-substitutes = true; diff --git a/modules/nix/nix-darwin.nix b/modules/nix/nix-darwin.nix index 7f07b458b..ad1ab8fbc 100644 --- a/modules/nix/nix-darwin.nix +++ b/modules/nix/nix-darwin.nix @@ -1,4 +1,4 @@ -{ config, pkgs, ... }: +{ config, pkgs, lib, ... }: let nix-tools = pkgs.callPackage ../../pkgs/nix-tools { @@ -7,22 +7,30 @@ let nixPackage = config.nix.package; }; + darwin-uninstaller = pkgs.callPackage ../../pkgs/darwin-uninstaller { }; + inherit (nix-tools) darwin-option darwin-rebuild darwin-version; in { - config = { + options = { + system.includeUninstaller = lib.mkOption { + type = lib.types.bool; + internal = true; + default = true; + }; + }; + config = { environment.systemPackages = [ # Include nix-tools by default darwin-option darwin-rebuild darwin-version - ]; + ] ++ lib.optional config.system.includeUninstaller darwin-uninstaller; system.build = { inherit darwin-option darwin-rebuild darwin-version; }; - }; } diff --git a/modules/nix/nixpkgs.nix b/modules/nix/nixpkgs.nix index 52aec9a88..8b3e428e7 100644 --- a/modules/nix/nixpkgs.nix +++ b/modules/nix/nixpkgs.nix @@ -143,7 +143,7 @@ in pkgs = mkOption { type = pkgsType; example = literalExpression "import {}"; - description = lib.mdDoc '' + description = '' If set, the pkgs argument to all nix-darwin modules is the value of this option, extended with `nixpkgs.overlays`, if that is also set. The nix-darwin and Nixpkgs architectures must @@ -171,7 +171,7 @@ in { allowBroken = true; allowUnfree = true; } ''; type = configType; - description = lib.mdDoc '' + description = '' The configuration of the Nix Packages collection. (For details, see the Nixpkgs documentation.) It allows you to set package configuration options. @@ -194,7 +194,7 @@ in ] ''; type = types.listOf overlayType; - description = lib.mdDoc '' + 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 @@ -214,7 +214,7 @@ in # 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; - description = lib.mdDoc '' + description = '' Specifies the platform where the nix-darwin configuration will run. To cross-compile, set also `nixpkgs.buildPlatform`. @@ -232,7 +232,7 @@ in apply = lib.systems.elaborate; defaultText = literalExpression ''config.nixpkgs.hostPlatform''; - description = lib.mdDoc '' + 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 change where it's built. Setting this option will cause nix-darwin to be @@ -266,7 +266,7 @@ in defaultText = lib.literalMD '' Traditionally `builtins.currentSystem`, but unset when invoking nix-darwin through `lib.darwinSystem`. ''; - description = lib.mdDoc '' + description = '' Specifies the Nix platform type on which nix-darwin should be built. It is better to specify `nixpkgs.hostPlatform` instead. @@ -281,7 +281,7 @@ in defaultText = literalMD '' `` or nix-darwin's `nixpkgs` flake input ''; - description = lib.mdDoc '' + description = '' The path to import Nixpkgs from. If you're setting a custom [](#opt-nixpkgs.pkgs) or `_module.args.pkgs`, setting this to something with `rev` and `shortRev` attributes (such as a diff --git a/modules/programs/bash/default.nix b/modules/programs/bash/default.nix index 61f82e01a..2e27ff935 100644 --- a/modules/programs/bash/default.nix +++ b/modules/programs/bash/default.nix @@ -12,19 +12,19 @@ in programs.bash.enable = mkOption { type = types.bool; default = true; - description = lib.mdDoc "Whether to configure bash as an interactive shell."; + description = "Whether to configure bash as an interactive shell."; }; programs.bash.interactiveShellInit = mkOption { default = ""; - description = lib.mdDoc "Shell script code called during interactive bash shell initialisation."; + description = "Shell script code called during interactive bash shell initialisation."; type = types.lines; }; programs.bash.enableCompletion = mkOption { type = types.bool; default = false; - description = lib.mdDoc '' + description = '' Enable bash completion for all interactive bash shells. NOTE. This doesn't work with bash 3.2, which is the default on macOS. diff --git a/modules/programs/direnv.nix b/modules/programs/direnv.nix new file mode 100644 index 000000000..243068d89 --- /dev/null +++ b/modules/programs/direnv.nix @@ -0,0 +1,136 @@ +{ + lib, + config, + pkgs, + ... +}: let + cfg = config.programs.direnv; +in { + meta.maintainers = [ + lib.maintainers.mattpolzin or "mattpolzin" + ]; + options.programs.direnv = { + + enable = lib.mkEnableOption '' + direnv integration. Takes care of both installation and + setting up the sourcing of the shell. Additionally enables nix-direnv + integration. + ''; + + package = lib.mkPackageOptionMD pkgs "direnv" {}; + + direnvrcExtra = lib.mkOption { + type = lib.types.lines; + default = ""; + example = '' + export FOO="foo" + echo "loaded direnv!" + ''; + description = '' + Extra lines to append to the sourced direnvrc + ''; + }; + + silent = lib.mkEnableOption '' + the hiding of direnv logging + ''; + + loadInNixShell = + (lib.mkEnableOption '' + loading direnv in `nix-shell` `nix shell` or `nix develop` + '') + // { + default = true; + }; + + nix-direnv = { + enable = + (lib.mkEnableOption '' + a faster, persistent implementation of use_nix and use_flake, to replace the built-in one + '') + // { + default = true; + }; + + package = lib.mkPackageOptionMD pkgs "nix-direnv" {}; + }; + }; + + config = lib.mkIf cfg.enable { + + programs = { + zsh.interactiveShellInit = '' + if ${lib.boolToString cfg.loadInNixShell} || printenv PATH | grep -vqc '/nix/store'; then + eval "$(${lib.getExe cfg.package} hook zsh)" + fi + ''; + + #$NIX_GCROOT for "nix develop" https://github.com/NixOS/nix/blob/6db66ebfc55769edd0c6bc70fcbd76246d4d26e0/src/nix/develop.cc#L530 + #$IN_NIX_SHELL for "nix-shell" + bash.interactiveShellInit = '' + if ${lib.boolToString cfg.loadInNixShell} || [ -z "$IN_NIX_SHELL$NIX_GCROOT$(printenv PATH | grep '/nix/store')" ] ; then + eval "$(${lib.getExe cfg.package} hook bash)" + fi + ''; + + fish.interactiveShellInit = '' + if ${lib.boolToString cfg.loadInNixShell}; + or printenv PATH | grep -vqc '/nix/store'; + ${lib.getExe cfg.package} hook fish | source + end + ''; + }; + + environment = { + systemPackages = + if cfg.loadInNixShell then [cfg.package] + else [ + #direnv has a fish library which sources direnv for some reason + (cfg.package.overrideAttrs (old: { + installPhase = + (old.installPhase or "") + + '' + rm -rf $out/share/fish + ''; + })) + ]; + + variables = { + DIRENV_CONFIG = "/etc/direnv"; + DIRENV_LOG_FORMAT = lib.mkIf cfg.silent ""; + }; + + etc = { + "direnv/direnvrc".text = '' + ${lib.optionalString cfg.nix-direnv.enable '' + #Load nix-direnv + source ${cfg.nix-direnv.package}/share/nix-direnv/direnvrc + ''} + + #Load direnvrcExtra + ${cfg.direnvrcExtra} + + #Load user-configuration if present (~/.direnvrc or ~/.config/direnv/direnvrc) + direnv_config_dir_home="''${DIRENV_CONFIG_HOME:-''${XDG_CONFIG_HOME:-$HOME/.config}/direnv}" + if [[ -f $direnv_config_dir_home/direnvrc ]]; then + source "$direnv_config_dir_home/direnvrc" >&2 + elif [[ -f $HOME/.direnvrc ]]; then + source "$HOME/.direnvrc" >&2 + fi + + unset direnv_config_dir_home + ''; + + "direnv/lib/zz-user.sh".text = '' + direnv_config_dir_home="''${DIRENV_CONFIG_HOME:-''${XDG_CONFIG_HOME:-$HOME/.config}/direnv}" + + for lib in "$direnv_config_dir_home/lib/"*.sh; do + source "$lib" + done + + unset direnv_config_dir_home + ''; + }; + }; + }; +} diff --git a/modules/programs/fish.nix b/modules/programs/fish.nix index 287cc710c..77276e671 100644 --- a/modules/programs/fish.nix +++ b/modules/programs/fish.nix @@ -51,7 +51,7 @@ in enable = mkOption { default = false; - description = lib.mdDoc '' + description = '' Whether to configure fish as an interactive shell. ''; type = types.bool; @@ -60,7 +60,7 @@ in useBabelfish = mkOption { type = types.bool; default = false; - description = lib.mdDoc '' + description = '' If enabled, the configured environment will be translated to native fish using [babelfish](https://github.com/bouk/babelfish). Otherwise, [foreign-env](https://github.com/oh-my-fish/plugin-foreign-env) will be used. ''; @@ -69,7 +69,7 @@ in babelfishPackage = mkOption { type = types.package; default = pkgs.babelfish; - description = lib.mdDoc '' + description = '' The babelfish package to use when useBabelfish is set to true. ''; @@ -78,7 +78,7 @@ in vendor.config.enable = mkOption { type = types.bool; default = true; - description = lib.mdDoc '' + description = '' Whether fish should source configuration snippets provided by other packages. ''; }; @@ -86,7 +86,7 @@ in vendor.completions.enable = mkOption { type = types.bool; default = true; - description = lib.mdDoc '' + description = '' Whether fish should use completion files provided by other packages. ''; }; @@ -94,14 +94,14 @@ in vendor.functions.enable = mkOption { type = types.bool; default = true; - description = lib.mdDoc '' + description = '' Whether fish should autoload fish functions provided by other packages. ''; }; shellAliases = mkOption { default = config.environment.shellAliases; - description = lib.mdDoc '' + description = '' Set of aliases for fish shell. See {option}`environment.shellAliases` for an option format description. ''; @@ -110,7 +110,7 @@ in shellInit = mkOption { default = ""; - description = lib.mdDoc '' + description = '' Shell script code called during fish shell initialisation. ''; type = types.lines; @@ -118,7 +118,7 @@ in loginShellInit = mkOption { default = ""; - description = lib.mdDoc '' + description = '' Shell script code called during fish login shell initialisation. ''; type = types.lines; @@ -126,7 +126,7 @@ in interactiveShellInit = mkOption { default = ""; - description = lib.mdDoc '' + description = '' Shell script code called during interactive fish shell initialisation. ''; type = types.lines; @@ -134,7 +134,7 @@ in promptInit = mkOption { default = ""; - description = lib.mdDoc '' + description = '' Shell script code used to initialise fish prompt. ''; type = types.lines; diff --git a/modules/programs/gnupg.nix b/modules/programs/gnupg.nix index bd2f96c2a..4c451eca5 100644 --- a/modules/programs/gnupg.nix +++ b/modules/programs/gnupg.nix @@ -13,7 +13,7 @@ in agent.enable = mkOption { type = types.bool; default = false; - description = lib.mdDoc '' + description = '' Enables GnuPG agent for every user session. ''; }; @@ -21,7 +21,7 @@ in agent.enableSSHSupport = mkOption { type = types.bool; default = false; - description = lib.mdDoc '' + description = '' Enable SSH agent support in GnuPG agent. Also sets SSH_AUTH_SOCK environment variable correctly. ''; diff --git a/modules/programs/info/default.nix b/modules/programs/info/default.nix index 93aaf7c60..cf857d9fd 100644 --- a/modules/programs/info/default.nix +++ b/modules/programs/info/default.nix @@ -11,7 +11,7 @@ in programs.info.enable = mkOption { type = types.bool; default = true; - description = lib.mdDoc "Whether to enable info pages and the {command}`info` command."; + description = "Whether to enable info pages and the {command}`info` command."; }; }; diff --git a/modules/programs/man.nix b/modules/programs/man.nix index fd0e01868..f15485b8a 100644 --- a/modules/programs/man.nix +++ b/modules/programs/man.nix @@ -8,7 +8,7 @@ with lib; programs.man.enable = mkOption { type = types.bool; default = true; - description = lib.mdDoc '' + description = '' Whether to enable manual pages and the {command}`man` command. This also includes "man" outputs of all `systemPackages`. ''; diff --git a/modules/programs/nix-index/default.nix b/modules/programs/nix-index/default.nix index 0685346c2..b6f86f59e 100644 --- a/modules/programs/nix-index/default.nix +++ b/modules/programs/nix-index/default.nix @@ -11,14 +11,14 @@ in programs.nix-index.enable = mkOption { type = types.bool; default = false; - description = lib.mdDoc "Whether to enable nix-index and its command-not-found helper."; + description = "Whether to enable nix-index and its command-not-found helper."; }; programs.nix-index.package = mkOption { type = types.package; default = pkgs.nix-index; defaultText = "pkgs.nix-index"; - description = lib.mdDoc "This option specifies the nix-index package to use."; + description = "This option specifies the nix-index package to use."; }; }; diff --git a/modules/programs/ssh/default.nix b/modules/programs/ssh/default.nix index 87978e6d3..d1a677014 100644 --- a/modules/programs/ssh/default.nix +++ b/modules/programs/ssh/default.nix @@ -14,7 +14,7 @@ let hostNames = mkOption { type = types.listOf types.str; default = []; - description = lib.mdDoc '' + description = '' A list of host names and/or IP numbers used for accessing the host's ssh service. ''; @@ -23,7 +23,7 @@ let default = null; type = types.nullOr types.str; example = "ecdsa-sha2-nistp521 AAAAE2VjZHN...UEPg=="; - description = lib.mdDoc '' + description = '' The public key data for the host. You can fetch a public key from a running SSH server with the {command}`ssh-keyscan` command. The public key should not include any host names, only @@ -33,7 +33,7 @@ let publicKeyFile = mkOption { default = null; type = types.nullOr types.path; - description = lib.mdDoc '' + description = '' The path to the public key file for the host. The public key file is read at build time and saved in the Nix store. You can fetch a public key file from a running SSH server @@ -54,7 +54,7 @@ let keys = mkOption { type = types.listOf types.str; default = []; - description = lib.mdDoc '' + description = '' A list of verbatim OpenSSH public keys that should be added to the user's authorized keys. The keys are added to a file that the SSH daemon reads in addition to the the user's authorized_keys file. @@ -68,7 +68,7 @@ let keyFiles = mkOption { type = types.listOf types.path; default = []; - description = lib.mdDoc '' + description = '' A list of files each containing one OpenSSH public key that should be added to the user's authorized keys. The contents of the files are read at build time and added to a file that the SSH daemon reads in @@ -106,7 +106,7 @@ in services.openssh.authorizedKeysFiles = mkOption { type = types.listOf types.str; default = []; - description = lib.mdDoc '' + description = '' Specify the rules for which files to read on the host. This is an advanced option. If you're looking to configure user @@ -122,7 +122,7 @@ in programs.ssh.knownHosts = mkOption { default = {}; type = types.attrsOf (types.submodule host); - description = lib.mdDoc '' + description = '' The set of system-wide known SSH hosts. ''; example = literalExpression '' @@ -151,12 +151,13 @@ in services.openssh.authorizedKeysFiles = [ "%h/.ssh/authorized_keys" "/etc/ssh/authorized_keys.d/%u" ]; environment.etc = authKeysFiles // - { "ssh/ssh_known_hosts".text = (flip (concatMapStringsSep "\n") knownHosts - (h: assert h.hostNames != []; - concatStringsSep "," h.hostNames + " " - + (if h.publicKey != null then h.publicKey else readFile h.publicKeyFile) - )) + "\n"; - + { "ssh/ssh_known_hosts" = mkIf (builtins.length knownHosts > 0) { + text = (flip (concatMapStringsSep "\n") knownHosts + (h: assert h.hostNames != []; + concatStringsSep "," h.hostNames + " " + + (if h.publicKey != null then h.publicKey else readFile h.publicKeyFile) + )) + "\n"; + }; "ssh/sshd_config.d/101-authorized-keys.conf" = { text = "AuthorizedKeysFile ${toString config.services.openssh.authorizedKeysFiles}\n"; # Allows us to automatically migrate from using a file to a symlink diff --git a/modules/programs/tmux.nix b/modules/programs/tmux.nix index 7278479c0..ae6fcbf98 100644 --- a/modules/programs/tmux.nix +++ b/modules/programs/tmux.nix @@ -46,47 +46,47 @@ in programs.tmux.enable = mkOption { type = types.bool; default = false; - description = lib.mdDoc "Whether to configure tmux."; + description = "Whether to configure tmux."; }; programs.tmux.enableSensible = mkOption { type = types.bool; default = false; example = true; - description = lib.mdDoc "Enable sensible configuration options for tmux."; + description = "Enable sensible configuration options for tmux."; }; programs.tmux.enableMouse = mkOption { type = types.bool; default = false; example = true; - description = lib.mdDoc "Enable mouse support for tmux."; + description = "Enable mouse support for tmux."; }; programs.tmux.enableFzf = mkOption { type = types.bool; default = false; example = true; - description = lib.mdDoc "Enable fzf keybindings for selecting tmux sessions and panes."; + description = "Enable fzf keybindings for selecting tmux sessions and panes."; }; programs.tmux.enableVim = mkOption { type = types.bool; default = false; example = true; - description = lib.mdDoc "Enable vim style keybindings for copy mode, and navigation of tmux panes."; + description = "Enable vim style keybindings for copy mode, and navigation of tmux panes."; }; programs.tmux.iTerm2 = mkOption { type = types.bool; default = false; example = true; - description = lib.mdDoc "Cater to iTerm2 and its tmux integration, as appropriate."; + description = "Cater to iTerm2 and its tmux integration, as appropriate."; }; programs.tmux.defaultCommand = mkOption { type = types.either types.str types.package; - description = lib.mdDoc "The default command to use for tmux panes."; + description = "The default command to use for tmux panes."; }; programs.tmux.tmuxOptions = mkOption { @@ -98,7 +98,7 @@ in programs.tmux.extraConfig = mkOption { type = types.lines; default = ""; - description = lib.mdDoc "Extra configuration to add to {file}`tmux.conf`."; + description = "Extra configuration to add to {file}`tmux.conf`."; }; }; diff --git a/modules/programs/vim.nix b/modules/programs/vim.nix index d51d0ac3f..345532e51 100644 --- a/modules/programs/vim.nix +++ b/modules/programs/vim.nix @@ -18,14 +18,14 @@ in programs.vim.enable = mkOption { type = types.bool; default = false; - description = lib.mdDoc "Whether to configure vim."; + description = "Whether to configure vim."; }; programs.vim.enableSensible = mkOption { type = types.bool; default = false; example = true; - description = lib.mdDoc "Enable sensible configuration options for vim."; + description = "Enable sensible configuration options for vim."; }; programs.vim.extraKnownPlugins = mkOption { @@ -46,14 +46,14 @@ in }; } ''; - description = lib.mdDoc "Custom plugin declarations to add to VAM's knownPlugins."; + description = "Custom plugin declarations to add to VAM's knownPlugins."; }; programs.vim.plugins = mkOption { type = types.listOf types.attrs; default = []; example = [ { names = [ "surround" "vim-nix" ]; } ]; - description = lib.mdDoc "VAM plugin dictionaries to use for vim_configurable."; + description = "VAM plugin dictionaries to use for vim_configurable."; }; programs.vim.package = mkOption { @@ -70,7 +70,7 @@ in programs.vim.vimConfig = mkOption { type = types.lines; default = ""; - description = lib.mdDoc "Extra vimrcConfig to use for vim_configurable."; + description = "Extra vimrcConfig to use for vim_configurable."; }; }; diff --git a/modules/programs/zsh/default.nix b/modules/programs/zsh/default.nix index 4e983e51d..fb928d632 100644 --- a/modules/programs/zsh/default.nix +++ b/modules/programs/zsh/default.nix @@ -1,9 +1,10 @@ -{ config, lib, pkgs, ... }: +{ config, lib, options, pkgs, ... }: with lib; let cfg = config.programs.zsh; + opt = options.programs.zsh; zshVariables = mapAttrsToList (n: v: ''${n}="${v}"'') cfg.variables; @@ -18,13 +19,13 @@ in programs.zsh.enable = mkOption { type = types.bool; default = false; - description = lib.mdDoc "Whether to configure zsh as an interactive shell."; + description = "Whether to configure zsh as an interactive shell."; }; programs.zsh.variables = mkOption { type = types.attrsOf (types.either types.str (types.listOf types.str)); default = {}; - description = lib.mdDoc '' + description = '' A set of environment variables used in the global environment. These variables will be set on shell initialisation. The value of each variable can be either a string or a list of @@ -37,61 +38,74 @@ in programs.zsh.shellInit = mkOption { type = types.lines; default = ""; - description = lib.mdDoc "Shell script code called during zsh shell initialisation."; + description = "Shell script code called during zsh shell initialisation."; }; programs.zsh.loginShellInit = mkOption { type = types.lines; default = ""; - description = lib.mdDoc "Shell script code called during zsh login shell initialisation."; + description = "Shell script code called during zsh login shell initialisation."; }; programs.zsh.interactiveShellInit = mkOption { type = types.lines; default = ""; - description = lib.mdDoc "Shell script code called during interactive zsh shell initialisation."; + description = "Shell script code called during interactive zsh shell initialisation."; }; programs.zsh.promptInit = mkOption { type = types.lines; default = "autoload -U promptinit && promptinit && prompt walters && setopt prompt_sp"; - description = lib.mdDoc "Shell script code used to initialise the zsh prompt."; + description = "Shell script code used to initialise the zsh prompt."; }; programs.zsh.enableCompletion = mkOption { type = types.bool; default = true; - description = lib.mdDoc "Enable zsh completion for all interactive zsh shells."; + description = "Enable zsh completion for all interactive zsh shells."; }; programs.zsh.enableBashCompletion = mkOption { type = types.bool; default = true; - description = lib.mdDoc "Enable bash completion for all interactive zsh shells."; + description = "Enable bash completion for all interactive zsh shells."; + }; + + programs.zsh.enableGlobalCompInit = mkOption { + type = types.bool; + default = cfg.enableCompletion; + defaultText = literalExpression "config.${opt.enableCompletion}"; + description = '' + Enable execution of compinit call for all interactive zsh shells. + + This option can be disabled if the user wants to extend its + `fpath` and a custom `compinit` + call in the local config is required. + ''; }; programs.zsh.enableFzfCompletion = mkOption { type = types.bool; default = false; - description = lib.mdDoc "Enable fzf completion."; + description = "Enable fzf completion."; }; programs.zsh.enableFzfGit = mkOption { type = types.bool; default = false; - description = lib.mdDoc "Enable fzf keybindings for C-g git browsing."; + description = "Enable fzf keybindings for C-g git browsing."; }; programs.zsh.enableFzfHistory = mkOption { type = types.bool; default = false; - description = lib.mdDoc "Enable fzf keybinding for Ctrl-r history search."; + description = "Enable fzf keybinding for Ctrl-r history search."; }; programs.zsh.enableSyntaxHighlighting = mkOption { type = types.bool; default = false; - description = lib.mdDoc "Enable zsh-syntax-highlighting."; + description = "Enable zsh-syntax-highlighting."; }; }; @@ -175,7 +189,7 @@ in ${cfg.promptInit} - ${optionalString cfg.enableCompletion "autoload -U compinit && compinit"} + ${optionalString cfg.enableGlobalCompInit "autoload -U compinit && compinit"} ${optionalString cfg.enableBashCompletion "autoload -U bashcompinit && bashcompinit"} ${optionalString cfg.enableSyntaxHighlighting @@ -205,5 +219,9 @@ in "2af1b563e389d11b76a651b446e858116d7a20370d9120a7e9f78991f3e5f336" # DeterminateSystems installer ]; + environment.etc."zshenv".knownSha256Hashes = [ + "d07015be6875f134976fce84c6c7a77b512079c1c5f9594dfa65c70b7968b65f" # DeterminateSystems installer + ]; + }; } diff --git a/modules/security/pam.nix b/modules/security/pam.nix index f0c77dc30..69b4c37ed 100644 --- a/modules/security/pam.nix +++ b/modules/security/pam.nix @@ -40,7 +40,7 @@ in { options = { security.pam.enableSudoTouchIdAuth = mkEnableOption "" // { - description = lib.mdDoc '' + description = '' Enable sudo authentication with Touch ID. When enabled, this option adds the following line to diff --git a/modules/security/pki/default.nix b/modules/security/pki/default.nix index a92f2d5bb..00d1f98cb 100644 --- a/modules/security/pki/default.nix +++ b/modules/security/pki/default.nix @@ -21,11 +21,19 @@ in { options = { + security.pki.installCACerts = mkOption { + type = types.bool; + default = true; + description = '' + Whether to enable certificate management with nix-darwin. + ''; + }; + security.pki.certificateFiles = mkOption { type = types.listOf types.path; default = []; example = literalExpression "[ \"\${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt\" ]"; - description = lib.mdDoc '' + description = '' A list of files containing trusted root certificates in PEM format. These are concatenated to form {file}`/etc/ssl/certs/ca-certificates.crt`, which is @@ -49,7 +57,7 @@ in ''' ] ''; - description = lib.mdDoc '' + description = '' A list of trusted root certificates in PEM format. ''; }; @@ -62,7 +70,7 @@ in "CA WoSign ECC Root" "Certification Authority of WoSign G2" ]; - description = lib.mdDoc '' + description = '' A list of blacklisted CA certificate names that won't be imported from the Mozilla Trust Store into {file}`/etc/ssl/certs/ca-certificates.crt`. Use the @@ -71,7 +79,7 @@ in }; }; - config = { + config = mkIf cfg.installCACerts { security.pki.certificateFiles = [ "${cacertPackage}/etc/ssl/certs/ca-bundle.crt" ]; diff --git a/modules/security/sandbox/default.nix b/modules/security/sandbox/default.nix index a80c9f6ff..d6987e65b 100644 --- a/modules/security/sandbox/default.nix +++ b/modules/security/sandbox/default.nix @@ -27,37 +27,37 @@ let type = types.listOf types.package; default = [ ]; apply = paths: pkgs.closureInfo { rootPaths = paths; }; - description = lib.mdDoc "List of store paths to make accessible."; + description = "List of store paths to make accessible."; }; readablePaths = mkOption { type = types.listOf types.path; default = [ ]; - description = lib.mdDoc "List of paths that should be read-only inside the sandbox."; + description = "List of paths that should be read-only inside the sandbox."; }; writablePaths = mkOption { type = types.listOf types.path; default = [ ]; - description = lib.mdDoc "List of paths that should be read/write inside the sandbox."; + description = "List of paths that should be read/write inside the sandbox."; }; allowSystemPaths = mkOption { type = types.bool; default = false; - description = lib.mdDoc "Whether to allow read access to FHS paths like /etc and /var."; + description = "Whether to allow read access to FHS paths like /etc and /var."; }; allowLocalNetworking = mkOption { type = types.bool; default = false; - description = lib.mdDoc "Whether to allow localhost network access inside the sandbox."; + description = "Whether to allow localhost network access inside the sandbox."; }; allowNetworking = mkOption { type = types.bool; default = false; - description = lib.mdDoc "Whether to allow network access inside the sandbox."; + description = "Whether to allow network access inside the sandbox."; }; }; @@ -133,7 +133,7 @@ in security.sandbox.profiles = mkOption { type = types.attrsOf (types.submodule profile); default = { }; - description = lib.mdDoc "Definition of sandbox profiles."; + description = "Definition of sandbox profiles."; }; }; diff --git a/modules/security/sudo.nix b/modules/security/sudo.nix new file mode 100644 index 000000000..5ceaea967 --- /dev/null +++ b/modules/security/sudo.nix @@ -0,0 +1,30 @@ +{ config, lib, ... }: + +with lib; + +let + cfg = config.security.sudo; +in +{ + meta.maintainers = [ + lib.maintainers.samasaur or "samasaur" + ]; + + options = { + security.sudo.extraConfig = mkOption { + type = types.nullOr types.lines; + default = null; + description = '' + Extra configuration text appended to {file}`sudoers`. + ''; + }; + }; + + config = { + environment.etc = { + "sudoers.d/10-nix-darwin-extra-config" = mkIf (cfg.extraConfig != null) { + text = cfg.extraConfig; + }; + }; + }; +} diff --git a/modules/services/activate-system/default.nix b/modules/services/activate-system/default.nix index 19034a162..c41d96379 100644 --- a/modules/services/activate-system/default.nix +++ b/modules/services/activate-system/default.nix @@ -11,7 +11,7 @@ in services.activate-system.enable = mkOption { type = types.bool; default = true; - description = lib.mdDoc "Whether to activate system at boot time."; + description = "Whether to activate system at boot time."; }; }; diff --git a/modules/services/autossh.nix b/modules/services/autossh.nix index 9905d6906..2df74ec65 100644 --- a/modules/services/autossh.nix +++ b/modules/services/autossh.nix @@ -22,18 +22,18 @@ in name = mkOption { type = types.str; example = "socks-peer"; - description = lib.mdDoc "Name of the local AutoSSH session"; + description = "Name of the local AutoSSH session"; }; user = mkOption { type = types.str; example = "bill"; - description = lib.mdDoc "Name of the user the AutoSSH session should run as"; + description = "Name of the user the AutoSSH session should run as"; }; monitoringPort = mkOption { type = types.int; default = 0; example = 20000; - description = lib.mdDoc '' + description = '' Port to be used by AutoSSH for peer monitoring. Note, that AutoSSH also uses mport+1. Value of 0 disables the keep-alive style monitoring @@ -42,7 +42,7 @@ in extraArguments = mkOption { type = types.str; example = "-N -D4343 bill@socks.example.net"; - description = lib.mdDoc '' + description = '' Arguments to be passed to AutoSSH and retransmitted to SSH process. Some meaningful options include -N (don't run remote command), -D (open SOCKS proxy on local port), -R (forward @@ -54,7 +54,7 @@ in }); default = []; - description = lib.mdDoc '' + description = '' List of AutoSSH sessions to start as systemd services. Each service is named 'autossh-{session.name}'. ''; diff --git a/modules/services/buildkite-agents.nix b/modules/services/buildkite-agents.nix index 094f2c9d1..4888247e9 100644 --- a/modules/services/buildkite-agents.nix +++ b/modules/services/buildkite-agents.nix @@ -4,14 +4,13 @@ with lib; let cfg = config.services.buildkite-agents; - mdDoc = lib.mdDoc or (x: "Documentation not rendered. Please upgrade to a newer NixOS with markdown support."); literalMD = lib.literalMD or (x: lib.literalDocBook "Documentation not rendered. Please upgrade to a newer NixOS with markdown support."); mkHookOption = { name, description, example ? null }: { inherit name; value = mkOption { default = null; - description = mdDoc description; + description = description; type = types.nullOr types.lines; } // (if example == null then {} else { inherit example; }); }; @@ -36,32 +35,32 @@ let enable = mkOption { default = true; type = types.bool; - description = mdDoc "Whether to enable this buildkite agent"; + description = "Whether to enable this buildkite agent"; }; package = mkOption { default = pkgs.buildkite-agent; defaultText = literalExpression "pkgs.buildkite-agent"; - description = mdDoc "Which buildkite-agent derivation to use"; + description = "Which buildkite-agent derivation to use"; type = types.package; }; dataDir = mkOption { default = "/var/lib/buildkite-agent-${name}"; - description = mdDoc "The workdir for the agent"; + description = "The workdir for the agent"; type = types.str; }; runtimePackages = mkOption { default = [ pkgs.bash pkgs.gnutar pkgs.gzip pkgs.git pkgs.nix ]; defaultText = literalExpression "[ pkgs.bash pkgs.gnutar pkgs.gzip pkgs.git pkgs.nix ]"; - description = mdDoc "Add programs to the buildkite-agent environment"; + description = "Add programs to the buildkite-agent environment"; type = types.listOf (types.either types.package types.path); }; tokenPath = mkOption { type = types.path; - description = mdDoc '' + description = '' The token from your Buildkite "Agents" page. A run-time path to the token file, which is supposed to be provisioned @@ -72,7 +71,7 @@ let name = mkOption { type = types.str; default = "%hostname-${name}-%n"; - description = mdDoc '' + description = '' The name of the agent as seen in the buildkite dashboard. ''; }; @@ -81,7 +80,7 @@ let type = types.attrsOf (types.either types.str (types.listOf types.str)); default = {}; example = { queue = "default"; docker = "true"; ruby2 ="true"; }; - description = mdDoc '' + description = '' Tags for the agent. ''; }; @@ -90,7 +89,7 @@ let type = types.lines; default = ""; example = "debug=true"; - description = mdDoc '' + description = '' Extra lines to be added verbatim to the configuration file. ''; }; @@ -98,7 +97,7 @@ let preCommands = mkOption { type = types.lines; default = ""; - description = lib.mdDoc '' + description = '' Extra commands to run before starting buildkite. ''; }; @@ -110,7 +109,7 @@ let ## don't end up in the Nix store. apply = final: if final == null then null else toString final; - description = mdDoc '' + description = '' OpenSSH private key A run-time path to the key file, which is supposed to be provisioned @@ -179,7 +178,7 @@ let type = types.path; default = hooksDir config; defaultText = literalMD "generated from {option}`services.buildkite-agents..hooks`"; - description = mdDoc '' + description = '' Path to the directory storing the hooks. Consider using {option}`services.buildkite-agents..hooks.` instead. @@ -190,7 +189,7 @@ let type = types.str; default = "${pkgs.bash}/bin/bash -e -c"; defaultText = literalExpression ''"''${pkgs.bash}/bin/bash -e -c"''; - description = mdDoc '' + description = '' Command that buildkite-agent 3 will execute when it spawns a shell. ''; }; @@ -203,7 +202,7 @@ in options.services.buildkite-agents = mkOption { type = types.attrsOf (types.submodule buildkiteOptions); default = {}; - description = mdDoc '' + description = '' Attribute set of buildkite agents. The attribute key is combined with the hostname and a unique integer to create the final agent name. This can be overridden by setting the `name` diff --git a/modules/services/cachix-agent.nix b/modules/services/cachix-agent.nix index 68bc61ce7..d9e4a909c 100644 --- a/modules/services/cachix-agent.nix +++ b/modules/services/cachix-agent.nix @@ -9,7 +9,7 @@ in { enable = mkOption { type = types.bool; default = false; - description = lib.mdDoc '' + description = '' Enable to run Cachix Agent as a system service. Read [Cachix Deploy](https://docs.cachix.org/deploy/) documentation for more information. @@ -19,13 +19,13 @@ in { name = mkOption { type = types.str; default = config.networking.hostName; - description = lib.mdDoc '' + description = '' Agent name, usually the same as the hostname. ''; }; package = mkOption { - description = lib.mdDoc '' + description = '' Package containing cachix executable. ''; type = types.package; @@ -36,7 +36,7 @@ in { credentialsFile = mkOption { type = types.path; default = "/etc/cachix-agent.token"; - description = lib.mdDoc '' + description = '' Required file that needs to contain: export CACHIX_AGENT_TOKEN=... @@ -46,7 +46,7 @@ in { logFile = mkOption { type = types.nullOr types.path; default = "/var/log/cachix-agent.log"; - description = lib.mdDoc "Absolute path to log all stderr and stdout"; + description = "Absolute path to log all stderr and stdout"; }; }; @@ -58,7 +58,7 @@ in { exec ${cfg.package}/bin/cachix deploy agent ${cfg.name} ''; - path = [ config.nix.package pkgs.coreutils ]; + path = [ config.nix.package pkgs.coreutils config.environment.systemPath ]; environment = { NIX_SSL_CERT_FILE = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"; diff --git a/modules/services/chunkwm.nix b/modules/services/chunkwm.nix index a5955cc93..354288a0d 100644 --- a/modules/services/chunkwm.nix +++ b/modules/services/chunkwm.nix @@ -12,51 +12,51 @@ in services.chunkwm.enable = mkOption { type = types.bool; default = false; - description = lib.mdDoc "Whether to enable the chunkwm window manager."; + description = "Whether to enable the chunkwm window manager."; }; services.chunkwm.package = mkOption { type = types.package; example = literalExpression "pkgs.chunkwm"; - description = lib.mdDoc "This option specifies the chunkwm package to use."; + description = "This option specifies the chunkwm package to use."; }; services.chunkwm.hotload = mkOption { type = types.bool; default = true; - description = lib.mdDoc "Whether to enable hotload."; + description = "Whether to enable hotload."; }; services.chunkwm.extraConfig = mkOption { type = types.lines; default = ""; example = ''chunkc tiling::rule --owner Emacs --state tile''; - description = lib.mdDoc "Additional commands for {file}`chunkwmrc`."; + description = "Additional commands for {file}`chunkwmrc`."; }; services.chunkwm.plugins.dir = mkOption { type = types.path; default = "/run/current-system/sw/lib/chunkwm/plugins"; - description = lib.mdDoc "Chunkwm Plugins directory."; + description = "Chunkwm Plugins directory."; }; services.chunkwm.plugins.list = mkOption { type = types.listOf (types.enum plugins); default = plugins; example = ["tiling"]; - description = lib.mdDoc "Chunkwm Plugins to enable."; + description = "Chunkwm Plugins to enable."; }; services.chunkwm.plugins."border".config = mkOption { type = types.lines; default = ''chunkc set focused_border_color 0xffc0b18b''; - description = lib.mdDoc "Optional border plugin configuration."; + description = "Optional border plugin configuration."; }; services.chunkwm.plugins."tiling".config = mkOption { type = types.lines; example = ''chunkc set global_desktop_mode bsp''; - description = lib.mdDoc "Optional tiling plugin configuration."; + description = "Optional tiling plugin configuration."; }; }; diff --git a/modules/services/dnsmasq.nix b/modules/services/dnsmasq.nix index 03071dbc3..7ea674f85 100644 --- a/modules/services/dnsmasq.nix +++ b/modules/services/dnsmasq.nix @@ -12,32 +12,32 @@ in services.dnsmasq.enable = mkOption { type = types.bool; default = false; - description = lib.mdDoc "Whether to enable DNSmasq."; + description = "Whether to enable DNSmasq."; }; services.dnsmasq.package = mkOption { type = types.path; default = pkgs.dnsmasq; defaultText = "pkgs.dnsmasq"; - description = lib.mdDoc "This option specifies the dnsmasq package to use."; + description = "This option specifies the dnsmasq package to use."; }; services.dnsmasq.bind = mkOption { type = types.str; default = "127.0.0.1"; - description = lib.mdDoc "This option specifies the interface on which DNSmasq will listen."; + description = "This option specifies the interface on which DNSmasq will listen."; }; services.dnsmasq.port = mkOption { type = types.int; default = 53; - description = lib.mdDoc "This option specifies port on which DNSmasq will listen."; + description = "This option specifies port on which DNSmasq will listen."; }; services.dnsmasq.addresses = mkOption { type = types.attrs; default = {}; - description = lib.mdDoc "List of domains that will be redirected by the DNSmasq."; + description = "List of domains that will be redirected by the DNSmasq."; example = literalExpression '' { localhost = "127.0.0.1"; } ''; diff --git a/modules/services/emacs.nix b/modules/services/emacs.nix index 88b5c8a65..4b9a3cb07 100644 --- a/modules/services/emacs.nix +++ b/modules/services/emacs.nix @@ -12,20 +12,20 @@ in { enable = mkOption { type = types.bool; default = false; - description = lib.mdDoc "Whether to enable the Emacs Daemon."; + description = "Whether to enable the Emacs Daemon."; }; package = mkOption { type = types.path; default = pkgs.emacs; - description = lib.mdDoc "This option specifies the emacs package to use."; + description = "This option specifies the emacs package to use."; }; additionalPath = mkOption { type = types.listOf types.str; default = [ ]; example = [ "/Users/my_user_name" ]; - description = lib.mdDoc '' + description = '' This option specifies additional PATH that the emacs daemon would have. Typically if you have binaries in your home directory that is what you would add your home path here. One caveat is that there won't be shell variable expansion, so you can't use $HOME for example @@ -35,7 +35,7 @@ in { exec = mkOption { type = types.str; default = "emacs"; - description = lib.mdDoc "Emacs command/binary to execute."; + description = "Emacs command/binary to execute."; }; }; }; diff --git a/modules/services/eternal-terminal.nix b/modules/services/eternal-terminal.nix index 35330806a..d243a6117 100644 --- a/modules/services/eternal-terminal.nix +++ b/modules/services/eternal-terminal.nix @@ -7,20 +7,20 @@ in { options = { services.eternal-terminal = { - enable = mkEnableOption (lib.mdDoc "Eternal Terminal server"); + enable = mkEnableOption "Eternal Terminal server"; package = mkOption { type = types.path; default = pkgs.eternal-terminal; defaultText = "pkgs.eternal-terminal"; - description = lib.mdDoc + description = "This option specifies the eternal-terminal package to use."; }; port = mkOption { default = 2022; type = types.port; - description = lib.mdDoc '' + description = '' The port the server should listen on. Will use the server's default (2022) if not specified. Make sure to open this port in the firewall if necessary. @@ -30,7 +30,7 @@ in { verbosity = mkOption { default = 0; type = types.enum (lib.range 0 9); - description = lib.mdDoc '' + description = '' The verbosity level (0-9). ''; }; @@ -38,7 +38,7 @@ in { silent = mkOption { default = false; type = types.bool; - description = lib.mdDoc '' + description = '' If enabled, disables all logging. ''; }; @@ -46,7 +46,7 @@ in { logSize = mkOption { default = 20971520; type = types.int; - description = lib.mdDoc '' + description = '' The maximum log size. ''; }; diff --git a/modules/services/github-runner/default.nix b/modules/services/github-runner/default.nix new file mode 100644 index 000000000..e860ecab5 --- /dev/null +++ b/modules/services/github-runner/default.nix @@ -0,0 +1,6 @@ +{ + imports = [ + ./options.nix + ./service.nix + ]; +} diff --git a/modules/services/github-runner/options.nix b/modules/services/github-runner/options.nix new file mode 100644 index 000000000..f6c48307a --- /dev/null +++ b/modules/services/github-runner/options.nix @@ -0,0 +1,269 @@ +{ lib +, pkgs +, ... +}: + +with lib; +{ + options.services.github-runners = mkOption { + description = '' + Multiple GitHub Runners. + + If `user` and `group` are set to `null`, the module will configure nix-darwin to + manage the `_github-runner` user and group. Note that multiple runner + configurations share the same user/group, which means they can access + resources from other runners. Make each runner use its own user and group if + this is not what you want. In this case, you will have to do the user and + group creation yourself. If only `user` is set, while `group` is set to + `null`, the service will infer the primary group of the `user`. + + For each GitHub runner, the system activation script creates the following + directories: + + * `/var/lib/github-runners/`: + State directory to store the runner registration credentials + * `/var/log/github-runners/`: + The launchd service writes the stdout and stderr streams to this + directory. + * `/var/run/github-runners/`: + Working directory for workflow files. The runner only uses this + directory if `workDir` is `null` (see the `workDir` option for details). + ''; + example = { + runner1 = { + enable = true; + url = "https://github.com/owner/repo"; + name = "runner1"; + tokenFile = "/secrets/token1"; + }; + + runner2 = { + enable = true; + url = "https://github.com/owner/repo"; + name = "runner2"; + tokenFile = "/secrets/token2"; + }; + }; + default = { }; + type = types.attrsOf (types.submodule ({ name, ... }: { + options = { + enable = mkOption { + default = false; + example = true; + description = '' + Whether to enable GitHub Actions runner. + + Note: GitHub recommends using self-hosted runners with private repositories only. Learn more here: + [About self-hosted runners](https://docs.github.com/en/actions/hosting-your-own-runners/about-self-hosted-runners). + ''; + type = types.bool; + }; + + url = mkOption { + type = types.str; + description = '' + Repository to add the runner to. + + Changing this option triggers a new runner registration. + + IMPORTANT: If your token is org-wide (not per repository), you need to + provide a github org link, not a single repository, so do it like this + `https://github.com/nixos`, not like this + `https://github.com/nixos/nixpkgs`. + Otherwise, you are going to get a `404 NotFound` + from `POST https://api.github.com/actions/runner-registration` + in the configure script. + ''; + example = "https://github.com/nixos/nixpkgs"; + }; + + tokenFile = mkOption { + type = types.path; + description = '' + The full path to a file which contains either + + * a fine-grained personal access token (PAT), + * a classic PAT + * or a runner registration token + + Changing this option or the `tokenFile`’s content triggers a new runner registration. + + 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. + + The file should contain exactly one line with the token without any newline. + (Use `echo -n '…token…' > …token file…` to make sure no newlines sneak in.) + + If the file contains a PAT, the service creates a new registration token + on startup as needed. + If a registration token is given, it can be used to re-register a runner of the same + name but is time-limited as noted above. + + For fine-grained PATs: + + Give it "Read and Write access to organization/repository self hosted runners", + depending on whether it is organization wide or per-repository. You might have to + experiment a little, fine-grained PATs are a `beta` Github feature and still subject + to change; nonetheless they are the best option at the moment. + + For classic PATs: + + Make sure the PAT has a scope of `admin:org` for organization-wide registrations + or a scope of `repo` for a single repository. + + For runner registration tokens: + + Nothing special needs to be done, but updating will break after one hour, + so these are not recommended. + ''; + example = "/run/secrets/github-runner/nixos.token"; + }; + + name = mkOption { + type = types.nullOr types.str; + description = '' + Name of the runner to configure. If null, defaults to the hostname. + + Changing this option triggers a new runner registration. + ''; + example = "nixos"; + default = name; + }; + + runnerGroup = mkOption { + type = types.nullOr types.str; + description = '' + Name of the runner group to add this runner to (defaults to the default runner group). + + Changing this option triggers a new runner registration. + ''; + default = null; + }; + + extraLabels = mkOption { + type = types.listOf types.str; + description = '' + Extra labels in addition to the default (unless disabled through the `noDefaultLabels` option). + + Changing this option triggers a new runner registration. + ''; + example = literalExpression ''[ "nixos" ]''; + default = [ ]; + }; + + noDefaultLabels = mkOption { + type = types.bool; + description = '' + Disables adding the default labels. Also see the `extraLabels` option. + + Changing this option triggers a new runner registration. + ''; + default = false; + }; + + replace = mkOption { + type = types.bool; + description = '' + Replace any existing runner with the same name. + + Without this flag, registering a new runner with the same name fails. + ''; + default = false; + }; + + extraPackages = mkOption { + type = types.listOf types.package; + description = '' + Extra packages to add to `PATH` of the service to make them available to workflows. + ''; + default = [ ]; + }; + + extraEnvironment = mkOption { + type = types.attrs; + description = '' + Extra environment variables to set for the runner, as an attrset. + ''; + example = { + GIT_CONFIG = "/path/to/git/config"; + }; + default = { }; + }; + + serviceOverrides = mkOption { + type = types.attrs; + description = '' + Modify the service. Can be used to, e.g., adjust the sandboxing options. + ''; + default = { }; + }; + + package = mkPackageOptionMD pkgs "github-runner" { }; + + ephemeral = mkOption { + type = types.bool; + description = '' + If enabled, causes the following behavior: + + - Passes the `--ephemeral` flag to the runner configuration script + - De-registers and stops the runner with GitHub after it has processed one job + - Restarts the service after its successful exit + - On start, wipes the state directory and configures a new runner + + You should only enable this option if `tokenFile` points to a file which contains a + personal access token (PAT). If you're using the option with a registration token, restarting the + service will fail as soon as the registration token expired. + + Changing this option triggers a new runner registration. + ''; + default = false; + }; + + user = mkOption { + type = types.nullOr types.str; + description = '' + User under which to run the service. + + If this option and the `group` option is set to `null`, nix-darwin creates + the `github-runner` user and group. + ''; + defaultText = literalExpression "username"; + default = null; + }; + + group = mkOption { + type = types.nullOr types.str; + description = '' + Group under which to run the service. + + If this option and the `user` option is set to `null`, nix-darwin creates + the `github-runner` user and group. + ''; + defaultText = literalExpression "groupname"; + default = null; + }; + + workDir = mkOption { + type = with types; nullOr str; + description = '' + Working directory, available as `$GITHUB_WORKSPACE` during workflow runs + and used as a default for [repository checkouts](https://github.com/actions/checkout). + The service cleans this directory on every service start. + + Changing this option triggers a new runner registration. + ''; + default = null; + }; + + nodeRuntimes = mkOption { + type = with types; nonEmptyListOf (enum [ "node20" ]); + default = [ "node20" ]; + description = '' + List of Node.js runtimes the runner should support. + ''; + }; + }; + })); + }; +} diff --git a/modules/services/github-runner/service.nix b/modules/services/github-runner/service.nix new file mode 100644 index 000000000..53f2cddb3 --- /dev/null +++ b/modules/services/github-runner/service.nix @@ -0,0 +1,181 @@ +{ config, lib, pkgs, ... }: +with lib; +let + mkSvcName = name: "github-runner-${name}"; + mkStateDir = cfg: "/var/lib/github-runners/${cfg.name}"; + mkLogDir = cfg: "/var/log/github-runners/${cfg.name}"; + mkWorkDir = cfg: if (cfg.workDir != null) then cfg.workDir else "/var/run/github-runners/${cfg.name}"; +in +{ + config.assertions = flatten ( + flip mapAttrsToList config.services.github-runners (name: cfg: map (mkIf cfg.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"; + } + { + assertion = !cfg.noDefaultLabels || (cfg.extraLabels != [ ]); + message = "`services.github-runners.${name}`: The `extraLabels` option is mandatory if `noDefaultLabels` is set"; + } + ]) + ); + + config.warnings = flatten ( + flip mapAttrsToList config.services.github-runners (name: cfg: map (mkIf cfg.enable) [ + ( + mkIf (hasPrefix builtins.storeDir cfg.tokenFile) + "`services.github-runners.${name}`: `tokenFile` contains a secret but points to the world-readable Nix store." + ) + ]) + ); + + # Create the necessary directories and make the service user/group their owner + # This has to happen *after* nix-darwin user creation and *before* any launchd service gets started. + config.system.activationScripts = mkMerge (flip mapAttrsToList config.services.github-runners (name: cfg: + let + user = config.launchd.daemons.${mkSvcName name}.serviceConfig.UserName; + group = + if config.launchd.daemons.${mkSvcName name}.serviceConfig.GroupName != null + then config.launchd.daemons.${mkSvcName name}.serviceConfig.GroupName + else ""; + in + { + launchd = mkIf cfg.enable { + text = mkBefore ('' + echo >&2 "setting up GitHub Runner '${cfg.name}'..." + + ${pkgs.coreutils}/bin/mkdir -p -m 0750 ${escapeShellArg (mkStateDir cfg)} + ${pkgs.coreutils}/bin/chown ${user}:${group} ${escapeShellArg (mkStateDir cfg)} + + ${pkgs.coreutils}/bin/mkdir -p -m 0750 ${escapeShellArg (mkLogDir cfg)} + ${pkgs.coreutils}/bin/chown ${user}:${group} ${escapeShellArg (mkLogDir cfg)} + '' + optionalString (cfg.workDir == null) '' + ${pkgs.coreutils}/bin/mkdir -p -m 0750 ${escapeShellArg (mkWorkDir cfg)} + ${pkgs.coreutils}/bin/chown ${user}:${group} ${escapeShellArg (mkWorkDir cfg)} + ''); + }; + })); + + config.launchd.daemons = flip mapAttrs' config.services.github-runners (name: cfg: + let + package = cfg.package.override (old: optionalAttrs (hasAttr "nodeRuntimes" old) { inherit (cfg) nodeRuntimes; }); + stateDir = mkStateDir cfg; + logDir = mkLogDir cfg; + workDir = mkWorkDir cfg; + in + nameValuePair + (mkSvcName name) + (mkIf cfg.enable { + environment = { + HOME = stateDir; + RUNNER_ROOT = stateDir; + } // cfg.extraEnvironment; + + # Minimal package set for `actions/checkout` + path = (with pkgs; [ + bash + coreutils + git + gnutar + gzip + ]) ++ [ + config.nix.package + ] ++ cfg.extraPackages; + + script = + let + configure = pkgs.writeShellApplication { + name = "configure-github-runner-${name}"; + text = '' + export RUNNER_ROOT + + args=( + --unattended + --disableupdate + --work ${escapeShellArg workDir} + --url ${escapeShellArg cfg.url} + --labels ${escapeShellArg (concatStringsSep "," cfg.extraLabels)} + ${optionalString (cfg.name != null ) "--name ${escapeShellArg cfg.name}"} + ${optionalString cfg.replace "--replace"} + ${optionalString (cfg.runnerGroup != null) "--runnergroup ${escapeShellArg cfg.runnerGroup}"} + ${optionalString cfg.ephemeral "--ephemeral"} + ${optionalString cfg.noDefaultLabels "--no-default-labels"} + ) + # If the token file contains a PAT (i.e., it starts with "ghp_" or "github_pat_"), we have to use the --pat option, + # if it is not a PAT, we assume it contains a registration token and use the --token option + token=$(<"${cfg.tokenFile}") + if [[ "$token" =~ ^ghp_* ]] || [[ "$token" =~ ^github_pat_* ]]; then + args+=(--pat "$token") + else + args+=(--token "$token") + fi + ${package}/bin/config.sh "''${args[@]}" + ''; + }; + in + '' + echo "Configuring GitHub Actions Runner" + + # Always clean the working directory + ${pkgs.findutils}/bin/find ${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 + fi + + # If the `.runner` file does not exist, we assume the runner is not configured + if [[ ! -f "$RUNNER_ROOT/.runner" ]]; then + ${getExe configure} + fi + + # Start the service + ${package}/bin/Runner.Listener run --startuptype service + ''; + + serviceConfig = mkMerge [ + { + GroupName = cfg.group; + KeepAlive = { + Crashed = false; + } // mkIf cfg.ephemeral { + SuccessfulExit = true; + }; + ProcessType = "Interactive"; + RunAtLoad = true; + StandardErrorPath = "${logDir}/launchd-stderr.log"; + StandardOutPath = "${logDir}/launchd-stdout.log"; + ThrottleInterval = 30; + UserName = if (cfg.user != null) then cfg.user else "_github-runner"; + WatchPaths = [ + "/etc/resolv.conf" + "/Library/Preferences/SystemConfiguration/NetworkInterfaces.plist" + cfg.tokenFile + ]; + WorkingDirectory = stateDir; + } + cfg.serviceOverrides + ]; + })); + + # If any GitHub runner configuration has set both `user` and `group` set to `null`, + # manage the user and group `_github-runner` through nix-darwin. + config.users = mkIf (any (cfg: cfg.enable && cfg.user == null && cfg.group == null) (attrValues config.services.github-runners)) { + users."_github-runner" = { + createHome = false; + description = "GitHub Runner service user"; + gid = config.users.groups."_github-runner".gid; + home = "/var/lib/github-runners"; + shell = "/bin/bash"; + uid = mkDefault 533; + }; + knownUsers = [ "_github-runner" ]; + + groups."_github-runner" = { + gid = mkDefault 533; + description = "GitHub Runner service user group"; + }; + knownGroups = [ "_github-runner" ]; + }; +} diff --git a/modules/services/gitlab-runner.nix b/modules/services/gitlab-runner.nix index 7651ba52e..94c291efd 100644 --- a/modules/services/gitlab-runner.nix +++ b/modules/services/gitlab-runner.nix @@ -117,11 +117,11 @@ let in { options.services.gitlab-runner = { - enable = mkEnableOption (lib.mdDoc "Gitlab Runner"); + enable = mkEnableOption "Gitlab Runner"; configFile = mkOption { type = types.nullOr types.path; default = null; - description = lib.mdDoc '' + description = '' Configuration file for gitlab-runner. {option}`configFile` takes precedence over {option}`services`. @@ -137,7 +137,7 @@ in type = types.int; default = 0; example = literalExpression "with lib; (length (attrNames config.services.gitlab-runner.services)) * 3"; - description = lib.mdDoc '' + description = '' Defines the interval length, in seconds, between new jobs check. The default value is 3; if set to 0 or lower, the default value will be used. @@ -148,7 +148,7 @@ in type = types.int; default = 1; example = literalExpression "config.nix.maxJobs"; - description = lib.mdDoc '' + description = '' Limits how many jobs globally can be run concurrently. The most upper limit of jobs using all defined runners. 0 does not mean unlimited. @@ -158,7 +158,7 @@ in type = types.nullOr types.str; default = null; example = "https://public:private@host:port/1"; - description = lib.mdDoc '' + description = '' Data Source Name for tracking of all system level errors to Sentry. ''; }; @@ -166,7 +166,7 @@ in type = types.nullOr types.str; default = null; example = "localhost:8080"; - description = lib.mdDoc '' + description = '' Address (<host>:<port>) on which the Prometheus metrics HTTP server should be listening. ''; @@ -178,7 +178,7 @@ in type = types.nullOr types.str; default = null; example = "0.0.0.0:8093"; - description = lib.mdDoc '' + description = '' An internal URL to be used for the session server. ''; }; @@ -186,7 +186,7 @@ in type = types.nullOr types.str; default = null; example = "runner-host-name.tld:8093"; - description = lib.mdDoc '' + description = '' The URL that the Runner will expose to GitLab to be used to access the session server. Fallbacks to {option}`listenAddress` if not defined. @@ -195,7 +195,7 @@ in sessionTimeout = mkOption { type = types.int; default = 1800; - description = lib.mdDoc '' + description = '' How long in seconds the session can stay active after the job completes (which will block the job from finishing). ''; @@ -208,7 +208,7 @@ in listenAddress = "0.0.0.0:8093"; } ''; - description = lib.mdDoc '' + description = '' The session server allows the user to interact with jobs that the Runner is responsible for. A good example of this is the [interactive web terminal](https://docs.gitlab.com/ee/ci/interactive_web_terminal/index.html). @@ -217,7 +217,7 @@ in gracefulTermination = mkOption { type = types.bool; default = false; - description = lib.mdDoc '' + description = '' Finish all remaining jobs before stopping. If not set gitlab-runner will stop immediatly without waiting for jobs to finish, which will lead to failed builds. @@ -227,7 +227,7 @@ in type = types.str; default = "infinity"; example = "5min 20s"; - description = lib.mdDoc '' + description = '' Time to wait until a graceful shutdown is turned into a forceful one. ''; }; @@ -236,17 +236,17 @@ in default = pkgs.gitlab-runner; defaultText = "pkgs.gitlab-runner"; example = literalExpression "pkgs.gitlab-runner_1_11"; - description = lib.mdDoc "Gitlab Runner package to use."; + description = "Gitlab Runner package to use."; }; extraPackages = mkOption { type = types.listOf types.package; default = [ ]; - description = lib.mdDoc '' + description = '' Extra packages to add to PATH for the gitlab-runner process. ''; }; services = mkOption { - description = lib.mdDoc "GitLab Runner services."; + description = "GitLab Runner services."; default = { }; example = literalExpression '' { @@ -328,7 +328,7 @@ in options = { registrationConfigFile = mkOption { type = types.path; - description = lib.mdDoc '' + description = '' Absolute path to a file with environment variables used for gitlab-runner registration. A list of all supported environment variables can be found in @@ -345,7 +345,7 @@ in type = types.listOf types.str; default = [ ]; example = [ "--docker-helper-image my/gitlab-runner-helper" ]; - description = lib.mdDoc '' + description = '' Extra command-line flags passed to `gitlab-runner register`. Execute `gitlab-runner register --help` @@ -356,7 +356,7 @@ in type = types.attrsOf types.str; default = { }; example = { NAME = "value"; }; - description = lib.mdDoc '' + description = '' Custom environment variables injected to build environment. For secrets you can use {option}`registrationConfigFile` with `RUNNER_ENV` variable set. @@ -365,7 +365,7 @@ in executor = mkOption { type = types.str; default = "docker"; - description = lib.mdDoc '' + description = '' Select executor, eg. shell, docker, etc. See [runner documentation](https://docs.gitlab.com/runner/executors/README.html) for more information. ''; @@ -374,7 +374,7 @@ in type = types.nullOr types.path; default = null; example = "/var/lib/gitlab-runner/builds"; - description = lib.mdDoc '' + description = '' Absolute path to a directory where builds will be stored in context of selected executor (Locally, Docker, SSH). ''; @@ -383,14 +383,14 @@ in type = types.nullOr types.str; default = null; example = "http://gitlab.example.local"; - description = lib.mdDoc '' + description = '' Overwrite the URL for the GitLab instance. Used if the Runner can’t connect to GitLab on the URL GitLab exposes itself. ''; }; dockerImage = mkOption { type = types.nullOr types.str; default = null; - description = lib.mdDoc '' + description = '' Docker image to be used. ''; }; @@ -398,7 +398,7 @@ in type = types.listOf types.str; default = [ ]; example = [ "/var/run/docker.sock:/var/run/docker.sock" ]; - description = lib.mdDoc '' + description = '' Bind-mount a volume and create it if it doesn't exist prior to mounting. ''; @@ -406,14 +406,14 @@ in dockerDisableCache = mkOption { type = types.bool; default = false; - description = lib.mdDoc '' + description = '' Disable all container caching. ''; }; dockerPrivileged = mkOption { type = types.bool; default = false; - description = lib.mdDoc '' + description = '' Give extended privileges to container. ''; }; @@ -421,7 +421,7 @@ in type = types.listOf types.str; default = [ ]; example = [ "other-host:127.0.0.1" ]; - description = lib.mdDoc '' + description = '' Add a custom host-to-IP mapping. ''; }; @@ -429,7 +429,7 @@ in type = types.listOf types.str; default = [ ]; example = [ "ruby:*" "python:*" "php:*" "my.registry.tld:5000/*:*" ]; - description = lib.mdDoc '' + description = '' Whitelist allowed images. ''; }; @@ -437,21 +437,21 @@ in type = types.listOf types.str; default = [ ]; example = [ "postgres:9" "redis:*" "mysql:*" ]; - description = lib.mdDoc '' + description = '' Whitelist allowed services. ''; }; preCloneScript = mkOption { type = types.nullOr types.path; default = null; - description = lib.mdDoc '' + description = '' Runner-specific command script executed before code is pulled. ''; }; preBuildScript = mkOption { type = types.nullOr types.path; default = null; - description = lib.mdDoc '' + description = '' Runner-specific command script executed after code is pulled, just before build executes. ''; @@ -459,7 +459,7 @@ in postBuildScript = mkOption { type = types.nullOr types.path; default = null; - description = lib.mdDoc '' + description = '' Runner-specific command script executed after code is pulled and just after build executes. ''; @@ -467,14 +467,14 @@ in tagList = mkOption { type = types.listOf types.str; default = [ ]; - description = lib.mdDoc '' + description = '' Tag list. ''; }; runUntagged = mkOption { type = types.bool; default = false; - description = lib.mdDoc '' + description = '' Register to run untagged builds; defaults to `true` when {option}`tagList` is empty. ''; @@ -482,7 +482,7 @@ in limit = mkOption { type = types.int; default = 0; - description = lib.mdDoc '' + description = '' Limit how many jobs can be handled concurrently by this service. 0 (default) simply means don't limit. ''; @@ -490,14 +490,14 @@ in requestConcurrency = mkOption { type = types.int; default = 0; - description = lib.mdDoc '' + description = '' Limit number of concurrent requests for new jobs from GitLab. ''; }; maximumTimeout = mkOption { type = types.int; default = 0; - description = lib.mdDoc '' + description = '' What is the maximum timeout (in seconds) that will be set for job when using this Runner. 0 (default) simply means don't limit. ''; @@ -505,7 +505,7 @@ in protected = mkOption { type = types.bool; default = false; - description = lib.mdDoc '' + description = '' When set to true Runner will only run on pipelines triggered on protected branches. ''; @@ -513,7 +513,7 @@ in debugTraceDisabled = mkOption { type = types.bool; default = false; - description = lib.mdDoc '' + description = '' When set to true Runner will disable the possibility of using the `CI_DEBUG_TRACE` feature. ''; diff --git a/modules/services/hercules-ci-agent/common.nix b/modules/services/hercules-ci-agent/common.nix index 6401f6f12..5a4b7391b 100644 --- a/modules/services/hercules-ci-agent/common.nix +++ b/modules/services/hercules-ci-agent/common.nix @@ -18,7 +18,6 @@ let types ; literalMD = lib.literalMD or (x: lib.literalDocBook "Documentation not rendered. Please upgrade to a newer NixOS with markdown support."); - mdDoc = lib.mdDoc or (x: "Documentation not rendered. Please upgrade to a newer NixOS with markdown support."); cfg = config.services.hercules-ci-agent; @@ -37,7 +36,7 @@ in enable = mkOption { type = types.bool; default = false; - description = mdDoc '' + description = '' Enable to run Hercules CI Agent as a system service. [Hercules CI](https://hercules-ci.com) is a @@ -47,7 +46,7 @@ in ''; }; package = mkOption { - description = mdDoc '' + description = '' Package containing the bin/hercules-ci-agent executable. ''; type = types.package; @@ -55,7 +54,7 @@ in defaultText = literalExpression "pkgs.hercules-ci-agent"; }; settings = mkOption { - description = mdDoc '' + description = '' These settings are written to the `agent.toml` file. Not all settings are listed as options, can be set nonetheless. @@ -75,7 +74,7 @@ in type = types.path; internal = true; defaultText = literalMD "generated `hercules-ci-agent.toml`"; - description = mdDoc '' + description = '' The fully assembled config file. ''; }; diff --git a/modules/services/hercules-ci-agent/default.nix b/modules/services/hercules-ci-agent/default.nix index 538e10443..d9fbf37bc 100644 --- a/modules/services/hercules-ci-agent/default.nix +++ b/modules/services/hercules-ci-agent/default.nix @@ -17,7 +17,7 @@ in logFile = mkOption { type = types.path; default = "/var/log/hercules-ci-agent.log"; - description = lib.mdDoc "Stdout and sterr of hercules-ci-agent process."; + description = "Stdout and sterr of hercules-ci-agent process."; }; }; diff --git a/modules/services/hercules-ci-agent/settings.nix b/modules/services/hercules-ci-agent/settings.nix index 157861a80..63894615f 100644 --- a/modules/services/hercules-ci-agent/settings.nix +++ b/modules/services/hercules-ci-agent/settings.nix @@ -7,7 +7,6 @@ let mkOption ; literalMD = lib.literalMD or (x: lib.literalDocBook "Documentation not rendered. Please upgrade to a newer NixOS with markdown support."); - mdDoc = lib.mdDoc or (x: "Documentation not rendered. Please upgrade to a newer NixOS with markdown support."); format = pkgs.formats.toml { }; @@ -15,7 +14,7 @@ let freeformType = format.type; options = { apiBaseUrl = mkOption { - description = mdDoc '' + description = '' API base URL that the agent will connect to. When using Hercules CI Enterprise, set this to the URL where your @@ -27,12 +26,12 @@ let baseDirectory = mkOption { type = types.path; default = "/var/lib/hercules-ci-agent"; - description = mdDoc '' + description = '' State directory (secrets, work directory, etc) for agent ''; }; concurrentTasks = mkOption { - description = mdDoc '' + description = '' Number of tasks to perform simultaneously. A task is a single derivation build, an evaluation or an effect run. @@ -56,7 +55,7 @@ let ''; }; labels = mkOption { - description = mdDoc '' + description = '' A key-value map of user data. This data will be available to organization members in the dashboard and API. @@ -75,7 +74,7 @@ let ''; }; workDirectory = mkOption { - description = mdDoc '' + description = '' The directory in which temporary subdirectories are created for task state. This includes sources for Nix evaluation. ''; type = types.path; @@ -83,7 +82,7 @@ let defaultText = literalExpression ''baseDirectory + "/work"''; }; staticSecretsDirectory = mkOption { - description = mdDoc '' + description = '' This is the default directory to look for statically configured secrets like `cluster-join-token.key`. See also `clusterJoinTokenPath` and `binaryCachesPath` for fine-grained configuration. @@ -93,7 +92,7 @@ let defaultText = literalExpression ''baseDirectory + "/secrets"''; }; clusterJoinTokenPath = mkOption { - description = mdDoc '' + description = '' Location of the cluster-join-token.key file. You can retrieve the contents of the file when creating a new agent via @@ -110,7 +109,7 @@ let defaultText = literalExpression ''staticSecretsDirectory + "/cluster-join-token.key"''; }; binaryCachesPath = mkOption { - description = mdDoc '' + description = '' Path to a JSON file containing binary cache secret keys. As these values are confidential, they should not be in the store, but @@ -124,7 +123,7 @@ let defaultText = literalExpression ''staticSecretsDirectory + "/binary-caches.json"''; }; secretsJsonPath = mkOption { - description = mdDoc '' + description = '' Path to a JSON file containing secrets for effects. As these values are confidential, they should not be in the store, but diff --git a/modules/services/ipfs.nix b/modules/services/ipfs.nix index 8087ba460..e7cdb746e 100644 --- a/modules/services/ipfs.nix +++ b/modules/services/ipfs.nix @@ -14,14 +14,14 @@ in enable = mkOption { type = types.bool; default = false; - description = lib.mdDoc "Whether to enable the ipfs daemon."; + description = "Whether to enable the ipfs daemon."; }; package = mkOption { - type = types.path; + type = types.package; default = pkgs.kubo; # defaultText = "pkgs.kubo"; - description = lib.mdDoc '' + description = '' The ipfs package to use. ''; }; @@ -29,8 +29,8 @@ in logFile = mkOption { type = types.nullOr types.path; default = null; - example = "/var/tmp/lorri.log"; - description = lib.mdDoc '' + example = "/var/tmp/ipfs.log"; + description = '' The logfile to use for the ipfs service. Alternatively {command}`sudo launchctl debug system/org.nixos.ipfs --stderr` can be used to stream the logs to a shell after restarting the service with @@ -41,20 +41,19 @@ in ipfsPath = mkOption { type = types.nullOr types.path; default = null; - description = lib.mdDoc "Set the IPFS_PATH environment variable."; + description = "Set the IPFS_PATH environment variable."; }; enableGarbageCollection = mkOption { type = types.bool; default = false; - description = lib.mdDoc "Passes --enable-gc flag to ipfs daemon."; + description = "Passes --enable-gc flag to ipfs daemon."; }; }; config = mkIf cfg.enable { - environment.systemPackages = [ pkgs.kubo ]; + environment.systemPackages = [ cfg.package ]; launchd.user.agents.ipfs = { - # command = with pkgs; "${ipfs}/bin/ipfs daemon"; serviceConfig = { ProgramArguments = [ "${cfg.package}/bin/ipfs" "daemon" ] ++ optionals (cfg.enableGarbageCollection) [ "--enable-gc" ]; diff --git a/modules/services/karabiner-elements/default.nix b/modules/services/karabiner-elements/default.nix index 7c0636c67..2f415b2d6 100644 --- a/modules/services/karabiner-elements/default.nix +++ b/modules/services/karabiner-elements/default.nix @@ -10,7 +10,7 @@ in { options = { - services.karabiner-elements.enable = mkEnableOption (lib.mdDoc "Karabiner-Elements"); + services.karabiner-elements.enable = mkEnableOption "Karabiner-Elements"; }; config = mkIf cfg.enable { diff --git a/modules/services/khd/default.nix b/modules/services/khd/default.nix index ef16a2bfb..7594baffe 100644 --- a/modules/services/khd/default.nix +++ b/modules/services/khd/default.nix @@ -13,27 +13,27 @@ in services.khd.enable = mkOption { type = types.bool; default = false; - description = lib.mdDoc "Whether to enable the khd hotkey daemon."; + description = "Whether to enable the khd hotkey daemon."; }; services.khd.package = mkOption { type = types.package; default = pkgs.khd; defaultText = "pkgs.khd"; - description = lib.mdDoc "This option specifies the khd package to use."; + description = "This option specifies the khd package to use."; }; services.khd.khdConfig = mkOption { type = types.lines; default = ""; example = "alt + shift - r : kwmc quit"; - description = lib.mdDoc "Config to use for {file}`khdrc`."; + description = "Config to use for {file}`khdrc`."; }; services.khd.i3Keybindings = mkOption { type = types.bool; default = false; - description = lib.mdDoc "Wether to configure i3 style keybindings for kwm."; + description = "Wether to configure i3 style keybindings for kwm."; }; }; diff --git a/modules/services/kwm/default.nix b/modules/services/kwm/default.nix index c6603b945..5fb6c5635 100644 --- a/modules/services/kwm/default.nix +++ b/modules/services/kwm/default.nix @@ -11,21 +11,21 @@ in services.kwm.enable = mkOption { type = types.bool; default = false; - description = lib.mdDoc "Whether to enable the khd window manager."; + description = "Whether to enable the khd window manager."; }; services.kwm.package = mkOption { type = types.path; default = pkgs.kwm; defaultText = "pkgs.kwm"; - description = lib.mdDoc "This option specifies the kwm package to use."; + description = "This option specifies the kwm package to use."; }; services.kwm.kwmConfig = mkOption { type = types.lines; default = ""; example = ''kwmc rule owner="iTerm2" properties={role="AXDialog"}''; - description = lib.mdDoc "Config to use for {file}`kwmrc`."; + description = "Config to use for {file}`kwmrc`."; }; }; diff --git a/modules/services/lorri.nix b/modules/services/lorri.nix index 246bcfa3f..0c1230043 100644 --- a/modules/services/lorri.nix +++ b/modules/services/lorri.nix @@ -11,14 +11,14 @@ in enable = mkOption { type = types.bool; default = false; - description = lib.mdDoc "Whether to enable the lorri service."; + description = "Whether to enable the lorri service."; }; logFile = mkOption { type = types.nullOr types.path; default = null; example = "/var/tmp/lorri.log"; - description = lib.mdDoc '' + description = '' The logfile to use for the lorri service. Alternatively {command}`sudo launchctl debug system/org.nixos.lorri --stderr` can be used to stream the logs to a shell after restarting the service with diff --git a/modules/services/mail/offlineimap.nix b/modules/services/mail/offlineimap.nix index b7913cb44..81c8bdbb2 100644 --- a/modules/services/mail/offlineimap.nix +++ b/modules/services/mail/offlineimap.nix @@ -7,32 +7,32 @@ let in { options.services.offlineimap = { - enable = mkEnableOption (lib.mdDoc "Offlineimap, a software to dispose your mailbox(es) as a local Maildir(s)"); + enable = mkEnableOption "Offlineimap, a software to dispose your mailbox(es) as a local Maildir(s)"; package = mkOption { type = types.package; default = pkgs.offlineimap; defaultText = "pkgs.offlineimap"; - description = lib.mdDoc "Offlineimap derivation to use."; + description = "Offlineimap derivation to use."; }; path = mkOption { type = types.listOf types.path; default = []; example = literalExpression "[ pkgs.pass pkgs.bash pkgs.notmuch ]"; - description = lib.mdDoc "List of derivations to put in Offlineimap's path."; + description = "List of derivations to put in Offlineimap's path."; }; startInterval = mkOption { type = types.nullOr types.int; default = 300; - description = lib.mdDoc "Optional key to start offlineimap services each N seconds"; + description = "Optional key to start offlineimap services each N seconds"; }; runQuick = mkOption { type = types.bool; default = false; - description = lib.mdDoc '' + description = '' Run only quick synchronizations. Ignore any flag updates on IMAP servers. If a flag on the remote IMAP changes, and we have the message locally, it will be left untouched in a quick run. ''; @@ -41,7 +41,7 @@ in { extraConfig = mkOption { type = types.lines; default = ""; - description = lib.mdDoc "Additional text to be appended to {file}`offlineimaprc`."; + description = "Additional text to be appended to {file}`offlineimaprc`."; }; }; diff --git a/modules/services/monitoring/telegraf.nix b/modules/services/monitoring/telegraf.nix index e3d32502e..f40e01302 100644 --- a/modules/services/monitoring/telegraf.nix +++ b/modules/services/monitoring/telegraf.nix @@ -10,12 +10,12 @@ let in { options = { services.telegraf = { - enable = mkEnableOption (lib.mdDoc "telegraf agent"); + enable = mkEnableOption "telegraf agent"; package = mkOption { default = pkgs.telegraf; defaultText = lib.literalExpression "pkgs.telegraf"; - description = lib.mdDoc "Which telegraf derivation to use"; + description = "Which telegraf derivation to use"; type = types.package; }; @@ -23,7 +23,7 @@ in { type = types.listOf types.path; default = [ ]; example = [ "/run/keys/telegraf.env" ]; - description = lib.mdDoc '' + description = '' File to load as environment file. This is useful to avoid putting secrets into the nix store. ''; @@ -31,7 +31,7 @@ in { extraConfig = mkOption { default = { }; - description = lib.mdDoc "Extra configuration options for telegraf"; + description = "Extra configuration options for telegraf"; type = settingsFormat.type; example = { outputs.influxdb = { @@ -47,7 +47,7 @@ in { configUrl = mkOption { default = null; - description = lib.mdDoc "Url to fetch config from"; + description = "Url to fetch config from"; type = types.nullOr types.str; }; }; diff --git a/modules/services/mopidy.nix b/modules/services/mopidy.nix index 2fb9a1594..be3c05e14 100644 --- a/modules/services/mopidy.nix +++ b/modules/services/mopidy.nix @@ -11,27 +11,27 @@ in services.mopidy.enable = mkOption { type = types.bool; default = false; - description = lib.mdDoc "Whether to enable the Mopidy Daemon."; + description = "Whether to enable the Mopidy Daemon."; }; services.mopidy.package = mkOption { type = types.path; default = pkgs.mopidy; defaultText = "pkgs.mopidy"; - description = lib.mdDoc "This option specifies the mopidy package to use."; + description = "This option specifies the mopidy package to use."; }; services.mopidy.mediakeys.enable = mkOption { type = types.bool; default = false; - description = lib.mdDoc "Whether to enable the Mopidy OSX Media Keys support daemon."; + description = "Whether to enable the Mopidy OSX Media Keys support daemon."; }; services.mopidy.mediakeys.package = mkOption { type = types.path; default = pkgs.pythonPackages.osxmpdkeys; defaultText = "pkgs.pythonPackages.osxmpdkeys"; - description = lib.mdDoc "This option specifies the mediakeys package to use."; + description = "This option specifies the mediakeys package to use."; }; }; diff --git a/modules/services/netbird.nix b/modules/services/netbird.nix index ad0bf3e49..5bc8ebdf9 100644 --- a/modules/services/netbird.nix +++ b/modules/services/netbird.nix @@ -5,12 +5,12 @@ let in { options.services.netbird = { - enable = mkEnableOption (lib.mdDoc "Netbird daemon"); + enable = mkEnableOption "Netbird daemon"; package = mkOption { type = types.package; default = pkgs.netbird; defaultText = literalExpression "pkgs.netbird"; - description = lib.mdDoc "The package to use for netbird"; + description = "The package to use for netbird"; }; }; config = mkIf cfg.enable { diff --git a/modules/services/nextdns/default.nix b/modules/services/nextdns/default.nix index 5ea5e75ac..23120965b 100644 --- a/modules/services/nextdns/default.nix +++ b/modules/services/nextdns/default.nix @@ -13,13 +13,13 @@ in { type = types.bool; default = false; description = - lib.mdDoc "Whether to enable the NextDNS DNS/53 to DoH Proxy service."; + "Whether to enable the NextDNS DNS/53 to DoH Proxy service."; }; arguments = mkOption { type = types.listOf types.str; default = [ ]; example = [ "-config" "10.0.3.0/24=abcdef" ]; - description = lib.mdDoc "Additional arguments to be passed to nextdns run."; + description = "Additional arguments to be passed to nextdns run."; }; }; }; diff --git a/modules/services/nix-daemon.nix b/modules/services/nix-daemon.nix index 35476a0af..42d31c946 100644 --- a/modules/services/nix-daemon.nix +++ b/modules/services/nix-daemon.nix @@ -11,20 +11,20 @@ in services.nix-daemon.enable = mkOption { type = types.bool; default = false; - description = lib.mdDoc "Whether to enable the nix-daemon service."; + description = "Whether to enable the nix-daemon service."; }; services.nix-daemon.enableSocketListener = mkOption { type = types.bool; default = false; - description = lib.mdDoc "Whether to make the nix-daemon service socket activated."; + description = "Whether to make the nix-daemon service socket activated."; }; services.nix-daemon.logFile = mkOption { type = types.nullOr types.path; default = null; example = "/var/log/nix-daemon.log"; - description = lib.mdDoc '' + description = '' The logfile to use for the nix-daemon service. Alternatively {command}`sudo launchctl debug system/org.nixos.nix-daemon --stderr` can be used to stream the logs to a shell after restarting the service with @@ -35,7 +35,7 @@ in services.nix-daemon.tempDir = mkOption { type = types.nullOr types.path; default = null; - description = lib.mdDoc "The TMPDIR to use for nix-daemon."; + description = "The TMPDIR to use for nix-daemon."; }; }; @@ -51,7 +51,7 @@ in serviceConfig.ProcessType = config.nix.daemonProcessType; serviceConfig.LowPriorityIO = config.nix.daemonIOLowPriority; serviceConfig.Label = "org.nixos.nix-daemon"; # must match daemon installed by Nix regardless of the launchd label Prefix - serviceConfig.SoftResourceLimits.NumberOfFiles = mkDefault 4096; + serviceConfig.SoftResourceLimits.NumberOfFiles = mkDefault 1048576; serviceConfig.StandardErrorPath = cfg.logFile; serviceConfig.KeepAlive = mkIf (!cfg.enableSocketListener) true; @@ -63,7 +63,10 @@ in serviceConfig.EnvironmentVariables = mkMerge [ config.nix.envVars - { NIX_SSL_CERT_FILE = mkDefault config.environment.variables.NIX_SSL_CERT_FILE; + { + NIX_SSL_CERT_FILE = mkIf + (config.environment.variables ? NIX_SSL_CERT_FILE) + (mkDefault config.environment.variables.NIX_SSL_CERT_FILE); TMPDIR = mkIf (cfg.tempDir != null) cfg.tempDir; # FIXME: workaround for https://github.com/NixOS/nix/issues/2523 OBJC_DISABLE_INITIALIZE_FORK_SAFETY = mkDefault "YES"; diff --git a/modules/services/nix-gc/default.nix b/modules/services/nix-gc/default.nix index a703ed41a..25ff83553 100644 --- a/modules/services/nix-gc/default.nix +++ b/modules/services/nix-gc/default.nix @@ -25,14 +25,14 @@ in automatic = mkOption { default = false; type = types.bool; - description = lib.mdDoc "Automatically run the garbage collector at a specific time."; + description = "Automatically run the garbage collector at a specific time."; }; # Not in NixOS module user = mkOption { type = types.nullOr types.str; default = null; - description = lib.mdDoc "User that runs the garbage collector."; + description = "User that runs the garbage collector."; }; interval = mkOption { @@ -48,7 +48,7 @@ in default = ""; example = "--max-freed $((64 * 1024**3))"; type = types.str; - description = lib.mdDoc '' + description = '' Options given to {file}`nix-collect-garbage` when the garbage collector is run automatically. ''; diff --git a/modules/services/nix-optimise/default.nix b/modules/services/nix-optimise/default.nix new file mode 100644 index 000000000..94f6e1cb9 --- /dev/null +++ b/modules/services/nix-optimise/default.nix @@ -0,0 +1,72 @@ +# Based off: +# https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/misc/nix-optimise.nix +# When making changes please try to keep it in sync. +{ config, lib, ... }: + + +let + inherit (lib) + mkIf + mkOption + mkRemovedOptionModule + optionalString + types + ; + + cfg = config.nix.optimise; +in + +{ + imports = [ + (mkRemovedOptionModule [ "nix" "optimise" "dates" ] "Use `nix.optimise.interval` instead.") + ]; + + ###### interface + + options = { + + nix.optimise = { + + automatic = mkOption { + type = types.bool; + default = false; + 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 = types.attrs; + default = { Hour = 3; Minute = 15; }; + description = "The time interval at which the optimiser will run."; + }; + + }; + + }; + + + ###### implementation + + config = mkIf cfg.automatic { + + launchd.daemons.nix-optimise = { + environment.NIX_REMOTE = optionalString config.nix.useDaemon "daemon"; + serviceConfig = { + ProgramArguments = [ + "/bin/sh" "-c" + "/bin/wait4path ${config.nix.package} && exec ${config.nix.package}/bin/nix-store --optimise" + ]; + RunAtLoad = false; + StartCalendarInterval = [ cfg.interval ]; + UserName = cfg.user; + }; + }; + + }; +} diff --git a/modules/services/ofborg/default.nix b/modules/services/ofborg/default.nix index 91510398d..4c356158a 100644 --- a/modules/services/ofborg/default.nix +++ b/modules/services/ofborg/default.nix @@ -12,13 +12,13 @@ in services.ofborg.enable = mkOption { type = types.bool; default = false; - description = lib.mdDoc "Whether to enable the ofborg builder service."; + description = "Whether to enable the ofborg builder service."; }; services.ofborg.package = mkOption { type = types.package; example = literalExpression "pkgs.ofborg"; - description = lib.mdDoc '' + description = '' This option specifies the ofborg package to use. eg. (import <ofborg> {}).ofborg.rs @@ -30,7 +30,7 @@ in services.ofborg.configFile = mkOption { type = types.path; - description = lib.mdDoc '' + description = '' Configuration file to use for ofborg. WARNING Don't use a path literal or derivation for this, @@ -41,7 +41,7 @@ in services.ofborg.logFile = mkOption { type = types.path; default = "/var/log/ofborg.log"; - description = lib.mdDoc "The logfile to use for the ofborg service."; + description = "The logfile to use for the ofborg service."; }; }; diff --git a/modules/services/postgresql/default.nix b/modules/services/postgresql/default.nix index 018b46eb0..e063944b7 100644 --- a/modules/services/postgresql/default.nix +++ b/modules/services/postgresql/default.nix @@ -40,12 +40,12 @@ in services.postgresql = { - enable = mkEnableOption (lib.mdDoc "PostgreSQL Server"); + enable = mkEnableOption "PostgreSQL Server"; package = mkOption { type = types.package; example = literalExpression "pkgs.postgresql_11"; - description = lib.mdDoc '' + description = '' PostgreSQL package to use. ''; }; @@ -53,7 +53,7 @@ in port = mkOption { type = types.int; default = 5432; - description = lib.mdDoc '' + description = '' The port on which PostgreSQL listens. ''; }; @@ -61,14 +61,14 @@ in checkConfig = mkOption { type = types.bool; default = true; - description = lib.mdDoc "Check the syntax of the configuration file at compile time"; + description = "Check the syntax of the configuration file at compile time"; }; dataDir = mkOption { type = types.path; defaultText = literalExpression ''"/var/lib/postgresql/''${config.services.postgresql.package.psqlSchema}"''; example = "/var/lib/postgresql/11"; - description = lib.mdDoc '' + description = '' The data directory for PostgreSQL. If left as the default value this directory will automatically be created before the PostgreSQL server starts, otherwise the sysadmin is responsible for ensuring the directory exists with appropriate ownership @@ -79,7 +79,7 @@ in authentication = mkOption { type = types.lines; default = ""; - description = lib.mdDoc '' + description = '' Defines how users authenticate themselves to the server. See the [ PostgreSQL documentation for pg_hba.conf](https://www.postgresql.org/docs/current/auth-pg-hba-conf.html) @@ -96,7 +96,7 @@ in identMap = mkOption { type = types.lines; default = ""; - description = lib.mdDoc '' + description = '' Defines the mapping from system users to database users. The general form is: @@ -109,7 +109,7 @@ in type = with types; listOf str; default = []; example = [ "--data-checksums" "--allow-group-access" ]; - description = lib.mdDoc '' + description = '' Additional arguments passed to `initdb` during data dir initialisation. ''; @@ -118,7 +118,7 @@ in initialScript = mkOption { type = types.nullOr types.path; default = null; - description = lib.mdDoc '' + description = '' A file containing SQL statements to execute on first startup. ''; }; @@ -126,7 +126,7 @@ in ensureDatabases = mkOption { type = types.listOf types.str; default = []; - description = lib.mdDoc '' + description = '' Ensures that the specified databases exist. This option will never delete existing databases, especially not when the value of this option is changed. This means that databases created once through this option or @@ -143,14 +143,14 @@ in options = { name = mkOption { type = types.str; - description = lib.mdDoc '' + description = '' Name of the user to ensure. ''; }; ensurePermissions = mkOption { type = types.attrsOf types.str; default = {}; - description = lib.mdDoc '' + description = '' Permissions to ensure for the user, specified as an attribute set. The attribute names specify the database and tables to grant the permissions for. The attribute values specify the permissions to grant. You may specify one or @@ -171,7 +171,7 @@ in }; }); default = []; - description = lib.mdDoc '' + description = '' Ensures that the specified users exist and have at least the ensured permissions. The PostgreSQL users will be identified using peer authentication. This authenticates the Unix user with the same name only, and that without the need for a password. @@ -200,7 +200,7 @@ in enableTCPIP = mkOption { type = types.bool; default = false; - description = lib.mdDoc '' + description = '' Whether PostgreSQL should listen on all network interfaces. If disabled, the database can only be accessed via its Unix domain socket or via TCP connections to localhost. @@ -211,7 +211,7 @@ in type = types.str; default = "[%p] "; example = "%m [%p] "; - description = lib.mdDoc '' + description = '' A printf-style string that is output at the beginning of each log line. Upstream default is `'%m [%p] '`, i.e. it includes the timestamp. We do not include the timestamp, because journal has it anyway. @@ -222,7 +222,7 @@ in type = types.listOf types.path; default = []; example = literalExpression "with pkgs.postgresql_11.pkgs; [ postgis pg_repack ]"; - description = lib.mdDoc '' + description = '' List of PostgreSQL plugins. PostgreSQL version for each plugin should match version for `services.postgresql.package` value. ''; @@ -231,7 +231,7 @@ in settings = mkOption { type = with types; attrsOf (oneOf [ bool float int str ]); default = {}; - description = lib.mdDoc '' + description = '' PostgreSQL configuration. Refer to for an overview of `postgresql.conf`. @@ -257,7 +257,7 @@ in recoveryConfig = mkOption { type = types.nullOr types.lines; default = null; - description = lib.mdDoc '' + description = '' Contents of the {file}`recovery.conf` file. ''; }; @@ -267,7 +267,7 @@ in default = "postgres"; internal = true; readOnly = true; - description = lib.mdDoc '' + description = '' PostgreSQL superuser account to use for various operations. Internal since changing this value would lead to breakage while setting up databases. ''; diff --git a/modules/services/privoxy/default.nix b/modules/services/privoxy/default.nix index 5f7780c37..b3147232b 100644 --- a/modules/services/privoxy/default.nix +++ b/modules/services/privoxy/default.nix @@ -10,40 +10,40 @@ in services.privoxy.enable = mkOption { type = types.bool; default = false; - description = lib.mdDoc "Whether to enable the privoxy proxy service."; + description = "Whether to enable the privoxy proxy service."; }; services.privoxy.listenAddress = mkOption { type = types.str; default = "127.0.0.1:8118"; - description = lib.mdDoc "The address and TCP port on which privoxy will listen."; + description = "The address and TCP port on which privoxy will listen."; }; services.privoxy.package = mkOption { type = types.package; default = pkgs.privoxy; example = literalExpression "pkgs.privoxy"; - description = lib.mdDoc "This option specifies the privoxy package to use."; + description = "This option specifies the privoxy package to use."; }; services.privoxy.config = mkOption { type = types.lines; default = ""; example = "forward / upstream.proxy:8080"; - description = lib.mdDoc "Config to use for privoxy"; + description = "Config to use for privoxy"; }; services.privoxy.templdir = mkOption { type = types.path; default = "${pkgs.privoxy}/etc/templates"; defaultText = "\${pkgs.privoxy}/etc/templates"; - description = lib.mdDoc "Directory for privoxy template files."; + description = "Directory for privoxy template files."; }; services.privoxy.confdir = mkOption { type = types.nullOr types.path; default = null; - description = lib.mdDoc "Directory for privoxy files such as .action and .filter."; + description = "Directory for privoxy files such as .action and .filter."; }; }; diff --git a/modules/services/redis/default.nix b/modules/services/redis/default.nix index 0fa0af7e3..ccacd3b5e 100644 --- a/modules/services/redis/default.nix +++ b/modules/services/redis/default.nix @@ -11,52 +11,52 @@ in services.redis.enable = mkOption { type = types.bool; default = false; - description = lib.mdDoc "Whether to enable the redis database service."; + description = "Whether to enable the redis database service."; }; services.redis.package = mkOption { type = types.path; default = pkgs.redis; defaultText = "pkgs.redis"; - description = lib.mdDoc "This option specifies the redis package to use"; + description = "This option specifies the redis package to use"; }; services.redis.dataDir = mkOption { type = types.nullOr types.path; default = "/var/lib/redis"; - description = lib.mdDoc "Data directory for the redis database."; + description = "Data directory for the redis database."; }; services.redis.port = mkOption { type = types.int; default = 6379; - description = lib.mdDoc "The port for Redis to listen to."; + description = "The port for Redis to listen to."; }; services.redis.bind = mkOption { type = types.nullOr types.str; default = null; # All interfaces - description = lib.mdDoc "The IP interface to bind to."; + description = "The IP interface to bind to."; example = "127.0.0.1"; }; services.redis.unixSocket = mkOption { type = types.nullOr types.path; default = null; - description = lib.mdDoc "The path to the socket to bind to."; + description = "The path to the socket to bind to."; example = "/var/run/redis.sock"; }; services.redis.appendOnly = mkOption { type = types.bool; default = false; - description = lib.mdDoc "By default data is only periodically persisted to disk, enable this option to use an append-only file for improved persistence."; + description = "By default data is only periodically persisted to disk, enable this option to use an append-only file for improved persistence."; }; services.redis.extraConfig = mkOption { type = types.lines; default = ""; - description = lib.mdDoc "Additional text to be appended to {file}`redis.conf`."; + description = "Additional text to be appended to {file}`redis.conf`."; }; }; diff --git a/modules/services/sketchybar/default.nix b/modules/services/sketchybar/default.nix index 0cc4f6fc7..228636e30 100644 --- a/modules/services/sketchybar/default.nix +++ b/modules/services/sketchybar/default.nix @@ -1,7 +1,7 @@ { config, lib, pkgs, ... }: let - inherit (lib) literalExpression maintainers mdDoc mkEnableOption mkIf mkPackageOptionMD mkOption optionals types; + inherit (lib) literalExpression maintainers mkEnableOption mkIf mkPackageOptionMD mkOption optionals types; cfg = config.services.sketchybar; @@ -15,7 +15,7 @@ in ]; options.services.sketchybar = { - enable = mkEnableOption (mdDoc "sketchybar"); + enable = mkEnableOption "sketchybar"; package = mkPackageOptionMD pkgs "sketchybar" { }; @@ -23,7 +23,7 @@ in type = types.listOf types.package; default = [ ]; example = literalExpression "[ pkgs.jq ]"; - description = mdDoc '' + description = '' Extra packages to add to PATH. ''; }; @@ -36,7 +36,7 @@ in sketchybar --update echo "sketchybar configuration loaded.." ''; - description = mdDoc '' + description = '' Contents of sketchybar's configuration file. If empty (the default), the configuration file won't be managed. See [documentation](https://felixkratz.github.io/SketchyBar/) diff --git a/modules/services/skhd/default.nix b/modules/services/skhd/default.nix index 4ec1e2bf1..72b52d4be 100644 --- a/modules/services/skhd/default.nix +++ b/modules/services/skhd/default.nix @@ -11,20 +11,20 @@ in services.skhd.enable = mkOption { type = types.bool; default = false; - description = lib.mdDoc "Whether to enable the skhd hotkey daemon."; + description = "Whether to enable the skhd hotkey daemon."; }; services.skhd.package = mkOption { type = types.package; default = pkgs.skhd; - description = lib.mdDoc "This option specifies the skhd package to use."; + description = "This option specifies the skhd package to use."; }; services.skhd.skhdConfig = mkOption { type = types.lines; default = ""; example = "alt + shift - r : chunkc quit"; - description = lib.mdDoc "Config to use for {file}`skhdrc`."; + description = "Config to use for {file}`skhdrc`."; }; }; diff --git a/modules/services/spacebar/default.nix b/modules/services/spacebar/default.nix index eb06cada5..a56dac537 100644 --- a/modules/services/spacebar/default.nix +++ b/modules/services/spacebar/default.nix @@ -22,12 +22,12 @@ in services.spacebar.enable = mkOption { type = bool; default = false; - description = lib.mdDoc "Whether to enable the spacebar spacebar."; + description = "Whether to enable the spacebar spacebar."; }; services.spacebar.package = mkOption { type = path; - description = lib.mdDoc "The spacebar package to use."; + description = "The spacebar package to use."; }; services.spacebar.config = mkOption { @@ -40,7 +40,7 @@ in foreground_color = "0xffa8a8a8"; } ''; - description = lib.mdDoc '' + description = '' Key/Value pairs to pass to spacebar's 'config' domain, via the configuration file. ''; }; @@ -51,7 +51,7 @@ in example = literalExpression '' echo "spacebar config loaded..." ''; - description = lib.mdDoc '' + description = '' Extra arbitrary configuration to append to the configuration file. ''; }; diff --git a/modules/services/spotifyd.nix b/modules/services/spotifyd.nix index 2469a2458..612bae13a 100644 --- a/modules/services/spotifyd.nix +++ b/modules/services/spotifyd.nix @@ -19,7 +19,7 @@ in enable = mkOption { type = types.bool; default = false; - description = lib.mdDoc '' + description = '' Whether to enable the spotifyd service. ''; }; @@ -28,7 +28,7 @@ in type = types.path; default = pkgs.spotifyd; defaultText = "pkgs.spotifyd"; - description = lib.mdDoc '' + description = '' The spotifyd package to use. ''; }; @@ -40,7 +40,7 @@ in bitrate = 160; volume_normalisation = true; }; - description = lib.mdDoc '' + description = '' Configuration for spotifyd, see for supported values. ''; diff --git a/modules/services/synapse-bt.nix b/modules/services/synapse-bt.nix index 3970cac76..d85a2cd0f 100644 --- a/modules/services/synapse-bt.nix +++ b/modules/services/synapse-bt.nix @@ -26,32 +26,32 @@ in enable = mkOption { type = types.bool; default = false; - description = lib.mdDoc "Whether to run Synapse BitTorrent Daemon."; + description = "Whether to run Synapse BitTorrent Daemon."; }; package = mkOption { type = types.package; default = pkgs.synapse-bt; defaultText = "pkgs.synapse-bt"; - description = lib.mdDoc "Synapse BitTorrent package to use."; + description = "Synapse BitTorrent package to use."; }; port = mkOption { type = types.int; default = 16384; - description = lib.mdDoc "The port on which Synapse BitTorrent listens."; + description = "The port on which Synapse BitTorrent listens."; }; downloadDir = mkOption { type = types.path; default = "/var/lib/synapse-bt"; example = "/var/lib/synapse-bt/downloads"; - description = lib.mdDoc "Download directory for Synapse BitTorrent."; + description = "Download directory for Synapse BitTorrent."; }; extraConfig = mkOption { default = {}; - description = lib.mdDoc "Extra configuration options for Synapse BitTorrent."; + description = "Extra configuration options for Synapse BitTorrent."; type = types.attrs; }; }; diff --git a/modules/services/synergy/default.nix b/modules/services/synergy/default.nix index 9933fe6eb..2a9e088ca 100644 --- a/modules/services/synergy/default.nix +++ b/modules/services/synergy/default.nix @@ -16,28 +16,28 @@ in default = pkgs.synergy; defaultText = "pkgs.synergy"; type = types.package; - description = lib.mdDoc "The package used for the synergy client and server."; + description = "The package used for the synergy client and server."; }; client = { enable = mkOption { default = false; type = types.bool; - description = lib.mdDoc '' + description = '' Whether to enable the Synergy client (receive keyboard and mouse events from a Synergy server). ''; }; screenName = mkOption { default = ""; type = types.str; - description = lib.mdDoc '' + description = '' Use the given name instead of the hostname to identify ourselves to the server. ''; }; serverAddress = mkOption { type = types.str; - description = lib.mdDoc '' + description = '' The server address is of the form: [hostname][:port]. The hostname must be the address or hostname of the server. The port overrides the default port, 24800. @@ -46,20 +46,20 @@ in autoStart = mkOption { default = true; type = types.bool; - description = lib.mdDoc "Whether the Synergy client should be started automatically."; + description = "Whether the Synergy client should be started automatically."; }; tls = { - enable = mkEnableOption (lib.mdDoc '' + enable = mkEnableOption '' Whether TLS encryption should be used. Using this requires a TLS certificate that can be generated by starting the Synergy GUI once and entering - a valid product key''); + a valid product key''; cert = mkOption { type = types.nullOr types.str; default = null; example = "~/.synergy/SSL/Synergy.pem"; - description = lib.mdDoc "The TLS certificate to use for encryption."; + description = "The TLS certificate to use for encryption."; }; }; }; @@ -68,19 +68,19 @@ in enable = mkOption { default = false; type = types.bool; - description = lib.mdDoc '' + description = '' Whether to enable the Synergy server (send keyboard and mouse events). ''; }; configFile = mkOption { default = "/etc/synergy-server.conf"; type = types.str; - description = lib.mdDoc "The Synergy server configuration file."; + description = "The Synergy server configuration file."; }; screenName = mkOption { default = ""; type = types.str; - description = lib.mdDoc '' + description = '' Use the given name instead of the hostname to identify this screen in the configuration. ''; @@ -88,25 +88,25 @@ in address = mkOption { default = ""; type = types.str; - description = lib.mdDoc "Address on which to listen for clients."; + description = "Address on which to listen for clients."; }; autoStart = mkOption { default = true; type = types.bool; - description = lib.mdDoc "Whether the Synergy server should be started automatically."; + description = "Whether the Synergy server should be started automatically."; }; tls = { - enable = mkEnableOption (lib.mdDoc '' + enable = mkEnableOption '' Whether TLS encryption should be used. Using this requires a TLS certificate that can be generated by starting the Synergy GUI once and entering - a valid product key''); + a valid product key''; cert = mkOption { type = types.nullOr types.str; default = null; example = "~/.synergy/SSL/Synergy.pem"; - description = lib.mdDoc "The TLS certificate to use for encryption."; + description = "The TLS certificate to use for encryption."; }; }; }; diff --git a/modules/services/tailscale.nix b/modules/services/tailscale.nix index 4135ade39..3c826cff8 100644 --- a/modules/services/tailscale.nix +++ b/modules/services/tailscale.nix @@ -13,20 +13,20 @@ in ]; options.services.tailscale = { - enable = mkEnableOption (lib.mdDoc "Tailscale client daemon"); + enable = mkEnableOption "Tailscale client daemon"; package = mkOption { type = types.package; default = pkgs.tailscale; defaultText = literalExpression "pkgs.tailscale"; - description = lib.mdDoc "The package to use for tailscale"; + description = "The package to use for tailscale"; }; overrideLocalDns = mkOption { type = types.bool; default = false; example = true; - description = lib.mdDoc '' + description = '' This option implements `Override local DNS` as it is not yet implemented in Tailscaled-on-macOS. To use this option, in the Tailscale control panel: diff --git a/modules/services/trezord.nix b/modules/services/trezord.nix new file mode 100644 index 000000000..8da05f342 --- /dev/null +++ b/modules/services/trezord.nix @@ -0,0 +1,47 @@ +{ config, lib, pkgs, ... }: + +with lib; +let + cfg = config.services.trezord; +in { + # Options copied from: + # https://github.com/NixOS/nixpkgs/blob/9d6e454b857fb472fa35fc8b098fa5ac307a0d7d/nixos/modules/services/hardware/trezord.nix#L16 + options = { + services.trezord = { + enable = mkOption { + type = types.bool; + default = false; + description = '' + Enable Trezor bridge daemon, for use with Trezor hardware wallets. + ''; + }; + + emulator.enable = mkOption { + type = types.bool; + default = false; + description = '' + Enable Trezor emulator support. + ''; + }; + + emulator.port = mkOption { + type = types.port; + default = 21324; + description = '' + Listening port for the Trezor emulator. + ''; + }; + }; + }; + + config = mkIf cfg.enable { + launchd.user.agents.trezord = { + serviceConfig = { + ProgramArguments = [ "${pkgs.trezord}/bin/trezord-go" ] + ++ optionals cfg.emulator.enable [ "-e" (builtins.toString cfg.emulator.port) ]; + KeepAlive = true; + RunAtLoad = true; + }; + }; + }; +} diff --git a/modules/services/wg-quick.nix b/modules/services/wg-quick.nix index 1e0b86519..fab7a845c 100644 --- a/modules/services/wg-quick.nix +++ b/modules/services/wg-quick.nix @@ -10,32 +10,32 @@ let allowedIPs = mkOption { type = types.listOf types.str; default = [ ]; - description = lib.mdDoc "List of IP addresses associated with this peer."; + description = "List of IP addresses associated with this peer."; }; endpoint = mkOption { type = types.nullOr types.str; default = null; - description = lib.mdDoc "IP and port to connect to this peer at."; + description = "IP and port to connect to this peer at."; }; persistentKeepalive = mkOption { type = types.nullOr types.int; default = null; - description = lib.mdDoc "Interval in seconds to send keepalive packets"; + description = "Interval in seconds to send keepalive packets"; }; presharedKeyFile = mkOption { type = types.nullOr types.str; default = null; description = - lib.mdDoc "Optional, path to file containing the pre-shared key for this peer."; + "Optional, path to file containing the pre-shared key for this peer."; }; publicKey = mkOption { default = null; type = types.str; - description = lib.mdDoc "The public key for this peer."; + description = "The public key for this peer."; }; }; }; @@ -45,75 +45,75 @@ let address = mkOption { type = types.nullOr (types.listOf types.str); default = [ ]; - description = lib.mdDoc "List of IP addresses for this interface."; + description = "List of IP addresses for this interface."; }; autostart = mkOption { type = types.bool; default = true; description = - lib.mdDoc "Whether to bring up this interface automatically during boot."; + "Whether to bring up this interface automatically during boot."; }; dns = mkOption { type = types.listOf types.str; default = [ ]; - description = lib.mdDoc "List of DNS servers for this interface."; + description = "List of DNS servers for this interface."; }; listenPort = mkOption { type = types.nullOr types.int; default = null; - description = lib.mdDoc "Port to listen on, randomly selected if not specified."; + description = "Port to listen on, randomly selected if not specified."; }; mtu = mkOption { type = types.nullOr types.int; default = null; description = - lib.mdDoc "MTU to set for this interface, automatically set if not specified"; + "MTU to set for this interface, automatically set if not specified"; }; peers = mkOption { type = types.listOf (types.submodule peerOpts); default = [ ]; - description = lib.mdDoc "List of peers associated with this interface."; + description = "List of peers associated with this interface."; }; preDown = mkOption { type = with types; coercedTo (listOf str) (concatStringsSep "\n") lines; default = ""; - description = lib.mdDoc "List of commadns to run before interface shutdown."; + description = "List of commadns to run before interface shutdown."; }; preUp = mkOption { type = with types; coercedTo (listOf str) (concatStringsSep "\n") lines; default = ""; - description = lib.mdDoc "List of commands to run before interface setup."; + description = "List of commands to run before interface setup."; }; postDown = mkOption { type = with types; coercedTo (listOf str) (concatStringsSep "\n") lines; default = ""; - description = lib.mdDoc "List of commands to run after interface shutdown"; + description = "List of commands to run after interface shutdown"; }; postUp = mkOption { type = with types; coercedTo (listOf str) (concatStringsSep "\n") lines; default = ""; - description = lib.mdDoc "List of commands to run after interface setup."; + description = "List of commands to run after interface setup."; }; privateKeyFile = mkOption { type = types.str; default = null; - description = lib.mdDoc "Path to file containing this interface's private key."; + description = "Path to file containing this interface's private key."; }; table = mkOption { type = types.nullOr types.str; default = null; - description = lib.mdDoc '' + description = '' Controls the routing table to which routes are added. There are two special values: `off` disables the creation of routes altogether, and `auto` (the default) adds routes to the default table and @@ -208,13 +208,13 @@ in { interfaces = mkOption { type = types.attrsOf (types.submodule interfaceOpts); default = { }; - description = lib.mdDoc "Set of wg-quick interfaces."; + description = "Set of wg-quick interfaces."; }; logDir = mkOption { type = types.str; default = "/var/log"; - description = lib.mdDoc "Directory to save wg-quick logs to."; + description = "Directory to save wg-quick logs to."; }; }; }; diff --git a/modules/services/yabai/default.nix b/modules/services/yabai/default.nix index d6af899c4..fe9d3f96f 100644 --- a/modules/services/yabai/default.nix +++ b/modules/services/yabai/default.nix @@ -7,9 +7,10 @@ let toYabaiConfig = opts: concatStringsSep "\n" (mapAttrsToList - (p: v: "yabai -m config ${p} ${toString v}") opts); + (p: v: "yabai -m config ${p} ${toString v}") + opts); - configFile = mkIf (cfg.config != {} || cfg.extraConfig != "") + configFile = mkIf (cfg.config != { } || cfg.extraConfig != "") "${pkgs.writeScript "yabairc" ( (if (cfg.config != {}) then "${toYabaiConfig cfg.config}" @@ -22,19 +23,19 @@ in services.yabai.enable = mkOption { type = bool; default = false; - description = lib.mdDoc "Whether to enable the yabai window manager."; + description = "Whether to enable the yabai window manager."; }; services.yabai.package = mkOption { type = path; default = pkgs.yabai; - description = lib.mdDoc "The yabai package to use."; + description = "The yabai package to use."; }; services.yabai.enableScriptingAddition = mkOption { type = bool; default = false; - description = lib.mdDoc '' + description = '' Whether to enable yabai's scripting-addition. SIP must be disabled for this to work. ''; @@ -42,7 +43,7 @@ in services.yabai.config = mkOption { type = attrs; - default = {}; + default = { }; example = literalExpression '' { focus_follows_mouse = "autoraise"; @@ -56,7 +57,7 @@ in window_gap = 10; } ''; - description = lib.mdDoc '' + description = '' Key/Value pairs to pass to yabai's 'config' domain, via the configuration file. ''; }; @@ -67,7 +68,7 @@ in example = literalExpression '' yabai -m rule --add app='System Preferences' manage=off ''; - description = lib.mdDoc "Extra arbitrary configuration to append to the configuration file"; + description = "Extra arbitrary configuration to append to the configuration file"; }; }; @@ -77,7 +78,7 @@ in launchd.user.agents.yabai = { serviceConfig.ProgramArguments = [ "${cfg.package}/bin/yabai" ] - ++ optionals (cfg.config != {} || cfg.extraConfig != "") [ "-c" configFile ]; + ++ optionals (cfg.config != { } || cfg.extraConfig != "") [ "-c" configFile ]; serviceConfig.KeepAlive = true; serviceConfig.RunAtLoad = true; @@ -90,17 +91,18 @@ in # TODO: [@cmacrae] Handle removal of yabai scripting additions (mkIf (cfg.enableScriptingAddition) { launchd.daemons.yabai-sa = { - script = '' - if [ ! $(${cfg.package}/bin/yabai --check-sa) ]; then - ${cfg.package}/bin/yabai --install-sa - fi - - ${cfg.package}/bin/yabai --load-sa - ''; - + script = "${cfg.package}/bin/yabai --load-sa"; serviceConfig.RunAtLoad = true; serviceConfig.KeepAlive.SuccessfulExit = false; }; + + environment.etc."sudoers.d/yabai".source = pkgs.runCommand "sudoers-yabai" {} '' + YABAI_BIN="${cfg.package}/bin/yabai" + SHASUM=$(sha256sum "$YABAI_BIN" | cut -d' ' -f1) + cat <"$out" + %admin ALL=(root) NOPASSWD: sha256:$SHASUM $YABAI_BIN --load-sa + EOF + ''; }) ]; } diff --git a/modules/system/activation-scripts.nix b/modules/system/activation-scripts.nix index 67d69bed7..1495a7b23 100644 --- a/modules/system/activation-scripts.nix +++ b/modules/system/activation-scripts.nix @@ -22,7 +22,7 @@ in internal = true; type = types.attrsOf (types.submodule script); default = {}; - description = lib.mdDoc '' + description = '' A set of shell script fragments that are executed when a NixOS system configuration is activated. Examples are updating /etc, creating accounts, and so on. Since these are executed @@ -69,6 +69,7 @@ in ${cfg.activationScripts.networking.text} ${cfg.activationScripts.keyboard.text} ${cfg.activationScripts.fonts.text} + ${cfg.activationScripts.nvram.text} ${cfg.activationScripts.postActivation.text} diff --git a/modules/system/checks.nix b/modules/system/checks.nix index 27188e350..f0f03e80e 100644 --- a/modules/system/checks.nix +++ b/modules/system/checks.nix @@ -191,6 +191,17 @@ let 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.optimiser.user = \"$USER\";" >&2 + echo >&2 + exit 2 + fi + ''; in { @@ -198,19 +209,19 @@ in system.checks.verifyNixPath = mkOption { type = types.bool; default = true; - description = lib.mdDoc "Whether to run the NIX_PATH validation checks."; + description = "Whether to run the NIX_PATH validation checks."; }; system.checks.verifyNixChannels = mkOption { type = types.bool; default = true; - description = lib.mdDoc "Whether to run the nix-channels validation checks."; + description = "Whether to run the nix-channels validation checks."; }; system.checks.verifyBuildUsers = mkOption { type = types.bool; default = true; - description = lib.mdDoc "Whether to run the Nix build users validation checks."; + description = "Whether to run the Nix build users validation checks."; }; system.checks.text = mkOption { @@ -230,6 +241,7 @@ in (mkIf (!config.nix.useDaemon) singleUser) 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) nixInstaller (mkIf cfg.verifyNixPath nixPath) diff --git a/modules/system/default.nix b/modules/system/default.nix index 0eb46a9d7..285936c56 100644 --- a/modules/system/default.nix +++ b/modules/system/default.nix @@ -22,7 +22,7 @@ in internal = true; type = types.attrsOf types.unspecified; default = {}; - description = lib.mdDoc '' + description = '' Attribute set of derivation used to setup the system. ''; }; @@ -30,7 +30,7 @@ in system.path = mkOption { internal = true; type = types.package; - description = lib.mdDoc '' + description = '' The packages you want in the system environment. ''; }; @@ -38,7 +38,7 @@ in system.profile = mkOption { type = types.path; default = "/nix/var/nix/profiles/system"; - description = lib.mdDoc '' + description = '' Profile to use for the system. ''; }; @@ -56,7 +56,7 @@ in internal = true; type = types.attrsOf types.unspecified; default = {}; - description = lib.mdDoc '' + description = '' `lib.mkDerivation` attributes that will be passed to the top level system builder. ''; }; @@ -66,7 +66,7 @@ in internal = true; default = []; example = [ { assertion = false; message = "you can't enable this for that reason"; } ]; - description = lib.mdDoc '' + description = '' This option allows modules to express conditions that must hold for the evaluation of the system configuration to succeed, along with associated error messages for the user. @@ -78,7 +78,7 @@ in default = []; type = types.listOf types.str; example = [ "The `foo' service is deprecated and will go away soon!" ]; - description = lib.mdDoc '' + description = '' This option allows modules to show warnings to users during the evaluation of the system configuration. ''; @@ -135,6 +135,7 @@ in echo -n "$systemConfig" > $out/systemConfig + echo -n "$darwinLabel" > $out/darwin-version ln -s $darwinVersionJson $out/darwin-version.json echo -n "$system" > $out/system diff --git a/modules/system/defaults-write.nix b/modules/system/defaults-write.nix index 2e56d74a5..7e1fc443f 100644 --- a/modules/system/defaults-write.nix +++ b/modules/system/defaults-write.nix @@ -5,18 +5,8 @@ with lib; let cfg = config.system.defaults; - boolValue = x: if x then "YES" else "NO"; - - writeValue = value: - if isBool value then "-bool ${boolValue value}" else - if isInt value then "-int ${toString value}" else - if isFloat value then "-float ${strings.floatToString value}" else - if isString value then "-string '${value}'" else - if isList value then "-array ${concatStringsSep " " (map (v: writeValue v)value)}" else - throw "invalid value type"; - writeDefault = domain: key: value: - "defaults write ${domain} '${key}' ${writeValue value}"; + "defaults write ${domain} '${key}' $'${strings.escape [ "'" ] (generators.toPlist { } value)}'"; defaultsToList = domain: attrs: mapAttrsToList (writeDefault domain) (filterAttrs (n: v: v != null) attrs); diff --git a/modules/system/defaults/ActivityMonitor.nix b/modules/system/defaults/ActivityMonitor.nix index 9f4617cbe..8786375f2 100644 --- a/modules/system/defaults/ActivityMonitor.nix +++ b/modules/system/defaults/ActivityMonitor.nix @@ -8,7 +8,7 @@ with lib; system.defaults.ActivityMonitor.ShowCategory = mkOption { type = types.nullOr (types.enum [100 101 102 103 104 105 106 107]); default = null; - description = lib.mdDoc '' + description = '' Change which processes to show. * 100: All Processes * 101: All Processes, Hierarchally @@ -25,7 +25,7 @@ with lib; system.defaults.ActivityMonitor.IconType = mkOption { type = types.nullOr types.int; default = null; - description = lib.mdDoc '' + description = '' Change the icon in the dock when running. * 0: Application Icon * 2: Network Usage @@ -39,7 +39,7 @@ with lib; system.defaults.ActivityMonitor.SortColumn = mkOption { type = types.nullOr types.str; default = null; - description = lib.mdDoc '' + description = '' Which column to sort the main activity page (such as "CPUUsage"). Default is null. ''; }; @@ -47,7 +47,7 @@ with lib; system.defaults.ActivityMonitor.SortDirection = mkOption { type = types.nullOr types.int; default = null; - description = lib.mdDoc '' + description = '' The sort direction of the sort column (0 is decending). Default is null. ''; }; @@ -55,7 +55,7 @@ with lib; system.defaults.ActivityMonitor.OpenMainWindow = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Open the main window when opening Activity Monitor. Default is true. ''; }; diff --git a/modules/system/defaults/CustomPreferences.nix b/modules/system/defaults/CustomPreferences.nix index 134c8d025..1b4b99b19 100644 --- a/modules/system/defaults/CustomPreferences.nix +++ b/modules/system/defaults/CustomPreferences.nix @@ -14,7 +14,7 @@ with lib; true; }; }; - description = lib.mdDoc '' + description = '' Sets custom user preferences ''; }; @@ -29,7 +29,7 @@ with lib; true; }; }; - description = lib.mdDoc '' + description = '' Sets custom system preferences ''; }; diff --git a/modules/system/defaults/GlobalPreferences.nix b/modules/system/defaults/GlobalPreferences.nix index e6964aad6..970971127 100644 --- a/modules/system/defaults/GlobalPreferences.nix +++ b/modules/system/defaults/GlobalPreferences.nix @@ -3,15 +3,7 @@ with lib; let - isFloat = x: isString x && builtins.match "^[+-]?([0-9]*[.])?[0-9]+$" x != null; - - float = mkOptionType { - name = "float"; - description = "float"; - check = isFloat; - merge = options.mergeOneOption; - }; - + inherit (config.lib.defaults.types) floatWithDeprecationError; in { options = { @@ -19,7 +11,7 @@ in { mkOption { type = types.nullOr (types.path); default = null; - description = lib.mdDoc '' + description = '' Sets the system-wide alert sound. Found under "Sound Effects" in the "Sound" section of "System Preferences". Look in "/System/Library/Sounds" for possible candidates. @@ -28,11 +20,12 @@ in { system.defaults.".GlobalPreferences"."com.apple.mouse.scaling" = mkOption { - type = types.nullOr float; + type = types.nullOr floatWithDeprecationError; default = null; - description = lib.mdDoc '' + example = -1.0; + description = '' Sets the mouse tracking speed. Found in the "Mouse" section of - "System Preferences". Set to -1 to disable mouse acceleration. + "System Preferences". Set to -1.0 to disable mouse acceleration. ''; }; }; diff --git a/modules/system/defaults/LaunchServices.nix b/modules/system/defaults/LaunchServices.nix index b76231f4e..d9ffcdaff 100644 --- a/modules/system/defaults/LaunchServices.nix +++ b/modules/system/defaults/LaunchServices.nix @@ -8,7 +8,7 @@ with lib; system.defaults.LaunchServices.LSQuarantine = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Whether to enable quarantine for downloaded applications. The default is true. ''; }; diff --git a/modules/system/defaults/NSGlobalDomain.nix b/modules/system/defaults/NSGlobalDomain.nix index 4f08d4ade..cd008e0ba 100644 --- a/modules/system/defaults/NSGlobalDomain.nix +++ b/modules/system/defaults/NSGlobalDomain.nix @@ -11,7 +11,7 @@ in { system.defaults.NSGlobalDomain.AppleShowAllFiles = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Whether to always show hidden files. The default is false. ''; }; @@ -19,7 +19,7 @@ in { system.defaults.NSGlobalDomain.AppleEnableMouseSwipeNavigateWithScrolls = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Enables swiping left or right with two fingers to navigate backward or forward. The default is true. ''; }; @@ -27,7 +27,7 @@ in { system.defaults.NSGlobalDomain.AppleEnableSwipeNavigateWithScrolls = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Enables swiping left or right with two fingers to navigate backward or forward. The default is true. ''; }; @@ -35,7 +35,7 @@ in { system.defaults.NSGlobalDomain.AppleFontSmoothing = mkOption { type = types.nullOr (types.enum [ 0 1 2 ]); default = null; - description = lib.mdDoc '' + description = '' Sets the level of font smoothing (sub-pixel font rendering). ''; }; @@ -43,7 +43,7 @@ in { system.defaults.NSGlobalDomain.AppleInterfaceStyle = mkOption { type = types.nullOr (types.enum [ "Dark" ]); default = null; - description = lib.mdDoc '' + description = '' Set to 'Dark' to enable dark mode, or leave unset for normal mode. ''; }; @@ -51,7 +51,7 @@ in { system.defaults.NSGlobalDomain.AppleInterfaceStyleSwitchesAutomatically = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Whether to automatically switch between light and dark mode. The default is false. ''; }; @@ -59,7 +59,7 @@ in { system.defaults.NSGlobalDomain.AppleKeyboardUIMode = mkOption { type = types.nullOr (types.enum [ 3 ]); default = null; - description = lib.mdDoc '' + description = '' Configures the keyboard control behavior. Mode 3 enables full keyboard control. ''; }; @@ -67,7 +67,7 @@ in { system.defaults.NSGlobalDomain.ApplePressAndHoldEnabled = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Whether to enable the press-and-hold feature. The default is true. ''; }; @@ -75,7 +75,7 @@ in { system.defaults.NSGlobalDomain.AppleShowAllExtensions = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Whether to show all file extensions in Finder. The default is false. ''; }; @@ -83,7 +83,7 @@ in { system.defaults.NSGlobalDomain.AppleShowScrollBars = mkOption { type = types.nullOr (types.enum [ "WhenScrolling" "Automatic" "Always" ]); default = null; - description = lib.mdDoc '' + description = '' When to show the scrollbars. Options are 'WhenScrolling', 'Automatic' and 'Always'. ''; }; @@ -91,7 +91,7 @@ in { system.defaults.NSGlobalDomain.AppleScrollerPagingBehavior = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Jump to the spot that's clicked on the scroll bar. The default is false. ''; }; @@ -99,7 +99,7 @@ in { system.defaults.NSGlobalDomain.NSAutomaticCapitalizationEnabled = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Whether to enable automatic capitalization. The default is true. ''; }; @@ -107,7 +107,7 @@ in { system.defaults.NSGlobalDomain.NSAutomaticDashSubstitutionEnabled = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Whether to enable smart dash substitution. The default is true. ''; }; @@ -115,7 +115,7 @@ in { system.defaults.NSGlobalDomain.NSAutomaticPeriodSubstitutionEnabled = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Whether to enable smart period substitution. The default is true. ''; }; @@ -123,7 +123,7 @@ in { system.defaults.NSGlobalDomain.NSAutomaticQuoteSubstitutionEnabled = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Whether to enable smart quote substitution. The default is true. ''; }; @@ -131,7 +131,7 @@ in { system.defaults.NSGlobalDomain.NSAutomaticSpellingCorrectionEnabled = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Whether to enable automatic spelling correction. The default is true. ''; }; @@ -139,7 +139,7 @@ in { system.defaults.NSGlobalDomain.NSAutomaticWindowAnimationsEnabled = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Whether to animate opening and closing of windows and popovers. The default is true. ''; }; @@ -147,7 +147,7 @@ in { system.defaults.NSGlobalDomain.NSDisableAutomaticTermination = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Whether to disable the automatic termination of inactive apps. ''; }; @@ -155,7 +155,7 @@ in { system.defaults.NSGlobalDomain.NSDocumentSaveNewDocumentsToCloud = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Whether to save new documents to iCloud by default. The default is true. ''; }; @@ -163,7 +163,7 @@ in { system.defaults.NSGlobalDomain.AppleWindowTabbingMode = mkOption { type = types.nullOr (types.enum [ "manual" "always" "fullscreen" ]); default = null; - description = lib.mdDoc '' + description = '' Sets the window tabbing when opening a new document: 'manual', 'always', or 'fullscreen'. The default is 'fullscreen'. ''; }; @@ -171,7 +171,7 @@ in { system.defaults.NSGlobalDomain.NSNavPanelExpandedStateForSaveMode = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Whether to use expanded save panel by default. The default is false. ''; }; @@ -179,7 +179,7 @@ in { system.defaults.NSGlobalDomain.NSNavPanelExpandedStateForSaveMode2 = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Whether to use expanded save panel by default. The default is false. ''; }; @@ -187,7 +187,7 @@ in { system.defaults.NSGlobalDomain.NSTableViewDefaultSizeMode = mkOption { type = types.nullOr (types.enum [ 1 2 3 ]); default = null; - description = lib.mdDoc '' + description = '' Sets the size of the finder sidebar icons: 1 (small), 2 (medium) or 3 (large). The default is 3. ''; }; @@ -195,7 +195,7 @@ in { system.defaults.NSGlobalDomain.NSTextShowsControlCharacters = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Whether to display ASCII control characters using caret notation in standard text views. The default is false. ''; }; @@ -203,7 +203,7 @@ in { system.defaults.NSGlobalDomain.NSUseAnimatedFocusRing = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Whether to enable the focus ring animation. The default is true. ''; }; @@ -211,7 +211,7 @@ in { system.defaults.NSGlobalDomain.NSScrollAnimationEnabled = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Whether to enable smooth scrolling. The default is true. ''; }; @@ -220,15 +220,23 @@ in { type = types.nullOr floatWithDeprecationError; default = null; example = 0.20; - description = lib.mdDoc '' + description = '' Sets the speed speed of window resizing. The default is given in the example. ''; }; + system.defaults.NSGlobalDomain.NSWindowShouldDragOnGesture = mkOption { + type = types.nullOr types.bool; + default = null; + description = '' + Whether to enable moving window by holding anywhere on it like on Linux. The default is false. + ''; + }; + system.defaults.NSGlobalDomain.InitialKeyRepeat = mkOption { type = types.nullOr types.int; default = null; - description = lib.mdDoc '' + description = '' Apple menu > System Preferences > Keyboard If you press and hold certain keyboard keys when in a text area, the key’s character begins to repeat. @@ -241,7 +249,7 @@ in { system.defaults.NSGlobalDomain.KeyRepeat = mkOption { type = types.nullOr types.int; default = null; - description = lib.mdDoc '' + description = '' Apple menu > System Preferences > Keyboard If you press and hold certain keyboard keys when in a text area, the key’s character begins to repeat. @@ -254,7 +262,7 @@ in { system.defaults.NSGlobalDomain.PMPrintingExpandedStateForPrint = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Whether to use the expanded print panel by default. The default is false. ''; }; @@ -262,7 +270,7 @@ in { system.defaults.NSGlobalDomain.PMPrintingExpandedStateForPrint2 = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Whether to use the expanded print panel by default. The default is false. ''; }; @@ -270,7 +278,7 @@ in { system.defaults.NSGlobalDomain."com.apple.keyboard.fnState" = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Use F1, F2, etc. keys as standard function keys. ''; }; @@ -278,7 +286,7 @@ in { system.defaults.NSGlobalDomain."com.apple.mouse.tapBehavior" = mkOption { type = types.nullOr (types.enum [ 1 ]); default = null; - description = lib.mdDoc '' + description = '' Configures the trackpad tap behavior. Mode 1 enables tap to click. ''; }; @@ -286,7 +294,7 @@ in { system.defaults.NSGlobalDomain."com.apple.sound.beep.volume" = mkOption { type = types.nullOr floatWithDeprecationError; default = null; - description = lib.mdDoc '' + description = '' Apple menu > System Preferences > Sound Sets the beep/alert volume level from 0.000 (muted) to 1.000 (100% volume). @@ -302,7 +310,7 @@ in { system.defaults.NSGlobalDomain."com.apple.sound.beep.feedback" = mkOption { type = types.nullOr types.int; default = null; - description = lib.mdDoc '' + description = '' Apple menu > System Preferences > Sound Make a feedback sound when the system volume changed. This setting accepts @@ -313,7 +321,7 @@ in { system.defaults.NSGlobalDomain."com.apple.trackpad.enableSecondaryClick" = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Whether to enable trackpad secondary click. The default is true. ''; }; @@ -321,7 +329,7 @@ in { system.defaults.NSGlobalDomain."com.apple.trackpad.trackpadCornerClickBehavior" = mkOption { type = types.nullOr (types.enum [ 1 ]); default = null; - description = lib.mdDoc '' + description = '' Configures the trackpad corner click behavior. Mode 1 enables right click. ''; }; @@ -329,7 +337,7 @@ in { system.defaults.NSGlobalDomain."com.apple.trackpad.scaling" = mkOption { type = types.nullOr floatWithDeprecationError; default = null; - description = lib.mdDoc '' + description = '' Configures the trackpad tracking speed (0 to 3). The default is "1". ''; }; @@ -337,7 +345,7 @@ in { system.defaults.NSGlobalDomain."com.apple.springing.enabled" = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Whether to enable spring loading (expose) for directories. ''; }; @@ -346,7 +354,7 @@ in { type = types.nullOr floatWithDeprecationError; default = null; example = 1.0; - description = lib.mdDoc '' + description = '' Set the spring loading delay for directories. The default is given in the example. ''; }; @@ -354,7 +362,7 @@ in { system.defaults.NSGlobalDomain."com.apple.swipescrolldirection" = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Whether to enable "Natural" scrolling direction. The default is true. ''; }; @@ -362,7 +370,7 @@ in { system.defaults.NSGlobalDomain.AppleMeasurementUnits = mkOption { type = types.nullOr (types.enum [ "Centimeters" "Inches" ]); default = null; - description = lib.mdDoc '' + description = '' Whether to use centimeters (metric) or inches (US, UK) as the measurement unit. The default is based on region settings. ''; }; @@ -370,7 +378,7 @@ in { system.defaults.NSGlobalDomain.AppleMetricUnits = mkOption { type = types.nullOr (types.enum [ 0 1 ]); default = null; - description = lib.mdDoc '' + description = '' Whether to use the metric system. The default is based on region settings. ''; }; @@ -378,7 +386,7 @@ in { system.defaults.NSGlobalDomain.AppleTemperatureUnit = mkOption { type = types.nullOr (types.enum [ "Celsius" "Fahrenheit" ]); default = null; - description = lib.mdDoc '' + description = '' Whether to use Celsius or Fahrenheit. The default is based on region settings. ''; }; @@ -386,7 +394,7 @@ in { system.defaults.NSGlobalDomain.AppleICUForce24HourTime = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Whether to use 24-hour or 12-hour time. The default is based on region settings. ''; }; @@ -394,7 +402,7 @@ in { system.defaults.NSGlobalDomain._HIHideMenuBar = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Whether to autohide the menu bar. The default is false. ''; }; diff --git a/modules/system/defaults/SoftwareUpdate.nix b/modules/system/defaults/SoftwareUpdate.nix index 2882e8c63..ec89bce56 100644 --- a/modules/system/defaults/SoftwareUpdate.nix +++ b/modules/system/defaults/SoftwareUpdate.nix @@ -7,7 +7,7 @@ with lib; system.defaults.SoftwareUpdate.AutomaticallyInstallMacOSUpdates = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Automatically install Mac OS software updates. Defaults to false. ''; }; diff --git a/modules/system/defaults/alf.nix b/modules/system/defaults/alf.nix index 6b82eca0f..96a980646 100644 --- a/modules/system/defaults/alf.nix +++ b/modules/system/defaults/alf.nix @@ -7,7 +7,7 @@ with lib; system.defaults.alf.globalstate = mkOption { type = types.nullOr types.int; default = null; - description = lib.mdDoc '' + description = '' Apple menu > System Preferences > Security and Privacy > Firewall Enable the internal firewall to prevent unauthorised applications, programs @@ -22,7 +22,7 @@ with lib; system.defaults.alf.allowsignedenabled = mkOption { type = types.nullOr types.int; default = null; - description = lib.mdDoc '' + description = '' Apple menu > System Preferences > Security and Privacy > Firewall Allows any signed Application to accept incoming requests. Default is true. @@ -35,7 +35,7 @@ with lib; system.defaults.alf.allowdownloadsignedenabled = mkOption { type = types.nullOr types.int; default = null; - description = lib.mdDoc '' + description = '' Apple menu > System Preferences > Security and Privacy > Firewall Allows any downloaded Application that has been signed to accept incoming requests. Default is 0. @@ -48,7 +48,7 @@ with lib; system.defaults.alf.loggingenabled = mkOption { type = types.nullOr types.int; default = null; - description = lib.mdDoc '' + description = '' Apple menu > System Preferences > Security and Privacy > Firewall Enable logging of requests made to the firewall. Default is 0. @@ -61,7 +61,7 @@ with lib; system.defaults.alf.stealthenabled = mkOption { type = types.nullOr types.int; default = null; - description = lib.mdDoc '' + description = '' Apple menu > System Preferences > Security and firewall Drops incoming requests via ICMP such as ping requests. Default is 0. diff --git a/modules/system/defaults/clock.nix b/modules/system/defaults/clock.nix index cd5c0e847..3fae46401 100644 --- a/modules/system/defaults/clock.nix +++ b/modules/system/defaults/clock.nix @@ -8,7 +8,7 @@ with lib; system.defaults.menuExtraClock.IsAnalog = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Show an analog clock instead of a digital one. Default is null. ''; }; @@ -16,7 +16,7 @@ with lib; system.defaults.menuExtraClock.Show24Hour = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Show a 24-hour clock, instead of a 12-hour clock. Default is null. ''; }; @@ -24,7 +24,7 @@ with lib; system.defaults.menuExtraClock.ShowAMPM = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Show the AM/PM label. Useful if Show24Hour is false. Default is null. ''; }; @@ -32,7 +32,7 @@ with lib; system.defaults.menuExtraClock.ShowDayOfMonth = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Show the day of the month. Default is null. ''; }; @@ -40,7 +40,7 @@ with lib; system.defaults.menuExtraClock.ShowDayOfWeek = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Show the day of the week. Default is null. ''; }; @@ -48,21 +48,19 @@ with lib; system.defaults.menuExtraClock.ShowDate = mkOption { type = types.nullOr (types.enum [ 0 1 2 ]); default = null; - description = lib.mdDoc '' + description = '' Show the full date. Default is null. - 0 = Show the date - 1 = Don't show - 2 = Don't show - - TODO: I don't know what the difference is between 1 and 2. + 0 = When space allows + 1 = Always + 2 = Never ''; }; system.defaults.menuExtraClock.ShowSeconds = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Show the clock with second precision, instead of minutes. Default is null. ''; }; diff --git a/modules/system/defaults/dock.nix b/modules/system/defaults/dock.nix index 7fda0daf5..8c9741c8c 100644 --- a/modules/system/defaults/dock.nix +++ b/modules/system/defaults/dock.nix @@ -11,7 +11,7 @@ in { system.defaults.dock.appswitcher-all-displays = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Whether to display the appswitcher on all displays or only the main one. The default is false. ''; }; @@ -19,7 +19,7 @@ in { system.defaults.dock.autohide = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Whether to automatically hide and show the dock. The default is false. ''; }; @@ -28,7 +28,7 @@ in { type = types.nullOr floatWithDeprecationError; default = null; example = 0.24; - description = lib.mdDoc '' + description = '' Sets the speed of the autohide delay. The default is given in the example. ''; }; @@ -37,7 +37,7 @@ in { type = types.nullOr floatWithDeprecationError; default = null; example = 1.0; - description = lib.mdDoc '' + description = '' Sets the speed of the animation when hiding/showing the Dock. The default is given in the example. ''; }; @@ -45,7 +45,7 @@ in { system.defaults.dock.dashboard-in-overlay = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Whether to hide Dashboard as a Space. The default is false. ''; }; @@ -53,7 +53,7 @@ in { system.defaults.dock.enable-spring-load-actions-on-all-items = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Enable spring loading for all Dock items. The default is false. ''; }; @@ -62,7 +62,7 @@ in { type = types.nullOr floatWithDeprecationError; default = null; example = 1.0; - description = lib.mdDoc '' + description = '' Sets the speed of the Mission Control animations. The default is given in the example. ''; }; @@ -70,7 +70,7 @@ in { system.defaults.dock.expose-group-by-app = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Whether to group windows by application in Mission Control's Exposé. The default is true. ''; }; @@ -78,7 +78,7 @@ in { system.defaults.dock.launchanim = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Animate opening applications from the Dock. The default is true. ''; }; @@ -86,7 +86,7 @@ in { system.defaults.dock.mineffect = mkOption { type = types.nullOr (types.enum [ "genie" "suck" "scale" ]); default = null; - description = lib.mdDoc '' + description = '' Set the minimize/maximize window effect. The default is genie. ''; }; @@ -94,7 +94,7 @@ in { system.defaults.dock.minimize-to-application = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Whether to minimize windows into their application icon. The default is false. ''; }; @@ -102,7 +102,7 @@ in { system.defaults.dock.mouse-over-hilite-stack = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Enable highlight hover effect for the grid view of a stack in the Dock. ''; }; @@ -110,7 +110,7 @@ in { system.defaults.dock.mru-spaces = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Whether to automatically rearrange spaces based on most recent use. The default is true. ''; }; @@ -118,15 +118,41 @@ in { system.defaults.dock.orientation = mkOption { type = types.nullOr (types.enum [ "bottom" "left" "right" ]); default = null; - description = lib.mdDoc '' + description = '' Position of the dock on screen. The default is "bottom". ''; }; + system.defaults.dock.persistent-apps = mkOption { + type = types.nullOr (types.listOf (types.either types.path types.str)); + default = null; + example = [ "/Applications/Safari.app" "/System/Applications/Utilities/Terminal.app" ]; + description = '' + Persistent applications in the dock. + ''; + apply = value: + if !(isList value) + then value + else map (app: { tile-data = { file-data = { _CFURLString = app; _CFURLStringType = 0; }; }; }) value; + }; + + system.defaults.dock.persistent-others = mkOption { + type = types.nullOr (types.listOf (types.either types.path types.str)); + default = null; + example = [ "~/Documents" "~/Downloads" ]; + description = '' + Persistent folders in the dock. + ''; + apply = value: + if !(isList value) + then value + else map (folder: { tile-data = { file-data = { _CFURLString = folder; _CFURLStringType = 15; }; }; }) value; + }; + system.defaults.dock.show-process-indicators = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Show indicator lights for open applications in the Dock. The default is true. ''; }; @@ -134,7 +160,7 @@ in { system.defaults.dock.showhidden = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Whether to make icons of hidden applications tranclucent. The default is false. ''; }; @@ -142,7 +168,7 @@ in { system.defaults.dock.show-recents = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Show recent applications in the dock. The default is true. ''; }; @@ -150,7 +176,7 @@ in { system.defaults.dock.static-only = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Show only open applications in the Dock. The default is false. ''; }; @@ -158,7 +184,7 @@ in { system.defaults.dock.tilesize = mkOption { type = types.nullOr types.int; default = null; - description = lib.mdDoc '' + description = '' Size of the icons in the dock. The default is 64. ''; }; @@ -166,7 +192,7 @@ in { system.defaults.dock.magnification = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Magnify icon on hover. The default is false. ''; }; @@ -174,7 +200,7 @@ in { system.defaults.dock.largesize = mkOption { type = types.nullOr (types.ints.between 16 128); default = null; - description = lib.mdDoc '' + description = '' Magnified icon size on hover. The default is 16. ''; }; @@ -183,7 +209,7 @@ in { system.defaults.dock.wvous-tl-corner = mkOption { type = types.nullOr types.ints.positive; default = null; - description = lib.mdDoc '' + description = '' Hot corner action for top left corner. Valid values include: * `1`: Disabled @@ -204,7 +230,7 @@ in { system.defaults.dock.wvous-bl-corner = mkOption { type = types.nullOr types.ints.positive; default = null; - description = lib.mdDoc '' + description = '' Hot corner action for bottom left corner. Valid values include: * `1`: Disabled @@ -225,7 +251,7 @@ in { system.defaults.dock.wvous-tr-corner = mkOption { type = types.nullOr types.ints.positive; default = null; - description = lib.mdDoc '' + description = '' Hot corner action for top right corner. Valid values include: * `1`: Disabled @@ -246,7 +272,7 @@ in { system.defaults.dock.wvous-br-corner = mkOption { type = types.nullOr types.ints.positive; default = null; - description = lib.mdDoc '' + description = '' Hot corner action for bottom right corner. Valid values include: * `1`: Disabled diff --git a/modules/system/defaults/finder.nix b/modules/system/defaults/finder.nix index 1137e6ce0..478639f6e 100644 --- a/modules/system/defaults/finder.nix +++ b/modules/system/defaults/finder.nix @@ -8,7 +8,7 @@ with lib; system.defaults.finder.AppleShowAllFiles = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Whether to always show hidden files. The default is false. ''; }; @@ -16,7 +16,7 @@ with lib; system.defaults.finder.ShowStatusBar = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Show status bar at bottom of finder windows with item/disk space stats. The default is false. ''; }; @@ -24,7 +24,7 @@ with lib; system.defaults.finder.ShowPathbar = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Show path breadcrumbs in finder windows. The default is false. ''; }; @@ -32,7 +32,7 @@ with lib; system.defaults.finder.FXDefaultSearchScope = mkOption { type = types.nullOr types.str; default = null; - description = lib.mdDoc '' + description = '' Change the default search scope. Use "SCcf" to default to current folder. The default is unset ("This Mac"). ''; @@ -41,7 +41,7 @@ with lib; system.defaults.finder.FXPreferredViewStyle = mkOption { type = types.nullOr types.str; default = null; - description = lib.mdDoc '' + description = '' Change the default finder view. "icnv" = Icon view, "Nlsv" = List view, "clmv" = Column View, "Flwv" = Gallery View The default is icnv. @@ -51,7 +51,7 @@ with lib; system.defaults.finder.AppleShowAllExtensions = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Whether to always show file extensions. The default is false. ''; }; @@ -59,7 +59,7 @@ with lib; system.defaults.finder.CreateDesktop = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Whether to show icons on the desktop or not. The default is true. ''; }; @@ -67,7 +67,7 @@ with lib; system.defaults.finder.QuitMenuItem = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Whether to allow quitting of the Finder. The default is false. ''; }; @@ -75,7 +75,7 @@ with lib; system.defaults.finder._FXShowPosixPathInTitle = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Whether to show the full POSIX filepath in the window title. The default is false. ''; }; @@ -83,7 +83,7 @@ with lib; system.defaults.finder.FXEnableExtensionChangeWarning = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Whether to show warnings when change the file extension of files. The default is true. ''; }; diff --git a/modules/system/defaults/loginwindow.nix b/modules/system/defaults/loginwindow.nix index 81f7dfa97..a8a06ebf8 100644 --- a/modules/system/defaults/loginwindow.nix +++ b/modules/system/defaults/loginwindow.nix @@ -7,7 +7,7 @@ with lib; system.defaults.loginwindow.SHOWFULLNAME = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Apple menu > System Preferences > Users and Groups > Login Options Displays login window as a name and password field instead of a list of users. @@ -18,7 +18,7 @@ with lib; system.defaults.loginwindow.autoLoginUser = mkOption { type = types.nullOr types.str; default = null; - description = lib.mdDoc '' + description = '' Apple menu > System Preferences > Users and Groups > Login Options Auto login the supplied user on boot. Default is Off. @@ -28,7 +28,7 @@ with lib; system.defaults.loginwindow.GuestEnabled = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Apple menu > System Preferences > Users and Groups > Login Options Allow users to login to the machine as guests using the Guest account. Default is true. @@ -38,7 +38,7 @@ with lib; system.defaults.loginwindow.LoginwindowText = mkOption { type = types.nullOr types.str; default = null; - description = lib.mdDoc '' + description = '' Text to be shown on the login window. Default is "\\\\U03bb". ''; }; @@ -46,7 +46,7 @@ with lib; system.defaults.loginwindow.ShutDownDisabled = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Apple menu > System Preferences > Users and Groups > Login Options Hides the Shut Down button on the login screen. Default is false. @@ -56,7 +56,7 @@ with lib; system.defaults.loginwindow.SleepDisabled = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Apple menu > System Preferences > Users and Groups > Login Options Hides the Sleep button on the login screen. Default is false. @@ -66,7 +66,7 @@ with lib; system.defaults.loginwindow.RestartDisabled = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Apple menu > System Preferences > Users and Groups > Login Options Hides the Restart button on the login screen. Default is false. @@ -76,7 +76,7 @@ with lib; system.defaults.loginwindow.ShutDownDisabledWhileLoggedIn = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Apple menu > System Preferences > Users and Groups > Login Options Disables the "Shutdown" option when users are logged in. Default is false. @@ -86,7 +86,7 @@ with lib; system.defaults.loginwindow.PowerOffDisabledWhileLoggedIn = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Apple menu > System Preferences > Users and Groups > Login Options If set to true, the Power Off menu item will be disabled when the user is logged in. Default is false. @@ -96,7 +96,7 @@ with lib; system.defaults.loginwindow.RestartDisabledWhileLoggedIn = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Apple menu > System Preferences > Users and Groups > Login Options Disables the “Restart” option when users are logged in. Default is false. @@ -106,7 +106,7 @@ with lib; system.defaults.loginwindow.DisableConsoleAccess = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Disables the ability for a user to access the console by typing “>console” for a username at the login window. Default is false. ''; diff --git a/modules/system/defaults/magicmouse.nix b/modules/system/defaults/magicmouse.nix index 56d7f71c6..9344ffeea 100644 --- a/modules/system/defaults/magicmouse.nix +++ b/modules/system/defaults/magicmouse.nix @@ -11,7 +11,7 @@ with lib; "TwoButton" ]); default = null; - description = lib.mdDoc '' + description = '' "OneButton": any tap is a left click. "TwoButton": allow left- and right-clicking. ''; diff --git a/modules/system/defaults/screencapture.nix b/modules/system/defaults/screencapture.nix index 4483fd630..f7b926a94 100644 --- a/modules/system/defaults/screencapture.nix +++ b/modules/system/defaults/screencapture.nix @@ -8,7 +8,7 @@ with lib; system.defaults.screencapture.location = mkOption { type = types.nullOr types.str; default = null; - description = lib.mdDoc '' + description = '' The filesystem path to which screencaptures should be written. ''; }; @@ -16,7 +16,7 @@ with lib; system.defaults.screencapture.type = mkOption { type = types.nullOr types.str; default = null; - description = lib.mdDoc '' + description = '' The image format to use, such as "jpg". ''; }; @@ -24,7 +24,7 @@ with lib; system.defaults.screencapture.disable-shadow = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Disable drop shadow border around screencaptures. The default is false. ''; }; diff --git a/modules/system/defaults/screensaver.nix b/modules/system/defaults/screensaver.nix index 68bd1e05e..3e5032b5c 100644 --- a/modules/system/defaults/screensaver.nix +++ b/modules/system/defaults/screensaver.nix @@ -8,7 +8,7 @@ with lib; system.defaults.screensaver.askForPassword = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' If true, the user is prompted for a password when the screen saver is unlocked or stopped. The default is false. ''; }; @@ -16,7 +16,7 @@ with lib; system.defaults.screensaver.askForPasswordDelay = mkOption { type = types.nullOr types.int; default = null; - description = lib.mdDoc '' + description = '' The number of seconds to delay before the password will be required to unlock or stop the screen saver (the grace period). ''; }; diff --git a/modules/system/defaults/smb.nix b/modules/system/defaults/smb.nix index b694059d9..0bc8be550 100644 --- a/modules/system/defaults/smb.nix +++ b/modules/system/defaults/smb.nix @@ -7,13 +7,13 @@ with lib; system.defaults.smb.NetBIOSName = mkOption { type = types.nullOr types.str; default = null; - description = lib.mdDoc "Hostname to use for NetBIOS."; + description = "Hostname to use for NetBIOS."; }; system.defaults.smb.ServerDescription = mkOption { type = types.nullOr types.str; default = null; - description = lib.mdDoc "Hostname to use for sharing services."; + description = "Hostname to use for sharing services."; }; }; } diff --git a/modules/system/defaults/spaces.nix b/modules/system/defaults/spaces.nix index 4b535d1cf..ac2355bbb 100644 --- a/modules/system/defaults/spaces.nix +++ b/modules/system/defaults/spaces.nix @@ -7,7 +7,7 @@ with lib; system.defaults.spaces.spans-displays = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Apple menu > System Preferences > Mission Control Displays have separate Spaces (note a logout is required before diff --git a/modules/system/defaults/trackpad.nix b/modules/system/defaults/trackpad.nix index ff5e2bb3c..edb637543 100644 --- a/modules/system/defaults/trackpad.nix +++ b/modules/system/defaults/trackpad.nix @@ -8,7 +8,7 @@ with lib; system.defaults.trackpad.Clicking = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Whether to enable trackpad tap to click. The default is false. ''; }; @@ -16,7 +16,7 @@ with lib; system.defaults.trackpad.Dragging = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Whether to enable tap-to-drag. The default is false. ''; }; @@ -24,7 +24,7 @@ with lib; system.defaults.trackpad.TrackpadRightClick = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Whether to enable trackpad right click. The default is false. ''; }; @@ -32,7 +32,7 @@ with lib; system.defaults.trackpad.TrackpadThreeFingerDrag = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Whether to enable three finger drag. The default is false. ''; }; @@ -40,7 +40,7 @@ with lib; system.defaults.trackpad.ActuationStrength = mkOption { type = types.nullOr (types.enum [ 0 1 ]); default = null; - description = lib.mdDoc '' + description = '' 0 to enable Silent Clicking, 1 to disable. The default is 1. ''; }; @@ -48,7 +48,7 @@ with lib; system.defaults.trackpad.FirstClickThreshold = mkOption { type = types.nullOr (types.enum [ 0 1 2 ]); default = null; - description = lib.mdDoc '' + description = '' For normal click: 0 for light clicking, 1 for medium, 2 for firm. The default is 1. ''; @@ -57,7 +57,7 @@ with lib; system.defaults.trackpad.SecondClickThreshold = mkOption { type = types.nullOr (types.enum [ 0 1 2 ]); default = null; - description = lib.mdDoc '' + description = '' For force touch: 0 for light clicking, 1 for medium, 2 for firm. The default is 1. ''; diff --git a/modules/system/defaults/universalaccess.nix b/modules/system/defaults/universalaccess.nix index 51a1fb7c3..8a2de90f8 100644 --- a/modules/system/defaults/universalaccess.nix +++ b/modules/system/defaults/universalaccess.nix @@ -9,16 +9,24 @@ with lib; type = types.nullOr types.float; default = null; example = 1.5; - description = lib.mdDoc '' + description = '' Set the size of cursor. 1 for normal, 4 for maximum. The default is 1. ''; }; + system.defaults.universalaccess.reduceMotion = mkOption { + type = types.nullOr types.bool; + default = null; + description = '' + Disable animation when switching screens or opening apps + ''; + }; + system.defaults.universalaccess.reduceTransparency = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Disable transparency in the menu bar and elsewhere. Requires macOS Yosemite or later. The default is false. @@ -28,7 +36,7 @@ with lib; system.defaults.universalaccess.closeViewScrollWheelToggle = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Use scroll gesture with the Ctrl (^) modifier key to zoom. The default is false. ''; @@ -37,7 +45,7 @@ with lib; system.defaults.universalaccess.closeViewZoomFollowsFocus = mkOption { type = types.nullOr types.bool; default = null; - description = lib.mdDoc '' + description = '' Follow the keyboard focus while zoomed in. Without setting `closeViewScrollWheelToggle` this has no effect. The default is false. diff --git a/modules/system/etc.nix b/modules/system/etc.nix index 9608033f7..008fb1c1f 100644 --- a/modules/system/etc.nix +++ b/modules/system/etc.nix @@ -20,7 +20,7 @@ in environment.etc = mkOption { type = types.attrsOf (types.submodule text); default = { }; - description = lib.mdDoc '' + description = '' Set of files that have to be linked in {file}`/etc`. ''; }; @@ -48,7 +48,7 @@ in etc} ) - declare -a etcProblems + declare -a etcProblems=() while IFS= read -r -d "" configFile; do subPath=''${configFile#"$systemConfig"/etc/} diff --git a/modules/system/keyboard.nix b/modules/system/keyboard.nix index 6e4275ed5..01e25256b 100644 --- a/modules/system/keyboard.nix +++ b/modules/system/keyboard.nix @@ -11,38 +11,38 @@ in system.keyboard.enableKeyMapping = mkOption { type = types.bool; default = false; - description = lib.mdDoc "Whether to enable keyboard mappings."; + description = "Whether to enable keyboard mappings."; }; system.keyboard.remapCapsLockToControl = mkOption { type = types.bool; default = false; - description = lib.mdDoc "Whether to remap the Caps Lock key to Control."; + description = "Whether to remap the Caps Lock key to Control."; }; system.keyboard.remapCapsLockToEscape = mkOption { type = types.bool; default = false; - description = lib.mdDoc "Whether to remap the Caps Lock key to Escape."; + description = "Whether to remap the Caps Lock key to Escape."; }; system.keyboard.nonUS.remapTilde = mkOption { type = types.bool; default = false; - description = lib.mdDoc "Whether to remap the Tilde key on non-us keyboards."; + description = "Whether to remap the Tilde key on non-us keyboards."; }; system.keyboard.swapLeftCommandAndLeftAlt = mkOption { type = types.bool; default = false; - description = lib.mdDoc "Whether to swap the left Command key and left Alt key."; + description = "Whether to swap the left Command key and left Alt key."; }; system.keyboard.userKeyMapping = mkOption { internal = true; type = types.listOf (types.attrsOf types.int); default = []; - description = lib.mdDoc '' + description = '' List of keyboard mappings to apply, for more information see . ''; diff --git a/modules/system/launchd.nix b/modules/system/launchd.nix index 7f6b4859a..cdb6549f3 100644 --- a/modules/system/launchd.nix +++ b/modules/system/launchd.nix @@ -59,7 +59,7 @@ in environment.launchAgents = mkOption { type = types.attrsOf (types.submodule text); default = { }; - description = lib.mdDoc '' + description = '' Set of files that have to be linked in {file}`/Library/LaunchAgents`. ''; }; @@ -67,7 +67,7 @@ in environment.launchDaemons = mkOption { type = types.attrsOf (types.submodule text); default = { }; - description = lib.mdDoc '' + description = '' Set of files that have to be linked in {file}`/Library/LaunchDaemons`. ''; }; @@ -75,7 +75,7 @@ in environment.userLaunchAgents = mkOption { type = types.attrsOf (types.submodule text); default = { }; - description = lib.mdDoc '' + description = '' Set of files that have to be linked in {file}`~/Library/LaunchAgents`. ''; }; diff --git a/modules/system/nvram.nix b/modules/system/nvram.nix new file mode 100644 index 000000000..48e75fb61 --- /dev/null +++ b/modules/system/nvram.nix @@ -0,0 +1,40 @@ +{ config, lib, pkgs, ... }: + +let + cfg = config.system; + + mkNvramVariables = + lib.attrsets.mapAttrsToList + (name: value: "nvram ${lib.escapeShellArg name}=${lib.escapeShellArg value}") + cfg.nvram.variables; +in + +{ + meta.maintainers = [ + lib.maintainers.samasaur or "samasaur" + ]; + + options = { + system.nvram.variables = lib.mkOption { + type = with lib.types; attrsOf str; + default = {}; + internal = true; + example = { + "StartupMute" = "%01"; + }; + description = '' + Non-volatile RAM variables to set. Removing a key-value pair from this + list will **not** return the variable to its previous value, but will + no longer set its value on system configuration activations. + ''; + }; + }; + + config = { + system.activationScripts.nvram.text = '' + echo "setting nvram variables..." >&2 + + ${builtins.concatStringsSep "\n" mkNvramVariables} + ''; + }; +} diff --git a/modules/system/patches.nix b/modules/system/patches.nix index 9ac15ecce..4f965014c 100644 --- a/modules/system/patches.nix +++ b/modules/system/patches.nix @@ -26,7 +26,7 @@ in '''') ] ''; - description = lib.mdDoc '' + description = '' Set of patches to apply to {file}`/`. ::: {.warning} diff --git a/modules/system/shells.nix b/modules/system/shells.nix index b3ecf30e4..0b599d98f 100644 --- a/modules/system/shells.nix +++ b/modules/system/shells.nix @@ -12,7 +12,7 @@ in type = types.listOf (types.either types.shellPackage types.path); default = []; example = literalExpression "[ pkgs.bashInteractive pkgs.zsh ]"; - description = lib.mdDoc '' + description = '' A list of permissible login shells for user accounts. No need to mention `/bin/sh` and other shells that are available by default on @@ -41,5 +41,9 @@ in ${concatStringsSep "\n" cfg.shells} ''; + environment.etc."shells".knownSha256Hashes = [ + "9d5aa72f807091b481820d12e693093293ba33c73854909ad7b0fb192c2db193" # macOS + ]; + }; } diff --git a/modules/system/startup.nix b/modules/system/startup.nix new file mode 100644 index 000000000..ae7f2ef08 --- /dev/null +++ b/modules/system/startup.nix @@ -0,0 +1,31 @@ +{ config, lib, pkgs, ... }: + +let + cfg = config.system.startup; +in + +{ + meta.maintainers = [ + lib.maintainers.samasaur or "samasaur" + ]; + + options = { + system.startup.chime = lib.mkOption { + type = with lib.types; nullOr bool; + default = null; + example = false; + description = '' + Whether to enable the startup chime. + + By default, this option does not affect your system configuration in any way. + However, this means that after it has been set once, unsetting it will not + return to the old behavior. It will allow the setting to be controlled in + System Settings, though. + ''; + }; + }; + + config = { + system.nvram.variables."StartupMute" = lib.mkIf (cfg.chime != null) (if cfg.chime then "%00" else "%01"); + }; +} diff --git a/modules/system/version.nix b/modules/system/version.nix index 3effb5057..fa6ce6e1e 100644 --- a/modules/system/version.nix +++ b/modules/system/version.nix @@ -36,7 +36,7 @@ in system.stateVersion = mkOption { type = types.int; default = 4; - description = lib.mdDoc '' + description = '' Every once in a while, a new NixOS release may change configuration defaults in a way incompatible with stateful data. For instance, if the default version of PostgreSQL @@ -51,14 +51,14 @@ in system.darwinLabel = mkOption { type = types.str; - description = lib.mdDoc "Label to be used in the names of generated outputs."; + description = "Label to be used in the names of generated outputs."; }; system.darwinVersion = mkOption { internal = true; type = types.str; default = "darwin${toString cfg.stateVersion}${cfg.darwinVersionSuffix}"; - description = lib.mdDoc "The full darwin version (e.g. `darwin4.2abdb5a`)."; + description = "The full darwin version (e.g. `darwin4.2abdb5a`)."; }; system.darwinVersionSuffix = mkOption { @@ -67,28 +67,28 @@ in default = if cfg.darwinRevision != null then ".${substring 0 7 cfg.darwinRevision}" else ""; - description = lib.mdDoc "The short darwin version suffix (e.g. `.2abdb5a`)."; + description = "The short darwin version suffix (e.g. `.2abdb5a`)."; }; system.darwinRevision = mkOption { internal = true; type = types.nullOr types.str; default = gitRevision (toString ../..); - description = lib.mdDoc "The darwin git revision from which this configuration was built."; + description = "The darwin git revision from which this configuration was built."; }; system.nixpkgsRelease = mkOption { readOnly = true; type = types.str; default = lib.trivial.release; - description = lib.mdDoc "The nixpkgs release (e.g. `16.03`)."; + description = "The nixpkgs release (e.g. `16.03`)."; }; system.nixpkgsVersion = mkOption { internal = true; type = types.str; default = cfg.nixpkgsRelease + cfg.nixpkgsVersionSuffix; - description = lib.mdDoc "The full nixpkgs version (e.g. `16.03.1160.f2d4ee1`)."; + description = "The full nixpkgs version (e.g. `16.03.1160.f2d4ee1`)."; }; system.nixpkgsVersionSuffix = mkOption { @@ -97,7 +97,7 @@ in default = if useSourceRevision then ".${lib.substring 0 8 (nixpkgsSrc.lastModifiedDate or nixpkgsSrc.lastModified or "19700101")}.${nixpkgsSrc.shortRev or "dirty"}" else lib.trivial.versionSuffix; - description = lib.mdDoc "The short nixpkgs version suffix (e.g. `.1160.f2d4ee1`)."; + description = "The short nixpkgs version suffix (e.g. `.1160.f2d4ee1`)."; }; system.nixpkgsRevision = mkOption { @@ -106,13 +106,13 @@ in default = if useSourceRevision && nixpkgsSrc ? rev then nixpkgsSrc.rev else lib.trivial.revisionWithDefault null; - description = lib.mdDoc "The nixpkgs git revision from which this configuration was built."; + description = "The nixpkgs git revision from which this configuration was built."; }; system.configurationRevision = mkOption { type = types.nullOr types.str; default = null; - description = lib.mdDoc "The Git revision of the top-level flake from which this configuration was built."; + description = "The Git revision of the top-level flake from which this configuration was built."; }; }; diff --git a/modules/time/default.nix b/modules/time/default.nix index 09b02a55f..28724a556 100644 --- a/modules/time/default.nix +++ b/modules/time/default.nix @@ -11,7 +11,7 @@ let echo "${cfg.timeZone} is not a valid timezone. The command 'listtimezones' will show a list of valid time zones." >&2 false fi - systemsetup -settimezone "${cfg.timeZone}" > /dev/null + systemsetup -settimezone "${cfg.timeZone}" 2>/dev/null 1>&2 ''; in @@ -23,7 +23,7 @@ in type = types.nullOr types.str; default = null; example = "America/New_York"; - description = lib.mdDoc '' + description = '' The time zone used when displaying times and dates. See or run {command}`sudo systemsetup -listtimezones` for a comprehensive list of possible values for this setting. diff --git a/modules/users/default.nix b/modules/users/default.nix index 571200248..cd0986d89 100644 --- a/modules/users/default.nix +++ b/modules/users/default.nix @@ -24,6 +24,14 @@ let deletedUsers = filter (n: isDeleted cfg.users n) cfg.knownUsers; packageUsers = filterAttrs (_: u: u.packages != []) cfg.users; + + # convert a valid argument to user.shell into a string that points to a shell + # executable. Logic copied from modules/system/shells.nix. + shellPath = v: + if types.shellPackage.check v + then "/run/current-system/sw${v.shellPath}" + else v; + in { @@ -31,7 +39,7 @@ in users.knownGroups = mkOption { type = types.listOf types.str; default = []; - description = lib.mdDoc '' + description = '' List of groups owned and managed by nix-darwin. Used to indicate what users are safe to create/delete based on the configuration. Don't add system groups to this. @@ -41,7 +49,7 @@ in users.knownUsers = mkOption { type = types.listOf types.str; default = []; - description = lib.mdDoc '' + description = '' List of users owned and managed by nix-darwin. Used to indicate what users are safe to create/delete based on the configuration. Don't add the admin user or other system users to this. @@ -51,13 +59,13 @@ in users.groups = mkOption { type = types.attrsOf (types.submodule group); default = {}; - description = lib.mdDoc "Configuration for groups."; + description = "Configuration for groups."; }; users.users = mkOption { type = types.attrsOf (types.submodule user); default = {}; - description = lib.mdDoc "Configuration for users."; + description = "Configuration for users."; }; users.gids = mkOption { @@ -76,7 +84,7 @@ in internal = true; type = types.bool; default = false; - description = lib.mdDoc "Remove and recreate existing groups/users."; + description = "Remove and recreate existing groups/users."; }; }; @@ -92,7 +100,7 @@ in ${optionalString cfg.forceRecreate '' g=$(dscl . -read '/Groups/${v.name}' PrimaryGroupID 2> /dev/null) || true g=''${g#PrimaryGroupID: } - if [ "$g" -eq ${toString v.gid} ]; then + if [[ "$g" -eq ${toString v.gid} ]]; then echo "deleting group ${v.name}..." >&2 dscl . -delete '/Groups/${v.name}' 2> /dev/null else @@ -141,7 +149,7 @@ in ${optionalString cfg.forceRecreate '' u=$(dscl . -read '/Users/${v.name}' UniqueID 2> /dev/null) || true u=''${u#UniqueID: } - if [ "$u" -eq ${toString v.uid} ]; then + if [[ "$u" -eq ${toString v.uid} ]]; then echo "deleting user ${v.name}..." >&2 dscl . -delete '/Users/${v.name}' 2> /dev/null else @@ -151,19 +159,20 @@ in u=$(dscl . -read '/Users/${v.name}' UniqueID 2> /dev/null) || true u=''${u#UniqueID: } - if [ -z "$u" ]; then - echo "creating user ${v.name}..." >&2 - dscl . -create '/Users/${v.name}' UniqueID ${toString v.uid} - dscl . -create '/Users/${v.name}' PrimaryGroupID ${toString v.gid} - dscl . -create '/Users/${v.name}' IsHidden ${if v.isHidden then "1" else "0"} - dscl . -create '/Users/${v.name}' RealName '${v.description}' - dscl . -create '/Users/${v.name}' NFSHomeDirectory '${v.home}' - dscl . -create '/Users/${v.name}' UserShell '${v.shell}' - ${optionalString v.createHome "createhomedir -cu '${v.name}'"} + if [[ -n "$u" && "$u" -ne "${toString v.uid}" ]]; then + echo "warning: existing user '${v.name}' has unexpected uid $u, skipping..." >&2 else - if [ "$u" -ne ${toString v.uid} ]; then - echo "warning: existing user '${v.name}' has unexpected uid $u, skipping..." >&2 + if [ -z "$u" ]; then + echo "creating user ${v.name}..." >&2 + dscl . -create '/Users/${v.name}' UniqueID ${toString v.uid} + dscl . -create '/Users/${v.name}' PrimaryGroupID ${toString v.gid} + dscl . -create '/Users/${v.name}' IsHidden ${if v.isHidden then "1" else "0"} + dscl . -create '/Users/${v.name}' RealName '${v.description}' + dscl . -create '/Users/${v.name}' NFSHomeDirectory '${v.home}' + ${optionalString v.createHome "createhomedir -cu '${v.name}'"} fi + # Always set the shell path, in case it was updated + dscl . -create '/Users/${v.name}' UserShell ${lib.escapeShellArg (shellPath v.shell)} fi '') createdUsers} diff --git a/modules/users/group.nix b/modules/users/group.nix index cfda76f34..1dc26f1f6 100644 --- a/modules/users/group.nix +++ b/modules/users/group.nix @@ -6,7 +6,7 @@ with lib; options = { name = mkOption { type = types.str; - description = lib.mdDoc '' + description = '' The group's name. If undefined, the name of the attribute set will be used. ''; @@ -17,19 +17,19 @@ with lib; name = "gid"; check = t: isInt t && t > 501; }; - description = lib.mdDoc "The group's GID."; + description = "The group's GID."; }; members = mkOption { type = types.listOf types.str; default = []; - description = lib.mdDoc "The group's members."; + description = "The group's members."; }; description = mkOption { type = types.str; default = ""; - description = lib.mdDoc "The group's description."; + description = "The group's description."; }; }; diff --git a/modules/users/user.nix b/modules/users/user.nix index 60592fc4d..4e3f1c940 100644 --- a/modules/users/user.nix +++ b/modules/users/user.nix @@ -6,7 +6,7 @@ with lib; options = { name = mkOption { type = types.str; - description = lib.mdDoc '' + description = '' The name of the user account. If undefined, the name of the attribute set will be used. ''; @@ -16,7 +16,7 @@ with lib; type = types.str; default = ""; example = "Alice Q. User"; - description = lib.mdDoc '' + description = '' A short description of the user account, typically the user's full name. ''; @@ -24,19 +24,19 @@ with lib; uid = mkOption { type = types.int; - description = lib.mdDoc "The user's UID."; + description = "The user's UID."; }; gid = mkOption { type = types.int; default = 20; - description = lib.mdDoc "The user's primary group."; + description = "The user's primary group."; }; isHidden = mkOption { type = types.bool; default = true; - description = lib.mdDoc "Whether to make the user account hidden."; + description = "Whether to make the user account hidden."; }; # extraGroups = mkOption { @@ -48,27 +48,27 @@ with lib; home = mkOption { type = types.path; default = "/var/empty"; - description = lib.mdDoc "The user's home directory."; + description = "The user's home directory."; }; createHome = mkOption { type = types.bool; default = false; - description = lib.mdDoc "Create the home directory when creating the user."; + description = "Create the home directory when creating the user."; }; shell = mkOption { type = types.either types.shellPackage types.path; default = "/sbin/nologin"; example = literalExpression "pkgs.bashInteractive"; - description = lib.mdDoc "The user's shell."; + description = "The user's shell."; }; packages = mkOption { type = types.listOf types.package; default = []; example = literalExpression "[ pkgs.firefox pkgs.thunderbird ]"; - description = lib.mdDoc '' + description = '' The set of packages that should be made availabe to the user. This is in contrast to {option}`environment.systemPackages`, which adds packages to all users. diff --git a/pkgs/darwin-uninstaller/configuration.nix b/pkgs/darwin-uninstaller/configuration.nix index 96a2165a2..6487774be 100644 --- a/pkgs/darwin-uninstaller/configuration.nix +++ b/pkgs/darwin-uninstaller/configuration.nix @@ -1,4 +1,4 @@ -{ config, lib, pkgs, ... }: +{ lib, ... }: with lib; diff --git a/pkgs/darwin-uninstaller/default.nix b/pkgs/darwin-uninstaller/default.nix index ca7be4891..3eb2c244e 100644 --- a/pkgs/darwin-uninstaller/default.nix +++ b/pkgs/darwin-uninstaller/default.nix @@ -1,18 +1,17 @@ -{ stdenv, nix, pkgs, nix-darwin }: +{ stdenv, lib, pkgs }: let - configuration = builtins.path { - name = "nix-darwin-uninstaller-configuration"; - path = ./.; - filter = name: _type: name != toString ./default.nix; + uninstallSystem = import ../../eval-config.nix { + inherit lib; + modules = [ + ./configuration.nix + { + nixpkgs.source = pkgs.path; + nixpkgs.hostPlatform = pkgs.stdenv.hostPlatform.system; + system.includeUninstaller = false; + } + ]; }; - - nixPath = pkgs.lib.concatStringsSep ":" [ - "darwin-config=${configuration}/configuration.nix" - "darwin=${nix-darwin}" - "nixpkgs=${pkgs.path}" - "$NIX_PATH" - ]; in stdenv.mkDerivation { @@ -62,10 +61,7 @@ stdenv.mkDerivation { esac fi - export nix=${nix} - export NIX_PATH=${nixPath} - system=$($nix/bin/nix-build '' -A system) - $system/sw/bin/darwin-rebuild switch + ${uninstallSystem.system}/sw/bin/darwin-rebuild activate if test -L /run/current-system; then sudo rm /run/current-system diff --git a/pkgs/nix-tools/darwin-rebuild.sh b/pkgs/nix-tools/darwin-rebuild.sh index d8c66bdd4..642226243 100644 --- a/pkgs/nix-tools/darwin-rebuild.sh +++ b/pkgs/nix-tools/darwin-rebuild.sh @@ -16,6 +16,14 @@ showSyntax() { exit 1 } +sudo() { + if command sudo --help | grep -- --preserve-env= >/dev/null; then + command sudo -H --preserve-env=PATH env "$@" + else + command sudo -H "$@" + fi +} + # Parse the command line. origArgs=("$@") extraMetadataFlags=() @@ -132,7 +140,7 @@ if [ -n "$flake" ]; then flakeAttr=${fragment} fi if [ -z "$flakeAttr" ]; then - flakeAttr=$(hostname -s) + flakeAttr=$(scutil --get LocalHostName) fi flakeAttr=darwinConfigurations.${flakeAttr} fi @@ -187,7 +195,7 @@ fi if [ "$action" = list ] || [ "$action" = rollback ]; then if [ "$USER" != root ] && [ ! -w $(dirname "$profile") ]; then - sudo -H nix-env -p "$profile" "${extraProfileFlags[@]}" + sudo nix-env -p "$profile" "${extraProfileFlags[@]}" else nix-env -p "$profile" "${extraProfileFlags[@]}" fi @@ -205,7 +213,7 @@ if [ -z "$systemConfig" ]; then exit 0; fi if [ "$action" = switch ]; then if [ "$USER" != root ] && [ ! -w $(dirname "$profile") ]; then - sudo -H nix-env -p "$profile" --set "$systemConfig" + sudo nix-env -p "$profile" --set "$systemConfig" else nix-env -p "$profile" --set "$systemConfig" fi diff --git a/pkgs/nix-tools/darwin-rebuild.zsh-completions b/pkgs/nix-tools/darwin-rebuild.zsh-completions new file mode 100644 index 000000000..466343fe9 --- /dev/null +++ b/pkgs/nix-tools/darwin-rebuild.zsh-completions @@ -0,0 +1,38 @@ +#compdef darwin-rebuild +#autoload + +_nix-common-options + +local -a _1st_arguments +_1st_arguments=( + 'edit:Open nix-darwin config in $EDITOR'\ + 'switch:Build, activate, and update the current generation'\ + 'activate:Activate an already built store path and update the current generation'\ + 'build:Build without activating or updating the current generation'\ + 'check:Build and run the activation sanity checks'\ + 'changelog:Show most recent entries in the changelog'\ +) + +_arguments \ + $__nix_search_path_args\ + '(--verbose -v)*'{--verbose,-v}'[Increase verbosity of diagnostic messages]'\ + '(--max-jobs -j)'{--max-jobs,-j}'[max number of build jobs in parallel]:jobs:'\ + '--cores[threads per job (e.g. -j argument to make)]:cores:'\ + '(--keep-going -k)'{--keep-going,-k}"[keep going until all builds are finished]"\ + '(--keep-failed -K)'{--keep-failed,-K}'[keep failed builds (usually in /tmp)]'\ + '--fallback[If binary download fails, fall back on building from source]'\ + '--show-trace[Print stack trace of evaluation errors]'\ + '*--option[set Nix configuration option]:options:_nix_options:value:_nix_options_value'\ + '*--arg[argument to pass to the Nix function]:Name:_nix_complete_function_arg:Value: '\ + '*--argstr[pass a string]:Name:_nix_complete_function_arg:String: '\ + '--list-generations[Print a list of all generations in the active profile]'\ + '--rollback[Roll back to the previous configuration]'\ + {--switch-generation,-G}'[Activate specified generation]'\ + '(--profile-name -p)'{--profile-name,-p}'[Profile to use to track current and previous system configurations]:Profile:_nix_profiles'\ + '1:: :->subcmds' && return 0 + +case $state in + subcmds) + _describe -t commands 'darwin-rebuild subcommands' _1st_arguments + ;; +esac diff --git a/pkgs/nix-tools/default.nix b/pkgs/nix-tools/default.nix index cb5d62f67..4e4336a87 100644 --- a/pkgs/nix-tools/default.nix +++ b/pkgs/nix-tools/default.nix @@ -33,6 +33,10 @@ in { inherit path profile; inherit (stdenv) shell; + postInstall = '' + mkdir -p $out/share/zsh/site-functions + cp ${./darwin-rebuild.zsh-completions} $out/share/zsh/site-functions/_darwin-rebuild + ''; } ./darwin-rebuild.sh; diff --git a/release.nix b/release.nix index d2edd8a81..98a58e72f 100644 --- a/release.nix +++ b/release.nix @@ -114,16 +114,19 @@ let tests.programs-ssh = makeTest ./tests/programs-ssh.nix; tests.programs-tmux = makeTest ./tests/programs-tmux.nix; tests.programs-zsh = makeTest ./tests/programs-zsh.nix; + tests.programs-ssh-empty-known-hosts = makeTest ./tests/programs-ssh-empty-known-hosts.nix; tests.security-pki = makeTest ./tests/security-pki.nix; tests.services-activate-system = makeTest ./tests/services-activate-system.nix; tests.services-activate-system-changed-label-prefix = makeTest ./tests/services-activate-system-changed-label-prefix.nix; tests.services-buildkite-agent = makeTest ./tests/services-buildkite-agent.nix; + tests.services-github-runners = makeTest ./tests/services-github-runners.nix; tests.services-lorri = makeTest ./tests/services-lorri.nix; tests.services-nix-daemon = makeTest ./tests/services-nix-daemon.nix; tests.sockets-nix-daemon = makeTest ./tests/sockets-nix-daemon.nix; tests.services-dnsmasq = makeTest ./tests/services-dnsmasq.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; tests.services-nextdns = makeTest ./tests/services-nextdns.nix; tests.services-ofborg = makeTest ./tests/services-ofborg.nix; tests.services-offlineimap = makeTest ./tests/services-offlineimap.nix; diff --git a/tests/fixtures/system-defaults-write/activate-user.txt b/tests/fixtures/system-defaults-write/activate-user.txt new file mode 100644 index 000000000..5fa595289 --- /dev/null +++ b/tests/fixtures/system-defaults-write/activate-user.txt @@ -0,0 +1,368 @@ +defaults write -g 'AppleEnableMouseSwipeNavigateWithScrolls' $' + + + +' +defaults write -g 'AppleEnableSwipeNavigateWithScrolls' $' + + + +' +defaults write -g 'AppleFontSmoothing' $' + + +1 +' +defaults write -g 'AppleICUForce24HourTime' $' + + + +' +defaults write -g 'AppleKeyboardUIMode' $' + + +3 +' +defaults write -g 'ApplePressAndHoldEnabled' $' + + + +' +defaults write -g 'AppleScrollerPagingBehavior' $' + + + +' +defaults write -g 'AppleShowAllExtensions' $' + + + +' +defaults write -g 'AppleShowAllFiles' $' + + + +' +defaults write -g 'AppleShowScrollBars' $' + + +Always +' +defaults write -g 'AppleWindowTabbingMode' $' + + +always +' +defaults write -g 'InitialKeyRepeat' $' + + +10 +' +defaults write -g 'KeyRepeat' $' + + +1 +' +defaults write -g 'NSAutomaticCapitalizationEnabled' $' + + + +' +defaults write -g 'NSAutomaticDashSubstitutionEnabled' $' + + + +' +defaults write -g 'NSAutomaticPeriodSubstitutionEnabled' $' + + + +' +defaults write -g 'NSAutomaticQuoteSubstitutionEnabled' $' + + + +' +defaults write -g 'NSAutomaticSpellingCorrectionEnabled' $' + + + +' +defaults write -g 'NSAutomaticWindowAnimationsEnabled' $' + + + +' +defaults write -g 'NSDisableAutomaticTermination' $' + + + +' +defaults write -g 'NSDocumentSaveNewDocumentsToCloud' $' + + + +' +defaults write -g 'NSNavPanelExpandedStateForSaveMode' $' + + + +' +defaults write -g 'NSNavPanelExpandedStateForSaveMode2' $' + + + +' +defaults write -g 'NSScrollAnimationEnabled' $' + + + +' +defaults write -g 'NSTableViewDefaultSizeMode' $' + + +2 +' +defaults write -g 'NSTextShowsControlCharacters' $' + + + +' +defaults write -g 'NSUseAnimatedFocusRing' $' + + + +' +defaults write -g 'NSWindowResizeTime' $' + + +0.010000 +' +defaults write -g 'NSWindowShouldDragOnGesture' $' + + + +' +defaults write -g 'PMPrintingExpandedStateForPrint' $' + + + +' +defaults write -g 'PMPrintingExpandedStateForPrint2' $' + + + +' +defaults write -g 'com.apple.keyboard.fnState' $' + + + +' +defaults write -g 'com.apple.mouse.tapBehavior' $' + + +1 +' +defaults write -g 'com.apple.springing.delay' $' + + +0.000000 +' +defaults write -g 'com.apple.springing.enabled' $' + + + +' +defaults write -g 'com.apple.swipescrolldirection' $' + + + +' +defaults write -g 'com.apple.trackpad.enableSecondaryClick' $' + + + +' +defaults write -g 'com.apple.trackpad.trackpadCornerClickBehavior' $' + + +1 +' + +defaults write .GlobalPreferences 'com.apple.sound.beep.sound' $' + + +/System/Library/Sounds/Funk.aiff +' + +defaults write com.apple.menuextra.clock 'Show24Hour' $' + + + +' +defaults write com.apple.menuextra.clock 'ShowDate' $' + + +2 +' +defaults write com.apple.menuextra.clock 'ShowDayOfWeek' $' + + + +' +defaults write com.apple.dock 'appswitcher-all-displays' $' + + + +' +defaults write com.apple.dock 'autohide-delay' $' + + +0.240000 +' +defaults write com.apple.dock 'orientation' $' + + +left +' +defaults write com.apple.dock 'persistent-apps' $' + + + + + tile-data + + file-data + + _CFURLString + MyApp.app + _CFURLStringType + 0 + + + + + tile-data + + file-data + + _CFURLString + Cool.app + _CFURLStringType + 0 + + + + +' +defaults write com.apple.dock 'persistent-others' $' + + + + + tile-data + + file-data + + _CFURLString + ~/Documents + _CFURLStringType + 15 + + + + + tile-data + + file-data + + _CFURLString + ~/Downloads + _CFURLStringType + 15 + + + + +' + + + +defaults write com.apple.screencapture 'location' $' + + +/tmp +' +defaults write com.apple.screensaver 'askForPassword' $' + + + +' +defaults write com.apple.screensaver 'askForPasswordDelay' $' + + +5 +' + + + +defaults write com.apple.universalaccess 'closeViewScrollWheelToggle' $' + + + +' +defaults write com.apple.universalaccess 'closeViewZoomFollowsFocus' $' + + + +' +defaults write com.apple.universalaccess 'mouseDriverCursorSize' $' + + +1.500000 +' +defaults write com.apple.universalaccess 'reduceMotion' $' + + + +' +defaults write com.apple.universalaccess 'reduceTransparency' $' + + + +' +defaults write com.apple.ActivityMonitor 'IconType' $' + + +3 +' +defaults write com.apple.ActivityMonitor 'OpenMainWindow' $' + + + +' +defaults write com.apple.ActivityMonitor 'ShowCategory' $' + + +103 +' +defaults write com.apple.ActivityMonitor 'SortColumn' $' + + +CPUUsage +' +defaults write com.apple.ActivityMonitor 'SortDirection' $' + + +0 +' +defaults write NSGlobalDomain 'TISRomanSwitchState' $' + + +1 +' +defaults write com.apple.Safari 'com.apple.Safari.ContentPageGroupIdentifier.WebKit2DeveloperExtrasEnabled' $' + + + +' diff --git a/tests/fixtures/system-defaults-write/activate.txt b/tests/fixtures/system-defaults-write/activate.txt new file mode 100644 index 000000000..b22bc6d49 --- /dev/null +++ b/tests/fixtures/system-defaults-write/activate.txt @@ -0,0 +1,10 @@ +defaults write /Library/Preferences/SystemConfiguration/com.apple.smb.server 'NetBIOSName' $' + + +IMAC-000000 +' +defaults write /Library/Preferences/SystemConfiguration/com.apple.smb.server 'ServerDescription' $' + + +Darwin\\\\U2019\'s iMac +' diff --git a/tests/networking-shell-escape.nix b/tests/networking-shell-escape.nix new file mode 100644 index 000000000..da399b18f --- /dev/null +++ b/tests/networking-shell-escape.nix @@ -0,0 +1,15 @@ + +{ config, pkgs, ... }: + +{ + networking.computerName = "\"Quotey McQuote's Macbook Pro\""; + networking.hostName = "\"Quotey-McQuote's-Macbook-Pro\""; + + test = '' + echo checking hostname in /activate >&2 + grep "scutil --set ComputerName '"\""Quotey McQuote's Macbook Pro"\""'" ${config.out}/activate + grep "scutil --set LocalHostName '"\""Quotey-McQuote's-Macbook-Pro"\""'" ${config.out}/activate + grep "scutil --set HostName "'"\""Quotey-McQuote's-Macbook-Pro"\""'" ${config.out}/activate + echo checking defaults write in ${config.out}/activate-user >&2 + ''; +} diff --git a/tests/programs-ssh-empty-known-hosts.nix b/tests/programs-ssh-empty-known-hosts.nix new file mode 100644 index 000000000..c6bbf3565 --- /dev/null +++ b/tests/programs-ssh-empty-known-hosts.nix @@ -0,0 +1,11 @@ +{ config, pkgs, ... }: + +{ + test = '' + echo >&2 "checking existance of /etc/ssh/ssh_known_hosts" + if test -e ${config.out}/etc/ssh/ssh_known_hosts; then + echo >&2 "/etc/ssh/ssh_known_hosts exists but it shouldn't!" + exit 1 + fi + ''; +} diff --git a/tests/services-github-runners.nix b/tests/services-github-runners.nix new file mode 100644 index 000000000..557875052 --- /dev/null +++ b/tests/services-github-runners.nix @@ -0,0 +1,20 @@ +{ config, pkgs, ... }: +{ + services.github-runners."a-runner" = { + enable = true; + url = "https://github.com/nixos/nixpkgs"; + tokenFile = "/secret/path/to/a/github/token"; + # We need an overridable derivation but cannot use the actual github-runner package + # since it still relies on Node.js 16 which is marked as insecure. + package = pkgs.hello; + }; + + test = '' + echo >&2 "checking github-runner service in /Library/LaunchDaemons" + grep "org.nixos.github-runner-a-runner" ${config.out}/Library/LaunchDaemons/org.nixos.github-runner-a-runner.plist + grep "_github-runner" ${config.out}/Library/LaunchDaemons/org.nixos.github-runner-a-runner.plist + + echo >&2 "checking for user in /activate" + grep "GitHub Runner service user" ${config.out}/activate + ''; +} diff --git a/tests/services-nix-optimise.nix b/tests/services-nix-optimise.nix new file mode 100644 index 000000000..b0ecf184b --- /dev/null +++ b/tests/services-nix-optimise.nix @@ -0,0 +1,25 @@ +{ config, pkgs, ... }: + +let + nix = pkgs.runCommand "nix-2.2" {} "mkdir -p $out"; +in + +{ + nix.optimise.automatic = true; + nix.optimise.user = "nixuser"; + nix.package = nix; + + test = '' + echo checking nix-optimise service in /Library/LaunchDaemons >&2 + grep "org.nixos.nix-optimise" \ + ${config.out}/Library/LaunchDaemons/org.nixos.nix-optimise.plist + grep "/bin/wait4path ${nix} && exec ${nix}/bin/nix-store --optimise" \ + ${config.out}/Library/LaunchDaemons/org.nixos.nix-optimise.plist + grep "UserName" ${config.out}/Library/LaunchDaemons/org.nixos.nix-optimise.plist + grep "nixuser" ${config.out}/Library/LaunchDaemons/org.nixos.nix-optimise.plist + (! grep "KeepAlive" ${config.out}/Library/LaunchDaemons/org.nixos.nix-optimise.plist) + + echo checking nix-optimise validation >&2 + (! grep "nix.optimise.user = " ${config.out}/activate-user) + ''; +} diff --git a/tests/system-defaults-write.nix b/tests/system-defaults-write.nix index dc4752eb9..e17d9502a 100644 --- a/tests/system-defaults-write.nix +++ b/tests/system-defaults-write.nix @@ -1,4 +1,4 @@ -{ config, pkgs, ... }: +{ config, pkgs, lib, ... }: { system.defaults.NSGlobalDomain.AppleShowAllFiles = true; @@ -27,6 +27,7 @@ system.defaults.NSGlobalDomain.NSUseAnimatedFocusRing = false; system.defaults.NSGlobalDomain.NSScrollAnimationEnabled = true; system.defaults.NSGlobalDomain.NSWindowResizeTime = 0.01; + system.defaults.NSGlobalDomain.NSWindowShouldDragOnGesture = true; system.defaults.NSGlobalDomain.InitialKeyRepeat = 10; system.defaults.NSGlobalDomain.KeyRepeat = 1; system.defaults.NSGlobalDomain.PMPrintingExpandedStateForPrint = true; @@ -45,12 +46,15 @@ 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-others = ["~/Documents" "~/Downloads"]; system.defaults.screencapture.location = "/tmp"; system.defaults.screensaver.askForPassword = true; system.defaults.screensaver.askForPasswordDelay = 5; system.defaults.smb.NetBIOSName = "IMAC-000000"; - system.defaults.smb.ServerDescription = ''Darwin\\\\U2019s iMac''; + system.defaults.smb.ServerDescription = ''Darwin\\\\U2019's iMac''; system.defaults.universalaccess.mouseDriverCursorSize = 1.5; + system.defaults.universalaccess.reduceMotion = true; system.defaults.universalaccess.reduceTransparency = true; system.defaults.universalaccess.closeViewScrollWheelToggle = true; system.defaults.universalaccess.closeViewZoomFollowsFocus = true; @@ -66,68 +70,19 @@ true; }; }; - test = '' - echo >&2 "checking defaults write in /activate" - grep "defaults write /Library/Preferences/SystemConfiguration/com.apple.smb.server 'NetBIOSName' -string 'IMAC-000000'" ${config.out}/activate - grep "defaults write /Library/Preferences/SystemConfiguration/com.apple.smb.server 'ServerDescription' -string 'Darwin.*s iMac'" ${config.out}/activate - - echo >&2 "checking defaults write in /activate-user" - grep "defaults write -g 'AppleShowAllFiles' -bool YES" ${config.out}/activate-user - grep "defaults write -g 'AppleEnableMouseSwipeNavigateWithScrolls' -bool NO" ${config.out}/activate-user - grep "defaults write -g 'AppleEnableSwipeNavigateWithScrolls' -bool NO" ${config.out}/activate-user - grep "defaults write -g 'AppleFontSmoothing' -int 1" ${config.out}/activate-user - grep "defaults write -g 'AppleICUForce24HourTime' -bool YES" ${config.out}/activate-user - grep "defaults write -g 'AppleKeyboardUIMode' -int 3" ${config.out}/activate-user - grep "defaults write -g 'ApplePressAndHoldEnabled' -bool YES" ${config.out}/activate-user - grep "defaults write -g 'AppleShowAllExtensions' -bool YES" ${config.out}/activate-user - grep "defaults write -g 'AppleShowScrollBars' -string 'Always'" ${config.out}/activate-user - grep "defaults write -g 'AppleScrollerPagingBehavior' -bool YES" ${config.out}/activate-user - grep "defaults write -g 'NSAutomaticCapitalizationEnabled' -bool NO" ${config.out}/activate-user - grep "defaults write -g 'NSAutomaticDashSubstitutionEnabled' -bool NO" ${config.out}/activate-user - grep "defaults write -g 'NSAutomaticPeriodSubstitutionEnabled' -bool NO" ${config.out}/activate-user - grep "defaults write -g 'NSAutomaticQuoteSubstitutionEnabled' -bool NO" ${config.out}/activate-user - grep "defaults write -g 'NSAutomaticSpellingCorrectionEnabled' -bool NO" ${config.out}/activate-user - grep "defaults write -g 'NSAutomaticWindowAnimationsEnabled' -bool NO" ${config.out}/activate-user - grep "defaults write -g 'NSDisableAutomaticTermination' -bool YES" ${config.out}/activate-user - grep "defaults write -g 'NSDocumentSaveNewDocumentsToCloud' -bool NO" ${config.out}/activate-user - grep "defaults write -g 'AppleWindowTabbingMode' -string 'always'" ${config.out}/activate-user - grep "defaults write -g 'NSNavPanelExpandedStateForSaveMode' -bool YES" ${config.out}/activate-user - grep "defaults write -g 'NSNavPanelExpandedStateForSaveMode2' -bool YES" ${config.out}/activate-user - grep "defaults write -g 'NSTableViewDefaultSizeMode' -int 2" ${config.out}/activate-user - grep "defaults write -g 'NSTextShowsControlCharacters' -bool YES" ${config.out}/activate-user - grep "defaults write -g 'NSUseAnimatedFocusRing' -bool NO" ${config.out}/activate-user - grep "defaults write -g 'NSScrollAnimationEnabled' -bool YES" ${config.out}/activate-user - grep "defaults write -g 'NSWindowResizeTime' -float 0.01" ${config.out}/activate-user - grep "defaults write -g 'InitialKeyRepeat' -int 10" ${config.out}/activate-user - grep "defaults write -g 'KeyRepeat' -int 1" ${config.out}/activate-user - grep "defaults write -g 'PMPrintingExpandedStateForPrint' -bool YES" ${config.out}/activate-user - grep "defaults write -g 'PMPrintingExpandedStateForPrint2' -bool YES" ${config.out}/activate-user - grep "defaults write -g 'com.apple.keyboard.fnState' -bool YES" ${config.out}/activate-user - grep "defaults write -g 'com.apple.mouse.tapBehavior' -int 1" ${config.out}/activate-user - grep "defaults write -g 'com.apple.trackpad.enableSecondaryClick' -bool YES" ${config.out}/activate-user - grep "defaults write -g 'com.apple.trackpad.trackpadCornerClickBehavior' -int 1" ${config.out}/activate-user - grep "defaults write -g 'com.apple.springing.enabled' -bool YES" ${config.out}/activate-user - grep "defaults write -g 'com.apple.springing.delay' -float 0.0" ${config.out}/activate-user - grep "defaults write -g 'com.apple.swipescrolldirection' -bool YES" ${config.out}/activate-user - grep "defaults write .GlobalPreferences 'com.apple.sound.beep.sound' -string '/System/Library/Sounds/Funk.aiff'" ${config.out}/activate-user - grep "defaults write com.apple.menuextra.clock 'Show24Hour' -bool NO" ${config.out}/activate-user - grep "defaults write com.apple.menuextra.clock 'ShowDayOfWeek' -bool YES" ${config.out}/activate-user - grep "defaults write com.apple.menuextra.clock 'ShowDate' -int 2" ${config.out}/activate-user - grep "defaults write com.apple.dock 'autohide-delay' -float 0.24" ${config.out}/activate-user - grep "defaults write com.apple.dock 'appswitcher-all-displays' -bool NO" ${config.out}/activate-user - grep "defaults write com.apple.dock 'orientation' -string 'left'" ${config.out}/activate-user - grep "defaults write com.apple.screencapture 'location' -string '/tmp'" ${config.out}/activate-user - grep "defaults write com.apple.screensaver 'askForPassword' -bool YES" ${config.out}/activate-user - grep "defaults write com.apple.screensaver 'askForPasswordDelay' -int 5" ${config.out}/activate-user - grep "defaults write com.apple.universalaccess 'mouseDriverCursorSize' -float 1.5" ${config.out}/activate-user - grep "defaults write com.apple.universalaccess 'reduceTransparency' -bool YES" ${config.out}/activate-user - grep "defaults write com.apple.universalaccess 'closeViewScrollWheelToggle' -bool YES" ${config.out}/activate-user - grep "defaults write com.apple.universalaccess 'closeViewZoomFollowsFocus' -bool YES" ${config.out}/activate-user - grep "defaults write com.apple.ActivityMonitor 'ShowCategory' -int 103" ${config.out}/activate-user - grep "defaults write com.apple.ActivityMonitor 'IconType' -int 3" ${config.out}/activate-user - grep "defaults write com.apple.ActivityMonitor 'SortColumn' -string 'CPUUsage'" ${config.out}/activate-user - grep "defaults write com.apple.ActivityMonitor 'SortDirection' -int 0" ${config.out}/activate-user - grep "defaults write com.apple.ActivityMonitor 'OpenMainWindow' -bool YES" ${config.out}/activate-user - grep "defaults write NSGlobalDomain 'TISRomanSwitchState' -int 1" ${config.out}/activate-user - ''; + test = lib.strings.concatMapStringsSep "\n" (x: '' + echo >&2 "checking defaults write in /${x}" + ${pkgs.python3}/bin/python3 <