Merge branch 'master' into invoiceplane-lang

This commit is contained in:
Jonas Heinrich
2025-01-04 14:09:17 +01:00
committed by GitHub
6082 changed files with 61888 additions and 50763 deletions
+2
View File
@@ -19,6 +19,8 @@ name: Codeowners v2
#
# This split is done because checking code owners requires handling untrusted PR input,
# while requesting code owners requires PR write access, and those shouldn't be mixed.
#
# Note that the latter is also used for ./eval.yml requesting reviewers.
on:
pull_request_target:
+48 -3
View File
@@ -133,6 +133,7 @@ jobs:
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ needs.get-merge-commit.outputs.mergedSha }}
fetch-depth: 2
path: nixpkgs
- name: Install Nix
@@ -194,12 +195,18 @@ jobs:
- name: Compare against the base branch
if: steps.baseRunId.outputs.baseRunId
run: |
nix-build nixpkgs/ci -A eval.compare \
git -C nixpkgs worktree add ../base ${{ needs.attrs.outputs.baseSha }}
git -C nixpkgs diff --name-only ${{ needs.attrs.outputs.baseSha }} ${{ needs.attrs.outputs.mergedSha }} \
| jq --raw-input --slurp 'split("\n")[:-1]' > touched-files.json
# Use the base branch to get accurate maintainer info
nix-build base/ci -A eval.compare \
--arg beforeResultDir ./baseResult \
--arg afterResultDir ./prResult \
--arg touchedFilesJson ./touched-files.json \
-o comparison
cat comparison/step-summary.md >> "$GITHUB_STEP_SUMMARY"
# TODO: Request reviews from maintainers for packages whose files are modified in the PR
- name: Upload the combined results
if: steps.baseRunId.outputs.baseRunId
@@ -212,18 +219,41 @@ jobs:
tag:
name: Tag
runs-on: ubuntu-latest
needs: process
needs: [ attrs, process ]
if: needs.process.outputs.baseRunId
permissions:
pull-requests: write
statuses: write
steps:
# See ./codeowners-v2.yml, reuse the same App because we need the same permissions
# Can't use the token received from permissions above, because it can't get enough permissions
- uses: actions/create-github-app-token@5d869da34e18e7287c1daad50e0b8ea0f506ce69 # v1.11.0
id: app-token
with:
app-id: ${{ vars.OWNER_APP_ID }}
private-key: ${{ secrets.OWNER_APP_PRIVATE_KEY }}
- name: Download process result
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
with:
name: comparison
path: comparison
- name: Install Nix
uses: cachix/install-nix-action@08dcb3a5e62fa31e2da3d490afc4176ef55ecd72 # v30
# Important: This workflow job runs with extra permissions,
# so we need to make sure to not run untrusted code from PRs
- name: Check out Nixpkgs at the base commit
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ needs.attrs.outputs.baseSha }}
path: base
sparse-checkout: ci
- name: Build the requestReviews derivation
run: nix-build base/ci -A requestReviews
- name: Tagging pull request
run: |
# Get all currently set rebuild labels
@@ -252,10 +282,25 @@ jobs:
/repos/"$REPOSITORY"/issues/"$NUMBER"/labels \
-f "labels[]=$toAdd"
done < <(comm -13 before after)
# maintainers.json contains GitHub IDs. Look up handles to request reviews from.
# There appears to be no API to request reviews based on GitHub IDs
jq -r 'keys[]' comparison/maintainers.json \
| while read -r id; do gh api /user/"$id" --jq .login; done \
| GH_TOKEN=${{ steps.app-token.outputs.token }} result/bin/process-reviewers.sh "$REPOSITORY" "$NUMBER" "$AUTHOR" \
> reviewers.json
# Request reviewers from maintainers of changed output paths
GH_TOKEN=${{ steps.app-token.outputs.token }} gh api \
--method POST \
/repos/"$REPOSITORY"/pulls/"$NUMBER"/requested_reviewers \
--input reviewers.json
env:
GH_TOKEN: ${{ github.token }}
REPOSITORY: ${{ github.repository }}
NUMBER: ${{ github.event.number }}
AUTHOR: ${{ github.event.pull_request.user.login }}
- name: Add eval summary to commit statuses
if: ${{ github.event_name == 'pull_request_target' }}
+4 -5
View File
@@ -1,18 +1,17 @@
name: "No channel PR"
on:
pull_request:
pull_request_target:
# Re-run should be triggered when the base branch is updated, instead of silently failing
types: [opened, synchronize, reopened, edited]
branches:
- 'nixos-**'
- 'nixpkgs-**'
permissions:
contents: read
permissions: {}
jobs:
fail:
permissions:
contents: none
name: "This PR is is targeting a channel branch"
runs-on: ubuntu-latest
steps:
-34
View File
@@ -1,34 +0,0 @@
name: "Set pending OfBorg status"
on:
pull_request_target:
# Sets the ofborg-eval status to "pending" to signal that we are waiting for
# OfBorg even if it is running late. The status will be overwritten by OfBorg
# once it starts evaluation.
# WARNING:
# When extending this action, be aware that $GITHUB_TOKEN allows (restricted) write access to
# the GitHub repository. This means that it should not evaluate user input in a
# way that allows code injection.
permissions:
contents: read
jobs:
action:
name: set-ofborg-pending
if: github.repository_owner == 'NixOS'
permissions:
statuses: write
runs-on: ubuntu-latest
steps:
- name: "Set pending OfBorg status"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
curl \
-X POST \
-H "Accept: application/vnd.github.v3+json" \
-H "Authorization: Bearer $GITHUB_TOKEN" \
-d '{"context": "ofborg-eval", "state": "pending", "description": "Waiting for OfBorg..."}' \
"https://api.github.com/repos/NixOS/nixpkgs/commits/${{ github.event.pull_request.head.sha }}/statuses"
-6
View File
@@ -33,12 +33,6 @@ jobs:
max-parallel: 1
matrix:
pairs:
- from: master
into: haskell-updates
- from: release-24.05
into: staging-next-24.05
- from: staging-next-24.05
into: staging-24.05
- from: release-24.11
into: staging-next-24.11
- from: staging-next-24.11
@@ -0,0 +1,59 @@
# This action periodically merges a merge base of master and staging into haskell-updates.
#
# haskell-updates is based on master (so there are little unrelated failures and the cache
# is already prepopulated), but needs to target staging due to the high amount of rebuilds
# it typically causes. To prevent unrelated commits clattering the GitHub UI, we need to
# take care to only merge the merge-base of master and staging into haskell-updates.
#
# See also https://github.com/NixOS/nixpkgs/issues/361143.
name: "Periodic Merges (haskell-updates)"
on:
schedule:
# * is a special character in YAML so you have to quote this string
# Merge every 24 hours
- cron: '0 0 * * *'
workflow_dispatch:
permissions:
contents: read
jobs:
periodic-merge:
permissions:
contents: write # for devmasx/merge-branch to merge branches
pull-requests: write # for peter-evans/create-or-update-comment to create or update comment
if: github.repository_owner == 'NixOS'
runs-on: ubuntu-latest
name: git merge-base master staging → haskell-updates
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0
# Note: If we want to do something similar for more branches, we can move this into a
# separate job, so we can use the matrix strategy again.
- name: Find merge base of master and staging
id: find_merge_base_step
run: |
merge_base="$(git merge-base refs/remotes/origin/master refs/remotes/origin/staging)"
echo "Found merge base: $merge_base" >&2
echo "merge_base=$merge_base" >> "$GITHUB_OUTPUT"
- name: git merge-base master staging → haskell-updates
uses: devmasx/merge-branch@854d3ac71ed1e9deb668e0074781b81fdd6e771f # 1.4.0
with:
type: now
head_to_merge: ${{ steps.find_merge_base_step.outputs.merge_base }}
target_branch: haskell-updates
github_token: ${{ secrets.GITHUB_TOKEN }}
- name: Comment on failure
uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v4.0.0
if: ${{ failure() }}
with:
issue-number: 367709
body: |
Periodic merge from `${{ steps.find_merge_base_step.outputs.merge_base }}` into `haskell-updates` has [failed](https://github.com/NixOS/nixpkgs/actions/runs/${{ github.run_id }}).
+3
View File
@@ -10,6 +10,9 @@ Fiona Behrens <me@kloenk.dev>
Fiona Behrens <me@kloenk.dev> <me@kloenk.de>
goatastronaut0212 <goatastronaut0212@outlook.com> <goatastronaut0212@proton.me>
Janne Heß <janne@hess.ooo> <dasJ@users.noreply.github.com>
jopejoe1 <nixpkgs@missing.ninja>
jopejoe1 <nixpkgs@missing.ninja> <johannes@joens.email>
jopejoe1 <nixpkgs@missing.ninja> <34899572+jopejoe1@users.noreply.github.com>
Jörg Thalheim <joerg@thalheim.io> <Mic92@users.noreply.github.com>
Lin Jian <me@linj.tech> <linj.dev@outlook.com>
Lin Jian <me@linj.tech> <75130626+jian-lin@users.noreply.github.com>
+1 -1
View File
@@ -1,4 +1,4 @@
Copyright (c) 2003-2024 Eelco Dolstra and the Nixpkgs/NixOS contributors
Copyright (c) 2003-2025 Eelco Dolstra and the Nixpkgs/NixOS contributors
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
+18 -4
View File
@@ -5,7 +5,11 @@
writeText,
...
}:
{ beforeResultDir, afterResultDir }:
{
beforeResultDir,
afterResultDir,
touchedFilesJson,
}:
let
/*
Derivation that computes which packages are affected (added, changed or removed) between two revisions of nixpkgs.
@@ -77,11 +81,11 @@ let
# - values: lists of `packagePlatformPath`s
diffAttrs = diff beforeAttrs afterAttrs;
rebuilds = uniqueStrings (diffAttrs.added ++ diffAttrs.changed);
rebuildsPackagePlatformAttrs = convertToPackagePlatformAttrs rebuilds;
changed-paths =
let
rebuilds = uniqueStrings (diffAttrs.added ++ diffAttrs.changed);
rebuildsPackagePlatformAttrs = convertToPackagePlatformAttrs rebuilds;
rebuildsByPlatform = groupByPlatform rebuildsPackagePlatformAttrs;
rebuildsByKernel = groupByKernel rebuildsPackagePlatformAttrs;
rebuildCountByKernel = lib.mapAttrs (
@@ -104,10 +108,17 @@ let
);
}
);
maintainers = import ./maintainers.nix {
changedattrs = lib.unique (map (a: a.packagePath) rebuildsPackagePlatformAttrs);
changedpathsjson = touchedFilesJson;
};
in
runCommand "compare"
{
nativeBuildInputs = [ jq ];
maintainers = builtins.toJSON maintainers;
passAsFile = [ "maintainers" ];
}
''
mkdir $out
@@ -115,5 +126,8 @@ runCommand "compare"
cp ${changed-paths} $out/changed-paths.json
jq -r -f ${./generate-step-summary.jq} < ${changed-paths} > $out/step-summary.md
cp "$maintainersPath" "$out/maintainers.json"
# TODO: Compare eval stats
''
+123
View File
@@ -0,0 +1,123 @@
# Almost directly vendored from https://github.com/NixOS/ofborg/blob/5a4e743f192fb151915fcbe8789922fa401ecf48/ofborg/src/maintainers.nix
{ changedattrs, changedpathsjson }:
let
pkgs = import ../../.. {
system = "x86_64-linux";
config = { };
overlays = [ ];
};
inherit (pkgs) lib;
changedpaths = builtins.fromJSON (builtins.readFile changedpathsjson);
anyMatchingFile =
filename:
let
matching = builtins.filter (changed: lib.strings.hasSuffix changed filename) changedpaths;
in
(builtins.length matching) > 0;
anyMatchingFiles = files: (builtins.length (builtins.filter anyMatchingFile files)) > 0;
enrichedAttrs = builtins.map (path: {
path = path;
name = builtins.concatStringsSep "." path;
}) changedattrs;
validPackageAttributes = builtins.filter (
pkg:
if (lib.attrsets.hasAttrByPath pkg.path pkgs) then
(
if (builtins.tryEval (lib.attrsets.attrByPath pkg.path null pkgs)).success then
true
else
builtins.trace "Failed to access ${pkg.name} even though it exists" false
)
else
builtins.trace "Failed to locate ${pkg.name}." false
) enrichedAttrs;
attrsWithPackages = builtins.map (
pkg: pkg // { package = lib.attrsets.attrByPath pkg.path null pkgs; }
) validPackageAttributes;
attrsWithMaintainers = builtins.map (
pkg: pkg // { maintainers = (pkg.package.meta or { }).maintainers or [ ]; }
) attrsWithPackages;
attrsWeCanPing = builtins.filter (
pkg:
if (builtins.length pkg.maintainers) > 0 then
true
else
builtins.trace "Package has no maintainers: ${pkg.name}" false
) attrsWithMaintainers;
relevantFilenames =
drv:
(lib.lists.unique (
builtins.map (pos: lib.strings.removePrefix (toString ../..) pos.file) (
builtins.filter (x: x != null) [
(builtins.unsafeGetAttrPos "maintainers" (drv.meta or { }))
(builtins.unsafeGetAttrPos "src" drv)
# broken because name is always set by stdenv:
# # A hack to make `nix-env -qa` and `nix search` ignore broken packages.
# # TODO(@oxij): remove this assert when something like NixOS/nix#1771 gets merged into nix.
# name = assert validity.handled; name + lib.optionalString
#(builtins.unsafeGetAttrPos "name" drv)
(builtins.unsafeGetAttrPos "pname" drv)
(builtins.unsafeGetAttrPos "version" drv)
# Use ".meta.position" for cases when most of the package is
# defined in a "common" section and the only place where
# reference to the file with a derivation the "pos"
# attribute.
#
# ".meta.position" has the following form:
# "pkgs/tools/package-management/nix/default.nix:155"
# We transform it to the following:
# { file = "pkgs/tools/package-management/nix/default.nix"; }
{ file = lib.head (lib.splitString ":" (drv.meta.position or "")); }
]
)
));
attrsWithFilenames = builtins.map (
pkg: pkg // { filenames = relevantFilenames pkg.package; }
) attrsWithMaintainers;
attrsWithModifiedFiles = builtins.filter (pkg: anyMatchingFiles pkg.filenames) attrsWithFilenames;
listToPing = lib.lists.flatten (
builtins.map (
pkg:
builtins.map (maintainer: {
id = maintainer.githubId;
packageName = pkg.name;
dueToFiles = pkg.filenames;
}) pkg.maintainers
) attrsWithModifiedFiles
);
byMaintainer = lib.lists.foldr (
ping: collector:
collector
// {
"${toString ping.id}" = [
{ inherit (ping) packageName dueToFiles; }
] ++ (collector."${toString ping.id}" or [ ]);
}
) { } listToPing;
textForPackages =
packages: lib.strings.concatStringsSep ", " (builtins.map (pkg: pkg.packageName) packages);
textPerMaintainer = lib.attrsets.mapAttrs (
maintainer: packages: "- @${maintainer} for ${textForPackages packages}"
) byMaintainer;
packagesPerMaintainer = lib.attrsets.mapAttrs (
maintainer: packages: builtins.map (pkg: pkg.packageName) packages
) byMaintainer;
in
packagesPerMaintainer
+22 -18
View File
@@ -11,6 +11,7 @@ rec {
into
{
name = "hello";
packagePath = [ "hello" ];
platform = "aarch64-linux";
}
*/
@@ -30,6 +31,9 @@ rec {
null
else
{
# [ "python312Packages" "numpy" ]
inherit packagePath;
# python312Packages.numpy
inherit name;
@@ -52,12 +56,12 @@ rec {
]
into
[
{ name = "hello"; platform = "aarch64-linux"; }
{ name = "hello"; platform = "x86_64-linux"; }
{ name = "hello"; platform = "aarch64-darwin"; }
{ name = "hello"; platform = "x86_64-darwin"; }
{ name = "bye"; platform = "aarch64-darwin"; }
{ name = "bye"; platform = "x86_64-darwin"; }
{ name = "hello"; platform = "aarch64-linux"; packagePath = [ "hello" ]; }
{ name = "hello"; platform = "x86_64-linux"; packagePath = [ "hello" ]; }
{ name = "hello"; platform = "aarch64-darwin"; packagePath = [ "hello" ]; }
{ name = "hello"; platform = "x86_64-darwin"; packagePath = [ "hello" ]; }
{ name = "bye"; platform = "aarch64-darwin"; packagePath = [ "hello" ]; }
{ name = "bye"; platform = "x86_64-darwin"; packagePath = [ "hello" ]; }
]
*/
convertToPackagePlatformAttrs =
@@ -120,12 +124,12 @@ rec {
Turns
[
{ name = "hello"; platform = "aarch64-linux"; }
{ name = "hello"; platform = "x86_64-linux"; }
{ name = "hello"; platform = "aarch64-darwin"; }
{ name = "hello"; platform = "x86_64-darwin"; }
{ name = "bye"; platform = "aarch64-darwin"; }
{ name = "bye"; platform = "x86_64-darwin"; }
{ name = "hello"; platform = "aarch64-linux"; ... }
{ name = "hello"; platform = "x86_64-linux"; ... }
{ name = "hello"; platform = "aarch64-darwin"; ... }
{ name = "hello"; platform = "x86_64-darwin"; ... }
{ name = "bye"; platform = "aarch64-darwin"; ... }
{ name = "bye"; platform = "x86_64-darwin"; ... }
]
into
{
@@ -145,12 +149,12 @@ rec {
# Turns
# [
# { name = "hello"; platform = "aarch64-linux"; }
# { name = "hello"; platform = "x86_64-linux"; }
# { name = "hello"; platform = "aarch64-darwin"; }
# { name = "hello"; platform = "x86_64-darwin"; }
# { name = "bye"; platform = "aarch64-darwin"; }
# { name = "bye"; platform = "x86_64-darwin"; }
# { name = "hello"; platform = "aarch64-linux"; ... }
# { name = "hello"; platform = "x86_64-linux"; ... }
# { name = "hello"; platform = "aarch64-darwin"; ... }
# { name = "hello"; platform = "x86_64-darwin"; ... }
# { name = "bye"; platform = "aarch64-darwin"; ... }
# { name = "bye"; platform = "x86_64-darwin"; ... }
# ]
#
# into
+1
View File
@@ -15,6 +15,7 @@ stdenvNoCC.mkDerivation {
root = ./.;
fileset = lib.fileset.unions [
./get-reviewers.sh
./process-reviewers.sh
./request-reviews.sh
./verify-base-branch.sh
./dev-branches.txt
+6 -36
View File
@@ -1,8 +1,6 @@
#!/usr/bin/env bash
# Get the code owners of the files changed by a PR,
# suitable to be consumed by the API endpoint to request reviews:
# https://docs.github.com/en/rest/pulls/review-requests?apiVersion=2022-11-28#request-reviewers-for-a-pull-request
# Get the code owners of the files changed by a PR, returning one username per line
set -euo pipefail
@@ -10,18 +8,15 @@ log() {
echo "$@" >&2
}
if (( "$#" < 7 )); then
log "Usage: $0 GIT_REPO OWNERS_FILE BASE_REPO BASE_REF HEAD_REF PR_NUMBER PR_AUTHOR"
if (( "$#" < 4 )); then
log "Usage: $0 GIT_REPO OWNERS_FILE BASE_REF HEAD_REF"
exit 1
fi
gitRepo=$1
ownersFile=$2
baseRepo=$3
baseRef=$4
headRef=$5
prNumber=$6
prAuthor=$7
baseRef=$3
headRef=$4
tmp=$(mktemp -d)
trap 'rm -rf "$tmp"' exit
@@ -98,29 +93,4 @@ for file in "${touchedFiles[@]}"; do
done
# Cannot request a review from the author
if [[ -v users[${prAuthor,,}] ]]; then
log "One or more files are owned by the PR author, ignoring"
unset 'users[${prAuthor,,}]'
fi
gh api \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"/repos/$baseRepo/pulls/$prNumber/reviews" \
--jq '.[].user.login' > "$tmp/already-reviewed-by"
# And we don't want to rerequest reviews from people who already reviewed
while read -r user; do
if [[ -v users[${user,,}] ]]; then
log "User $user is a code owner but has already left a review, ignoring"
unset 'users[${user,,}]'
fi
done < "$tmp/already-reviewed-by"
# Turn it into a JSON for the GitHub API call to request PR reviewers
jq -n \
--arg users "${!users[*]}" \
'{
reviewers: $users | split(" "),
}'
printf "%s\n" "${!users[@]}"
+65
View File
@@ -0,0 +1,65 @@
#!/usr/bin/env bash
# Process reviewers for a PR, reading line-separated usernames on stdin,
# returning a JSON suitable to be consumed by the API endpoint to request reviews:
# https://docs.github.com/en/rest/pulls/review-requests?apiVersion=2022-11-28#request-reviewers-for-a-pull-request
set -euo pipefail
log() {
echo "$@" >&2
}
if (( "$#" < 3 )); then
log "Usage: $0 BASE_REPO PR_NUMBER PR_AUTHOR"
exit 1
fi
baseRepo=$1
prNumber=$2
prAuthor=$3
tmp=$(mktemp -d)
trap 'rm -rf "$tmp"' exit
declare -A users=()
while read -r handle && [[ -n "$handle" ]]; do
users[${handle,,}]=
done
# Cannot request a review from the author
if [[ -v users[${prAuthor,,}] ]]; then
log "One or more files are owned by the PR author, ignoring"
unset 'users[${prAuthor,,}]'
fi
gh api \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"/repos/$baseRepo/pulls/$prNumber/reviews" \
--jq '.[].user.login' > "$tmp/already-reviewed-by"
# And we don't want to rerequest reviews from people who already reviewed
while read -r user; do
if [[ -v users[${user,,}] ]]; then
log "User $user is a code owner but has already left a review, ignoring"
unset 'users[${user,,}]'
fi
done < "$tmp/already-reviewed-by"
for user in "${!users[@]}"; do
if ! gh api \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"/repos/$baseRepo/collaborators/$user" >&2; then
log "User $user is not a repository collaborator, probably missed the automated invite to the maintainers team (see <https://github.com/NixOS/nixpkgs/issues/234293>), ignoring"
unset 'users[$user]'
fi
done
# Turn it into a JSON for the GitHub API call to request PR reviewers
jq -n \
--arg users "${!users[*]}" \
'{
reviewers: $users | split(" "),
}'
+2 -1
View File
@@ -78,7 +78,8 @@ if ! "$SCRIPT_DIR"/verify-base-branch.sh "$tmp/nixpkgs.git" "$headRef" "$baseRep
fi
log "Getting code owners to request reviews from"
"$SCRIPT_DIR"/get-reviewers.sh "$tmp/nixpkgs.git" "$ownersFile" "$baseRepo" "$baseBranch" "$headRef" "$prNumber" "$prAuthor" > "$tmp/reviewers.json"
"$SCRIPT_DIR"/get-reviewers.sh "$tmp/nixpkgs.git" "$ownersFile" "$baseBranch" "$headRef" | \
"$SCRIPT_DIR"/process-reviewers.sh "$baseRepo" "$prNumber" "$prAuthor" > "$tmp/reviewers.json"
log "Requesting reviews from: $(<"$tmp/reviewers.json")"
+1 -1
View File
@@ -728,7 +728,7 @@ buildPythonPackage rec {
(fetchDebianPatch {
inherit pname version;
debianRevision = "5";
name = "Add-quotes-to-SOAPAction-header-in-SoapClient.patch";
patch = "Add-quotes-to-SOAPAction-header-in-SoapClient.patch";
hash = "sha256-xA8Wnrpr31H8wy3zHSNfezFNjUJt1HbSXn3qUMzeKc0=";
})
];
+3 -4
View File
@@ -94,10 +94,7 @@
stdenvNoCC.mkDerivation {
name = "nixpkgs-lib-docs";
src = lib.fileset.toSource {
root = ../..;
fileset = ../../lib;
};
src = ../../lib;
nativeBuildInputs = [
nixdoc
@@ -105,6 +102,8 @@ stdenvNoCC.mkDerivation {
];
installPhase = ''
cd ..
export NIX_STATE_DIR=$(mktemp -d)
nix-instantiate --eval --strict --json ${./lib-function-locations.nix} \
--arg nixpkgsPath "./." \
+16 -10
View File
@@ -25,16 +25,22 @@ stdenvNoCC.mkDerivation (
nativeBuildInputs = [ nixos-render-docs ];
src = lib.fileset.toSource {
root = ../.;
fileset = lib.fileset.unions [
(lib.fileset.fileFilter (file: file.hasExt "md" || file.hasExt "md.in") ../.)
../style.css
../anchor-use.js
../anchor.min.js
../manpage-urls.json
../redirects.json
];
src = lib.cleanSourceWith {
src = ../.;
filter =
path: type:
type == "directory"
|| lib.hasSuffix ".md" path
|| lib.hasSuffix ".md.in" path
|| lib.elem path (
map toString [
../style.css
../anchor-use.js
../anchor.min.js
../manpage-urls.json
../redirects.json
]
);
};
postPatch = ''
-1
View File
@@ -95,6 +95,5 @@ scheme.section.md
swift.section.md
tcl.section.md
texlive.section.md
titanium.section.md
vim.section.md
```
@@ -1,110 +0,0 @@
# Titanium {#titanium}
The Nixpkgs repository contains facilities to deploy a variety of versions of
the [Titanium SDK](https://www.appcelerator.com) versions, a cross-platform
mobile app development framework using JavaScript as an implementation language,
and includes a function abstraction making it possible to build Titanium
applications for Android and iOS devices from source code.
Not all Titanium features supported -- currently, it can only be used to build
Android and iOS apps.
## Building a Titanium app {#building-a-titanium-app}
We can build a Titanium app from source for Android or iOS and for debugging or
release purposes by invoking the `titaniumenv.buildApp {}` function:
```nix
titaniumenv.buildApp {
name = "myapp";
src = ./myappsource;
preBuild = "";
target = "android"; # or 'iphone'
tiVersion = "7.1.0.GA";
release = true;
androidsdkArgs = {
platformVersions = [ "25" "26" ];
};
androidKeyStore = ./keystore;
androidKeyAlias = "myfirstapp";
androidKeyStorePassword = "secret";
xcodeBaseDir = "/Applications/Xcode.app";
xcodewrapperArgs = {
version = "9.3";
};
iosMobileProvisioningProfile = ./myprovisioning.profile;
iosCertificateName = "My Company";
iosCertificate = ./mycertificate.p12;
iosCertificatePassword = "secret";
iosVersion = "11.3";
iosBuildStore = false;
enableWirelessDistribution = true;
installURL = "/installipa.php";
}
```
The `titaniumenv.buildApp {}` function takes the following parameters:
* The `name` parameter refers to the name in the Nix store.
* The `src` parameter refers to the source code location of the app that needs
to be built.
* `preRebuild` contains optional build instructions that are carried out before
the build starts.
* `target` indicates for which device the app must be built. Currently only
'android' and 'iphone' (for iOS) are supported.
* `tiVersion` can be used to optionally override the requested Titanium version
in `tiapp.xml`. If not specified, it will use the version in `tiapp.xml`.
* `release` should be set to true when building an app for submission to the
Google Playstore or Apple Appstore. Otherwise, it should be false.
When the `target` has been set to `android`, we can configure the following
parameters:
* The `androidSdkArgs` parameter refers to an attribute set that propagates all
parameters to the `androidenv.composeAndroidPackages {}` function. This can
be used to install all relevant Android plugins that may be needed to perform
the Android build. If no parameters are given, it will deploy the platform
SDKs for API-levels 25 and 26 by default.
When the `release` parameter has been set to true, you need to provide
parameters to sign the app:
* `androidKeyStore` is the path to the keystore file
* `androidKeyAlias` is the key alias
* `androidKeyStorePassword` refers to the password to open the keystore file.
When the `target` has been set to `iphone`, we can configure the following
parameters:
* The `xcodeBaseDir` parameter refers to the location where Xcode has been
installed. When none value is given, the above value is the default.
* The `xcodewrapperArgs` parameter passes arbitrary parameters to the
`xcodeenv.composeXcodeWrapper {}` function. This can, for example, be used
to adjust the default version of Xcode.
When `release` has been set to true, you also need to provide the following
parameters:
* `iosMobileProvisioningProfile` refers to a mobile provisioning profile needed
for signing.
* `iosCertificateName` refers to the company name in the P12 certificate.
* `iosCertificate` refers to the path to the P12 file.
* `iosCertificatePassword` contains the password to open the P12 file.
* `iosVersion` refers to the iOS SDK version to use. It defaults to the latest
version.
* `iosBuildStore` should be set to `true` when building for the Apple Appstore
submission. For enterprise or ad-hoc builds it should be set to `false`.
When `enableWirelessDistribution` has been enabled, you must also provide the
path of the PHP script (`installURL`) (that is included with the iOS build
environment) to enable wireless ad-hoc installations.
## Emulating or simulating the app {#emulating-or-simulating-the-app}
It is also possible to simulate the correspond iOS simulator build by using
`xcodeenv.simulateApp {}` and emulate an Android APK by using
`androidenv.emulateApp {}`.
+4
View File
@@ -14,3 +14,7 @@ development.md
contributing.md
interoperability.md
```
```{=include=} appendix html:into-file=//release-notes.html
release-notes/release-notes.md
```
+5 -2
View File
@@ -7,9 +7,12 @@ The module system is a language for handling configuration, implemented as a Nix
Compared to plain Nix, it adds documentation, type checking and composition or extensibility.
::: {.note}
This chapter is new and not complete yet. For a gentle introduction to the module system, in the context of NixOS, see [Writing NixOS Modules](https://nixos.org/manual/nixos/unstable/index.html#sec-writing-modules) in the NixOS manual.
:::
This chapter is new and not complete yet.
See also:
- Introduction to the module system, in the context of NixOS, see [Writing NixOS Modules](https://nixos.org/manual/nixos/unstable/index.html#sec-writing-modules) in the NixOS manual.
- Generic guide to the module system on [nix.dev](https://nix.dev/tutorials/module-system/index.html).
:::
## `lib.evalModules` {#module-system-lib-evalModules}
+1 -1
View File
@@ -98,5 +98,5 @@ substituteAllFiles {
}
```
in the resulting derivation, every instance of `@hello@` will be replaced with `there` in `$out/foo.txt` and` `$out/bar.txt`; `baz.txt` will not be processed nor will it appear in `$out`.
in the resulting derivation, every instance of `@hello@` will be replaced with `there` in `$out/foo.txt` and `$out/bar.txt`; `baz.txt` will not be processed nor will it appear in `$out`.
:::
+21 -9
View File
@@ -1,4 +1,7 @@
{
"chap-release-notes": [
"release-notes.html#chap-release-notes"
],
"nixpkgs-manual": [
"index.html#nixpkgs-manual"
],
@@ -50,6 +53,24 @@
"chap-overlays": [
"index.html#chap-overlays"
],
"sec-nixpkgs-release-25.05": [
"release-notes.html#sec-nixpkgs-release-25.05"
],
"sec-nixpkgs-release-25.05-incompatibilities": [
"release-notes.html#sec-nixpkgs-release-25.05-incompatibilities"
],
"sec-nixpkgs-release-25.05-incompatibilities-titanium-removed": [
"release-notes.html#sec-nixpkgs-release-25.05-incompatibilities-titanium-removed",
"index.html#titanium",
"index.html#building-a-titanium-app",
"index.html#emulating-or-simulating-the-app"
],
"sec-nixpkgs-release-25.05-lib": [
"release-notes.html#sec-nixpkgs-release-25.05-lib"
],
"sec-nixpkgs-release-25.05-lib-breaking": [
"release-notes.html#sec-nixpkgs-release-25.05-lib-breaking"
],
"sec-overlays-install": [
"index.html#sec-overlays-install"
],
@@ -3736,15 +3757,6 @@
"sec-language-texlive-lualatex-font-cache": [
"index.html#sec-language-texlive-lualatex-font-cache"
],
"titanium": [
"index.html#titanium"
],
"building-a-titanium-app": [
"index.html#building-a-titanium-app"
],
"emulating-or-simulating-the-app": [
"index.html#emulating-or-simulating-the-app"
],
"vim": [
"index.html#vim"
],
+7
View File
@@ -0,0 +1,7 @@
# Release Notes {#chap-release-notes}
This section lists the release notes for each stable version of Nixpkgs and current unstable revision.
```{=include=} sections
rl-2505.section.md
```
+19
View File
@@ -0,0 +1,19 @@
# Nixpkgs 25.05 (2025.05/??) {#sec-nixpkgs-release-25.05}
## Backward Incompatibilities {#sec-nixpkgs-release-25.05-incompatibilities}
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
### Titanium removed {#sec-nixpkgs-release-25.05-incompatibilities-titanium-removed}
- `titaniumenv`, `titanium`, and `titanium-alloy` have been removed due to lack of maintenance in Nixpkgs.
## Nixpkgs Library {#sec-nixpkgs-release-25.05-lib}
### Breaking changes {#sec-nixpkgs-release-25.05-lib-breaking}
- Structure of the `functor` of some types has changed. `functor` is an implementation detail and should not be relied upon. If you did rely on it let us know in this [PR](https://github.com/NixOS/nixpkgs/pull/363565).
- [`lib.types.enum`](https://nixos.org/manual/nixos/unstable/#sec-option-types-basic): Previously the `functor.payload` was the list of enum values directly. Now it is an attribute set containing the values in the `values` attribute.
- [`lib.types.separatedString`](https://nixos.org/manual/nixos/unstable/#sec-option-types-string): Previously the `functor.payload` was the seperator directly. Now it is an attribute set containing the seperator in the `sep` attribute.
+1 -1
View File
@@ -416,7 +416,7 @@ in {
*/
oldestSupportedRelease =
# Update on master only. Do not backport.
2405;
2411;
/**
Whether a feature is supported in all supported releases (at the time of
+119 -2
View File
@@ -1632,6 +1632,12 @@
matrix = "@anthonyrsl:matrix.org";
keys = [ { fingerprint = "472D 368A F107 F443 F3A5 C712 9DC4 987B 1A55 E75E"; } ];
};
antipatico = {
email = "code@bootkit.dev";
github = "antipatico";
githubId = 14838767;
name = "Jacopo Scannella";
};
antoinerg = {
email = "roygobeil.antoine@gmail.com";
github = "antoinerg";
@@ -2510,6 +2516,12 @@
githubId = 66330398;
name = "Victor Hang";
};
baongoc124 = {
email = "baongoc124@gmail.com";
github = "baongoc124";
githubId = 766221;
name = "Ngoc Nguyen";
};
barab-i = {
email = "barab_i@outlook.com";
github = "barab-i";
@@ -4931,6 +4943,12 @@
github = "damhiya";
githubId = 13533446;
};
damidoug = {
email = "contact@damidoug.dev";
github = "damidoug";
githubId = 75175586;
name = "Douglas Damiano";
};
DamienCassou = {
email = "damien@cassou.me";
github = "DamienCassou";
@@ -5874,6 +5892,11 @@
githubId = 283316;
name = "Dane Lipscombe";
};
dlurak = {
github = "dlurak";
githubId = 84224239;
name = "dlurak";
};
dmadisetti = {
email = "nix@madisetti.me";
github = "dmadisetti";
@@ -5970,6 +5993,12 @@
githubId = 57304299;
keys = [ { fingerprint = "33CD 5C0A 673C C54D 661E 5E4C 0DB5 361B EEE5 30AB"; } ];
};
dopplerian = {
name = "Dopplerian";
github = "Dopplerian";
githubId = 53937537;
keys = [ { fingerprint = "BBC4 C071 516B A147 8D07 F9DC D2FD E6EC 2E8C 2BF4"; } ];
};
doriath = {
email = "tomasz.zurkowski@gmail.com";
github = "doriath";
@@ -9200,6 +9229,13 @@
githubId = 287215;
keys = [ { fingerprint = "D618 7A03 A40A 3D56 62F5 4B46 03EF BF83 9A5F DC15"; } ];
};
hlad = {
email = "hlad+nix@hlad.org";
name = "Marek Hladky";
matrix = "@hlad:hlad.org";
github = "hlad";
githubId = 6285728;
};
hleboulanger = {
email = "hleboulanger@protonmail.com";
name = "Harold Leboulanger";
@@ -10116,6 +10152,12 @@
githubId = 45084216;
keys = [ { fingerprint = "1BF9 8D10 E0D0 0B41 5723 5836 4C13 3A84 E646 9228"; } ];
};
jaculabilis = {
name = "Tim Van Baak";
email = "tim.vanbaak@gmail.com";
github = "Jaculabilis";
githubId = 10787844;
};
jaduff = {
email = "jdduffpublic@proton.me";
github = "jaduff";
@@ -11117,11 +11159,11 @@
githubId = 13179;
};
jopejoe1 = {
email = "johannes@joens.email";
email = "nixpkgs@missing.ninja";
matrix = "@jopejoe1:matrix.org";
github = "jopejoe1";
githubId = 34899572;
name = "Johannes Jöns";
name = "jopejoe1";
};
jordanisaacs = {
name = "Jordan Isaacs";
@@ -12493,6 +12535,12 @@
githubId = 168301;
name = "Victor Engmark";
};
l1npengtul = {
email = "l1npengtul@l1npengtul.lol";
github = "l1npengtul";
githubId = 35755164;
name = "l1npengtul";
};
l33tname = {
name = "l33tname";
email = "hi@l33t.name";
@@ -13714,6 +13762,17 @@
githubId = 24735185;
name = "Mahmoud Ayman";
};
mahtaran = {
email = "luka.leer@gmail.com";
github = "mahtaran";
githubId = 22727323;
name = "Luka Leer";
keys = [
{
fingerprint = "C7FF B72E 0527 423A D470 E132 AA82 C4EB CB16 82E0";
}
];
};
majesticmullet = {
email = "hoccthomas@gmail.com.au";
github = "MajesticMullet";
@@ -15282,6 +15341,12 @@
githubId = 44561540;
name = "Synth Morxemplum";
};
MostafaKhaled = {
email = "mostafa.khaled.5422@gmail.com";
github = "mostafa-khaled775";
githubId = 112074172;
name = "Mostafa Khaled";
};
MostAwesomeDude = {
email = "cds@corbinsimpson.com";
github = "MostAwesomeDude";
@@ -15609,6 +15674,12 @@
githubId = 38578268;
name = "Morgan Wolfe";
};
mx2uller = {
email = "mx2uller@pm.me";
github = "mx2uller";
githubId = 93703653;
name = "Marko Müller";
};
mxkrsv = {
email = "mxkrsv@disroot.org";
github = "mxkrsv";
@@ -15637,6 +15708,12 @@
githubId = 9636071;
name = "Myrl Hex";
};
myypo = {
email = "nikirsmcgl@gmail.com";
github = "myypo";
githubId = 110892040;
name = "Mykyta Polchanov";
};
mzacho = {
email = "nixpkgs@martinzacho.net";
github = "mzacho";
@@ -16542,6 +16619,13 @@
githubId = 22592293;
name = "Kartik Gokte";
};
nullcube = {
email = "nullcub3@gmail.com";
name = "NullCube";
github = "nullcub3";
githubId = 51034487;
matrix = "@nullcube:matrix.org";
};
nullishamy = {
email = "spam@amyerskine.me";
name = "nullishamy";
@@ -18620,6 +18704,12 @@
githubId = 40905037;
name = "qwqawawow";
};
qxrein = {
email = "mnv07@proton.me";
github = "qxrein";
githubId = 101001298;
name = "qxrein";
};
qyliss = {
email = "hi@alyssa.is";
github = "alyssais";
@@ -21639,6 +21729,13 @@
githubId = 22163194;
name = "Stel Abrego";
};
stellessia = {
name = "Rachel Podya";
email = "homicide@disroot.org";
github = "stellessia";
githubId = 81514356;
keys = [ { fingerprint = "38E8 7F79 AE86 CA98 F8BC 45F8 1060 00A0 5E5B DB90"; } ];
};
stepbrobd = {
name = "Yifei Sun";
email = "ysun@hey.com";
@@ -21720,6 +21817,13 @@
githubId = 853468;
name = "Steven Roose";
};
stevestreza = {
email = "nixpkgs@stevestreza.com";
github = "stevestreza";
githubId = 28552;
name = "Steve Streza";
keys = [ { fingerprint = "DFED 4E42 34E7 348C 57D4 6568 C4DC 30F8 5ABC 6FA1"; } ];
};
stianlagstad = {
email = "stianlagstad@gmail.com";
github = "stianlagstad";
@@ -22264,6 +22368,12 @@
github = "teatwig";
githubId = 18734648;
};
tebriel = {
email = "tebriel@frodux.in";
name = "tebriel";
github = "tebriel";
githubId = 821688;
};
techknowlogick = {
email = "techknowlogick@gitea.com";
github = "techknowlogick";
@@ -24378,6 +24488,13 @@
githubId = 20464732;
name = "Willi Butz";
};
willow_ch = {
email = "nix@w.wolo.dev";
github = "spaghetus";
githubId = 28763739;
name = "Willow Carlson-Huber";
keys = [ { fingerprint = "FE21E0981CDFD50ADD086423C21A693BA4693A60"; } ];
};
willswats = {
email = "williamstuwatson@gmail.com";
github = "willswats";
+1
View File
@@ -197,6 +197,7 @@ with lib.maintainers;
siraben
vbgl
alizter
stepbrobd
];
scope = "Maintain the Coq theorem prover and related packages.";
shortName = "Coq";
+2
View File
@@ -79,6 +79,8 @@ let
prepareManualFromMD = ''
cp -r --no-preserve=all $inputs/* .
cp -r ${../../../doc/release-notes} ./release-notes-nixpkgs
substituteInPlace ./manual.md \
--replace-fail '@NIXOS_VERSION@' "${version}"
substituteInPlace ./configuration/configuration.md \
+16 -4
View File
@@ -1886,11 +1886,23 @@
"sec-release-25.05-notable-changes": [
"release-notes.html#sec-release-25.05-notable-changes"
],
"sec-release-25.05-lib": [
"release-notes.html#sec-release-25.05-lib"
"sec-nixpkgs-release-25.05": [
"release-notes.html#sec-nixpkgs-release-25.05"
],
"sec-release-25.05-lib-breaking": [
"release-notes.html#sec-release-25.05-lib-breaking"
"sec-nixpkgs-release-25.05-incompatibilities": [
"release-notes.html#sec-nixpkgs-release-25.05-incompatibilities"
],
"sec-nixpkgs-release-25.05-incompatibilities-titanium-removed": [
"release-notes.html#sec-nixpkgs-release-25.05-incompatibilities-titanium-removed",
"index.html#titanium",
"index.html#building-a-titanium-app",
"index.html#emulating-or-simulating-the-app"
],
"sec-nixpkgs-release-25.05-lib": [
"release-notes.html#sec-nixpkgs-release-25.05-lib"
],
"sec-nixpkgs-release-25.05-lib-breaking": [
"release-notes.html#sec-nixpkgs-release-25.05-lib-breaking"
],
"sec-release-24.11": [
"release-notes.html#sec-release-24.11"
@@ -51,6 +51,8 @@
- [networking.modemmanager](options.html#opt-networking.modemmanager) has been split out of [networking.networkmanager](options.html#opt-networking.networkmanager). NetworkManager still enables ModemManager by default, but options exist now to run NetworkManager without ModemManager.
- [ncps](https://github.com/kalbasit/ncps), a Nix binary cache proxy service implemented in Go using [go-nix](https://github.com/nix-community/go-nix). Available as [services.ncps](options.html#opt-services.ncps.enable).
- [Conduwuit](https://conduwuit.puppyirl.gay/), a federated chat server implementing the Matrix protocol, forked from Conduit. Available as [services.conduwuit](#opt-services.conduwuit.enable).
- [Traccar](https://www.traccar.org/), a modern GPS Tracking Platform. Available as [services.traccar](#opt-services.traccar.enable).
@@ -79,6 +81,8 @@
- [Actual Budget](https://actualbudget.org/), a local-first personal finance app. Available as [services.actual](#opt-services.actual.enable).
- [immich-public-proxy](https://github.com/alangrainger/immich-public-proxy), a proxy for sharing Immich albums without exposing the Immich API. Available as [services.immich-public-proxy](#opt-services.immich-public-proxy.enable).
- [mqtt-exporter](https://github.com/kpetremann/mqtt-exporter/), a Prometheus exporter for exposing messages from MQTT. Available as [services.prometheus.exporters.mqtt](#opt-services.prometheus.exporters.mqtt.enable).
- [nvidia-gpu](https://github.com/utkuozdemir/nvidia_gpu_exporter), a Prometheus exporter that scrapes `nvidia-smi` for GPU metrics. Available as [services.prometheus.exporters.nvidia-gpu](#opt-services.prometheus.exporters.nvidia-gpu.enable).
@@ -113,6 +117,15 @@
- `ps3-disc-dumper` was updated to 4.2.5, which removed the CLI project and now exclusively offers the GUI
- [](#opt-services.nextcloud.config.dbtype) is unset by default, the previous default was `sqlite`.
This was done because `sqlite` is not a reasonable default since it's
[not recommended by upstream](https://docs.nextcloud.com/server/30/admin_manual/installation/system_requirements.html)
and thus doesn't qualify as default.
- Nextcloud's default FPM pool settings have been increased according to upstream recommentations. It's advised
to review the new defaults and description of
[](#opt-services.nextcloud.poolSettings).
- `asusd` has been upgraded to version 6 which supports multiple aura devices. To account for this, the single `auraConfig` configuration option has been replaced with `auraConfigs` which is an attribute set of config options per each device. The config files may also be now specified as either source files or text strings; to account for this you will need to specify that `text` is used for your existing configs, e.g.:
```diff
-services.asusd.asusdConfig = '''file contents'''
@@ -127,6 +140,11 @@
- `zammad` has had its support for MySQL removed, since it was never working correctly and is now deprecated upstream. Check the [migration guide](https://docs.zammad.org/en/latest/appendix/migrate-to-postgresql.html) for how to convert your database to PostgreSQL.
- The `earlyoom` service is now using upstream systemd service, which enables
hardening and filesystem isolation by default. If you need filesystem write
access or want to access home directory via `killHook`, hardening setting can
be changed via, e.g. `systemd.services.earlyoom.serviceConfig.ProtectSystem`.
- `nodePackages.vls` has been deprecated, as the upstream consumer of it, vetur, has been deprecated by upstream. Upstream suggests migrating to Volar for Vue LSP tooling instead.
- `nodePackages.create-react-native-app` has been removed, as it is deprecated. Upstream suggests using a framework for React Native apps instead.
@@ -151,8 +169,12 @@
- `ente-auth` now uses the name `enteauth` for its binary. The previous name was `ente_auth`.
- `foundationdb` was upgraded to 7.3.
- `fluxus` has been removed, as it depends on `racket_7_9` and had no updates in 9 years.
- `sm64ex-coop` has been removed as it was archived upstream. Consider migrating to `sm64coopdx`.
- `renovate` was updated to v39. See the [upstream release notes](https://docs.renovatebot.com/release-notes-for-major-versions/#version-39) for breaking changes.
Like upstream's docker images, renovate now runs on NodeJS 22.
@@ -295,6 +317,10 @@
- `services.avahi.ipv6` now defaults to true.
- For matrix homeserver Synapse we are now following the upstream recommendation to enable jemalloc as the memory allocator by default.
- `services.kmonad` now creates a determinate symlink (in `/dev/input/by-id/`) to each of KMonad virtual devices.
- `bind.cacheNetworks` now only controls access for recursive queries, where it previously controlled access for all queries.
- Caddy can now be built with plugins by using `caddy.withPlugins`, a `passthru` function that accepts an attribute set as a parameter. The `plugins` argument represents a list of Caddy plugins, with each Caddy plugin being a versioned module. The `hash` argument represents the `vendorHash` of the resulting Caddy source code with the plugins added.
@@ -329,10 +355,6 @@
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
## Nixpkgs Library {#sec-release-25.05-lib}
### Breaking changes {#sec-release-25.05-lib-breaking}
- Structure of the `functor` of some types has changed. `functor` is an implementation detail and should not be relied upon. If you did rely on it let us know in this [PR](https://github.com/NixOS/nixpkgs/pull/363565).
- [`lib.types.enum`](https://nixos.org/manual/nixos/unstable/#sec-option-types-basic): Previously the `functor.payload` was the list of enum values directly. Now it is an attribute set containing the values in the `values` attribute.
- [`lib.types.separatedString`](https://nixos.org/manual/nixos/unstable/#sec-option-types-string): Previously the `functor.payload` was the seperator directly. Now it is an attribute set containing the seperator in the `sep` attribute.
```{=include=} sections
../release-notes-nixpkgs/rl-2505.section.md
```
+8
View File
@@ -65,6 +65,14 @@ let
withWarnings = x:
lib.warnIf (evalConfigArgs?extraArgs) "The extraArgs argument to eval-config.nix is deprecated. Please set config._module.args instead."
lib.warnIf (evalConfigArgs?check) "The check argument to eval-config.nix is deprecated. Please set config._module.check instead."
lib.warnIf (specialArgs?pkgs) ''
You have set specialArgs.pkgs, which means that options like nixpkgs.config
and nixpkgs.overlays will be ignored. If you wish to reuse an already created
pkgs, which you know is configured correctly for this NixOS configuration,
please import the `nixosModules.pkgsReadOnly` module from the nixpkgs flake or
`(modulesPath + "/misc/nixpkgs/read-only.nix"), and set `{ nixpkgs.pkgs = <your pkgs>; }`.
This properly disables the ignored options to prevent future surprises.
''
x;
legacyModules =
-3
View File
@@ -619,9 +619,6 @@ let format' = format; in let
# __noChroot for example).
export HOME=$TMPDIR
NIXOS_INSTALL_BOOTLOADER=1 nixos-enter --root $mountPoint -- /nix/var/nix/profiles/system/bin/switch-to-configuration boot
# The above scripts will generate a random machine-id and we don't want to bake a single ID into all our images
rm -f $mountPoint/etc/machine-id
''}
# Set the ownerships of the contents. The modes are set in preVM.
+1 -11
View File
@@ -14,22 +14,12 @@
extraPythonPackages ? (_: [ ]),
nixosTests,
}:
let
fs = lib.fileset;
in
python3Packages.buildPythonApplication {
pname = "nixos-test-driver";
version = "1.1";
pyproject = true;
src = fs.toSource {
root = ./.;
fileset = fs.unions [
./pyproject.toml
./test_driver
./extract-docstrings.py
];
};
src = ./src;
build-system = with python3Packages; [
setuptools
@@ -11,6 +11,6 @@ in
runCommand "nixos-test-driver-docstrings" env ''
mkdir $out
python3 ${./extract-docstrings.py} ${./test_driver/machine.py} \
python3 ${./src/extract-docstrings.py} ${./src/test_driver/machine.py} \
> $out/machine-methods.md
''
+29 -13
View File
@@ -8,19 +8,35 @@ let
cfg = config.fonts.fontDir;
x11Fonts = pkgs.runCommand "X11-fonts" { preferLocalBuild = true; } ''
mkdir -p "$out/share/X11/fonts"
font_regexp='.*\.\(ttf\|ttc\|otb\|otf\|pcf\|pfa\|pfb\|bdf\)\(\.gz\)?'
find ${toString config.fonts.packages} -regex "$font_regexp" \
-exec ln -sf -t "$out/share/X11/fonts" '{}' \;
cd "$out/share/X11/fonts"
${lib.optionalString cfg.decompressFonts ''
${pkgs.gzip}/bin/gunzip -f *.gz
''}
${pkgs.xorg.mkfontscale}/bin/mkfontscale
${pkgs.xorg.mkfontdir}/bin/mkfontdir
cat $(find ${pkgs.xorg.fontalias}/ -name fonts.alias) >fonts.alias
'';
x11Fonts = pkgs.callPackage (
{
runCommand,
gzip,
xorg,
}:
runCommand "X11-fonts"
{
preferLocalBuild = true;
nativeBuildInputs = [
gzip
xorg.mkfontscale
xorg.mkfontdir
];
}
''
mkdir -p "$out/share/X11/fonts"
font_regexp='.*\.\(ttf\|ttc\|otb\|otf\|pcf\|pfa\|pfb\|bdf\)\(\.gz\)?'
find ${toString config.fonts.packages} -regex "$font_regexp" \
-exec ln -sf -t "$out/share/X11/fonts" '{}' \;
cd "$out/share/X11/fonts"
${lib.optionalString cfg.decompressFonts ''
gunzip -f *.gz
''}
mkfontscale
mkfontdir
cat $(find ${pkgs.xorg.fontalias}/ -name fonts.alias) >fonts.alias
''
) { };
in
+2
View File
@@ -1160,6 +1160,7 @@
./services/networking/nats.nix
./services/networking/nbd.nix
./services/networking/ncdns.nix
./services/networking/ncps.nix
./services/networking/ndppd.nix
./services/networking/nebula.nix
./services/networking/netbird.nix
@@ -1485,6 +1486,7 @@
./services/web-apps/icingaweb2/module-monitoring.nix
./services/web-apps/ifm.nix
./services/web-apps/immich.nix
./services/web-apps/immich-public-proxy.nix
./services/web-apps/invidious.nix
./services/web-apps/invoiceplane.nix
./services/web-apps/isso.nix
+34 -28
View File
@@ -1,40 +1,46 @@
# This module defines a small NixOS configuration. It does not
# contain any graphical stuff.
{ config, lib, ... }:
with lib;
{
documentation.enable = mkDefault false;
lib,
...
}:
let
inherit (lib) mkDefault;
in
{
documentation = {
enable = mkDefault false;
doc.enable = mkDefault false;
info.enable = mkDefault false;
man.enable = mkDefault false;
nixos.enable = mkDefault false;
};
documentation.doc.enable = mkDefault false;
environment = {
# Perl is a default package.
defaultPackages = mkDefault [ ];
stub-ld.enable = mkDefault false;
};
documentation.info.enable = mkDefault false;
documentation.man.enable = mkDefault false;
documentation.nixos.enable = mkDefault false;
# Perl is a default package.
environment.defaultPackages = mkDefault [ ];
environment.stub-ld.enable = mkDefault false;
# The lessopen package pulls in Perl.
programs.less.lessopen = mkDefault null;
programs = {
# The lessopen package pulls in Perl.
less.lessopen = mkDefault null;
command-not-found.enable = mkDefault false;
};
# This pulls in nixos-containers which depends on Perl.
boot.enableContainers = mkDefault false;
programs.command-not-found.enable = mkDefault false;
services = {
logrotate.enable = mkDefault false;
udisks2.enable = mkDefault false;
};
services.logrotate.enable = mkDefault false;
services.udisks2.enable = mkDefault false;
xdg.autostart.enable = mkDefault false;
xdg.icons.enable = mkDefault false;
xdg.mime.enable = mkDefault false;
xdg.sounds.enable = mkDefault false;
xdg = {
autostart.enable = mkDefault false;
icons.enable = mkDefault false;
mime.enable = mkDefault false;
sounds.enable = mkDefault false;
};
}
+1 -1
View File
@@ -75,7 +75,7 @@ let
{
freeformType = attrsOf (either scalarType (listOf scalarType));
# Client system-options file directives are explained here:
# https://www.ibm.com/docs/en/storage-protect/8.1.24?topic=commands-processing-options
# https://www.ibm.com/docs/en/storage-protect/8.1.25?topic=commands-processing-options
options.servername = mkOption {
type = servernameType;
default = name;
@@ -45,6 +45,12 @@ in
description = "Port to run Navidrome on.";
type = port;
};
EnableInsightsCollector = mkOption {
default = false;
description = "Enable anonymous usage data collection, see <https://www.navidrome.org/docs/getting-started/insights/> for details.";
type = bool;
};
};
};
default = { };
+2 -2
View File
@@ -44,8 +44,8 @@ let
borgWrapper () {
local result
borg "$@" && result=$? || result=$?
if [[ -z "${toString cfg.failOnWarnings}" ]] && [[ "$result" == 1 ]]; then
echo "ignoring warning return value 1"
if [[ -z "${toString cfg.failOnWarnings}" ]] && [[ "$result" == 1 || ("$result" -ge 100 && "$result" -le 127) ]]; then
echo "ignoring warning return value $result"
return 0
else
return "$result"
+1 -1
View File
@@ -412,7 +412,7 @@ in
]}
PATH=${config.systemd.services."restic-backups-${name}".environment.PATH}:$PATH
exec ${resticCmd} $@
exec ${resticCmd} "$@"
'') (lib.filterAttrs (_: v: v.createWrapper) config.services.restic.backups);
};
}
+1 -1
View File
@@ -89,7 +89,7 @@ in
environment.HOME = "/var/lib/tsm-backup";
serviceConfig = {
# for exit status description see
# https://www.ibm.com/docs/en/storage-protect/8.1.24?topic=clients-client-return-codes
# https://www.ibm.com/docs/en/storage-protect/8.1.25?topic=clients-client-return-codes
SuccessExitStatus = "4 8";
# The `-se` option must come after the command.
# The `-optfile` option suppresses a `dsm.opt`-not-found warning.
@@ -80,9 +80,10 @@ in
let
args = lib.map lib.escapeShellArg (
[
"-l"
"--verbose"
"--user"
cfg.username
"-i"
"--identity-file"
cfg.identityFilePath
cfg.host
cfg.remoteFilesystem
@@ -205,9 +205,14 @@ in
};
extraConfig = mkOption {
description = "Kubernetes kubelet extra configuration file entries.";
description = ''
Kubernetes kubelet extra configuration file entries.
See also [Set Kubelet Parameters Via A Configuration File](https://kubernetes.io/docs/tasks/administer-cluster/kubelet-config-file/)
and [Kubelet Configuration](https://kubernetes.io/docs/reference/config-api/kubelet-config.v1beta1/).
'';
default = { };
type = attrsOf attrs;
type = attrsOf ((pkgs.formats.json { }).type);
};
featureGates = mkOption {
@@ -515,12 +515,12 @@ in
''
set -eou pipefail
compression=$(sed -nr 's/compress_build_logs_compression = ()/\1/p' ${baseDir}/hydra.conf)
if [[ $compression == "" ]]; then
compression="bzip2"
if [[ $compression == "" || $compression == bzip2 ]]; then
compressionCmd=(bzip2)
elif [[ $compression == zstd ]]; then
compression="zstd --rm"
compressionCmd=(zstd --rm)
fi
find ${baseDir}/build-logs -type f -name "*.drv" -mtime +3 -size +0c -print0 | xargs -0 -r "$compression" --force --quiet
find ${baseDir}/build-logs -type f -name "*.drv" -mtime +3 -size +0c -print0 | xargs -0 -r "''${compressionCmd[@]}" --force --quiet
'';
startAt = "Sun 01:45";
serviceConfig.Slice = "system-hydra.slice";
@@ -18,7 +18,7 @@ To enable FoundationDB, add the following to your
```nix
{
services.foundationdb.enable = true;
services.foundationdb.package = pkgs.foundationdb71; # FoundationDB 7.1.x
services.foundationdb.package = pkgs.foundationdb73; # FoundationDB 7.r3.x
}
```
@@ -68,7 +68,7 @@ necessary Python modules).
```ShellSession
a@link> cat fdb-status.py
#! /usr/bin/env nix-shell
#! nix-shell -i python -p python pythonPackages.foundationdb71
#! nix-shell -i python -p python pythonPackages.foundationdb73
import fdb
import json
+53 -29
View File
@@ -2,6 +2,7 @@
config,
lib,
pkgs,
utils,
...
}:
@@ -15,6 +16,7 @@ let
options = {
name = lib.mkOption {
type = lib.types.str;
default = name;
example = "laptop-internal";
description = "Keyboard name.";
};
@@ -35,16 +37,16 @@ let
Since KMonad runs as an unprivileged user, it may sometimes
need extra permissions in order to read the keyboard device
file. If your keyboard's device file isn't in the input
group you'll need to list its group in this option.
group, you'll need to list its group in this option.
'';
};
defcfg = {
enable = lib.mkEnableOption ''
Automatically generate the defcfg block.
automatic generation of the defcfg block.
When this is option is set to true the config option for
this keyboard should not include a defcfg block.
When this option is set to true, the config option for
this keyboard should not include a defcfg block
'';
compose = {
@@ -55,15 +57,15 @@ let
};
delay = lib.mkOption {
type = lib.types.int;
type = lib.types.ints.unsigned;
default = 5;
description = "The delay (in milliseconds) between compose key sequences.";
};
};
fallthrough = lib.mkEnableOption "Re-emit unhandled key events.";
fallthrough = lib.mkEnableOption "re-emitting unhandled key events";
allowCommands = lib.mkEnableOption "Allow keys to run shell commands.";
allowCommands = lib.mkEnableOption "keys to run shell commands";
};
config = lib.mkOption {
@@ -71,12 +73,10 @@ let
description = "Keyboard configuration.";
};
};
config = {
name = lib.mkDefault name;
};
};
mkName = name: "kmonad-" + name;
# Create a complete KMonad configuration file:
mkCfg =
keyboard:
@@ -84,7 +84,7 @@ let
defcfg = ''
(defcfg
input (device-file "${keyboard.device}")
output (uinput-sink "kmonad-${keyboard.name}")
output (uinput-sink "${mkName keyboard.name}")
${lib.optionalString (keyboard.defcfg.compose.key != null) ''
cmp-seq ${keyboard.defcfg.compose.key}
cmp-seq-delay ${toString keyboard.defcfg.compose.delay}
@@ -95,9 +95,9 @@ let
'';
in
pkgs.writeTextFile {
name = "kmonad-${keyboard.name}.cfg";
name = "${mkName keyboard.name}.kbd";
text = lib.optionalString keyboard.defcfg.enable (defcfg + "\n") + keyboard.config;
checkPhase = "${cfg.package}/bin/kmonad -d $out";
checkPhase = "${lib.getExe cfg.package} -d $out";
};
# Build a systemd path config that starts the service below when a
@@ -105,7 +105,7 @@ let
mkPath =
keyboard:
let
name = "kmonad-${keyboard.name}";
name = mkName keyboard.name;
in
lib.nameValuePair name {
description = "KMonad trigger for ${keyboard.device}";
@@ -119,19 +119,8 @@ let
# Build a systemd service that starts KMonad:
mkService =
keyboard:
let
cmd =
[
(lib.getExe cfg.package)
"--input"
''device-file "${keyboard.device}"''
]
++ cfg.extraArgs
++ [ "${mkCfg keyboard}" ];
in
lib.nameValuePair "kmonad-${keyboard.name}" {
lib.nameValuePair (mkName keyboard.name) {
description = "KMonad for ${keyboard.device}";
script = lib.escapeShellArgs cmd;
unitConfig = {
# Control rate limiting.
# Stop the restart logic if we restart more than
@@ -140,6 +129,10 @@ let
StartLimitBurst = 5;
};
serviceConfig = {
ExecStart = ''
${lib.getExe cfg.package} ${mkCfg keyboard} \
${utils.escapeSystemdExecArgs cfg.extraArgs}
'';
Restart = "always";
# Restart at increasing intervals from 2s to 1m
RestartSec = 2;
@@ -155,13 +148,26 @@ let
config.users.groups.uinput.name
] ++ keyboard.extraGroups;
};
# make sure the new config is used after nixos-rebuild switch
# stopIfChanged controls[0] how a service is "restarted" during
# nixos-rebuild switch. By default, stopIfChanged is true, which stops
# the old service and then starts the new service after config updates.
# Since we use path-based activation[1] here, the service unit will
# immediately[2] be started by the path unit. Probably that start is
# before config updates, whcih causes the service unit to use the old
# config after nixos-rebuild switch. Setting stopIfChanged to false works
# around this issue by restarting the service after config updates.
# [0]: https://nixos.org/manual/nixos/unstable/#sec-switching-systems
# [1]: man 7 daemon
# [2]: man 5 systemd.path
stopIfChanged = false;
};
in
{
options.services.kmonad = {
enable = lib.mkEnableOption "KMonad: An advanced keyboard manager.";
enable = lib.mkEnableOption "KMonad: an advanced keyboard manager";
package = lib.mkPackageOption pkgs "kmonad" { };
package = lib.mkPackageOption pkgs "KMonad" { default = "kmonad"; };
keyboards = lib.mkOption {
type = lib.types.attrsOf (lib.types.submodule keyboard);
@@ -183,9 +189,27 @@ in
config = lib.mkIf cfg.enable {
hardware.uinput.enable = true;
services.udev.extraRules =
let
mkRule = name: ''
ACTION=="add", KERNEL=="event*", SUBSYSTEM=="input", ATTRS{name}=="${name}", ATTRS{id/product}=="5679", ATTRS{id/vendor}=="1235", SYMLINK+="input/by-id/${name}"
'';
in
lib.foldlAttrs (
rules: _: keyboard:
rules + "\n" + mkRule (mkName keyboard.name)
) "" cfg.keyboards;
systemd = {
paths = lib.mapAttrs' (_: mkPath) cfg.keyboards;
services = lib.mapAttrs' (_: mkService) cfg.keyboards;
};
};
meta = {
maintainers = with lib.maintainers; [
linj
rvdp
];
};
}
+2 -1
View File
@@ -705,7 +705,7 @@ in
withJemalloc = mkOption {
type = types.bool;
default = false;
default = true;
description = ''
Whether to preload jemalloc to reduce memory fragmentation and overall usage.
'';
@@ -1462,6 +1462,7 @@ in
baseServiceConfig = {
environment = optionalAttrs (cfg.withJemalloc) {
LD_PRELOAD = "${pkgs.jemalloc}/lib/libjemalloc.so";
PYTHONMALLOC = "malloc";
};
serviceConfig = {
Type = "notify";
+1 -1
View File
@@ -49,7 +49,7 @@ in
config = lib.mkIf cfg.enable {
services.upower.enable = lib.elem "battery" cfg.order;
services.upower.enable = lib.mkIf (lib.elem "battery" cfg.order) true;
systemd.user.services.dwm-status = {
description = "Highly performant and configurable DWM status service";
+10 -3
View File
@@ -20,6 +20,12 @@ in
default = 5055;
description = ''The port which the Jellyseerr web UI should listen to.'';
};
configDir = lib.mkOption {
type = lib.types.path;
default = "/var/lib/jellyseerr/config";
description = "Config data directory";
};
};
config = lib.mkIf cfg.enable {
@@ -27,14 +33,15 @@ in
description = "Jellyseerr, a requests manager for Jellyfin";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
environment.PORT = toString cfg.port;
environment = {
PORT = toString cfg.port;
CONFIG_DIRECTORY = cfg.configDir;
};
serviceConfig = {
Type = "exec";
StateDirectory = "jellyseerr";
WorkingDirectory = "${cfg.package}/libexec/jellyseerr/deps/jellyseerr";
DynamicUser = true;
ExecStart = lib.getExe cfg.package;
BindPaths = [ "/var/lib/jellyseerr/:${cfg.package}/libexec/jellyseerr/deps/jellyseerr/config/" ];
Restart = "on-failure";
ProtectHome = true;
ProtectSystem = "strict";
+6 -3
View File
@@ -24,9 +24,12 @@ in
description = "Whether to enable the PyKMS service.";
};
package = lib.mkPackageOption pkgs "pykms" { };
listenAddress = lib.mkOption {
type = lib.types.str;
default = "0.0.0.0";
example = "::";
description = "The IP address on which to listen.";
};
@@ -78,13 +81,13 @@ in
wantedBy = [ "multi-user.target" ];
# python programs with DynamicUser = true require HOME to be set
environment.HOME = libDir;
serviceConfig = with pkgs; {
serviceConfig = {
DynamicUser = true;
StateDirectory = baseNameOf libDir;
ExecStartPre = "${lib.getBin pykms}/libexec/create_pykms_db.sh ${libDir}/clients.db";
ExecStartPre = "${lib.getBin cfg.package}/libexec/create_pykms_db.sh ${libDir}/clients.db";
ExecStart = lib.concatStringsSep " " (
[
"${lib.getBin pykms}/bin/server"
"${lib.getBin cfg.package}/bin/server"
"--logfile=STDOUT"
"--loglevel=${cfg.logLevel}"
"--sqlite=${libDir}/clients.db"
@@ -31,7 +31,7 @@ let
'';
in
{
meta.maintainers = with lib.maintainers; [ ];
meta.maintainers = with lib.maintainers; [ jvanbruegge ];
options.services.tandoor-recipes = {
enable = lib.mkOption {
@@ -498,16 +498,16 @@ in
ca.cert = if needToCreateCA then "${cfg.dataDir}/keys/ca.cert" else "${cfg.pki.manual.ca.cert}";
};
systemd.tmpfiles.rules = [
"d ${cfg.dataDir} 0770 ${cfg.user} ${cfg.group}"
"z ${cfg.dataDir} 0770 ${cfg.user} ${cfg.group}"
];
systemd.services.taskserver-init = {
wantedBy = [ "taskserver.service" ];
before = [ "taskserver.service" ];
description = "Initialize Taskserver Data Directory";
preStart = ''
mkdir -m 0770 -p "${cfg.dataDir}"
chown "${cfg.user}:${cfg.group}" "${cfg.dataDir}"
'';
script = ''
${taskd} init
touch "${cfg.dataDir}/.is_initialized"
@@ -36,8 +36,6 @@ let
${lib.optionalString (cfg.cert != null) "cert=${cfg.cert}"}
${lib.optionalString (cfg.pkey != null) "pkey=${cfg.pkey}"}
${lib.optionalString (cfg.dh-file != null) "dh-file=${cfg.dh-file}"}
no-stdout-log
syslog
pidfile=${pidfile}
${lib.optionalString cfg.secure-stun "secure-stun"}
${lib.optionalString cfg.no-cli "no-cli"}
@@ -153,6 +153,8 @@ in
'';
};
package = lib.mkPackageOption pkgs "keepalived" { };
openFirewall = mkOption {
type = types.bool;
default = false;
@@ -334,7 +336,7 @@ in
umask 077
${pkgs.envsubst}/bin/envsubst -i "${keepalivedConf}" > ${finalConfigFile}
'');
ExecStart = "${pkgs.keepalived}/sbin/keepalived"
ExecStart = "${lib.getExe cfg.package}"
+ " -f ${finalConfigFile}"
+ " -p ${pidFile}"
+ optionalString cfg.snmp.enable " --snmp";
+326
View File
@@ -0,0 +1,326 @@
{
config,
pkgs,
lib,
...
}:
let
cfg = config.services.ncps;
logLevels = [
"trace"
"debug"
"info"
"warn"
"error"
"fatal"
"panic"
];
globalFlags = lib.concatStringsSep " " (
[ "--log-level='${cfg.logLevel}'" ]
++ (lib.optionals cfg.openTelemetry.enable (
[
"--otel-enabled"
]
++ (lib.optional (
cfg.openTelemetry.grpcURL != null
) "--otel-grpc-url='${cfg.openTelemetry.grpcURL}'")
))
);
serveFlags = lib.concatStringsSep " " (
[
"--cache-hostname='${cfg.cache.hostName}'"
"--cache-data-path='${cfg.cache.dataPath}'"
"--cache-database-url='${cfg.cache.databaseURL}'"
"--server-addr='${cfg.server.addr}'"
]
++ (lib.optional cfg.cache.allowDeleteVerb "--cache-allow-delete-verb")
++ (lib.optional cfg.cache.allowPutVerb "--cache-allow-put-verb")
++ (lib.optional (cfg.cache.maxSize != null) "--cache-max-size='${cfg.cache.maxSize}'")
++ (lib.optionals (cfg.cache.lru.schedule != null) [
"--cache-lru-schedule='${cfg.cache.lru.schedule}'"
"--cache-lru-schedule-timezone='${cfg.cache.lru.scheduleTimeZone}'"
])
++ (lib.optional (cfg.cache.secretKeyPath != null) "--cache-secret-key-path='%d/secretKey'")
++ (lib.forEach cfg.upstream.caches (url: "--upstream-cache='${url}'"))
++ (lib.forEach cfg.upstream.publicKeys (pk: "--upstream-public-key='${pk}'"))
);
isSqlite = lib.strings.hasPrefix "sqlite:" cfg.cache.databaseURL;
dbPath = lib.removePrefix "sqlite:" cfg.cache.databaseURL;
dbDir = dirOf dbPath;
in
{
options = {
services.ncps = {
enable = lib.mkEnableOption "ncps: Nix binary cache proxy service implemented in Go";
package = lib.mkPackageOption pkgs "ncps" { };
dbmatePackage = lib.mkPackageOption pkgs "dbmate" { };
openTelemetry = {
enable = lib.mkEnableOption "Enable OpenTelemetry logs, metrics, and tracing";
grpcURL = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
description = ''
Configure OpenTelemetry gRPC URL. Missing or "https" scheme enables
secure gRPC, "insecure" otherwise. Omit to emit telemetry to
stdout.
'';
};
};
logLevel = lib.mkOption {
type = lib.types.enum logLevels;
default = "info";
description = ''
Set the level for logging. Refer to
<https://pkg.go.dev/github.com/rs/zerolog#readme-leveled-logging> for
more information.
'';
};
cache = {
allowDeleteVerb = lib.mkEnableOption ''
Whether to allow the DELETE verb to delete narinfo and nar files from
the cache.
'';
allowPutVerb = lib.mkEnableOption ''
Whether to allow the PUT verb to push narinfo and nar files directly
to the cache.
'';
hostName = lib.mkOption {
type = lib.types.str;
description = ''
The hostname of the cache server. **This is used to generate the
private key used for signing store paths (.narinfo)**
'';
};
dataPath = lib.mkOption {
type = lib.types.str;
default = "/var/lib/ncps";
description = ''
The local directory for storing configuration and cached store paths
'';
};
databaseURL = lib.mkOption {
type = lib.types.str;
default = "sqlite:${cfg.cache.dataPath}/db/db.sqlite";
defaultText = "sqlite:/var/lib/ncps/db/db.sqlite";
description = ''
The URL of the database (currently only SQLite is supported)
'';
};
lru = {
schedule = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
example = "0 2 * * *";
description = ''
The cron spec for cleaning the store to keep it under
config.ncps.cache.maxSize. Refer to
https://pkg.go.dev/github.com/robfig/cron/v3#hdr-Usage for
documentation.
'';
};
scheduleTimeZone = lib.mkOption {
type = lib.types.str;
default = "Local";
example = "America/Los_Angeles";
description = ''
The name of the timezone to use for the cron schedule. See
<https://en.wikipedia.org/wiki/List_of_tz_database_time_zones>
for a comprehensive list of possible values for this setting.
'';
};
};
maxSize = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
example = "100G";
description = ''
The maximum size of the store. It can be given with units such as
5K, 10G etc. Supported units: B, K, M, G, T.
'';
};
secretKeyPath = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
description = ''
The path to load the secretKey for signing narinfos. Leave this
empty to automatically generate a private/public key.
'';
};
};
server = {
addr = lib.mkOption {
type = lib.types.str;
default = ":8501";
description = ''
The address and port the server listens on.
'';
};
};
upstream = {
caches = lib.mkOption {
type = lib.types.listOf lib.types.str;
example = [ "https://cache.nixos.org" ];
description = ''
A list of URLs of upstream binary caches.
'';
};
publicKeys = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
example = [ "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" ];
description = ''
A list of public keys of upstream caches in the format
`host[-[0-9]*]:public-key`. This flag is used to verify the
signatures of store paths downloaded from upstream caches.
'';
};
};
};
};
config = lib.mkIf cfg.enable {
assertions = [
{
assertion = cfg.cache.lru.schedule == null || cfg.cache.maxSize != null;
message = "You must specify config.ncps.cache.lru.schedule when config.ncps.cache.maxSize is set";
}
{
assertion = cfg.cache.secretKeyPath == null || (builtins.pathExists cfg.cache.secretKeyPath);
message = "config.ncps.cache.secresecretKeyPath=${cfg.cache.secretKeyPath} must exist but does not";
}
];
users.users.ncps = {
isSystemUser = true;
group = "ncps";
};
users.groups.ncps = { };
systemd.services.ncps-create-datadirs = {
description = "Created required directories by ncps";
serviceConfig = {
Type = "oneshot";
UMask = "0066";
};
script =
(lib.optionalString (cfg.cache.dataPath != "/var/lib/ncps") ''
if ! test -d ${cfg.cache.dataPath}; then
mkdir -p ${cfg.cache.dataPath}
chown ncps:ncps ${cfg.cache.dataPath}
fi
'')
+ (lib.optionalString isSqlite ''
if ! test -d ${dbDir}; then
mkdir -p ${dbDir}
chown ncps:ncps ${dbDir}
fi
'');
wantedBy = [ "ncps.service" ];
before = [ "ncps.service" ];
};
systemd.services.ncps = {
description = "ncps binary cache proxy service";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
preStart = ''
${lib.getExe cfg.dbmatePackage} --migrations-dir=${cfg.package}/share/ncps/db/migrations --url=${cfg.cache.databaseURL} up
'';
serviceConfig = lib.mkMerge [
{
ExecStart = "${lib.getExe cfg.package} ${globalFlags} serve ${serveFlags}";
User = "ncps";
Group = "ncps";
Restart = "on-failure";
RuntimeDirectory = "ncps";
}
# credentials
(lib.mkIf (cfg.cache.secretKeyPath != null) {
LoadCredential = "secretKey:${cfg.cache.secretKeyPath}";
})
# ensure permissions on required directories
(lib.mkIf (cfg.cache.dataPath != "/var/lib/ncps") {
ReadWritePaths = [ cfg.cache.dataPath ];
})
(lib.mkIf (cfg.cache.dataPath == "/var/lib/ncps") {
StateDirectory = "ncps";
StateDirectoryMode = "0700";
})
(lib.mkIf (isSqlite && !lib.strings.hasPrefix "/var/lib/ncps" dbDir) {
ReadWritePaths = [ dbDir ];
})
# Hardening
{
SystemCallFilter = [
"@system-service"
"~@privileged"
"~@resources"
];
CapabilityBoundingSet = "";
PrivateUsers = true;
DevicePolicy = "closed";
DeviceAllow = [ "" ];
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectControlGroups = true;
ProtectKernelLogs = true;
ProtectHostname = true;
ProtectClock = true;
ProtectProc = "invisible";
ProtectSystem = "strict";
ProtectHome = true;
RestrictSUIDSGID = true;
RestrictRealtime = true;
MemoryDenyWriteExecute = true;
ProcSubset = "pid";
RestrictNamespaces = true;
SystemCallArchitectures = "native";
PrivateNetwork = false;
PrivateTmp = true;
PrivateDevices = true;
PrivateMounts = true;
NoNewPrivileges = true;
LockPersonality = true;
RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6";
LimitNOFILE = 65536;
UMask = "0066";
}
];
unitConfig.RequiresMountsFor = lib.concatStringsSep " " (
[ "${cfg.cache.dataPath}" ] ++ lib.optional (isSqlite) dbDir
);
};
};
meta.maintainers = with lib.maintainers; [ kalbasit ];
}
+2 -2
View File
@@ -143,10 +143,10 @@ in
restartTriggers = [ cfg.unifiPackage cfg.mongodbPackage ];
serviceConfig = {
Type = "simple";
Type = "notify";
ExecStart = "${cmd} start";
ExecStop = "${cmd} stop";
Restart = "on-failure";
Restart = "always";
TimeoutSec = "5min";
User = "unifi";
UMask = "0077";
+1 -1
View File
@@ -419,7 +419,7 @@ in
${optionalString (containsGutenprint cfg.drivers) ''
if [ -d /var/lib/cups/ppd ]; then
${getGutenprint cfg.drivers}/bin/cups-genppdupdate -p /var/lib/cups/ppd
${getGutenprint cfg.drivers}/bin/cups-genppdupdate -x -p /var/lib/cups/ppd
fi
''}
'';
+7 -10
View File
@@ -4,9 +4,6 @@
pkgs,
...
}:
with lib;
let
cfg = config.services.manticore;
@@ -14,7 +11,7 @@ let
toSphinx =
{
mkKeyValue ? generators.mkKeyValueDefault { } "=",
mkKeyValue ? lib.generators.mkKeyValueDefault { } "=",
listsAsDuplicateKeys ? true,
}:
attrsOfAttrs:
@@ -22,7 +19,7 @@ let
# map function to string for each key val
mapAttrsToStringsSep =
sep: mapFn: attrs:
concatStringsSep sep (mapAttrsToList mapFn attrs);
lib.concatStringsSep sep (lib.mapAttrsToList mapFn attrs);
mkSection =
sectName: sectValues:
''
@@ -46,9 +43,9 @@ in
options = {
services.manticore = {
enable = mkEnableOption "Manticoresearch";
enable = lib.mkEnableOption "Manticoresearch";
settings = mkOption {
settings = lib.mkOption {
default = {
searchd = {
listen = [
@@ -67,10 +64,10 @@ in
<https://manual.manticoresearch.com/Server%20settings>
for more information.
'';
type = types.submodule {
type = lib.types.submodule {
freeformType = format.type;
};
example = literalExpression ''
example = lib.literalExpression ''
{
searchd = {
listen = [
@@ -90,7 +87,7 @@ in
};
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
systemd = {
packages = [ pkgs.manticoresearch ];
+22 -25
View File
@@ -4,16 +4,13 @@
pkgs,
...
}:
with lib;
let
cfg = config.services.meilisearch;
in
{
meta.maintainers = with maintainers; [
meta.maintainers = with lib.maintainers; [
Br1ght0ne
happysalada
];
@@ -22,37 +19,37 @@ in
###### interface
options.services.meilisearch = {
enable = mkEnableOption "MeiliSearch - a RESTful search API";
enable = lib.mkEnableOption "MeiliSearch - a RESTful search API";
package = mkPackageOption pkgs "meilisearch" {
package = lib.mkPackageOption pkgs "meilisearch" {
extraDescription = ''
Use this if you require specific features to be enabled. The default package has no features.
'';
};
listenAddress = mkOption {
listenAddress = lib.mkOption {
description = "MeiliSearch listen address.";
default = "127.0.0.1";
type = types.str;
type = lib.types.str;
};
listenPort = mkOption {
listenPort = lib.mkOption {
description = "MeiliSearch port to listen on.";
default = 7700;
type = types.port;
type = lib.types.port;
};
environment = mkOption {
environment = lib.mkOption {
description = "Defines the running environment of MeiliSearch.";
default = "development";
type = types.enum [
type = lib.types.enum [
"development"
"production"
];
};
# TODO change this to LoadCredentials once possible
masterKeyEnvironmentFile = mkOption {
masterKeyEnvironmentFile = lib.mkOption {
description = ''
Path to file which contains the master key.
By doing so, all routes will be protected and will require a key to be accessed.
@@ -61,10 +58,10 @@ in
MEILI_MASTER_KEY=my_secret_key
'';
default = null;
type = with types; nullOr path;
type = with lib.types; nullOr path;
};
noAnalytics = mkOption {
noAnalytics = lib.mkOption {
description = ''
Deactivates analytics.
Analytics allow MeiliSearch to know how many users are using MeiliSearch,
@@ -72,10 +69,10 @@ in
This process is entirely anonymous.
'';
default = true;
type = types.bool;
type = lib.types.bool;
};
logLevel = mkOption {
logLevel = lib.mkOption {
description = ''
Defines how much detail should be present in MeiliSearch's logs.
MeiliSearch currently supports four log levels, listed in order of increasing verbosity:
@@ -86,10 +83,10 @@ in
Useful when diagnosing issues and debugging
'';
default = "INFO";
type = types.str;
type = lib.types.str;
};
maxIndexSize = mkOption {
maxIndexSize = lib.mkOption {
description = ''
Sets the maximum size of the index.
Value must be given in bytes or explicitly stating a base unit.
@@ -97,10 +94,10 @@ in
Default is 100 GiB
'';
default = "107374182400";
type = types.str;
type = lib.types.str;
};
payloadSizeLimit = mkOption {
payloadSizeLimit = lib.mkOption {
description = ''
Sets the maximum size of accepted JSON payloads.
Value must be given in bytes or explicitly stating a base unit.
@@ -108,14 +105,14 @@ in
Default is ~ 100 MB
'';
default = "104857600";
type = types.str;
type = lib.types.str;
};
};
###### implementation
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
# used to restore dumps
environment.systemPackages = [ cfg.package ];
@@ -127,7 +124,7 @@ in
environment = {
MEILI_DB_PATH = "/var/lib/meilisearch";
MEILI_HTTP_ADDR = "${cfg.listenAddress}:${toString cfg.listenPort}";
MEILI_NO_ANALYTICS = boolToString cfg.noAnalytics;
MEILI_NO_ANALYTICS = lib.boolToString cfg.noAnalytics;
MEILI_ENV = cfg.environment;
MEILI_DUMP_DIR = "/var/lib/meilisearch/dumps";
MEILI_LOG_LEVEL = cfg.logLevel;
@@ -137,7 +134,7 @@ in
ExecStart = "${cfg.package}/bin/meilisearch";
DynamicUser = true;
StateDirectory = "meilisearch";
EnvironmentFile = mkIf (cfg.masterKeyEnvironmentFile != null) cfg.masterKeyEnvironmentFile;
EnvironmentFile = lib.mkIf (cfg.masterKeyEnvironmentFile != null) cfg.masterKeyEnvironmentFile;
};
};
};
+6 -9
View File
@@ -4,9 +4,6 @@
pkgs,
...
}:
with lib;
let
cfg = config.services.opensearch;
@@ -28,7 +25,7 @@ in
{
options.services.opensearch = {
enable = mkEnableOption "OpenSearch";
enable = lib.mkEnableOption "OpenSearch";
package = lib.mkPackageOption pkgs "OpenSearch" {
default = [ "opensearch" ];
@@ -113,13 +110,13 @@ in
rootLogger.level = info
rootLogger.appenderRef.console.ref = console
'';
type = types.str;
type = lib.types.str;
};
dataDir = lib.mkOption {
type = lib.types.path;
default = "/var/lib/opensearch";
apply = converge (removeSuffix "/");
apply = lib.converge (lib.removeSuffix "/");
description = ''
Data directory for OpenSearch. If you change this, you need to
manually create the directory. You also need to create the
@@ -173,7 +170,7 @@ in
};
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
systemd.services.opensearch = {
description = "OpenSearch Daemon";
wantedBy = [ "multi-user.target" ];
@@ -194,7 +191,7 @@ in
set -o errexit -o pipefail -o nounset -o errtrace
shopt -s inherit_errexit
''
+ (optionalString (!config.boot.isContainer) ''
+ (lib.optionalString (!config.boot.isContainer) ''
# Only set vm.max_map_count if lower than ES required minimum
# This avoids conflict if configured via boot.kernel.sysctl
if [ $(${pkgs.procps}/bin/sysctl -n vm.max_map_count) -lt 262144 ]; then
@@ -268,7 +265,7 @@ in
TimeoutStartSec = "infinity";
DynamicUser = usingDefaultUserAndGroup && usingDefaultDataDir;
}
// (optionalAttrs (usingDefaultDataDir) {
// (lib.optionalAttrs (usingDefaultDataDir) {
StateDirectory = "opensearch";
StateDirectoryMode = "0700";
});
+34 -36
View File
@@ -4,8 +4,6 @@
pkgs,
...
}:
with lib;
let
cfg = config.services.qdrant;
@@ -17,9 +15,9 @@ in
options = {
services.qdrant = {
enable = mkEnableOption "Vector Search Engine for the next generation of AI applications";
enable = lib.mkEnableOption "Vector Search Engine for the next generation of AI applications";
settings = mkOption {
settings = lib.mkOption {
description = ''
Configuration for Qdrant
Refer to <https://github.com/qdrant/qdrant/blob/master/config/config.yaml> for details on supported values.
@@ -43,7 +41,7 @@ in
telemetry_disabled = true;
};
defaultText = literalExpression ''
defaultText = lib.literalExpression ''
{
storage = {
storage_path = "/var/lib/qdrant/storage";
@@ -64,41 +62,41 @@ in
};
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
services.qdrant.settings = {
service.static_content_dir = mkDefault pkgs.qdrant-web-ui;
storage.storage_path = mkDefault "/var/lib/qdrant/storage";
storage.snapshots_path = mkDefault "/var/lib/qdrant/snapshots";
service.static_content_dir = lib.mkDefault pkgs.qdrant-web-ui;
storage.storage_path = lib.mkDefault "/var/lib/qdrant/storage";
storage.snapshots_path = lib.mkDefault "/var/lib/qdrant/snapshots";
# The following default values are the same as in the default config,
# they are just written here for convenience.
storage.on_disk_payload = mkDefault true;
storage.wal.wal_capacity_mb = mkDefault 32;
storage.wal.wal_segments_ahead = mkDefault 0;
storage.performance.max_search_threads = mkDefault 0;
storage.performance.max_optimization_threads = mkDefault 1;
storage.optimizers.deleted_threshold = mkDefault 0.2;
storage.optimizers.vacuum_min_vector_number = mkDefault 1000;
storage.optimizers.default_segment_number = mkDefault 0;
storage.optimizers.max_segment_size_kb = mkDefault null;
storage.optimizers.memmap_threshold_kb = mkDefault null;
storage.optimizers.indexing_threshold_kb = mkDefault 20000;
storage.optimizers.flush_interval_sec = mkDefault 5;
storage.optimizers.max_optimization_threads = mkDefault 1;
storage.hnsw_index.m = mkDefault 16;
storage.hnsw_index.ef_construct = mkDefault 100;
storage.hnsw_index.full_scan_threshold_kb = mkDefault 10000;
storage.hnsw_index.max_indexing_threads = mkDefault 0;
storage.hnsw_index.on_disk = mkDefault false;
storage.hnsw_index.payload_m = mkDefault null;
service.max_request_size_mb = mkDefault 32;
service.max_workers = mkDefault 0;
service.http_port = mkDefault 6333;
service.grpc_port = mkDefault 6334;
service.enable_cors = mkDefault true;
cluster.enabled = mkDefault false;
storage.on_disk_payload = lib.mkDefault true;
storage.wal.wal_capacity_mb = lib.mkDefault 32;
storage.wal.wal_segments_ahead = lib.mkDefault 0;
storage.performance.max_search_threads = lib.mkDefault 0;
storage.performance.max_optimization_threads = lib.mkDefault 1;
storage.optimizers.deleted_threshold = lib.mkDefault 0.2;
storage.optimizers.vacuum_min_vector_number = lib.mkDefault 1000;
storage.optimizers.default_segment_number = lib.mkDefault 0;
storage.optimizers.max_segment_size_kb = lib.mkDefault null;
storage.optimizers.memmap_threshold_kb = lib.mkDefault null;
storage.optimizers.indexing_threshold_kb = lib.mkDefault 20000;
storage.optimizers.flush_interval_sec = lib.mkDefault 5;
storage.optimizers.max_optimization_threads = lib.mkDefault 1;
storage.hnsw_index.m = lib.mkDefault 16;
storage.hnsw_index.ef_construct = lib.mkDefault 100;
storage.hnsw_index.full_scan_threshold_kb = lib.mkDefault 10000;
storage.hnsw_index.max_indexing_threads = lib.mkDefault 0;
storage.hnsw_index.on_disk = lib.mkDefault false;
storage.hnsw_index.payload_m = lib.mkDefault null;
service.max_request_size_mb = lib.mkDefault 32;
service.max_workers = lib.mkDefault 0;
service.http_port = lib.mkDefault 6333;
service.grpc_port = lib.mkDefault 6334;
service.enable_cors = lib.mkDefault true;
cluster.enabled = lib.mkDefault false;
# the following have been altered for security
service.host = mkDefault "127.0.0.1";
telemetry_disabled = mkDefault true;
service.host = lib.mkDefault "127.0.0.1";
telemetry_disabled = lib.mkDefault true;
};
systemd.services.qdrant = {
+5 -8
View File
@@ -4,9 +4,6 @@
pkgs,
...
}:
with lib;
let
cfg = config.services.quickwit;
@@ -19,7 +16,7 @@ in
{
options.services.quickwit = {
enable = mkEnableOption "Quickwit";
enable = lib.mkEnableOption "Quickwit";
package = lib.mkPackageOption pkgs "Quickwit" {
default = [ "quickwit" ];
@@ -83,7 +80,7 @@ in
dataDir = lib.mkOption {
type = lib.types.path;
default = "/var/lib/quickwit";
apply = converge (removeSuffix "/");
apply = lib.converge (lib.removeSuffix "/");
description = ''
Data directory for Quickwit. If you change this, you need to
manually create the directory. You also need to create the
@@ -130,7 +127,7 @@ in
};
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
systemd.services.quickwit = {
description = "Quickwit";
wantedBy = [ "multi-user.target" ];
@@ -143,7 +140,7 @@ in
{
ExecStart = ''
${cfg.package}/bin/quickwit run --config ${quickwitYml} \
${escapeShellArgs cfg.extraFlags}
${lib.escapeShellArgs cfg.extraFlags}
'';
User = cfg.user;
Group = cfg.group;
@@ -186,7 +183,7 @@ in
"@chown"
];
}
// (optionalAttrs (usingDefaultDataDir) {
// (lib.optionalAttrs (usingDefaultDataDir) {
StateDirectory = "quickwit";
StateDirectoryMode = "0700";
});
+35 -38
View File
@@ -4,15 +4,12 @@
pkgs,
...
}:
with lib;
let
cfg = config.services.certmgr;
specs = mapAttrsToList (n: v: rec {
specs = lib.mapAttrsToList (n: v: rec {
name = n + ".json";
path = if isAttrs v then pkgs.writeText name (builtins.toJSON v) else v;
path = if lib.isAttrs v then pkgs.writeText name (builtins.toJSON v) else v;
}) cfg.specs;
allSpecs = pkgs.linkFarm "certmgr.d" specs;
@@ -29,59 +26,59 @@ let
);
specPaths = map dirOf (
concatMap (
lib.concatMap (
spec:
if isAttrs spec then
collect isString (filterAttrsRecursive (n: v: isAttrs v || n == "path") spec)
if lib.isAttrs spec then
lib.collect lib.isString (lib.filterAttrsRecursive (n: v: lib.isAttrs v || n == "path") spec)
else
[ spec ]
) (attrValues cfg.specs)
) (lib.attrValues cfg.specs)
);
preStart = ''
${concatStringsSep " \\\n" ([ "mkdir -p" ] ++ map escapeShellArg specPaths)}
${lib.concatStringsSep " \\\n" ([ "mkdir -p" ] ++ map lib.escapeShellArg specPaths)}
${cfg.package}/bin/certmgr -f ${certmgrYaml} check
'';
in
{
options.services.certmgr = {
enable = mkEnableOption "certmgr";
enable = lib.mkEnableOption "certmgr";
package = mkPackageOption pkgs "certmgr" { };
package = lib.mkPackageOption pkgs "certmgr" { };
defaultRemote = mkOption {
type = types.str;
defaultRemote = lib.mkOption {
type = lib.types.str;
default = "127.0.0.1:8888";
description = "The default CA host:port to use.";
};
validMin = mkOption {
validMin = lib.mkOption {
default = "72h";
type = types.str;
type = lib.types.str;
description = "The interval before a certificate expires to start attempting to renew it.";
};
renewInterval = mkOption {
renewInterval = lib.mkOption {
default = "30m";
type = types.str;
type = lib.types.str;
description = "How often to check certificate expirations and how often to update the cert_next_expires metric.";
};
metricsAddress = mkOption {
metricsAddress = lib.mkOption {
default = "127.0.0.1";
type = types.str;
type = lib.types.str;
description = "The address for the Prometheus HTTP endpoint.";
};
metricsPort = mkOption {
metricsPort = lib.mkOption {
default = 9488;
type = types.ints.u16;
type = lib.types.ints.u16;
description = "The port for the Prometheus HTTP endpoint.";
};
specs = mkOption {
specs = lib.mkOption {
default = { };
example = literalExpression ''
example = lib.literalExpression ''
{
exampleCert =
let
@@ -119,21 +116,21 @@ in
}
'';
type =
with types;
with lib.types;
attrsOf (
either path (submodule {
options = {
service = mkOption {
service = lib.mkOption {
type = nullOr str;
default = null;
description = "The service on which to perform \<action\> after fetching.";
};
action = mkOption {
action = lib.mkOption {
type = addCheck str (
x:
cfg.svcManager == "command"
|| elem x [
|| lib.elem x [
"restart"
"reload"
"nop"
@@ -144,22 +141,22 @@ in
};
# These ought all to be specified according to certmgr spec def.
authority = mkOption {
authority = lib.mkOption {
type = attrs;
description = "certmgr spec authority object.";
};
certificate = mkOption {
certificate = lib.mkOption {
type = nullOr attrs;
description = "certmgr spec certificate object.";
};
private_key = mkOption {
private_key = lib.mkOption {
type = nullOr attrs;
description = "certmgr spec private_key object.";
};
request = mkOption {
request = lib.mkOption {
type = nullOr attrs;
description = "certmgr spec request object.";
};
@@ -173,9 +170,9 @@ in
'';
};
svcManager = mkOption {
svcManager = lib.mkOption {
default = "systemd";
type = types.enum [
type = lib.types.enum [
"circus"
"command"
"dummy"
@@ -193,7 +190,7 @@ in
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
assertions = [
{
assertion = cfg.specs != { };
@@ -201,10 +198,10 @@ in
}
{
assertion =
!any (hasAttrByPath [
!lib.any (lib.hasAttrByPath [
"authority"
"auth_key"
]) (attrValues cfg.specs);
]) (lib.attrValues cfg.specs);
message = ''
Inline services.certmgr.specs are added to the Nix store rendering them world readable.
Specify paths as specs, if you want to use include auth_key - or use the auth_key_file option."
@@ -214,7 +211,7 @@ in
systemd.services.certmgr = {
description = "certmgr";
path = mkIf (cfg.svcManager == "command") [ pkgs.bash ];
path = lib.mkIf (cfg.svcManager == "command") [ pkgs.bash ];
wants = [ "network-online.target" ];
after = [ "network-online.target" ];
wantedBy = [ "multi-user.target" ];
+52 -55
View File
@@ -5,19 +5,16 @@
pkgs,
...
}:
with lib;
let
cfg = config.services.cfssl;
in
{
options.services.cfssl = {
enable = mkEnableOption "the CFSSL CA api-server";
enable = lib.mkEnableOption "the CFSSL CA api-server";
dataDir = mkOption {
dataDir = lib.mkOption {
default = "/var/lib/cfssl";
type = types.path;
type = lib.types.path;
description = ''
The work directory for CFSSL.
@@ -30,51 +27,51 @@ in
'';
};
address = mkOption {
address = lib.mkOption {
default = "127.0.0.1";
type = types.str;
type = lib.types.str;
description = "Address to bind.";
};
port = mkOption {
port = lib.mkOption {
default = 8888;
type = types.port;
type = lib.types.port;
description = "Port to bind.";
};
ca = mkOption {
defaultText = literalExpression ''"''${cfg.dataDir}/ca.pem"'';
type = types.str;
ca = lib.mkOption {
defaultText = lib.literalExpression ''"''${cfg.dataDir}/ca.pem"'';
type = lib.types.str;
description = "CA used to sign the new certificate -- accepts '[file:]fname' or 'env:varname'.";
};
caKey = mkOption {
defaultText = literalExpression ''"file:''${cfg.dataDir}/ca-key.pem"'';
type = types.str;
caKey = lib.mkOption {
defaultText = lib.literalExpression ''"file:''${cfg.dataDir}/ca-key.pem"'';
type = lib.types.str;
description = "CA private key -- accepts '[file:]fname' or 'env:varname'.";
};
caBundle = mkOption {
caBundle = lib.mkOption {
default = null;
type = types.nullOr types.path;
type = lib.types.nullOr lib.types.path;
description = "Path to root certificate store.";
};
intBundle = mkOption {
intBundle = lib.mkOption {
default = null;
type = types.nullOr types.path;
type = lib.types.nullOr lib.types.path;
description = "Path to intermediate certificate store.";
};
intDir = mkOption {
intDir = lib.mkOption {
default = null;
type = types.nullOr types.path;
type = lib.types.nullOr lib.types.path;
description = "Intermediates directory.";
};
metadata = mkOption {
metadata = lib.mkOption {
default = null;
type = types.nullOr types.path;
type = lib.types.nullOr lib.types.path;
description = ''
Metadata file for root certificate presence.
The content of the file is a json dictionary (k,v): each key k is
@@ -83,81 +80,81 @@ in
'';
};
remote = mkOption {
remote = lib.mkOption {
default = null;
type = types.nullOr types.str;
type = lib.types.nullOr lib.types.str;
description = "Remote CFSSL server.";
};
configFile = mkOption {
configFile = lib.mkOption {
default = null;
type = types.nullOr types.str;
type = lib.types.nullOr lib.types.str;
description = "Path to configuration file. Do not put this in nix-store as it might contain secrets.";
};
responder = mkOption {
responder = lib.mkOption {
default = null;
type = types.nullOr types.path;
type = lib.types.nullOr lib.types.path;
description = "Certificate for OCSP responder.";
};
responderKey = mkOption {
responderKey = lib.mkOption {
default = null;
type = types.nullOr types.str;
type = lib.types.nullOr lib.types.str;
description = "Private key for OCSP responder certificate. Do not put this in nix-store.";
};
tlsKey = mkOption {
tlsKey = lib.mkOption {
default = null;
type = types.nullOr types.str;
type = lib.types.nullOr lib.types.str;
description = "Other endpoint's CA private key. Do not put this in nix-store.";
};
tlsCert = mkOption {
tlsCert = lib.mkOption {
default = null;
type = types.nullOr types.path;
type = lib.types.nullOr lib.types.path;
description = "Other endpoint's CA to set up TLS protocol.";
};
mutualTlsCa = mkOption {
mutualTlsCa = lib.mkOption {
default = null;
type = types.nullOr types.path;
type = lib.types.nullOr lib.types.path;
description = "Mutual TLS - require clients be signed by this CA.";
};
mutualTlsCn = mkOption {
mutualTlsCn = lib.mkOption {
default = null;
type = types.nullOr types.str;
type = lib.types.nullOr lib.types.str;
description = "Mutual TLS - regex for whitelist of allowed client CNs.";
};
tlsRemoteCa = mkOption {
tlsRemoteCa = lib.mkOption {
default = null;
type = types.nullOr types.path;
type = lib.types.nullOr lib.types.path;
description = "CAs to trust for remote TLS requests.";
};
mutualTlsClientCert = mkOption {
mutualTlsClientCert = lib.mkOption {
default = null;
type = types.nullOr types.path;
type = lib.types.nullOr lib.types.path;
description = "Mutual TLS - client certificate to call remote instance requiring client certs.";
};
mutualTlsClientKey = mkOption {
mutualTlsClientKey = lib.mkOption {
default = null;
type = types.nullOr types.path;
type = lib.types.nullOr lib.types.path;
description = "Mutual TLS - client key to call remote instance requiring client certs. Do not put this in nix-store.";
};
dbConfig = mkOption {
dbConfig = lib.mkOption {
default = null;
type = types.nullOr types.path;
type = lib.types.nullOr lib.types.path;
description = "Certificate db configuration file. Path must be writeable.";
};
logLevel = mkOption {
logLevel = lib.mkOption {
default = 1;
type = types.enum [
type = lib.types.enum [
0
1
2
@@ -169,7 +166,7 @@ in
};
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
users.groups.cfssl = {
gid = config.ids.gids.cfssl;
};
@@ -196,7 +193,7 @@ in
ExecStart =
with cfg;
let
opt = n: v: optionalString (v != null) ''-${n}="${v}"'';
opt = n: v: lib.optionalString (v != null) ''-${n}="${v}"'';
in
lib.concatStringsSep " \\\n" [
"${pkgs.cfssl}/bin/cfssl serve"
@@ -223,7 +220,7 @@ in
(opt "loglevel" (toString logLevel))
];
}
(mkIf (cfg.dataDir == options.services.cfssl.dataDir.default) {
(lib.mkIf (cfg.dataDir == options.services.cfssl.dataDir.default) {
StateDirectory = baseNameOf cfg.dataDir;
StateDirectoryMode = 700;
})
@@ -231,8 +228,8 @@ in
};
services.cfssl = {
ca = mkDefault "${cfg.dataDir}/ca.pem";
caKey = mkDefault "${cfg.dataDir}/ca-key.pem";
ca = lib.mkDefault "${cfg.dataDir}/ca.pem";
caKey = lib.mkDefault "${cfg.dataDir}/ca-key.pem";
};
};
}
+45 -46
View File
@@ -1,13 +1,12 @@
{ config, lib, pkgs, ... }:
with lib;
let
clamavUser = "clamav";
stateDir = "/var/lib/clamav";
clamavGroup = clamavUser;
cfg = config.services.clamav;
toKeyValue = generators.toKeyValue {
mkKeyValue = generators.mkKeyValueDefault { } " ";
toKeyValue = lib.generators.toKeyValue {
mkKeyValue = lib.generators.mkKeyValueDefault { } " ";
listsAsDuplicateKeys = true;
};
@@ -19,19 +18,19 @@ let
in
{
imports = [
(mkRemovedOptionModule [ "services" "clamav" "updater" "config" ] "Use services.clamav.updater.settings instead.")
(mkRemovedOptionModule [ "services" "clamav" "updater" "extraConfig" ] "Use services.clamav.updater.settings instead.")
(mkRemovedOptionModule [ "services" "clamav" "daemon" "extraConfig" ] "Use services.clamav.daemon.settings instead.")
(lib.mkRemovedOptionModule [ "services" "clamav" "updater" "config" ] "Use services.clamav.updater.settings instead.")
(lib.mkRemovedOptionModule [ "services" "clamav" "updater" "extraConfig" ] "Use services.clamav.updater.settings instead.")
(lib.mkRemovedOptionModule [ "services" "clamav" "daemon" "extraConfig" ] "Use services.clamav.daemon.settings instead.")
];
options = {
services.clamav = {
package = mkPackageOption pkgs "clamav" { };
package = lib.mkPackageOption pkgs "clamav" { };
daemon = {
enable = mkEnableOption "ClamAV clamd daemon";
enable = lib.mkEnableOption "ClamAV clamd daemon";
settings = mkOption {
type = with types; attrsOf (oneOf [ bool int str (listOf str) ]);
settings = lib.mkOption {
type = with lib.types; attrsOf (oneOf [ bool int str (listOf str) ]);
default = { };
description = ''
ClamAV configuration. Refer to <https://linux.die.net/man/5/clamd.conf>,
@@ -40,18 +39,18 @@ in
};
};
updater = {
enable = mkEnableOption "ClamAV freshclam updater";
enable = lib.mkEnableOption "ClamAV freshclam updater";
frequency = mkOption {
type = types.int;
frequency = lib.mkOption {
type = lib.types.int;
default = 12;
description = ''
Number of database checks per day.
'';
};
interval = mkOption {
type = types.str;
interval = lib.mkOption {
type = lib.types.str;
default = "hourly";
description = ''
How often freshclam is invoked. See systemd.time(7) for more
@@ -59,8 +58,8 @@ in
'';
};
settings = mkOption {
type = with types; attrsOf (oneOf [ bool int str (listOf str) ]);
settings = lib.mkOption {
type = with lib.types; attrsOf (oneOf [ bool int str (listOf str) ]);
default = { };
description = ''
freshclam configuration. Refer to <https://linux.die.net/man/5/freshclam.conf>,
@@ -69,10 +68,10 @@ in
};
};
fangfrisch = {
enable = mkEnableOption "ClamAV fangfrisch updater";
enable = lib.mkEnableOption "ClamAV fangfrisch updater";
interval = mkOption {
type = types.str;
interval = lib.mkOption {
type = lib.types.str;
default = "hourly";
description = ''
How often freshclam is invoked. See systemd.time(7) for more
@@ -80,9 +79,9 @@ in
'';
};
settings = mkOption {
settings = lib.mkOption {
type = lib.types.submodule {
freeformType = with types; attrsOf (attrsOf (oneOf [ str int bool ]));
freeformType = with lib.types; attrsOf (attrsOf (oneOf [ str int bool ]));
};
default = { };
example = {
@@ -100,10 +99,10 @@ in
};
scanner = {
enable = mkEnableOption "ClamAV scanner";
enable = lib.mkEnableOption "ClamAV scanner";
interval = mkOption {
type = types.str;
interval = lib.mkOption {
type = lib.types.str;
default = "*-*-* 04:00:00";
description = ''
How often clamdscan is invoked. See systemd.time(7) for more
@@ -112,8 +111,8 @@ in
'';
};
scanDirectories = mkOption {
type = with types; listOf str;
scanDirectories = lib.mkOption {
type = with lib.types; listOf str;
default = [ "/home" "/var/lib" "/tmp" "/etc" "/var/tmp" ];
description = ''
List of directories to scan.
@@ -124,7 +123,7 @@ in
};
};
config = mkIf (cfg.updater.enable || cfg.daemon.enable) {
config = lib.mkIf (cfg.updater.enable || cfg.daemon.enable) {
environment.systemPackages = [ cfg.package ];
users.users.${clamavUser} = {
@@ -153,12 +152,12 @@ in
};
services.clamav.fangfrisch.settings = {
DEFAULT.db_url = mkDefault "sqlite:////var/lib/clamav/fangfrisch_db.sqlite";
DEFAULT.local_directory = mkDefault stateDir;
DEFAULT.log_level = mkDefault "INFO";
urlhaus.enabled = mkDefault "yes";
urlhaus.max_size = mkDefault "2MB";
sanesecurity.enabled = mkDefault "yes";
DEFAULT.db_url = lib.mkDefault "sqlite:////var/lib/clamav/fangfrisch_db.sqlite";
DEFAULT.local_directory = lib.mkDefault stateDir;
DEFAULT.log_level = lib.mkDefault "INFO";
urlhaus.enabled = lib.mkDefault "yes";
urlhaus.max_size = lib.mkDefault "2MB";
sanesecurity.enabled = lib.mkDefault "yes";
};
environment.etc."clamav/freshclam.conf".source = freshclamConfigFile;
@@ -168,10 +167,10 @@ in
description = "ClamAV Antivirus Slice";
};
systemd.services.clamav-daemon = mkIf cfg.daemon.enable {
systemd.services.clamav-daemon = lib.mkIf cfg.daemon.enable {
description = "ClamAV daemon (clamd)";
after = optionals cfg.updater.enable [ "clamav-freshclam.service" ];
wants = optionals cfg.updater.enable [ "clamav-freshclam.service" ];
after = lib.optionals cfg.updater.enable [ "clamav-freshclam.service" ];
wants = lib.optionals cfg.updater.enable [ "clamav-freshclam.service" ];
wantedBy = [ "multi-user.target" ];
restartTriggers = [ clamdConfigFile ];
@@ -189,7 +188,7 @@ in
};
};
systemd.timers.clamav-freshclam = mkIf cfg.updater.enable {
systemd.timers.clamav-freshclam = lib.mkIf cfg.updater.enable {
description = "Timer for ClamAV virus database updater (freshclam)";
wantedBy = [ "timers.target" ];
timerConfig = {
@@ -198,7 +197,7 @@ in
};
};
systemd.services.clamav-freshclam = mkIf cfg.updater.enable {
systemd.services.clamav-freshclam = lib.mkIf cfg.updater.enable {
description = "ClamAV virus database updater (freshclam)";
restartTriggers = [ freshclamConfigFile ];
requires = [ "network-online.target" ];
@@ -217,7 +216,7 @@ in
};
};
systemd.services.clamav-fangfrisch-init = mkIf cfg.fangfrisch.enable {
systemd.services.clamav-fangfrisch-init = lib.mkIf cfg.fangfrisch.enable {
wantedBy = [ "multi-user.target" ];
# if the sqlite file can be found assume the database has already been initialised
script = ''
@@ -239,7 +238,7 @@ in
};
};
systemd.timers.clamav-fangfrisch = mkIf cfg.fangfrisch.enable {
systemd.timers.clamav-fangfrisch = lib.mkIf cfg.fangfrisch.enable {
description = "Timer for ClamAV virus database updater (fangfrisch)";
wantedBy = [ "timers.target" ];
timerConfig = {
@@ -248,7 +247,7 @@ in
};
};
systemd.services.clamav-fangfrisch = mkIf cfg.fangfrisch.enable {
systemd.services.clamav-fangfrisch = lib.mkIf cfg.fangfrisch.enable {
description = "ClamAV virus database updater (fangfrisch)";
restartTriggers = [ fangfrischConfigFile ];
requires = [ "network-online.target" ];
@@ -266,7 +265,7 @@ in
};
};
systemd.timers.clamdscan = mkIf cfg.scanner.enable {
systemd.timers.clamdscan = lib.mkIf cfg.scanner.enable {
description = "Timer for ClamAV virus scanner";
wantedBy = [ "timers.target" ];
timerConfig = {
@@ -275,10 +274,10 @@ in
};
};
systemd.services.clamdscan = mkIf cfg.scanner.enable {
systemd.services.clamdscan = lib.mkIf cfg.scanner.enable {
description = "ClamAV virus scanner";
after = optionals cfg.updater.enable [ "clamav-freshclam.service" ];
wants = optionals cfg.updater.enable [ "clamav-freshclam.service" ];
after = lib.optionals cfg.updater.enable [ "clamav-freshclam.service" ];
wants = lib.optionals cfg.updater.enable [ "clamav-freshclam.service" ];
serviceConfig = {
Type = "oneshot";
+21 -24
View File
@@ -4,20 +4,17 @@
pkgs,
...
}:
with lib;
let
cfg = config.services.endlessh-go;
in
{
options.services.endlessh-go = {
enable = mkEnableOption "endlessh-go service";
enable = lib.mkEnableOption "endlessh-go service";
package = mkPackageOption pkgs "endlessh-go" { };
package = lib.mkPackageOption pkgs "endlessh-go" { };
listenAddress = mkOption {
type = types.str;
listenAddress = lib.mkOption {
type = lib.types.str;
default = "0.0.0.0";
example = "[::]";
description = ''
@@ -25,8 +22,8 @@ in
'';
};
port = mkOption {
type = types.port;
port = lib.mkOption {
type = lib.types.port;
default = 2222;
example = 22;
description = ''
@@ -38,10 +35,10 @@ in
};
prometheus = {
enable = mkEnableOption "Prometheus integration";
enable = lib.mkEnableOption "Prometheus integration";
listenAddress = mkOption {
type = types.str;
listenAddress = lib.mkOption {
type = lib.types.str;
default = "0.0.0.0";
example = "[::]";
description = ''
@@ -50,8 +47,8 @@ in
'';
};
port = mkOption {
type = types.port;
port = lib.mkOption {
type = lib.types.port;
default = 2112;
example = 9119;
description = ''
@@ -61,8 +58,8 @@ in
};
};
extraOptions = mkOption {
type = with types; listOf str;
extraOptions = lib.mkOption {
type = with lib.types; listOf str;
default = [ ];
example = [
"-conn_type=tcp4"
@@ -73,8 +70,8 @@ in
'';
};
openFirewall = mkOption {
type = types.bool;
openFirewall = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to open a firewall port for the SSH listener.
@@ -82,7 +79,7 @@ in
};
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
systemd.services.endlessh-go = {
description = "SSH tarpit";
requires = [ "network.target" ];
@@ -90,21 +87,21 @@ in
serviceConfig =
let
needsPrivileges = cfg.port < 1024 || cfg.prometheus.port < 1024;
capabilities = [ "" ] ++ optionals needsPrivileges [ "CAP_NET_BIND_SERVICE" ];
capabilities = [ "" ] ++ lib.optionals needsPrivileges [ "CAP_NET_BIND_SERVICE" ];
rootDirectory = "/run/endlessh-go";
in
{
Restart = "always";
ExecStart =
with cfg;
concatStringsSep " " (
lib.concatStringsSep " " (
[
(lib.getExe cfg.package)
"-logtostderr"
"-host=${listenAddress}"
"-port=${toString port}"
]
++ optionals prometheus.enable [
++ lib.optionals prometheus.enable [
"-enable_prometheus"
"-prometheus_host=${prometheus.listenAddress}"
"-prometheus_port=${toString prometheus.port}"
@@ -152,8 +149,8 @@ in
};
};
networking.firewall.allowedTCPPorts = with cfg; optionals openFirewall [ port ];
networking.firewall.allowedTCPPorts = with cfg; lib.optionals openFirewall [ port ];
};
meta.maintainers = with maintainers; [ azahi ];
meta.maintainers = with lib.maintainers; [ azahi ];
}
+12 -15
View File
@@ -4,18 +4,15 @@
pkgs,
...
}:
with lib;
let
cfg = config.services.endlessh;
in
{
options.services.endlessh = {
enable = mkEnableOption "endlessh service";
enable = lib.mkEnableOption "endlessh service";
port = mkOption {
type = types.port;
port = lib.mkOption {
type = lib.types.port;
default = 2222;
example = 22;
description = ''
@@ -26,8 +23,8 @@ in
'';
};
extraOptions = mkOption {
type = with types; listOf str;
extraOptions = lib.mkOption {
type = with lib.types; listOf str;
default = [ ];
example = [
"-6"
@@ -39,8 +36,8 @@ in
'';
};
openFirewall = mkOption {
type = types.bool;
openFirewall = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to open a firewall port for the SSH listener.
@@ -48,7 +45,7 @@ in
};
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
systemd.services.endlessh = {
description = "SSH tarpit";
requires = [ "network.target" ];
@@ -56,14 +53,14 @@ in
serviceConfig =
let
needsPrivileges = cfg.port < 1024;
capabilities = [ "" ] ++ optionals needsPrivileges [ "CAP_NET_BIND_SERVICE" ];
capabilities = [ "" ] ++ lib.optionals needsPrivileges [ "CAP_NET_BIND_SERVICE" ];
rootDirectory = "/run/endlessh";
in
{
Restart = "always";
ExecStart =
with cfg;
concatStringsSep " " (
lib.concatStringsSep " " (
[
"${pkgs.endlessh}/bin/endlessh"
"-p ${toString port}"
@@ -112,8 +109,8 @@ in
};
};
networking.firewall.allowedTCPPorts = with cfg; optionals openFirewall [ port ];
networking.firewall.allowedTCPPorts = with cfg; lib.optionals openFirewall [ port ];
};
meta.maintainers = with maintainers; [ azahi ];
meta.maintainers = with lib.maintainers; [ azahi ];
}
+74 -77
View File
@@ -4,47 +4,44 @@
pkgs,
...
}:
with lib;
let
cfg = config.services.fail2ban;
settingsFormat = pkgs.formats.keyValue { };
configFormat = pkgs.formats.ini {
mkKeyValue = generators.mkKeyValueDefault { } " = ";
mkKeyValue = lib.generators.mkKeyValueDefault { } " = ";
};
mkJailConfig =
name: attrs:
optionalAttrs (name != "DEFAULT") { inherit (attrs) enabled; }
// optionalAttrs (attrs.filter != null) {
filter = if (builtins.isString filter) then filter else name;
lib.optionalAttrs (name != "DEFAULT") { inherit (attrs) enabled; }
// lib.optionalAttrs (attrs.filter != null) {
filter = if (builtins.isString lib.filter) then lib.filter else name;
}
// attrs.settings;
mkFilter =
name: attrs:
nameValuePair "fail2ban/filter.d/${name}.conf" {
lib.nameValuePair "fail2ban/filter.d/${name}.conf" {
source = configFormat.generate "filter.d/${name}.conf" attrs.filter;
};
fail2banConf = configFormat.generate "fail2ban.local" cfg.daemonSettings;
strJails = filterAttrs (_: builtins.isString) cfg.jails;
attrsJails = filterAttrs (_: builtins.isAttrs) cfg.jails;
strJails = lib.filterAttrs (_: builtins.isString) cfg.jails;
attrsJails = lib.filterAttrs (_: builtins.isAttrs) cfg.jails;
jailConf =
let
configFile = configFormat.generate "jail.local" (
{ INCLUDES.before = "paths-nixos.conf"; } // (mapAttrs mkJailConfig attrsJails)
{ INCLUDES.before = "paths-nixos.conf"; } // (lib.mapAttrs mkJailConfig attrsJails)
);
extraConfig = concatStringsSep "\n" (
attrValues (
mapAttrs (
extraConfig = lib.concatStringsSep "\n" (
lib.attrValues (
lib.mapAttrs (
name: def:
optionalString (def != "") ''
lib.optionalString (def != "") ''
[${name}]
${def}
''
@@ -74,12 +71,12 @@ in
{
imports = [
(mkRemovedOptionModule [
(lib.mkRemovedOptionModule [
"services"
"fail2ban"
"daemonConfig"
] "The daemon is now configured through the attribute set `services.fail2ban.daemonSettings`.")
(mkRemovedOptionModule [ "services" "fail2ban" "extraSettings" ]
(lib.mkRemovedOptionModule [ "services" "fail2ban" "extraSettings" ]
"The extra default configuration can now be set using `services.fail2ban.jails.DEFAULT.settings`."
)
];
@@ -88,9 +85,9 @@ in
options = {
services.fail2ban = {
enable = mkOption {
enable = lib.mkOption {
default = false;
type = types.bool;
type = lib.types.bool;
description = ''
Whether to enable the fail2ban service.
@@ -99,20 +96,20 @@ in
'';
};
package = mkPackageOption pkgs "fail2ban" {
package = lib.mkPackageOption pkgs "fail2ban" {
example = "fail2ban_0_11";
};
packageFirewall = mkOption {
packageFirewall = lib.mkOption {
default = config.networking.firewall.package;
defaultText = literalExpression "config.networking.firewall.package";
type = types.package;
defaultText = lib.literalExpression "config.networking.firewall.package";
type = lib.types.package;
description = "The firewall package used by fail2ban service. Defaults to the package for your firewall (iptables or nftables).";
};
extraPackages = mkOption {
extraPackages = lib.mkOption {
default = [ ];
type = types.listOf types.package;
type = lib.types.listOf lib.types.package;
example = lib.literalExpression "[ pkgs.ipset ]";
description = ''
Extra packages to be made available to the fail2ban service. The example contains
@@ -120,23 +117,23 @@ in
'';
};
bantime = mkOption {
bantime = lib.mkOption {
default = "10m";
type = types.str;
type = lib.types.str;
example = "1h";
description = "Number of seconds that a host is banned.";
};
maxretry = mkOption {
maxretry = lib.mkOption {
default = 3;
type = types.ints.unsigned;
type = lib.types.ints.unsigned;
description = "Number of failures before a host gets banned.";
};
banaction = mkOption {
banaction = lib.mkOption {
default = if config.networking.nftables.enable then "nftables-multiport" else "iptables-multiport";
defaultText = literalExpression ''if config.networking.nftables.enable then "nftables-multiport" else "iptables-multiport"'';
type = types.str;
defaultText = lib.literalExpression ''if config.networking.nftables.enable then "nftables-multiport" else "iptables-multiport"'';
type = lib.types.str;
description = ''
Default banning action (e.g. iptables, iptables-new, iptables-multiport,
iptables-ipset-proto6-allports, shorewall, etc). It is used to
@@ -145,10 +142,10 @@ in
'';
};
banaction-allports = mkOption {
banaction-allports = lib.mkOption {
default = if config.networking.nftables.enable then "nftables-allports" else "iptables-allports";
defaultText = literalExpression ''if config.networking.nftables.enable then "nftables-allports" else "iptables-allports"'';
type = types.str;
defaultText = lib.literalExpression ''if config.networking.nftables.enable then "nftables-allports" else "iptables-allports"'';
type = lib.types.str;
description = ''
Default banning action (e.g. iptables, iptables-new, iptables-multiport,
shorewall, etc) for "allports" jails. It is used to define action_* variables. Can be overridden
@@ -156,18 +153,18 @@ in
'';
};
bantime-increment.enable = mkOption {
bantime-increment.enable = lib.mkOption {
default = false;
type = types.bool;
type = lib.types.bool;
description = ''
"bantime.increment" allows to use database for searching of previously banned ip's to increase
a default ban time using special formula, default it is banTime * 1, 2, 4, 8, 16, 32 ...
'';
};
bantime-increment.rndtime = mkOption {
bantime-increment.rndtime = lib.mkOption {
default = null;
type = types.nullOr types.str;
type = lib.types.nullOr lib.types.str;
example = "8m";
description = ''
"bantime.rndtime" is the max number of seconds using for mixing with random time
@@ -175,18 +172,18 @@ in
'';
};
bantime-increment.maxtime = mkOption {
bantime-increment.maxtime = lib.mkOption {
default = null;
type = types.nullOr types.str;
type = lib.types.nullOr lib.types.str;
example = "48h";
description = ''
"bantime.maxtime" is the max number of seconds using the ban time can reach (don't grows further)
'';
};
bantime-increment.factor = mkOption {
bantime-increment.factor = lib.mkOption {
default = null;
type = types.nullOr types.str;
type = lib.types.nullOr lib.types.str;
example = "4";
description = ''
"bantime.factor" is a coefficient to calculate exponent growing of the formula or common multiplier,
@@ -194,9 +191,9 @@ in
'';
};
bantime-increment.formula = mkOption {
bantime-increment.formula = lib.mkOption {
default = null;
type = types.nullOr types.str;
type = lib.types.nullOr lib.types.str;
example = "ban.Time * math.exp(float(ban.Count+1)*banFactor)/math.exp(1*banFactor)";
description = ''
"bantime.formula" used by default to calculate next value of ban time, default value below,
@@ -204,9 +201,9 @@ in
'';
};
bantime-increment.multipliers = mkOption {
bantime-increment.multipliers = lib.mkOption {
default = null;
type = types.nullOr types.str;
type = lib.types.nullOr lib.types.str;
example = "1 2 4 8 16 32 64";
description = ''
"bantime.multipliers" used to calculate next value of ban time instead of formula, corresponding
@@ -216,9 +213,9 @@ in
'';
};
bantime-increment.overalljails = mkOption {
bantime-increment.overalljails = lib.mkOption {
default = null;
type = types.nullOr types.bool;
type = lib.types.nullOr lib.types.bool;
example = true;
description = ''
"bantime.overalljails" (if true) specifies the search of IP in the database will be executed
@@ -226,9 +223,9 @@ in
'';
};
ignoreIP = mkOption {
ignoreIP = lib.mkOption {
default = [ ];
type = types.listOf types.str;
type = lib.types.listOf lib.types.str;
example = [
"192.168.0.0/16"
"2001:DB8::42"
@@ -239,10 +236,10 @@ in
'';
};
daemonSettings = mkOption {
daemonSettings = lib.mkOption {
inherit (configFormat) type;
defaultText = literalExpression ''
defaultText = lib.literalExpression ''
{
Definition = {
logtarget = "SYSLOG";
@@ -258,9 +255,9 @@ in
'';
};
jails = mkOption {
jails = lib.mkOption {
default = { };
example = literalExpression ''
example = lib.literalExpression ''
{
apache-nohome-iptables = {
settings = {
@@ -287,26 +284,26 @@ in
};
'';
type =
with types;
with lib.types;
attrsOf (
either lines (
submodule (
{ name, ... }:
{
options = {
enabled = mkEnableOption "this jail" // {
enabled = lib.mkEnableOption "this jail" // {
default = true;
readOnly = name == "DEFAULT";
};
filter = mkOption {
filter = lib.mkOption {
type = nullOr (either str configFormat.type);
default = null;
description = "Content of the filter used for this jail.";
};
settings = mkOption {
settings = lib.mkOption {
inherit (settingsFormat) type;
default = { };
@@ -344,7 +341,7 @@ in
###### implementation
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
assertions = [
{
assertion = cfg.bantime-increment.formula == null || cfg.bantime-increment.multipliers == null;
@@ -354,7 +351,7 @@ in
}
];
warnings = mkIf (!config.networking.firewall.enable && !config.networking.nftables.enable) [
warnings = lib.mkIf (!config.networking.firewall.enable && !config.networking.nftables.enable) [
"fail2ban can not be used without a firewall"
];
@@ -371,14 +368,14 @@ in
"fail2ban/action.d".source = "${cfg.package}/etc/fail2ban/action.d/*.conf";
"fail2ban/filter.d".source = "${cfg.package}/etc/fail2ban/filter.d/*.conf";
}
// (mapAttrs' mkFilter (
filterAttrs (_: v: v.filter != null && !builtins.isString v.filter) attrsJails
// (lib.mapAttrs' mkFilter (
lib.filterAttrs (_: v: v.filter != null && !builtins.isString v.filter) attrsJails
));
systemd.packages = [ cfg.package ];
systemd.services.fail2ban = {
wantedBy = [ "multi-user.target" ];
partOf = optional config.networking.firewall.enable "firewall.service";
partOf = lib.optional config.networking.firewall.enable "firewall.service";
restartTriggers = [
fail2banConf
@@ -423,29 +420,29 @@ in
# Defaults for the daemon settings
services.fail2ban.daemonSettings.Definition = {
logtarget = mkDefault "SYSLOG";
socket = mkDefault "/run/fail2ban/fail2ban.sock";
pidfile = mkDefault "/run/fail2ban/fail2ban.pid";
dbfile = mkDefault "/var/lib/fail2ban/fail2ban.sqlite3";
logtarget = lib.mkDefault "SYSLOG";
socket = lib.mkDefault "/run/fail2ban/fail2ban.sock";
pidfile = lib.mkDefault "/run/fail2ban/fail2ban.pid";
dbfile = lib.mkDefault "/var/lib/fail2ban/fail2ban.sqlite3";
};
# Add some reasonable default jails. The special "DEFAULT" jail
# sets default values for all other jails.
services.fail2ban.jails = mkMerge [
services.fail2ban.jails = lib.mkMerge [
{
DEFAULT.settings =
(optionalAttrs cfg.bantime-increment.enable (
(lib.optionalAttrs cfg.bantime-increment.enable (
{
"bantime.increment" = cfg.bantime-increment.enable;
}
// (mapAttrs' (name: nameValuePair "bantime.${name}") (
filterAttrs (n: v: v != null && n != "enable") cfg.bantime-increment
// (lib.mapAttrs' (name: lib.nameValuePair "bantime.${name}") (
lib.filterAttrs (n: v: v != null && n != "enable") cfg.bantime-increment
))
))
// {
# Miscellaneous options
inherit (cfg) banaction maxretry bantime;
ignoreip = ''127.0.0.1/8 ${optionalString config.networking.enableIPv6 "::1"} ${concatStringsSep " " cfg.ignoreIP}'';
ignoreip = ''127.0.0.1/8 ${lib.optionalString config.networking.enableIPv6 "::1"} ${lib.concatStringsSep " " cfg.ignoreIP}'';
backend = "systemd";
# Actions
banaction_allports = cfg.banaction-allports;
@@ -453,15 +450,15 @@ in
}
# Block SSH if there are too many failing connection attempts.
(mkIf config.services.openssh.enable {
sshd.settings.port = mkDefault (
concatMapStringsSep "," builtins.toString config.services.openssh.ports
(lib.mkIf config.services.openssh.enable {
sshd.settings.port = lib.mkDefault (
lib.concatMapStringsSep "," builtins.toString config.services.openssh.ports
);
})
];
# Benefits from verbose sshd logging to observe failed login attempts,
# so we set that here unless the user overrode it.
services.openssh.settings.LogLevel = mkDefault "VERBOSE";
services.openssh.settings.LogLevel = lib.mkDefault "VERBOSE";
};
}
+10 -13
View File
@@ -1,7 +1,4 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.fprintd;
@@ -18,12 +15,12 @@ in
services.fprintd = {
enable = mkEnableOption "fprintd daemon and PAM module for fingerprint readers handling";
enable = lib.mkEnableOption "fprintd daemon and PAM module for fingerprint readers handling";
package = mkOption {
type = types.package;
package = lib.mkOption {
type = lib.types.package;
default = fprintdPkg;
defaultText = literalExpression "if config.services.fprintd.tod.enable then pkgs.fprintd-tod else pkgs.fprintd";
defaultText = lib.literalExpression "if config.services.fprintd.tod.enable then pkgs.fprintd-tod else pkgs.fprintd";
description = ''
fprintd package to use.
'';
@@ -31,11 +28,11 @@ in
tod = {
enable = mkEnableOption "Touch OEM Drivers library support";
enable = lib.mkEnableOption "Touch OEM Drivers library support";
driver = mkOption {
type = types.package;
example = literalExpression "pkgs.libfprint-2-tod1-goodix";
driver = lib.mkOption {
type = lib.types.package;
example = lib.literalExpression "pkgs.libfprint-2-tod1-goodix";
description = ''
Touch OEM Drivers (TOD) package to use.
'';
@@ -47,7 +44,7 @@ in
###### implementation
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
services.dbus.packages = [ cfg.package ];
@@ -55,7 +52,7 @@ in
systemd.packages = [ cfg.package ];
systemd.services.fprintd.environment = mkIf cfg.tod.enable {
systemd.services.fprintd.environment = lib.mkIf cfg.tod.enable {
FP_TOD_DRIVERS_DIR = "${cfg.tod.driver}${cfg.tod.driver.driverPath}";
};
+23 -27
View File
@@ -1,14 +1,10 @@
# This module defines global configuration for Haka.
{
config,
lib,
pkgs,
...
}:
with lib;
let
cfg = config.services.haka;
@@ -23,14 +19,14 @@ let
else
"${haka}/share/haka/sample/${cfg.configFile}"
}
${optionalString (builtins.lessThan 0 cfg.threads) "thread = ${cfg.threads}"}
${lib.optionalString (builtins.lessThan 0 cfg.threads) "thread = ${cfg.threads}"}
[packet]
${optionalString cfg.pcap ''module = "packet/pcap"''}
${optionalString cfg.nfqueue ''module = "packet/nqueue"''}
${optionalString cfg.dump.enable ''dump = "yes"''}
${optionalString cfg.dump.enable ''dump_input = "${cfg.dump.input}"''}
${optionalString cfg.dump.enable ''dump_output = "${cfg.dump.output}"''}
${lib.optionalString cfg.pcap ''module = "packet/pcap"''}
${lib.optionalString cfg.nfqueue ''module = "packet/nqueue"''}
${lib.optionalString cfg.dump.enable ''dump = "yes"''}
${lib.optionalString cfg.dump.enable ''dump_input = "${cfg.dump.input}"''}
${lib.optionalString cfg.dump.enable ''dump_output = "${cfg.dump.output}"''}
interfaces = "${lib.strings.concatStringsSep "," cfg.interfaces}"
@@ -62,14 +58,14 @@ in
services.haka = {
enable = mkEnableOption "Haka";
enable = lib.mkEnableOption "Haka";
package = mkPackageOption pkgs "haka" { };
package = lib.mkPackageOption pkgs "haka" { };
configFile = mkOption {
configFile = lib.mkOption {
default = "empty.lua";
example = "/srv/haka/myfilter.lua";
type = types.str;
type = lib.types.str;
description = ''
Specify which configuration file Haka uses.
It can be absolute path or a path relative to the sample directory of
@@ -77,46 +73,46 @@ in
'';
};
interfaces = mkOption {
interfaces = lib.mkOption {
default = [ "eth0" ];
example = [ "any" ];
type = with types; listOf str;
type = with lib.types; listOf str;
description = ''
Specify which interface(s) Haka listens to.
Use 'any' to listen to all interfaces.
'';
};
threads = mkOption {
threads = lib.mkOption {
default = 0;
example = 4;
type = types.int;
type = lib.types.int;
description = ''
The number of threads that will be used.
All system threads are used by default.
'';
};
pcap = mkOption {
pcap = lib.mkOption {
default = true;
type = types.bool;
type = lib.types.bool;
description = "Whether to enable pcap";
};
nfqueue = mkEnableOption "nfqueue";
nfqueue = lib.mkEnableOption "nfqueue";
dump.enable = mkEnableOption "dump";
dump.input = mkOption {
dump.enable = lib.mkEnableOption "dump";
dump.input = lib.mkOption {
default = "/tmp/input.pcap";
example = "/path/to/file.pcap";
type = types.path;
type = lib.types.path;
description = "Path to file where incoming packets are dumped";
};
dump.output = mkOption {
dump.output = lib.mkOption {
default = "/tmp/output.pcap";
example = "/path/to/file.pcap";
type = types.path;
type = lib.types.path;
description = "Path to file where outgoing packets are dumped";
};
};
@@ -124,7 +120,7 @@ in
###### implementation
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
assertions = [
{
+4 -7
View File
@@ -4,9 +4,6 @@
pkgs,
...
}:
with lib;
let
cfg = config.services.haveged;
@@ -20,14 +17,14 @@ in
services.haveged = {
enable = mkEnableOption ''
enable = lib.mkEnableOption ''
haveged entropy daemon, which refills /dev/random when low.
NOTE: does nothing on kernels newer than 5.6
'';
# source for the note https://github.com/jirka-h/haveged/issues/57
refill_threshold = mkOption {
type = types.int;
refill_threshold = lib.mkOption {
type = lib.types.int;
default = 1024;
description = ''
The number of bits of available entropy beneath which
@@ -39,7 +36,7 @@ in
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
# https://github.com/jirka-h/haveged/blob/a4b69d65a8dfc5a9f52ff8505c7f58dcf8b9234f/contrib/Fedora/haveged.service
systemd.services.haveged = {
@@ -4,9 +4,6 @@
lib,
...
}:
with lib;
let
cfg = config.services.hologram-agent;
@@ -19,20 +16,20 @@ in
{
options = {
services.hologram-agent = {
enable = mkOption {
type = types.bool;
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Whether to enable the Hologram agent for AWS instance credentials";
};
dialAddress = mkOption {
type = types.str;
dialAddress = lib.mkOption {
type = lib.types.str;
default = "localhost:3100";
description = "Hologram server and port.";
};
httpPort = mkOption {
type = types.str;
httpPort = lib.mkOption {
type = lib.types.str;
default = "80";
description = "Port for metadata service to listen on.";
};
@@ -40,7 +37,7 @@ in
};
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
boot.kernelModules = [ "dummy" ];
networking.interfaces.dummy0.ipv4.addresses = [
@@ -4,9 +4,6 @@
lib,
...
}:
with lib;
let
cfg = config.services.hologram-server;
@@ -38,93 +35,93 @@ in
{
options = {
services.hologram-server = {
enable = mkOption {
type = types.bool;
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Whether to enable the Hologram server for AWS instance credentials";
};
listenAddress = mkOption {
type = types.str;
listenAddress = lib.mkOption {
type = lib.types.str;
default = "0.0.0.0:3100";
description = "Address and port to listen on";
};
ldapHost = mkOption {
type = types.str;
ldapHost = lib.mkOption {
type = lib.types.str;
description = "Address of the LDAP server to use";
};
ldapInsecure = mkOption {
type = types.bool;
ldapInsecure = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Whether to connect to LDAP over SSL or not";
};
ldapUserAttr = mkOption {
type = types.str;
ldapUserAttr = lib.mkOption {
type = lib.types.str;
default = "cn";
description = "The LDAP attribute for usernames";
};
ldapBaseDN = mkOption {
type = types.str;
ldapBaseDN = lib.mkOption {
type = lib.types.str;
description = "The base DN for your Hologram users";
};
ldapBindDN = mkOption {
type = types.str;
ldapBindDN = lib.mkOption {
type = lib.types.str;
description = "DN of account to use to query the LDAP server";
};
ldapBindPassword = mkOption {
type = types.str;
ldapBindPassword = lib.mkOption {
type = lib.types.str;
description = "Password of account to use to query the LDAP server";
};
enableLdapRoles = mkOption {
type = types.bool;
enableLdapRoles = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Whether to assign user roles based on the user's LDAP group memberships";
};
groupClassAttr = mkOption {
type = types.str;
groupClassAttr = lib.mkOption {
type = lib.types.str;
default = "groupOfNames";
description = "The objectclass attribute to search for groups when enableLdapRoles is true";
};
roleAttr = mkOption {
type = types.str;
roleAttr = lib.mkOption {
type = lib.types.str;
default = "businessCategory";
description = "Which LDAP group attribute to search for authorized role ARNs";
};
awsAccount = mkOption {
type = types.str;
awsAccount = lib.mkOption {
type = lib.types.str;
description = "AWS account number";
};
awsDefaultRole = mkOption {
type = types.str;
awsDefaultRole = lib.mkOption {
type = lib.types.str;
description = "AWS default role";
};
statsAddress = mkOption {
type = types.str;
statsAddress = lib.mkOption {
type = lib.types.str;
default = "";
description = "Address of statsd server";
};
cacheTimeoutSeconds = mkOption {
type = types.int;
cacheTimeoutSeconds = lib.mkOption {
type = lib.types.int;
default = 3600;
description = "How often (in seconds) to refresh the LDAP cache";
};
};
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
systemd.services.hologram-server = {
description = "Provide EC2 instance credentials to machines outside of EC2";
after = [ "network.target" ];
+5 -8
View File
@@ -4,38 +4,35 @@
pkgs,
...
}:
with lib;
let
cfg = config.services.infnoise;
in
{
options = {
services.infnoise = {
enable = mkEnableOption "the Infinite Noise TRNG driver";
enable = lib.mkEnableOption "the Infinite Noise TRNG driver";
fillDevRandom = mkOption {
fillDevRandom = lib.mkOption {
description = ''
Whether to run the infnoise driver as a daemon to refill /dev/random.
If disabled, you can use the `infnoise` command-line tool to
manually obtain randomness.
'';
type = types.bool;
type = lib.types.bool;
default = true;
};
};
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
environment.systemPackages = [ pkgs.infnoise ];
services.udev.extraRules = ''
SUBSYSTEM=="usb", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6015", SYMLINK+="infnoise", TAG+="systemd", GROUP="dialout", MODE="0664", ENV{SYSTEMD_WANTS}="infnoise.service"
'';
systemd.services.infnoise = mkIf cfg.fillDevRandom {
systemd.services.infnoise = lib.mkIf cfg.fillDevRandom {
description = "Infinite Noise TRNG driver";
bindsTo = [ "dev-infnoise.device" ];
+4 -7
View File
@@ -4,9 +4,6 @@
pkgs,
...
}:
with lib;
let
cfg = config.services.munge;
@@ -20,11 +17,11 @@ in
options = {
services.munge = {
enable = mkEnableOption "munge service";
enable = lib.mkEnableOption "munge service";
password = mkOption {
password = lib.mkOption {
default = "/etc/munge/munge.key";
type = types.path;
type = lib.types.path;
description = ''
The path to a daemon's secret key.
'';
@@ -36,7 +33,7 @@ in
###### implementation
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
environment.systemPackages = [ pkgs.munge ];
@@ -1,21 +1,18 @@
{ config, lib, pkgs, utils, ... }:
with lib;
let
cfg = config.services.nginx.sso;
format = pkgs.formats.yaml { };
configPath = "/var/lib/nginx-sso/config.yaml";
in {
options.services.nginx.sso = {
enable = mkEnableOption "nginx-sso service";
enable = lib.mkEnableOption "nginx-sso service";
package = mkPackageOption pkgs "nginx-sso" { };
package = lib.mkPackageOption pkgs "nginx-sso" { };
configuration = mkOption {
configuration = lib.mkOption {
type = format.type;
default = {};
example = literalExpression ''
example = lib.literalExpression ''
{
listen = { addr = "127.0.0.1"; port = 8080; };
@@ -48,7 +45,7 @@ in {
};
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
systemd.services.nginx-sso = {
description = "Nginx SSO Backend";
after = [ "network.target" ];
+49 -44
View File
@@ -4,14 +4,11 @@
pkgs,
...
}:
with lib;
let
cfg = config.services.opensnitch;
format = pkgs.formats.json { };
predefinedRules = flip mapAttrs cfg.rules (
predefinedRules = lib.flip lib.mapAttrs cfg.rules (
name: cfg: {
file = pkgs.writeText "rule" (builtins.toJSON cfg);
}
@@ -21,11 +18,11 @@ in
{
options = {
services.opensnitch = {
enable = mkEnableOption "Opensnitch application firewall";
enable = lib.mkEnableOption "Opensnitch application firewall";
rules = mkOption {
rules = lib.mkOption {
default = { };
example = literalExpression ''
example = lib.literalExpression ''
{
"tor" = {
"name" = "tor";
@@ -50,28 +47,28 @@ in
for available options.
'';
type = types.submodule {
type = lib.types.submodule {
freeformType = format.type;
};
};
settings = mkOption {
type = types.submodule {
settings = lib.mkOption {
type = lib.types.submodule {
freeformType = format.type;
options = {
Server = {
Address = mkOption {
type = types.str;
Address = lib.mkOption {
type = lib.types.str;
description = ''
Unix socket path (unix:///tmp/osui.sock, the "unix:///" part is
mandatory) or TCP socket (192.168.1.100:50051).
'';
};
LogFile = mkOption {
type = types.path;
LogFile = lib.mkOption {
type = lib.types.path;
description = ''
File to write logs to (use /dev/stdout to write logs to standard
output).
@@ -80,8 +77,8 @@ in
};
DefaultAction = mkOption {
type = types.enum [
DefaultAction = lib.mkOption {
type = lib.types.enum [
"allow"
"deny"
];
@@ -91,15 +88,15 @@ in
'';
};
InterceptUnknown = mkOption {
type = types.bool;
InterceptUnknown = lib.mkOption {
type = lib.types.bool;
description = ''
Whether to intercept spare connections.
'';
};
ProcMonitorMethod = mkOption {
type = types.enum [
ProcMonitorMethod = lib.mkOption {
type = lib.types.enum [
"ebpf"
"proc"
"ftrace"
@@ -110,8 +107,8 @@ in
'';
};
LogLevel = mkOption {
type = types.enum [
LogLevel = lib.mkOption {
type = lib.types.enum [
0
1
2
@@ -124,8 +121,8 @@ in
'';
};
Firewall = mkOption {
type = types.enum [
Firewall = lib.mkOption {
type = lib.types.enum [
"iptables"
"nftables"
];
@@ -136,15 +133,15 @@ in
Stats = {
MaxEvents = mkOption {
type = types.int;
MaxEvents = lib.mkOption {
type = lib.types.int;
description = ''
Max events to send to the GUI.
'';
};
MaxStats = mkOption {
type = types.int;
MaxStats = lib.mkOption {
type = lib.types.int;
description = ''
Max stats per item to keep in backlog.
'';
@@ -152,14 +149,14 @@ in
};
Ebpf.ModulesPath = mkOption {
type = types.path;
Ebpf.ModulesPath = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default =
if cfg.settings.ProcMonitorMethod == "ebpf" then
"${config.boot.kernelPackages.opensnitch-ebpf}/etc/opensnitchd"
else
null;
defaultText = literalExpression ''
defaultText = lib.literalExpression ''
if cfg.settings.ProcMonitorMethod == "ebpf" then
"\\$\\{config.boot.kernelPackages.opensnitch-ebpf\\}/etc/opensnitchd"
else null;
@@ -170,8 +167,8 @@ in
'';
};
Rules.Path = mkOption {
type = types.path;
Rules.Path = lib.mkOption {
type = lib.types.path;
default = "/var/lib/opensnitch/rules";
description = ''
Path to the directory where firewall rules can be found and will
@@ -189,10 +186,10 @@ in
};
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
# pkg.opensnitch is referred to elsewhere in the module so we don't need to worry about it being garbage collected
services.opensnitch.settings = mapAttrs (_: v: mkDefault v) (
services.opensnitch.settings = lib.mapAttrs (_: v: lib.mkDefault v) (
builtins.fromJSON (
builtins.unsafeDiscardStringContext (
builtins.readFile "${pkgs.opensnitch}/etc/opensnitchd/default-config.json"
@@ -205,14 +202,20 @@ in
services.opensnitchd = {
wantedBy = [ "multi-user.target" ];
serviceConfig = {
ExecStart = [
""
"${pkgs.opensnitch}/bin/opensnitchd --config-file ${format.generate "default-config.json" cfg.settings}"
];
ExecStart =
let
preparedSettings = removeAttrs cfg.settings (
lib.optional (cfg.settings.ProcMonitorMethod != "ebpf") "Ebpf"
);
in
[
""
"${pkgs.opensnitch}/bin/opensnitchd --config-file ${format.generate "default-config.json" preparedSettings}"
];
};
preStart = mkIf (cfg.rules != { }) (
preStart = lib.mkIf (cfg.rules != { }) (
let
rules = flip mapAttrsToList predefinedRules (
rules = lib.flip lib.mapAttrsToList predefinedRules (
file: content: {
inherit (content) file;
local = "${cfg.settings.Rules.Path}/${file}.json";
@@ -225,11 +228,13 @@ in
# declared in `cfg.rules` (i.e. all networks that were "removed" from
# `cfg.rules`).
find ${cfg.settings.Rules.Path} -type l -lname '${builtins.storeDir}/*' ${
optionalString (rules != { }) ''
-not \( ${concatMapStringsSep " -o " ({ local, ... }: "-name '${baseNameOf local}*'") rules} \) \
lib.optionalString (rules != { }) ''
-not \( ${
lib.concatMapStringsSep " -o " ({ local, ... }: "-name '${baseNameOf local}*'") rules
} \) \
''
} -delete
${concatMapStrings (
${lib.concatMapStrings (
{ file, local }:
''
ln -sf '${file}' "${local}"
@@ -4,25 +4,22 @@
pkgs,
...
}:
with lib;
let
cfg = config.services.passSecretService;
in
{
options.services.passSecretService = {
enable = mkEnableOption "pass secret service";
enable = lib.mkEnableOption "pass secret service";
package = mkPackageOption pkgs "pass-secret-service" {
package = lib.mkPackageOption pkgs "pass-secret-service" {
example = "pass-secret-service.override { python3 = pkgs.python310 }";
};
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
systemd.packages = [ cfg.package ];
services.dbus.packages = [ cfg.package ];
};
meta.maintainers = with maintainers; [ aidalgol ];
meta.maintainers = with lib.maintainers; [ aidalgol ];
}
+53 -52
View File
@@ -4,9 +4,6 @@
pkgs,
...
}:
with lib;
let
cfg = config.services.physlock;
in
@@ -19,8 +16,8 @@ in
services.physlock = {
enable = mkOption {
type = types.bool;
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to enable the {command}`physlock` screen locking mechanism.
@@ -35,8 +32,8 @@ in
'';
};
allowAnyUser = mkOption {
type = types.bool;
allowAnyUser = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to allow any user to lock the screen. This will install a
@@ -46,24 +43,24 @@ in
'';
};
disableSysRq = mkOption {
type = types.bool;
disableSysRq = lib.mkOption {
type = lib.types.bool;
default = true;
description = ''
Whether to disable SysRq when locked with physlock.
'';
};
lockMessage = mkOption {
type = types.str;
lockMessage = lib.mkOption {
type = lib.types.str;
default = "";
description = ''
Message to show on physlock login terminal.
'';
};
muteKernelMessages = mkOption {
type = types.bool;
muteKernelMessages = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Disable kernel messages on console while physlock is running.
@@ -72,24 +69,24 @@ in
lockOn = {
suspend = mkOption {
type = types.bool;
suspend = lib.mkOption {
type = lib.types.bool;
default = true;
description = ''
Whether to lock screen with physlock just before suspend.
'';
};
hibernate = mkOption {
type = types.bool;
hibernate = lib.mkOption {
type = lib.types.bool;
default = true;
description = ''
Whether to lock screen with physlock just before hibernate.
'';
};
extraTargets = mkOption {
type = types.listOf types.str;
extraTargets = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
example = [ "display-manager.service" ];
description = ''
@@ -110,46 +107,50 @@ in
###### implementation
config = mkIf cfg.enable (mkMerge [
{
config = lib.mkIf cfg.enable (
lib.mkMerge [
{
# for physlock -l and physlock -L
environment.systemPackages = [ pkgs.physlock ];
# for physlock -l and physlock -L
environment.systemPackages = [ pkgs.physlock ];
systemd.services.physlock = {
enable = true;
description = "Physlock";
wantedBy =
optional cfg.lockOn.suspend "suspend.target"
++ optional cfg.lockOn.hibernate "hibernate.target"
++ cfg.lockOn.extraTargets;
before =
optional cfg.lockOn.suspend "systemd-suspend.service"
++ optional cfg.lockOn.hibernate "systemd-hibernate.service"
++ optional (cfg.lockOn.hibernate || cfg.lockOn.suspend) "systemd-suspend-then-hibernate.service"
++ cfg.lockOn.extraTargets;
serviceConfig = {
Type = "forking";
ExecStart = "${pkgs.physlock}/bin/physlock -d${optionalString cfg.muteKernelMessages "m"}${optionalString cfg.disableSysRq "s"}${
optionalString (cfg.lockMessage != "") " -p \"${cfg.lockMessage}\""
}";
systemd.services.physlock = {
enable = true;
description = "Physlock";
wantedBy =
lib.optional cfg.lockOn.suspend "suspend.target"
++ lib.optional cfg.lockOn.hibernate "hibernate.target"
++ cfg.lockOn.extraTargets;
before =
lib.optional cfg.lockOn.suspend "systemd-suspend.service"
++ lib.optional cfg.lockOn.hibernate "systemd-hibernate.service"
++ lib.optional (
cfg.lockOn.hibernate || cfg.lockOn.suspend
) "systemd-suspend-then-hibernate.service"
++ cfg.lockOn.extraTargets;
serviceConfig = {
Type = "forking";
ExecStart = "${pkgs.physlock}/bin/physlock -d${lib.optionalString cfg.muteKernelMessages "m"}${lib.optionalString cfg.disableSysRq "s"}${
lib.optionalString (cfg.lockMessage != "") " -p \"${cfg.lockMessage}\""
}";
};
};
};
security.pam.services.physlock = { };
security.pam.services.physlock = { };
}
}
(mkIf cfg.allowAnyUser {
(lib.mkIf cfg.allowAnyUser {
security.wrappers.physlock = {
setuid = true;
owner = "root";
group = "root";
source = "${pkgs.physlock}/bin/physlock";
};
security.wrappers.physlock = {
setuid = true;
owner = "root";
group = "root";
source = "${pkgs.physlock}/bin/physlock";
};
})
]);
})
]
);
}
+15 -18
View File
@@ -4,9 +4,6 @@
pkgs,
...
}:
with lib;
let
cfg = config.services.sks;
sksPkg = cfg.package;
@@ -16,7 +13,7 @@ let
in
{
meta.maintainers = with maintainers; [
meta.maintainers = with lib.maintainers; [
calbrecht
jcumming
];
@@ -25,15 +22,15 @@ in
services.sks = {
enable = mkEnableOption ''
enable = lib.mkEnableOption ''
SKS (synchronizing key server for OpenPGP) and start the database
server. You need to create "''${dataDir}/dump/*.gpg" for the initial
import'';
package = mkPackageOption pkgs "sks" { };
package = lib.mkPackageOption pkgs "sks" { };
dataDir = mkOption {
type = types.path;
dataDir = lib.mkOption {
type = lib.types.path;
default = "/var/db/sks";
example = "/var/lib/sks";
# TODO: The default might change to "/var/lib/sks" as this is more
@@ -46,8 +43,8 @@ in
'';
};
extraDbConfig = mkOption {
type = types.str;
extraDbConfig = lib.mkOption {
type = lib.types.str;
default = "";
description = ''
Set contents of the files "KDB/DB_CONFIG" and "PTree/DB_CONFIG" within
@@ -60,28 +57,28 @@ in
'';
};
hkpAddress = mkOption {
hkpAddress = lib.mkOption {
default = [
"127.0.0.1"
"::1"
];
type = types.listOf types.str;
type = lib.types.listOf lib.types.str;
description = ''
Domain names, IPv4 and/or IPv6 addresses to listen on for HKP
requests.
'';
};
hkpPort = mkOption {
hkpPort = lib.mkOption {
default = 11371;
type = types.ints.u16;
type = lib.types.ints.u16;
description = "HKP port to listen on.";
};
webroot = mkOption {
type = types.nullOr types.path;
webroot = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = "${sksPkg.webSamples}/OpenPKG";
defaultText = literalExpression ''"''${package.webSamples}/OpenPKG"'';
defaultText = lib.literalExpression ''"''${package.webSamples}/OpenPKG"'';
description = ''
Source directory (will be symlinked, if not null) for the files the
built-in webserver should serve. SKS (''${pkgs.sks.webSamples})
@@ -96,7 +93,7 @@ in
};
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
users = {
users.sks = {
+25 -28
View File
@@ -4,9 +4,6 @@
pkgs,
...
}:
with lib;
let
cfg = config.services.sshguard;
@@ -19,7 +16,7 @@ let
"-o cat"
"-n1"
]
++ (map (name: "-t ${escapeShellArg name}") cfg.services)
++ (map (name: "-t ${lib.escapeShellArg name}") cfg.services)
);
backend = if config.networking.nftables.enable then "sshg-fw-nft-sets" else "sshg-fw-ipset";
in
@@ -36,40 +33,40 @@ in
options = {
services.sshguard = {
enable = mkOption {
enable = lib.mkOption {
default = false;
type = types.bool;
type = lib.types.bool;
description = "Whether to enable the sshguard service.";
};
attack_threshold = mkOption {
attack_threshold = lib.mkOption {
default = 30;
type = types.int;
type = lib.types.int;
description = ''
Block attackers when their cumulative attack score exceeds threshold. Most attacks have a score of 10.
'';
};
blacklist_threshold = mkOption {
blacklist_threshold = lib.mkOption {
default = null;
example = 120;
type = types.nullOr types.int;
type = lib.types.nullOr lib.types.int;
description = ''
Blacklist an attacker when its score exceeds threshold. Blacklisted addresses are loaded from and added to blacklist-file.
'';
};
blacklist_file = mkOption {
blacklist_file = lib.mkOption {
default = "/var/lib/sshguard/blacklist.db";
type = types.path;
type = lib.types.path;
description = ''
Blacklist an attacker when its score exceeds threshold. Blacklisted addresses are loaded from and added to blacklist-file.
'';
};
blocktime = mkOption {
blocktime = lib.mkOption {
default = 120;
type = types.int;
type = lib.types.int;
description = ''
Block attackers for initially blocktime seconds after exceeding threshold. Subsequent blocks increase by a factor of 1.5.
@@ -77,33 +74,33 @@ in
'';
};
detection_time = mkOption {
detection_time = lib.mkOption {
default = 1800;
type = types.int;
type = lib.types.int;
description = ''
Remember potential attackers for up to detection_time seconds before resetting their score.
'';
};
whitelist = mkOption {
whitelist = lib.mkOption {
default = [ ];
example = [
"198.51.100.56"
"198.51.100.2"
];
type = types.listOf types.str;
type = lib.types.listOf lib.types.str;
description = ''
Whitelist a list of addresses, hostnames, or address blocks.
'';
};
services = mkOption {
services = lib.mkOption {
default = [ "sshd" ];
example = [
"sshd"
"exim"
];
type = types.listOf types.str;
type = lib.types.listOf lib.types.str;
description = ''
Systemd services sshguard should receive logs of.
'';
@@ -113,7 +110,7 @@ in
###### implementation
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
environment.etc."sshguard.conf".source = configFile;
@@ -122,7 +119,7 @@ in
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
partOf = optional config.networking.firewall.enable "firewall.service";
partOf = lib.optional config.networking.firewall.enable "firewall.service";
restartTriggers = [ configFile ];
@@ -149,21 +146,21 @@ in
# of the ipsets. So instead, we create both the ipsets and
# firewall rules before sshguard starts.
preStart =
optionalString config.networking.firewall.enable ''
lib.optionalString config.networking.firewall.enable ''
${pkgs.ipset}/bin/ipset -quiet create -exist sshguard4 hash:net family inet
${pkgs.iptables}/bin/iptables -I INPUT -m set --match-set sshguard4 src -j DROP
''
+ optionalString (config.networking.firewall.enable && config.networking.enableIPv6) ''
+ lib.optionalString (config.networking.firewall.enable && config.networking.enableIPv6) ''
${pkgs.ipset}/bin/ipset -quiet create -exist sshguard6 hash:net family inet6
${pkgs.iptables}/bin/ip6tables -I INPUT -m set --match-set sshguard6 src -j DROP
'';
postStop =
optionalString config.networking.firewall.enable ''
lib.optionalString config.networking.firewall.enable ''
${pkgs.iptables}/bin/iptables -D INPUT -m set --match-set sshguard4 src -j DROP
${pkgs.ipset}/bin/ipset -quiet destroy sshguard4
''
+ optionalString (config.networking.firewall.enable && config.networking.enableIPv6) ''
+ lib.optionalString (config.networking.firewall.enable && config.networking.enableIPv6) ''
${pkgs.iptables}/bin/ip6tables -D INPUT -m set --match-set sshguard6 src -j DROP
${pkgs.ipset}/bin/ipset -quiet destroy sshguard6
'';
@@ -179,11 +176,11 @@ in
"-a ${toString cfg.attack_threshold}"
"-p ${toString cfg.blocktime}"
"-s ${toString cfg.detection_time}"
(optionalString (
(lib.optionalString (
cfg.blacklist_threshold != null
) "-b ${toString cfg.blacklist_threshold}:${cfg.blacklist_file}")
]
++ (map (name: "-w ${escapeShellArg name}") cfg.whitelist)
++ (map (name: "-w ${lib.escapeShellArg name}") cfg.whitelist)
);
in
"${pkgs.sshguard}/bin/sshguard ${args}";
@@ -4,9 +4,6 @@
pkgs,
...
}:
with lib;
let
cfg = config.services.sslmate-agent;
@@ -16,11 +13,11 @@ in
options = {
services.sslmate-agent = {
enable = mkEnableOption "sslmate-agent, a daemon for managing SSL/TLS certificates on a server";
enable = lib.mkEnableOption "sslmate-agent, a daemon for managing SSL/TLS certificates on a server";
};
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
environment.systemPackages = with pkgs; [ sslmate-agent ];
systemd = {
+9 -10
View File
@@ -4,23 +4,22 @@
pkgs,
...
}:
with lib;
let
cfg = config.services.tang;
in
{
options.services.tang = {
enable = mkEnableOption "tang";
enable = lib.mkEnableOption "tang";
package = mkOption {
type = types.package;
package = lib.mkOption {
type = lib.types.package;
default = pkgs.tang;
defaultText = literalExpression "pkgs.tang";
defaultText = lib.literalExpression "pkgs.tang";
description = "The tang package to use.";
};
listenStream = mkOption {
type = with types; listOf str;
listenStream = lib.mkOption {
type = with lib.types; listOf str;
default = [ "7654" ];
example = [
"198.168.100.1:7654"
@@ -33,9 +32,9 @@ in
'';
};
ipAddressAllow = mkOption {
ipAddressAllow = lib.mkOption {
example = [ "192.168.1.0/24" ];
type = types.listOf types.str;
type = lib.types.listOf lib.types.str;
description = ''
Whitelist a list of address prefixes.
Preferably, internal addresses should be used.
@@ -43,7 +42,7 @@ in
};
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
environment.systemPackages = [ cfg.package ];
systemd.services."tangd@" = {
File diff suppressed because it is too large Load Diff
+9 -10
View File
@@ -4,7 +4,6 @@
pkgs,
...
}:
with lib;
let
cfg = config.services.tor;
@@ -29,8 +28,8 @@ in
services.tor.tsocks = {
enable = mkOption {
type = types.bool;
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to build tsocks wrapper script to relay application traffic via Tor.
@@ -45,8 +44,8 @@ in
'';
};
server = mkOption {
type = types.str;
server = lib.mkOption {
type = lib.types.str;
default = "localhost:9050";
example = "192.168.0.20";
description = ''
@@ -54,8 +53,8 @@ in
'';
};
config = mkOption {
type = types.lines;
config = lib.mkOption {
type = lib.types.lines;
default = "";
description = ''
Extra configuration. Contents will be added verbatim to TSocks
@@ -69,13 +68,13 @@ in
###### implementation
config = mkIf cfg.tsocks.enable {
config = lib.mkIf cfg.tsocks.enable {
environment.systemPackages = [ torify ]; # expose it to the users
services.tor.tsocks.config = ''
server = ${toString (head (splitString ":" cfg.tsocks.server))}
server_port = ${toString (tail (splitString ":" cfg.tsocks.server))}
server = ${toString (lib.head (lib.splitString ":" cfg.tsocks.server))}
server_port = ${toString (lib.tail (lib.splitString ":" cfg.tsocks.server))}
local = 127.0.0.0/255.128.0.0
local = 127.128.0.0/255.192.0.0
+19 -22
View File
@@ -1,14 +1,11 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.tor.torsocks;
optionalNullStr = b: v: optionalString (b != null) v;
optionalNullStr = b: v: lib.optionalString (b != null) v;
configFile = server: ''
TorAddress ${toString (head (splitString ":" server))}
TorPort ${toString (tail (splitString ":" server))}
TorAddress ${toString (lib.head (lib.splitString ":" server))}
TorPort ${toString (lib.tail (lib.splitString ":" server))}
OnionAddrRange ${cfg.onionAddrRange}
@@ -34,18 +31,18 @@ in
{
options = {
services.tor.torsocks = {
enable = mkOption {
type = types.bool;
enable = lib.mkOption {
type = lib.types.bool;
default = config.services.tor.enable && config.services.tor.client.enable;
defaultText = literalExpression "config.services.tor.enable && config.services.tor.client.enable";
defaultText = lib.literalExpression "config.services.tor.enable && config.services.tor.client.enable";
description = ''
Whether to build `/etc/tor/torsocks.conf`
containing the specified global torsocks configuration.
'';
};
server = mkOption {
type = types.str;
server = lib.mkOption {
type = lib.types.str;
default = "127.0.0.1:9050";
example = "192.168.0.20:1234";
description = ''
@@ -54,8 +51,8 @@ in
'';
};
fasterServer = mkOption {
type = types.str;
fasterServer = lib.mkOption {
type = lib.types.str;
default = "127.0.0.1:9063";
example = "192.168.0.20:1234";
description = ''
@@ -64,8 +61,8 @@ in
'';
};
onionAddrRange = mkOption {
type = types.str;
onionAddrRange = lib.mkOption {
type = lib.types.str;
default = "127.42.42.0/24";
description = ''
Tor hidden sites do not have real IP addresses. This
@@ -77,8 +74,8 @@ in
'';
};
socks5Username = mkOption {
type = types.nullOr types.str;
socks5Username = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
example = "bob";
description = ''
@@ -87,8 +84,8 @@ in
'';
};
socks5Password = mkOption {
type = types.nullOr types.str;
socks5Password = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
example = "sekret";
description = ''
@@ -97,8 +94,8 @@ in
'';
};
allowInbound = mkOption {
type = types.bool;
allowInbound = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Set Torsocks to accept inbound connections. If set to
@@ -110,7 +107,7 @@ in
};
};
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
environment.systemPackages = [ pkgs.torsocks (wrapTorsocks "torsocks-faster" cfg.fasterServer) ];
environment.etc."tor/torsocks.conf" =
+32 -34
View File
@@ -4,14 +4,12 @@
pkgs,
...
}:
with lib;
let
cfg = config.services.usbguard;
# valid policy options
policy = (
types.enum [
lib.types.enum [
"allow"
"block"
"reject"
@@ -30,13 +28,13 @@ let
PresentDevicePolicy=${cfg.presentDevicePolicy}
PresentControllerPolicy=${cfg.presentControllerPolicy}
InsertedDevicePolicy=${cfg.insertedDevicePolicy}
RestoreControllerDeviceState=${boolToString cfg.restoreControllerDeviceState}
RestoreControllerDeviceState=${lib.boolToString cfg.restoreControllerDeviceState}
# this does not seem useful for endusers to change
DeviceManagerBackend=uevent
IPCAllowedUsers=${concatStringsSep " " cfg.IPCAllowedUsers}
IPCAllowedGroups=${concatStringsSep " " cfg.IPCAllowedGroups}
IPCAllowedUsers=${lib.concatStringsSep " " cfg.IPCAllowedUsers}
IPCAllowedGroups=${lib.concatStringsSep " " cfg.IPCAllowedGroups}
IPCAccessControlFiles=/var/lib/usbguard/IPCAccessControl.d/
DeviceRulesWithPort=${boolToString cfg.deviceRulesWithPort}
DeviceRulesWithPort=${lib.boolToString cfg.deviceRulesWithPort}
# HACK: that way audit logs still land in the journal
AuditFilePath=/dev/null
'';
@@ -50,16 +48,16 @@ in
options = {
services.usbguard = {
enable = mkEnableOption "USBGuard daemon";
enable = lib.mkEnableOption "USBGuard daemon";
package = mkPackageOption pkgs "usbguard" {
package = lib.mkPackageOption pkgs "usbguard" {
extraDescription = ''
If you do not need the Qt GUI, use `pkgs.usbguard-nox` to save disk space.
'';
};
ruleFile = mkOption {
type = types.nullOr types.path;
ruleFile = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = "/var/lib/usbguard/rules.conf";
example = "/run/secrets/usbguard-rules";
description = ''
@@ -71,8 +69,8 @@ in
'';
};
rules = mkOption {
type = types.nullOr types.lines;
rules = lib.mkOption {
type = lib.types.nullOr lib.types.lines;
default = null;
example = ''
allow with-interface equals { 08:*:* }
@@ -92,8 +90,8 @@ in
'';
};
implicitPolicyTarget = mkOption {
type = types.enum [
implicitPolicyTarget = lib.mkOption {
type = lib.types.enum [
"allow"
"block"
"reject"
@@ -106,7 +104,7 @@ in
'';
};
presentDevicePolicy = mkOption {
presentDevicePolicy = lib.mkOption {
type = policy;
default = "apply-policy";
description = ''
@@ -117,7 +115,7 @@ in
'';
};
presentControllerPolicy = mkOption {
presentControllerPolicy = lib.mkOption {
type = policy;
default = "keep";
description = ''
@@ -126,8 +124,8 @@ in
'';
};
insertedDevicePolicy = mkOption {
type = types.enum [
insertedDevicePolicy = lib.mkOption {
type = lib.types.enum [
"block"
"reject"
"apply-policy"
@@ -139,8 +137,8 @@ in
'';
};
restoreControllerDeviceState = mkOption {
type = types.bool;
restoreControllerDeviceState = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
The USBGuard daemon modifies some attributes of controller
@@ -151,8 +149,8 @@ in
'';
};
IPCAllowedUsers = mkOption {
type = types.listOf types.str;
IPCAllowedUsers = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ "root" ];
example = [
"root"
@@ -163,8 +161,8 @@ in
'';
};
IPCAllowedGroups = mkOption {
type = types.listOf types.str;
IPCAllowedGroups = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
example = [ "wheel" ];
description = ''
@@ -173,21 +171,21 @@ in
'';
};
deviceRulesWithPort = mkOption {
type = types.bool;
deviceRulesWithPort = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Generate device specific rules including the "via-port" attribute.
'';
};
dbus.enable = mkEnableOption "USBGuard dbus daemon";
dbus.enable = lib.mkEnableOption "USBGuard dbus daemon";
};
};
###### implementation
config = mkIf cfg.enable {
config = lib.mkIf cfg.enable {
environment.systemPackages = [ cfg.package ];
@@ -239,7 +237,7 @@ in
};
};
usbguard-dbus = mkIf cfg.dbus.enable {
usbguard-dbus = lib.mkIf cfg.dbus.enable {
description = "USBGuard D-Bus Service";
wantedBy = [ "multi-user.target" ];
@@ -261,7 +259,7 @@ in
groupCheck =
(lib.concatStrings (map (g: "subject.isInGroup(\"${g}\") || ") cfg.IPCAllowedGroups)) + "false";
in
optionalString cfg.dbus.enable ''
lib.optionalString cfg.dbus.enable ''
polkit.addRule(function(action, subject) {
if ((action.id == "org.usbguard.Policy1.listRules" ||
action.id == "org.usbguard.Policy1.appendRule" ||
@@ -278,15 +276,15 @@ in
'';
};
imports = [
(mkRemovedOptionModule [ "services" "usbguard" "IPCAccessControlFiles" ]
(lib.mkRemovedOptionModule [ "services" "usbguard" "IPCAccessControlFiles" ]
"The usbguard module now hardcodes IPCAccessControlFiles to /var/lib/usbguard/IPCAccessControl.d."
)
(mkRemovedOptionModule [
(lib.mkRemovedOptionModule [
"services"
"usbguard"
"auditFilePath"
] "Removed usbguard module audit log files. Audit logs can be found in the systemd journal.")
(mkRenamedOptionModule
(lib.mkRenamedOptionModule
[ "services" "usbguard" "implictPolicyTarget" ]
[ "services" "usbguard" "implicitPolicyTarget" ]
)

Some files were not shown because too many files have changed in this diff Show More