Project import generated by Copybara.
GitOrigin-RevId: 062a0c5437b68f950b081bbfc8a699d57a4ee026
This commit is contained in:
parent
75a5b40962
commit
8e65f7f0cc
2156 changed files with 58830 additions and 19294 deletions
32
third_party/nixpkgs/.git-blame-ignore-revs
vendored
Normal file
32
third_party/nixpkgs/.git-blame-ignore-revs
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
# This file contains a list of commits that are not likely what you
|
||||
# are looking for in a blame, such as mass reformatting or renaming.
|
||||
# You can set this file as a default ignore file for blame by running
|
||||
# the following command.
|
||||
#
|
||||
# $ git config blame.ignoreRevsFile .git-blame-ignore-revs
|
||||
#
|
||||
# To temporarily not use this file add
|
||||
# --ignore-revs-file=""
|
||||
# to your blame command.
|
||||
#
|
||||
# The ignoreRevsFile can't be set globally due to blame failing if the file isn't present.
|
||||
# To not have to set the option in every repository it is needed in,
|
||||
# save the following script in your path with the name "git-bblame"
|
||||
# now you can run
|
||||
# $ git bblame $FILE
|
||||
# to use the .git-blame-ignore-revs file if it is present.
|
||||
#
|
||||
# #!/usr/bin/env bash
|
||||
# repo_root=$(git rev-parse --show-toplevel)
|
||||
# if [[ -e $repo_root/.git-blame-ignore-revs ]]; then
|
||||
# git blame --ignore-revs-file="$repo_root/.git-blame-ignore-revs" $@
|
||||
# else
|
||||
# git blame $@
|
||||
# fi
|
||||
|
||||
|
||||
# nixos/modules/rename: Sort alphabetically
|
||||
1f71224fe86605ef4cd23ed327b3da7882dad382
|
||||
|
||||
# nixos: fix module paths in rename.nix
|
||||
d08ede042b74b8199dc748323768227b88efcf7c
|
4
third_party/nixpkgs/.github/CODEOWNERS
vendored
4
third_party/nixpkgs/.github/CODEOWNERS
vendored
|
@ -226,10 +226,10 @@
|
|||
/pkgs/applications/editors/neovim @jonringer @teto
|
||||
|
||||
# VimPlugins
|
||||
/pkgs/misc/vim-plugins @jonringer @softinio
|
||||
/pkgs/applications/editors/vim/plugins @jonringer
|
||||
|
||||
# VsCode Extensions
|
||||
/pkgs/misc/vscode-extensions @jonringer
|
||||
/pkgs/applications/editors/vscode/extensions @jonringer
|
||||
|
||||
# Prometheus exporter modules and tests
|
||||
/nixos/modules/services/monitoring/prometheus/exporters.nix @WilliButz
|
||||
|
|
2
third_party/nixpkgs/.github/labeler.yml
vendored
2
third_party/nixpkgs/.github/labeler.yml
vendored
|
@ -142,7 +142,7 @@
|
|||
"6.topic: vim":
|
||||
- doc/languages-frameworks/vim.section.md
|
||||
- pkgs/applications/editors/vim/**/*
|
||||
- pkgs/misc/vim-plugins/**/*
|
||||
- pkgs/applications/editors/vim/plugins/**/*
|
||||
- nixos/modules/programs/neovim.nix
|
||||
- pkgs/applications/editors/neovim/**/*
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ jobs:
|
|||
if: github.repository_owner == 'NixOS' && github.event.pull_request.merged == true && (github.event_name != 'labeled' || startsWith('backport', github.event.label.name))
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
# required to find all branches
|
||||
fetch-depth: 0
|
||||
|
|
|
@ -14,7 +14,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
# we don't limit this action to only NixOS repo since the checks are cheap and useful developer feedback
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: cachix/install-nix-action@v16
|
||||
# explicit list of supportedSystems is needed until aarch64-darwin becomes part of the trunk jobset
|
||||
- run: nix-build pkgs/top-level/release.nix -A tarball.nixpkgs-basic-release-checks --arg supportedSystems '[ "aarch64-darwin" "aarch64-linux" "x86_64-linux" "x86_64-darwin" ]'
|
||||
|
|
|
@ -24,7 +24,7 @@ jobs:
|
|||
- name: print list of changed files
|
||||
run: |
|
||||
cat "$HOME/changed_files"
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
# pull_request_target checks out the base branch by default
|
||||
ref: refs/pull/${{ github.event.pull_request.number }}/merge
|
||||
|
|
|
@ -13,7 +13,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
if: github.repository_owner == 'NixOS'
|
||||
steps:
|
||||
- uses: actions/labeler@v3
|
||||
- uses: actions/labeler@v4
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
sync-labels: true
|
||||
|
|
|
@ -14,7 +14,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
if: github.repository_owner == 'NixOS'
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
# pull_request_target checks out the base branch by default
|
||||
ref: refs/pull/${{ github.event.pull_request.number }}/merge
|
||||
|
|
|
@ -14,7 +14,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
if: github.repository_owner == 'NixOS'
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
# pull_request_target checks out the base branch by default
|
||||
ref: refs/pull/${{ github.event.pull_request.number }}/merge
|
||||
|
|
|
@ -15,7 +15,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
if: github.repository_owner == 'NixOS'
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
# pull_request_target checks out the base branch by default
|
||||
ref: refs/pull/${{ github.event.pull_request.number }}/merge
|
||||
|
|
|
@ -38,7 +38,7 @@ jobs:
|
|||
into: staging-21.11
|
||||
name: ${{ matrix.pairs.from }} → ${{ matrix.pairs.into }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: ${{ matrix.pairs.from }} → ${{ matrix.pairs.into }}
|
||||
uses: devmasx/merge-branch@1.4.0
|
||||
|
|
|
@ -32,7 +32,7 @@ jobs:
|
|||
into: staging
|
||||
name: ${{ matrix.pairs.from }} → ${{ matrix.pairs.into }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: ${{ matrix.pairs.from }} → ${{ matrix.pairs.into }}
|
||||
uses: devmasx/merge-branch@1.4.0
|
||||
|
|
|
@ -10,7 +10,7 @@ jobs:
|
|||
if: github.repository_owner == 'NixOS' && github.ref == 'refs/heads/master' # ensure workflow_dispatch only runs on master
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: cachix/install-nix-action@v16
|
||||
- name: setup
|
||||
id: setup
|
||||
|
|
|
@ -56,7 +56,7 @@ Use `programs.steam.enable = true;` if you want to add steam to systemPackages a
|
|||
|
||||
## steam-run {#sec-steam-run}
|
||||
|
||||
The FHS-compatible chroot used for Steam can also be used to run other Linux games that expect a FHS environment. To use it, install the `steam-run-native` package and run the game with
|
||||
The FHS-compatible chroot used for Steam can also be used to run other Linux games that expect a FHS environment. To use it, install the `steam-run` package and run the game with
|
||||
|
||||
```
|
||||
steam-run ./foo
|
||||
|
|
|
@ -98,7 +98,7 @@ We use jbidwatcher as an example for a discontinued project here.
|
|||
1. Create a new branch for your change, e.g. `git checkout -b jbidwatcher`
|
||||
1. Remove the actual package including its directory, e.g. `rm -rf pkgs/applications/misc/jbidwatcher`
|
||||
1. Remove the package from the list of all packages (`pkgs/top-level/all-packages.nix`).
|
||||
1. Add an alias for the package name in `pkgs/top-level/aliases.nix` (There is also `pkgs/misc/vim-plugins/aliases.nix`. Package sets typically do not have aliases, so we can't add them there.)
|
||||
1. Add an alias for the package name in `pkgs/top-level/aliases.nix` (There is also `pkgs/applications/editors/vim/plugins/aliases.nix`. Package sets typically do not have aliases, so we can't add them there.)
|
||||
|
||||
For example in this case:
|
||||
|
||||
|
|
|
@ -29,7 +29,8 @@ The recommended way of defining a derivation for a Coq library, is to use the `c
|
|||
* `releaseRev` (optional, defaults to `(v: v)`), provides a default mapping from release names to revision hashes/branch names/tags,
|
||||
* `displayVersion` (optional), provides a way to alter the computation of `name` from `pname`, by explaining how to display version numbers,
|
||||
* `namePrefix` (optional, defaults to `[ "coq" ]`), provides a way to alter the computation of `name` from `pname`, by explaining which dependencies must occur in `name`,
|
||||
* `extraBuildInputs` (optional), by default `buildInputs` just contains `coq`, this allows to add more build inputs,
|
||||
* `extraNativeBuildInputs` (optional), by default `nativeBuildInputs` just contains `coq`, this allows to add more native build inputs, `nativeBuildInputs` are executables and `buildInputs` are libraries and dependencies,
|
||||
* `extraBuildInputs` (optional), this allows to add more build inputs,
|
||||
* `mlPlugin` (optional, defaults to `false`). Some extensions (plugins) might require OCaml and sometimes other OCaml packages. Standard dependencies can be added by setting the current option to `true`. For a finer grain control, the `coq.ocamlPackages` attribute can be used in `extraBuildInputs` to depend on the same package set Coq was built against.
|
||||
* `useDune2ifVersion` (optional, default to `(x: false)` uses Dune2 to build the package if the provided predicate evaluates to true on the version, e.g. `useDune2if = versions.isGe "1.1"` will use dune if the version of the package is greater or equal to `"1.1"`,
|
||||
* `useDune2` (optional, defaults to `false`) uses Dune2 to build the package if set to true, the presence of this attribute overrides the behavior of the previous one.
|
||||
|
|
|
@ -979,6 +979,31 @@ with import <nixpkgs> {};
|
|||
in python.withPackages(ps: [ps.blaze])).env
|
||||
```
|
||||
|
||||
#### Optional extra dependencies
|
||||
|
||||
Some packages define optional dependencies for additional features. With
|
||||
`setuptools` this is called `extras_require` and `flit` calls it `extras-require`. A
|
||||
method for supporting this is by declaring the extras of a package in its
|
||||
`passthru`, e.g. in case of the package `dask`
|
||||
|
||||
```nix
|
||||
passthru.extras-require = {
|
||||
complete = [ distributed ];
|
||||
};
|
||||
```
|
||||
|
||||
and letting the package requiring the extra add the list to its dependencies
|
||||
|
||||
```nix
|
||||
propagatedBuildInputs = [
|
||||
...
|
||||
] ++ dask.extras-require.complete;
|
||||
```
|
||||
|
||||
Note this method is preferred over adding parameters to builders, as that can
|
||||
result in packages depending on different variants and thereby causing
|
||||
collisions.
|
||||
|
||||
#### `buildPythonApplication` function {#buildpythonapplication-function}
|
||||
|
||||
The `buildPythonApplication` function is practically the same as
|
||||
|
|
|
@ -464,6 +464,8 @@ you of the correct hash.
|
|||
be disabled by setting `dontUseCargoParallelTests`.
|
||||
* `cargoInstallHook`: install binaries and static/shared libraries
|
||||
that were built using `cargoBuildHook`.
|
||||
* `bindgenHook`: for crates which use `bindgen` as a build dependency, lets
|
||||
`bindgen` find `libclang` and `libclang` find the libraries in `buildInputs`.
|
||||
|
||||
### Examples {#examples}
|
||||
|
||||
|
|
|
@ -309,9 +309,9 @@ Sample output2:
|
|||
|
||||
## Adding new plugins to nixpkgs {#adding-new-plugins-to-nixpkgs}
|
||||
|
||||
Nix expressions for Vim plugins are stored in [pkgs/misc/vim-plugins](https://github.com/NixOS/nixpkgs/tree/master/pkgs/misc/vim-plugins). For the vast majority of plugins, Nix expressions are automatically generated by running [`./update.py`](https://github.com/NixOS/nixpkgs/blob/master/pkgs/misc/vim-plugins/update.py). This creates a [generated.nix](https://github.com/NixOS/nixpkgs/blob/master/pkgs/misc/vim-plugins/generated.nix) file based on the plugins listed in [vim-plugin-names](https://github.com/NixOS/nixpkgs/blob/master/pkgs/misc/vim-plugins/vim-plugin-names). Plugins are listed in alphabetical order in `vim-plugin-names` using the format `[github username]/[repository]@[gitref]`. For example https://github.com/scrooloose/nerdtree becomes `scrooloose/nerdtree`.
|
||||
Nix expressions for Vim plugins are stored in [pkgs/applications/editors/vim/plugins](https://github.com/NixOS/nixpkgs/tree/master/pkgs/applications/editors/vim/plugins). For the vast majority of plugins, Nix expressions are automatically generated by running [`./update.py`](https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/editors/vim/plugins/update.py). This creates a [generated.nix](https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/editors/vim/plugins/generated.nix) file based on the plugins listed in [vim-plugin-names](https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/editors/vim/plugins/vim-plugin-names). Plugins are listed in alphabetical order in `vim-plugin-names` using the format `[github username]/[repository]@[gitref]`. For example https://github.com/scrooloose/nerdtree becomes `scrooloose/nerdtree`.
|
||||
|
||||
Some plugins require overrides in order to function properly. Overrides are placed in [overrides.nix](https://github.com/NixOS/nixpkgs/blob/master/pkgs/misc/vim-plugins/overrides.nix). Overrides are most often required when a plugin requires some dependencies, or extra steps are required during the build process. For example `deoplete-fish` requires both `deoplete-nvim` and `vim-fish`, and so the following override was added:
|
||||
Some plugins require overrides in order to function properly. Overrides are placed in [overrides.nix](https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/editors/vim/plugins/overrides.nix). Overrides are most often required when a plugin requires some dependencies, or extra steps are required during the build process. For example `deoplete-fish` requires both `deoplete-nvim` and `vim-fish`, and so the following override was added:
|
||||
|
||||
```nix
|
||||
deoplete-fish = super.deoplete-fish.overrideAttrs(old: {
|
||||
|
@ -330,13 +330,13 @@ Finally, there are some plugins that are also packaged in nodePackages because t
|
|||
Run the update script with a GitHub API token that has at least `public_repo` access. Running the script without the token is likely to result in rate-limiting (429 errors). For steps on creating an API token, please refer to [GitHub's token documentation](https://docs.github.com/en/free-pro-team@latest/github/authenticating-to-github/creating-a-personal-access-token).
|
||||
|
||||
```sh
|
||||
GITHUB_API_TOKEN=my_token ./pkgs/misc/vim-plugins/update.py
|
||||
GITHUB_API_TOKEN=my_token ./pkgs/applications/editors/vim/plugins/update.py
|
||||
```
|
||||
|
||||
Alternatively, set the number of processes to a lower count to avoid rate-limiting.
|
||||
|
||||
```sh
|
||||
./pkgs/misc/vim-plugins/update.py --proc 1
|
||||
./pkgs/applications/editors/vim/plugins/update.py --proc 1
|
||||
```
|
||||
|
||||
## Important repositories {#important-repositories}
|
||||
|
|
2
third_party/nixpkgs/lib/default.nix
vendored
2
third_party/nixpkgs/lib/default.nix
vendored
|
@ -126,7 +126,7 @@ let
|
|||
getValues getFiles
|
||||
optionAttrSetToDocList optionAttrSetToDocList'
|
||||
scrubOptionValue literalExpression literalExample literalDocBook
|
||||
showOption showFiles unknownModule mkOption;
|
||||
showOption showFiles unknownModule mkOption mkPackageOption;
|
||||
inherit (self.types) isType setType defaultTypeMerge defaultFunctor
|
||||
isOptionType mkOptionType;
|
||||
inherit (self.asserts)
|
||||
|
|
5
third_party/nixpkgs/lib/modules.nix
vendored
5
third_party/nixpkgs/lib/modules.nix
vendored
|
@ -138,7 +138,7 @@ rec {
|
|||
# support for that, in turn it's lazy in its values. This means e.g.
|
||||
# a `_module.args.pkgs = import (fetchTarball { ... }) {}` won't
|
||||
# start a download when `pkgs` wasn't evaluated.
|
||||
type = types.lazyAttrsOf types.unspecified;
|
||||
type = types.lazyAttrsOf types.raw;
|
||||
internal = true;
|
||||
description = "Arguments passed to each module.";
|
||||
};
|
||||
|
@ -151,8 +151,7 @@ rec {
|
|||
};
|
||||
|
||||
_module.freeformType = mkOption {
|
||||
# Disallow merging for now, but could be implemented nicely with a `types.optionType`
|
||||
type = types.nullOr (types.uniq types.attrs);
|
||||
type = types.nullOr types.optionType;
|
||||
internal = true;
|
||||
default = null;
|
||||
description = ''
|
||||
|
|
27
third_party/nixpkgs/lib/tests/modules.sh
vendored
27
third_party/nixpkgs/lib/tests/modules.sh
vendored
|
@ -240,6 +240,11 @@ checkConfigOutput '^"24"$' config.foo ./freeform-attrsOf.nix ./freeform-str-dep-
|
|||
checkConfigError 'infinite recursion encountered' config.foo ./freeform-attrsOf.nix ./freeform-unstr-dep-str.nix
|
||||
checkConfigError 'The option .* is used but not defined' config.foo ./freeform-lazyAttrsOf.nix ./freeform-unstr-dep-str.nix
|
||||
checkConfigOutput '^"24"$' config.foo ./freeform-lazyAttrsOf.nix ./freeform-unstr-dep-str.nix ./define-value-string.nix
|
||||
# submodules in freeformTypes should have their locations annotated
|
||||
checkConfigOutput '/freeform-submodules.nix"$' config.fooDeclarations.0 ./freeform-submodules.nix
|
||||
# freeformTypes can get merged using `types.type`, including submodules
|
||||
checkConfigOutput '^10$' config.free.xxx.foo ./freeform-submodules.nix
|
||||
checkConfigOutput '^10$' config.free.yyy.bar ./freeform-submodules.nix
|
||||
|
||||
## types.anything
|
||||
# Check that attribute sets are merged recursively
|
||||
|
@ -284,6 +289,28 @@ checkConfigOutput '^"a b"$' config.resultFoo ./declare-variants.nix ./define-var
|
|||
checkConfigOutput '^"a y z"$' config.resultFooBar ./declare-variants.nix ./define-variant.nix
|
||||
checkConfigOutput '^"a b c"$' config.resultFooFoo ./declare-variants.nix ./define-variant.nix
|
||||
|
||||
## emptyValue's
|
||||
checkConfigOutput "[ ]" config.list.a ./emptyValues.nix
|
||||
checkConfigOutput "{ }" config.attrs.a ./emptyValues.nix
|
||||
checkConfigOutput "null" config.null.a ./emptyValues.nix
|
||||
checkConfigOutput "{ }" config.submodule.a ./emptyValues.nix
|
||||
# These types don't have empty values
|
||||
checkConfigError 'The option .int.a. is used but not defined' config.int.a ./emptyValues.nix
|
||||
checkConfigError 'The option .nonEmptyList.a. is used but not defined' config.nonEmptyList.a ./emptyValues.nix
|
||||
|
||||
## types.raw
|
||||
checkConfigOutput "{ foo = <CODE>; }" config.unprocessedNesting ./raw.nix
|
||||
checkConfigOutput "10" config.processedToplevel ./raw.nix
|
||||
checkConfigError "The option .multiple. is defined multiple times" config.multiple ./raw.nix
|
||||
checkConfigOutput "bar" config.priorities ./raw.nix
|
||||
|
||||
# Test that types.optionType merges types correctly
|
||||
checkConfigOutput '^10$' config.theOption.int ./optionTypeMerging.nix
|
||||
checkConfigOutput '^"hello"$' config.theOption.str ./optionTypeMerging.nix
|
||||
|
||||
# Test that types.optionType correctly annotates option locations
|
||||
checkConfigError 'The option .theOption.nested. in .other.nix. is already declared in .optionTypeFile.nix.' config.theOption.nested ./optionTypeFile.nix
|
||||
|
||||
cat <<EOF
|
||||
====== module tests ======
|
||||
$pass Pass
|
||||
|
|
36
third_party/nixpkgs/lib/tests/modules/emptyValues.nix
vendored
Normal file
36
third_party/nixpkgs/lib/tests/modules/emptyValues.nix
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
{ lib, ... }:
|
||||
let
|
||||
inherit (lib) types;
|
||||
in {
|
||||
|
||||
options = {
|
||||
int = lib.mkOption {
|
||||
type = types.lazyAttrsOf types.int;
|
||||
};
|
||||
list = lib.mkOption {
|
||||
type = types.lazyAttrsOf (types.listOf types.int);
|
||||
};
|
||||
nonEmptyList = lib.mkOption {
|
||||
type = types.lazyAttrsOf (types.nonEmptyListOf types.int);
|
||||
};
|
||||
attrs = lib.mkOption {
|
||||
type = types.lazyAttrsOf (types.attrsOf types.int);
|
||||
};
|
||||
null = lib.mkOption {
|
||||
type = types.lazyAttrsOf (types.nullOr types.int);
|
||||
};
|
||||
submodule = lib.mkOption {
|
||||
type = types.lazyAttrsOf (types.submodule {});
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
int.a = lib.mkIf false null;
|
||||
list.a = lib.mkIf false null;
|
||||
nonEmptyList.a = lib.mkIf false null;
|
||||
attrs.a = lib.mkIf false null;
|
||||
null.a = lib.mkIf false null;
|
||||
submodule.a = lib.mkIf false null;
|
||||
};
|
||||
|
||||
}
|
22
third_party/nixpkgs/lib/tests/modules/freeform-submodules.nix
vendored
Normal file
22
third_party/nixpkgs/lib/tests/modules/freeform-submodules.nix
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
{ lib, options, ... }: with lib.types; {
|
||||
|
||||
options.fooDeclarations = lib.mkOption {
|
||||
default = (options.free.type.getSubOptions [])._freeformOptions.foo.declarations;
|
||||
};
|
||||
|
||||
options.free = lib.mkOption {
|
||||
type = submodule {
|
||||
config._module.freeformType = lib.mkMerge [
|
||||
(attrsOf (submodule {
|
||||
options.foo = lib.mkOption {};
|
||||
}))
|
||||
(attrsOf (submodule {
|
||||
options.bar = lib.mkOption {};
|
||||
}))
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
config.free.xxx.foo = 10;
|
||||
config.free.yyy.bar = 10;
|
||||
}
|
28
third_party/nixpkgs/lib/tests/modules/optionTypeFile.nix
vendored
Normal file
28
third_party/nixpkgs/lib/tests/modules/optionTypeFile.nix
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
{ config, lib, ... }: {
|
||||
|
||||
_file = "optionTypeFile.nix";
|
||||
|
||||
options.theType = lib.mkOption {
|
||||
type = lib.types.optionType;
|
||||
};
|
||||
|
||||
options.theOption = lib.mkOption {
|
||||
type = config.theType;
|
||||
default = {};
|
||||
};
|
||||
|
||||
config.theType = lib.mkMerge [
|
||||
(lib.types.submodule {
|
||||
options.nested = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
};
|
||||
})
|
||||
(lib.types.submodule {
|
||||
_file = "other.nix";
|
||||
options.nested = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
};
|
||||
})
|
||||
];
|
||||
|
||||
}
|
27
third_party/nixpkgs/lib/tests/modules/optionTypeMerging.nix
vendored
Normal file
27
third_party/nixpkgs/lib/tests/modules/optionTypeMerging.nix
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
{ config, lib, ... }: {
|
||||
|
||||
options.theType = lib.mkOption {
|
||||
type = lib.types.optionType;
|
||||
};
|
||||
|
||||
options.theOption = lib.mkOption {
|
||||
type = config.theType;
|
||||
};
|
||||
|
||||
config.theType = lib.mkMerge [
|
||||
(lib.types.submodule {
|
||||
options.int = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 10;
|
||||
};
|
||||
})
|
||||
(lib.types.submodule {
|
||||
options.str = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
};
|
||||
})
|
||||
];
|
||||
|
||||
config.theOption.str = "hello";
|
||||
|
||||
}
|
30
third_party/nixpkgs/lib/tests/modules/raw.nix
vendored
Normal file
30
third_party/nixpkgs/lib/tests/modules/raw.nix
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
{ lib, ... }: {
|
||||
|
||||
options = {
|
||||
processedToplevel = lib.mkOption {
|
||||
type = lib.types.raw;
|
||||
};
|
||||
unprocessedNesting = lib.mkOption {
|
||||
type = lib.types.raw;
|
||||
};
|
||||
multiple = lib.mkOption {
|
||||
type = lib.types.raw;
|
||||
};
|
||||
priorities = lib.mkOption {
|
||||
type = lib.types.raw;
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
processedToplevel = lib.mkIf true 10;
|
||||
unprocessedNesting.foo = throw "foo";
|
||||
multiple = lib.mkMerge [
|
||||
"foo"
|
||||
"foo"
|
||||
];
|
||||
priorities = lib.mkMerge [
|
||||
"foo"
|
||||
(lib.mkForce "bar")
|
||||
];
|
||||
};
|
||||
}
|
44
third_party/nixpkgs/lib/types.nix
vendored
44
third_party/nixpkgs/lib/types.nix
vendored
|
@ -61,7 +61,11 @@ let
|
|||
boolToString
|
||||
;
|
||||
|
||||
inherit (lib.modules) mergeDefinitions;
|
||||
inherit (lib.modules)
|
||||
mergeDefinitions
|
||||
fixupOptionType
|
||||
mergeOptionDecls
|
||||
;
|
||||
outer_types =
|
||||
rec {
|
||||
isType = type: x: (x._type or "") == type;
|
||||
|
@ -162,6 +166,13 @@ rec {
|
|||
# nixos/doc/manual/development/option-types.xml!
|
||||
types = rec {
|
||||
|
||||
raw = mkOptionType rec {
|
||||
name = "raw";
|
||||
description = "raw value";
|
||||
check = value: true;
|
||||
merge = mergeOneOption;
|
||||
};
|
||||
|
||||
anything = mkOptionType {
|
||||
name = "anything";
|
||||
description = "anything";
|
||||
|
@ -390,7 +401,7 @@ rec {
|
|||
).optionalValue
|
||||
) def.value
|
||||
) defs)));
|
||||
emptyValue = { value = {}; };
|
||||
emptyValue = { value = []; };
|
||||
getSubOptions = prefix: elemType.getSubOptions (prefix ++ ["*"]);
|
||||
getSubModules = elemType.getSubModules;
|
||||
substSubModules = m: listOf (elemType.substSubModules m);
|
||||
|
@ -402,7 +413,7 @@ rec {
|
|||
let list = addCheck (types.listOf elemType) (l: l != []);
|
||||
in list // {
|
||||
description = "non-empty " + list.description;
|
||||
# Note: emptyValue is left as is, because another module may define an element.
|
||||
emptyValue = { }; # no .value attr, meaning unset
|
||||
};
|
||||
|
||||
attrsOf = elemType: mkOptionType rec {
|
||||
|
@ -503,7 +514,7 @@ rec {
|
|||
|
||||
functionTo = elemType: mkOptionType {
|
||||
name = "functionTo";
|
||||
description = "function that evaluates to a(n) ${elemType.name}";
|
||||
description = "function that evaluates to a(n) ${elemType.description}";
|
||||
check = isFunction;
|
||||
merge = loc: defs:
|
||||
fnArgs: (mergeDefinitions (loc ++ [ "[function body]" ]) elemType (map (fn: { inherit (fn) file; value = fn.value fnArgs; }) defs)).mergedValue;
|
||||
|
@ -518,6 +529,31 @@ rec {
|
|||
modules = toList modules;
|
||||
};
|
||||
|
||||
# The type of a type!
|
||||
optionType = mkOptionType {
|
||||
name = "optionType";
|
||||
description = "optionType";
|
||||
check = value: value._type or null == "option-type";
|
||||
merge = loc: defs:
|
||||
let
|
||||
# Prepares the type definitions for mergeOptionDecls, which
|
||||
# annotates submodules types with file locations
|
||||
optionModules = map ({ value, file }:
|
||||
{
|
||||
_file = file;
|
||||
# There's no way to merge types directly from the module system,
|
||||
# but we can cheat a bit by just declaring an option with the type
|
||||
options = lib.mkOption {
|
||||
type = value;
|
||||
};
|
||||
}
|
||||
) defs;
|
||||
# Merges all the types into a single one, including submodule merging.
|
||||
# This also propagates file information to all submodules
|
||||
mergedOption = fixupOptionType loc (mergeOptionDecls loc optionModules);
|
||||
in mergedOption.type;
|
||||
};
|
||||
|
||||
submoduleWith =
|
||||
{ modules
|
||||
, specialArgs ? {}
|
||||
|
|
|
@ -2418,6 +2418,23 @@
|
|||
githubId = 5510514;
|
||||
name = "Conrad Mearns";
|
||||
};
|
||||
corbanr = {
|
||||
email = "corban@raunco.co";
|
||||
github = "CorbanR";
|
||||
githubId = 1918683;
|
||||
matrix = "@corbansolo:matrix.org";
|
||||
name = "Corban Raun";
|
||||
keys = [
|
||||
{
|
||||
longkeyid = "rsa4096/0xA697A56F1F151189";
|
||||
fingerprint = "6607 0B24 8CE5 64ED 22CE 0950 A697 A56F 1F15 1189";
|
||||
}
|
||||
{
|
||||
longkeyid = "ed25519/0x230F4AC153F90F29";
|
||||
fingerprint = "D8CB 816A B678 A4E6 1EC7 5325 230F 4AC1 53F9 0F29";
|
||||
}
|
||||
];
|
||||
};
|
||||
couchemar = {
|
||||
email = "couchemar@yandex.ru";
|
||||
github = "couchemar";
|
||||
|
@ -2993,6 +3010,12 @@
|
|||
githubId = 8404455;
|
||||
name = "Diego Lelis";
|
||||
};
|
||||
DieracDelta = {
|
||||
email = "justin@restivo.me";
|
||||
github = "DieracDelta";
|
||||
githubId = 13730968;
|
||||
name = "Justin Restivo";
|
||||
};
|
||||
diffumist = {
|
||||
email = "git@diffumist.me";
|
||||
github = "diffumist";
|
||||
|
@ -6327,6 +6350,12 @@
|
|||
githubId = 37185887;
|
||||
name = "Calvin Kim";
|
||||
};
|
||||
keldu = {
|
||||
email = "mail@keldu.de";
|
||||
github = "keldu";
|
||||
githubId = 15373888;
|
||||
name = "Claudius Holeksa";
|
||||
};
|
||||
kennyballou = {
|
||||
email = "kb@devnulllabs.io";
|
||||
github = "kennyballou";
|
||||
|
@ -6524,7 +6553,7 @@
|
|||
githubId = 18447310;
|
||||
};
|
||||
kloenk = {
|
||||
email = "me@kloenk.de";
|
||||
email = "me@kloenk.dev";
|
||||
matrix = "@kloenk:petabyte.dev";
|
||||
name = "Finn Behrens";
|
||||
github = "kloenk";
|
||||
|
@ -7898,12 +7927,6 @@
|
|||
github = "kira-bruneau";
|
||||
githubId = 382041;
|
||||
};
|
||||
meutraa = {
|
||||
email = "paul+nixpkgs@lost.host";
|
||||
name = "Paul Meredith";
|
||||
github = "meutraa";
|
||||
githubId = 68550871;
|
||||
};
|
||||
mephistophiles = {
|
||||
email = "mussitantesmortem@gmail.com";
|
||||
name = "Maxim Zhukov";
|
||||
|
@ -7946,6 +7969,12 @@
|
|||
githubId = 668926;
|
||||
name = "Maximilian Güntner";
|
||||
};
|
||||
mh = {
|
||||
email = "68288772+markus-heinrich@users.noreply.github.com";
|
||||
github = "markus-heinrich";
|
||||
githubId = 68288772;
|
||||
name = "Markus Heinrich";
|
||||
};
|
||||
mhaselsteiner = {
|
||||
email = "magdalena.haselsteiner@gmx.at";
|
||||
github = "mhaselsteiner";
|
||||
|
@ -8540,6 +8569,12 @@
|
|||
githubId = 9636071;
|
||||
name = "Myrl Hex";
|
||||
};
|
||||
n0emis = {
|
||||
email = "nixpkgs@n0emis.network";
|
||||
github = "n0emis";
|
||||
githubId = 22817873;
|
||||
name = "Ember Keske";
|
||||
};
|
||||
nadrieril = {
|
||||
email = "nadrieril@gmail.com";
|
||||
github = "nadrieril";
|
||||
|
@ -9253,6 +9288,12 @@
|
|||
githubId = 15930073;
|
||||
name = "Moritz Scheuren";
|
||||
};
|
||||
ozkutuk = {
|
||||
email = "ozkutuk@protonmail.com";
|
||||
github = "ozkutuk";
|
||||
githubId = 5948762;
|
||||
name = "Berk Özkütük";
|
||||
};
|
||||
pablovsky = {
|
||||
email = "dealberapablo07@gmail.com";
|
||||
github = "pablo1107";
|
||||
|
@ -10264,6 +10305,13 @@
|
|||
githubId = 6047658;
|
||||
name = "Ryan Horiguchi";
|
||||
};
|
||||
rhysmdnz = {
|
||||
email = "rhys@memes.nz";
|
||||
matrix = "@rhys:memes.nz";
|
||||
github = "rhysmdnz";
|
||||
githubId = 2162021;
|
||||
name = "Rhys Davies";
|
||||
};
|
||||
ribose-jeffreylau = {
|
||||
name = "Jeffrey Lau";
|
||||
email = "jeffrey.lau@ribose.com";
|
||||
|
@ -10940,6 +10988,12 @@
|
|||
githubId = 19472270;
|
||||
name = "Sebastian";
|
||||
};
|
||||
sebastianblunt = {
|
||||
name = "Sebastian Blunt";
|
||||
email = "nix@sebastianblunt.com";
|
||||
github = "sebastianblunt";
|
||||
githubId = 47431204;
|
||||
};
|
||||
sebbadk = {
|
||||
email = "sebastian@sebba.dk";
|
||||
github = "SEbbaDK";
|
||||
|
@ -11547,6 +11601,12 @@
|
|||
githubId = 1699155;
|
||||
name = "Steve Elliott";
|
||||
};
|
||||
stehessel = {
|
||||
email = "stephan@stehessel.de";
|
||||
github = "stehessel";
|
||||
githubId = 55607356;
|
||||
name = "Stephan Heßelmann";
|
||||
};
|
||||
stelcodes = {
|
||||
email = "stel@stel.codes";
|
||||
github = "stelcodes";
|
||||
|
@ -12792,9 +12852,9 @@
|
|||
githubId = 5837359;
|
||||
name = "Adrian Pistol";
|
||||
};
|
||||
vika_nezrimaya = {
|
||||
vikanezrimaya = {
|
||||
email = "vika@fireburn.ru";
|
||||
github = "kisik21";
|
||||
github = "vikanezrimaya";
|
||||
githubId = 7953163;
|
||||
name = "Vika Shleina";
|
||||
keys = [{
|
||||
|
@ -12818,6 +12878,12 @@
|
|||
githubId = 118959;
|
||||
name = "VinyMeuh";
|
||||
};
|
||||
viraptor = {
|
||||
email = "nix@viraptor.info";
|
||||
github = "viraptor";
|
||||
githubId = 188063;
|
||||
name = "Stanisław Pitucha";
|
||||
};
|
||||
viric = {
|
||||
email = "viric@viric.name";
|
||||
github = "viric";
|
||||
|
@ -13164,7 +13230,7 @@
|
|||
name = "Wayne Scott";
|
||||
};
|
||||
wucke13 = {
|
||||
email = "info@wucke13.de";
|
||||
email = "wucke13@gmail.com";
|
||||
github = "wucke13";
|
||||
githubId = 20400405;
|
||||
name = "Wucke";
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Used by pkgs/misc/vim-plugins/update.py and pkgs/applications/editors/kakoune/plugins/update.py
|
||||
# Used by pkgs/applications/editors/vim/plugins/update.py and pkgs/applications/editors/kakoune/plugins/update.py
|
||||
|
||||
# format:
|
||||
# $ nix run nixpkgs.python3Packages.black -c black update.py
|
||||
|
@ -73,9 +73,13 @@ def retry(ExceptionToCheck: Any, tries: int = 4, delay: float = 3, backoff: floa
|
|||
|
||||
return deco_retry
|
||||
|
||||
@dataclass
|
||||
class FetchConfig:
|
||||
proc: int
|
||||
github_token: str
|
||||
|
||||
def make_request(url: str) -> urllib.request.Request:
|
||||
token = os.getenv("GITHUB_API_TOKEN")
|
||||
|
||||
def make_request(url: str, token=None) -> urllib.request.Request:
|
||||
headers = {}
|
||||
if token is not None:
|
||||
headers["Authorization"] = f"token {token}"
|
||||
|
@ -90,6 +94,7 @@ class Repo:
|
|||
self.branch = branch
|
||||
self.alias = alias
|
||||
self.redirect: Dict[str, str] = {}
|
||||
self.token = "dummy_token"
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
|
@ -132,10 +137,11 @@ class Repo:
|
|||
|
||||
class RepoGitHub(Repo):
|
||||
def __init__(
|
||||
self, owner: str, repo: str, branch: str, alias: Optional[str]
|
||||
self, owner: str, repo: str, branch: str, alias: Optional[str]
|
||||
) -> None:
|
||||
self.owner = owner
|
||||
self.repo = repo
|
||||
self.token = None
|
||||
'''Url to the repo'''
|
||||
super().__init__(self.url(""), branch, alias)
|
||||
log.debug("Instantiating github repo %s/%s", self.owner, self.repo)
|
||||
|
@ -150,7 +156,7 @@ class RepoGitHub(Repo):
|
|||
@retry(urllib.error.URLError, tries=4, delay=3, backoff=2)
|
||||
def has_submodules(self) -> bool:
|
||||
try:
|
||||
req = make_request(self.url(f"blob/{self.branch}/.gitmodules"))
|
||||
req = make_request(self.url(f"blob/{self.branch}/.gitmodules"), self.token)
|
||||
urllib.request.urlopen(req, timeout=10).close()
|
||||
except urllib.error.HTTPError as e:
|
||||
if e.code == 404:
|
||||
|
@ -162,7 +168,7 @@ class RepoGitHub(Repo):
|
|||
@retry(urllib.error.URLError, tries=4, delay=3, backoff=2)
|
||||
def latest_commit(self) -> Tuple[str, datetime]:
|
||||
commit_url = self.url(f"commits/{self.branch}.atom")
|
||||
commit_req = make_request(commit_url)
|
||||
commit_req = make_request(commit_url, self.token)
|
||||
with urllib.request.urlopen(commit_req, timeout=10) as req:
|
||||
self._check_for_redirect(commit_url, req)
|
||||
xml = req.read()
|
||||
|
@ -291,15 +297,41 @@ class Editor:
|
|||
"""To fill the cache"""
|
||||
return get_current_plugins(self)
|
||||
|
||||
def load_plugin_spec(self, plugin_file) -> List[PluginDesc]:
|
||||
return load_plugin_spec(plugin_file)
|
||||
def load_plugin_spec(self, config: FetchConfig, plugin_file) -> List[PluginDesc]:
|
||||
plugins = []
|
||||
with open(plugin_file) as f:
|
||||
for line in f:
|
||||
if line.startswith("#"):
|
||||
continue
|
||||
plugin = parse_plugin_line(config, line)
|
||||
plugins.append(plugin)
|
||||
return plugins
|
||||
|
||||
def generate_nix(self, plugins, outfile: str):
|
||||
'''Returns nothing for now, writes directly to outfile'''
|
||||
raise NotImplementedError()
|
||||
|
||||
def get_update(self, input_file: str, outfile: str, proc: int):
|
||||
return get_update(input_file, outfile, proc, editor=self)
|
||||
def get_update(self, input_file: str, outfile: str, config: FetchConfig):
|
||||
cache: Cache = Cache(self.get_current_plugins(), self.cache_file)
|
||||
_prefetch = functools.partial(prefetch, cache=cache)
|
||||
|
||||
def update() -> dict:
|
||||
plugin_names = self.load_plugin_spec(config, input_file)
|
||||
|
||||
try:
|
||||
pool = Pool(processes=config.proc)
|
||||
results = pool.map(_prefetch, plugin_names)
|
||||
finally:
|
||||
cache.store()
|
||||
|
||||
plugins, redirects = check_results(results)
|
||||
|
||||
self.generate_nix(plugins, outfile)
|
||||
|
||||
return redirects
|
||||
|
||||
return update
|
||||
|
||||
|
||||
@property
|
||||
def attr_path(self):
|
||||
|
@ -345,7 +377,15 @@ class Editor:
|
|||
dest="proc",
|
||||
type=int,
|
||||
default=30,
|
||||
help="Number of concurrent processes to spawn. Export GITHUB_API_TOKEN allows higher values.",
|
||||
help="Number of concurrent processes to spawn. Setting --github-token allows higher values.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--github-token",
|
||||
"-t",
|
||||
type=str,
|
||||
default=os.getenv("GITHUB_API_TOKEN"),
|
||||
help="""Allows to set --proc to higher values.
|
||||
Uses GITHUB_API_TOKEN environment variables as the default value.""",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--no-commit", "-n", action="store_true", default=False,
|
||||
|
@ -414,8 +454,8 @@ def prefetch_plugin(
|
|||
)
|
||||
|
||||
|
||||
def fetch_plugin_from_pluginline(plugin_line: str) -> Plugin:
|
||||
plugin, _ = prefetch_plugin(parse_plugin_line(plugin_line))
|
||||
def fetch_plugin_from_pluginline(config: FetchConfig, plugin_line: str) -> Plugin:
|
||||
plugin, _ = prefetch_plugin(parse_plugin_line(config, plugin_line))
|
||||
return plugin
|
||||
|
||||
|
||||
|
@ -465,7 +505,7 @@ def make_repo(uri, branch, alias) -> Repo:
|
|||
repo = Repo(uri.strip(), branch, alias)
|
||||
return repo
|
||||
|
||||
def parse_plugin_line(line: str) -> PluginDesc:
|
||||
def parse_plugin_line(config: FetchConfig, line: str) -> PluginDesc:
|
||||
branch = "HEAD"
|
||||
alias = None
|
||||
uri = line
|
||||
|
@ -476,21 +516,11 @@ def parse_plugin_line(line: str) -> PluginDesc:
|
|||
uri, branch = uri.split("@")
|
||||
|
||||
repo = make_repo(uri.strip(), branch.strip(), alias)
|
||||
repo.token = config.github_token
|
||||
|
||||
return PluginDesc(repo, branch.strip(), alias)
|
||||
|
||||
|
||||
def load_plugin_spec(plugin_file: str) -> List[PluginDesc]:
|
||||
plugins = []
|
||||
with open(plugin_file) as f:
|
||||
for line in f:
|
||||
if line.startswith("#"):
|
||||
continue
|
||||
plugin = parse_plugin_line(line)
|
||||
plugins.append(plugin)
|
||||
return plugins
|
||||
|
||||
|
||||
def get_cache_path(cache_file_name: str) -> Optional[Path]:
|
||||
xdg_cache = os.environ.get("XDG_CACHE_HOME", None)
|
||||
if xdg_cache is None:
|
||||
|
@ -556,6 +586,7 @@ def prefetch(
|
|||
|
||||
|
||||
def rewrite_input(
|
||||
config: FetchConfig,
|
||||
input_file: Path,
|
||||
deprecated: Path,
|
||||
redirects: Dict[str, str] = None,
|
||||
|
@ -573,8 +604,8 @@ def rewrite_input(
|
|||
with open(deprecated, "r") as f:
|
||||
deprecations = json.load(f)
|
||||
for old, new in redirects.items():
|
||||
old_plugin = fetch_plugin_from_pluginline(old)
|
||||
new_plugin = fetch_plugin_from_pluginline(new)
|
||||
old_plugin = fetch_plugin_from_pluginline(config, old)
|
||||
new_plugin = fetch_plugin_from_pluginline(config, new)
|
||||
if old_plugin.normalized_name != new_plugin.normalized_name:
|
||||
deprecations[old_plugin.normalized_name] = {
|
||||
"new": new_plugin.normalized_name,
|
||||
|
@ -600,40 +631,21 @@ def commit(repo: git.Repo, message: str, files: List[Path]) -> None:
|
|||
print("no changes in working tree to commit")
|
||||
|
||||
|
||||
def get_update(input_file: str, outfile: str, proc: int, editor: Editor):
|
||||
cache: Cache = Cache(editor.get_current_plugins(), editor.cache_file)
|
||||
_prefetch = functools.partial(prefetch, cache=cache)
|
||||
|
||||
def update() -> dict:
|
||||
plugin_names = editor.load_plugin_spec(input_file)
|
||||
|
||||
try:
|
||||
pool = Pool(processes=proc)
|
||||
results = pool.map(_prefetch, plugin_names)
|
||||
finally:
|
||||
cache.store()
|
||||
|
||||
plugins, redirects = check_results(results)
|
||||
|
||||
editor.generate_nix(plugins, outfile)
|
||||
|
||||
return redirects
|
||||
|
||||
return update
|
||||
|
||||
|
||||
def update_plugins(editor: Editor, args):
|
||||
"""The main entry function of this module. All input arguments are grouped in the `Editor`."""
|
||||
|
||||
log.setLevel(LOG_LEVELS[args.debug])
|
||||
log.info("Start updating plugins")
|
||||
update = editor.get_update(args.input_file, args.outfile, args.proc)
|
||||
fetch_config = FetchConfig(args.proc, args.github_token)
|
||||
update = editor.get_update(args.input_file, args.outfile, fetch_config)
|
||||
|
||||
redirects = update()
|
||||
editor.rewrite_input(args.input_file, editor.deprecated, redirects)
|
||||
editor.rewrite_input(fetch_config, args.input_file, editor.deprecated, redirects)
|
||||
|
||||
autocommit = not args.no_commit
|
||||
|
||||
nixpkgs_repo = None
|
||||
if autocommit:
|
||||
nixpkgs_repo = git.Repo(editor.root, search_parent_directories=True)
|
||||
commit(nixpkgs_repo, f"{editor.attr_path}: update", [args.outfile])
|
||||
|
@ -648,9 +660,9 @@ def update_plugins(editor: Editor, args):
|
|||
)
|
||||
|
||||
for plugin_line in args.add_plugins:
|
||||
editor.rewrite_input(args.input_file, editor.deprecated, append=(plugin_line + "\n",))
|
||||
editor.rewrite_input(fetch_config, args.input_file, editor.deprecated, append=(plugin_line + "\n",))
|
||||
update()
|
||||
plugin = fetch_plugin_from_pluginline(plugin_line)
|
||||
plugin = fetch_plugin_from_pluginline(fetch_config, plugin_line)
|
||||
if autocommit:
|
||||
commit(
|
||||
nixpkgs_repo,
|
||||
|
|
202
third_party/nixpkgs/maintainers/scripts/remove-old-aliases.py
vendored
Executable file
202
third_party/nixpkgs/maintainers/scripts/remove-old-aliases.py
vendored
Executable file
|
@ -0,0 +1,202 @@
|
|||
#!/usr/bin/env nix-shell
|
||||
#!nix-shell -i python3 -p "python3.withPackages(ps: with ps; [ ])" nix
|
||||
"""
|
||||
A program to remove old aliases or convert old aliases to throws
|
||||
Example usage:
|
||||
./maintainers/scripts/remove-old-aliases.py --year 2018 --file ./pkgs/top-level/aliases.nix
|
||||
|
||||
Check this file with mypy after every change!
|
||||
$ mypy --strict maintainers/scripts/remove-old-aliases.py
|
||||
"""
|
||||
import argparse
|
||||
import shutil
|
||||
import subprocess
|
||||
from datetime import date as datetimedate
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def process_args() -> argparse.Namespace:
|
||||
"""process args"""
|
||||
arg_parser = argparse.ArgumentParser()
|
||||
arg_parser.add_argument(
|
||||
"--year", required=True, type=int, help="operate on aliases older than $year"
|
||||
)
|
||||
arg_parser.add_argument(
|
||||
"--month",
|
||||
type=int,
|
||||
default=1,
|
||||
help="operate on aliases older than $year-$month",
|
||||
)
|
||||
arg_parser.add_argument("--file", required=True, type=Path, help="alias file")
|
||||
arg_parser.add_argument(
|
||||
"--dry-run", action="store_true", help="don't modify files, only print results"
|
||||
)
|
||||
return arg_parser.parse_args()
|
||||
|
||||
|
||||
def get_date_lists(
|
||||
txt: list[str], cutoffdate: datetimedate
|
||||
) -> tuple[list[str], list[str], list[str]]:
|
||||
"""get a list of lines in which the date is older than $cutoffdate"""
|
||||
date_older_list: list[str] = []
|
||||
date_older_throw_list: list[str] = []
|
||||
date_sep_line_list: list[str] = []
|
||||
|
||||
for lineno, line in enumerate(txt, start=1):
|
||||
line = line.rstrip()
|
||||
my_date = None
|
||||
for string in line.split():
|
||||
string = string.strip(":")
|
||||
try:
|
||||
# strip ':' incase there is a string like 2019-11-01:
|
||||
my_date = datetime.strptime(string, "%Y-%m-%d").date()
|
||||
except ValueError:
|
||||
try:
|
||||
my_date = datetime.strptime(string, "%Y-%m").date()
|
||||
except ValueError:
|
||||
continue
|
||||
|
||||
if my_date is None or my_date > cutoffdate:
|
||||
continue
|
||||
|
||||
if "=" not in line:
|
||||
date_sep_line_list.append(f"{lineno} {line}")
|
||||
# 'if' lines could be complicated
|
||||
elif "if " in line and "if =" not in line:
|
||||
print(f"RESOLVE MANUALLY {line}")
|
||||
elif "throw" in line:
|
||||
date_older_throw_list.append(line)
|
||||
else:
|
||||
date_older_list.append(line)
|
||||
|
||||
return (
|
||||
date_older_list,
|
||||
date_sep_line_list,
|
||||
date_older_throw_list,
|
||||
)
|
||||
|
||||
|
||||
def convert_to_throw(date_older_list: list[str]) -> list[tuple[str, str]]:
|
||||
"""convert a list of lines to throws"""
|
||||
converted_list = []
|
||||
for line in date_older_list.copy():
|
||||
indent: str = " " * (len(line) - len(line.lstrip()))
|
||||
before_equal = ""
|
||||
after_equal = ""
|
||||
try:
|
||||
before_equal, after_equal = (x.strip() for x in line.split("=", maxsplit=2))
|
||||
except ValueError as err:
|
||||
print(err, line, "\n")
|
||||
date_older_list.remove(line)
|
||||
continue
|
||||
|
||||
alias = before_equal.strip()
|
||||
after_equal_list = [x.strip(";:") for x in after_equal.split()]
|
||||
|
||||
converted = (
|
||||
f"{indent}{alias} = throw \"'{alias}' has been renamed to/replaced by"
|
||||
f" '{after_equal_list.pop(0)}'\";"
|
||||
f' # Converted to throw {datetime.today().strftime("%Y-%m-%d")}'
|
||||
)
|
||||
converted_list.append((line, converted))
|
||||
|
||||
return converted_list
|
||||
|
||||
|
||||
def generate_text_to_write(
|
||||
txt: list[str],
|
||||
date_older_list: list[str],
|
||||
converted_to_throw: list[tuple[str, str]],
|
||||
date_older_throw_list: list[str],
|
||||
) -> list[str]:
|
||||
"""generate a list of text to be written to the aliasfile"""
|
||||
text_to_write: list[str] = []
|
||||
for line in txt:
|
||||
text_to_append: str = ""
|
||||
if converted_to_throw:
|
||||
for tupl in converted_to_throw:
|
||||
if line == tupl[0]:
|
||||
text_to_append = f"{tupl[1]}\n"
|
||||
if line not in date_older_list and line not in date_older_throw_list:
|
||||
text_to_append = f"{line}\n"
|
||||
if text_to_append:
|
||||
text_to_write.append(text_to_append)
|
||||
|
||||
return text_to_write
|
||||
|
||||
|
||||
def write_file(
|
||||
aliasfile: Path,
|
||||
text_to_write: list[str],
|
||||
) -> None:
|
||||
"""write file"""
|
||||
temp_aliasfile = Path(f"{aliasfile}.raliases")
|
||||
with open(temp_aliasfile, "w", encoding="utf-8") as far:
|
||||
for line in text_to_write:
|
||||
far.write(line)
|
||||
print("\nChecking the syntax of the new aliasfile")
|
||||
try:
|
||||
subprocess.run(
|
||||
["nix-instantiate", "--eval", temp_aliasfile],
|
||||
check=True,
|
||||
stdout=subprocess.DEVNULL,
|
||||
)
|
||||
except subprocess.CalledProcessError:
|
||||
print(
|
||||
"\nSyntax check failed,",
|
||||
"there may have been a line which only has\n"
|
||||
'aliasname = "reason why";\n'
|
||||
"when it should have been\n"
|
||||
'aliasname = throw "reason why";',
|
||||
)
|
||||
temp_aliasfile.unlink()
|
||||
return
|
||||
shutil.move(f"{aliasfile}.raliases", aliasfile)
|
||||
print(f"{aliasfile} modified! please verify with 'git diff'.")
|
||||
|
||||
|
||||
def main() -> None:
|
||||
"""main"""
|
||||
args = process_args()
|
||||
|
||||
aliasfile = Path(args.file).absolute()
|
||||
cutoffdate = (datetime.strptime(f"{args.year}-{args.month}-01", "%Y-%m-%d")).date()
|
||||
|
||||
txt: list[str] = (aliasfile.read_text(encoding="utf-8")).splitlines()
|
||||
|
||||
date_older_list: list[str] = []
|
||||
date_sep_line_list: list[str] = []
|
||||
date_older_throw_list: list[str] = []
|
||||
|
||||
date_older_list, date_sep_line_list, date_older_throw_list = get_date_lists(
|
||||
txt, cutoffdate
|
||||
)
|
||||
|
||||
converted_to_throw: list[tuple[str, str]] = []
|
||||
converted_to_throw = convert_to_throw(date_older_list)
|
||||
|
||||
if date_older_list:
|
||||
print(" Will be converted to throws. ".center(100, "-"))
|
||||
for l_n in date_older_list:
|
||||
print(l_n)
|
||||
|
||||
if date_older_throw_list:
|
||||
print(" Will be removed. ".center(100, "-"))
|
||||
for l_n in date_older_throw_list:
|
||||
print(l_n)
|
||||
|
||||
if date_sep_line_list:
|
||||
print(" On separate line, resolve manually. ".center(100, "-"))
|
||||
for l_n in date_sep_line_list:
|
||||
print(l_n)
|
||||
|
||||
if not args.dry_run:
|
||||
text_to_write = generate_text_to_write(
|
||||
txt, date_older_list, converted_to_throw, date_older_throw_list
|
||||
)
|
||||
write_file(aliasfile, text_to_write)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -147,7 +147,7 @@ let
|
|||
|
||||
to run update script for specific package, or
|
||||
|
||||
% nix-shell maintainers/scripts/update.nix --arg predicate '(path: pkg: builtins.isList pkg.updateScript && builtins.length pkg.updateScript >= 1 && (let script = builtins.head pkg.updateScript; in builtins.isAttrs script && script.name == "gnome-update-script"))'
|
||||
% nix-shell maintainers/scripts/update.nix --arg predicate '(path: pkg: pkg.updateScript.name or null == "gnome-update-script")'
|
||||
|
||||
to run update script for all packages matching given predicate, or
|
||||
|
||||
|
|
|
@ -88,6 +88,10 @@ async def commit_changes(name: str, merge_lock: asyncio.Lock, worktree: str, bra
|
|||
async with merge_lock:
|
||||
await check_subprocess('git', 'add', *change['files'], cwd=worktree)
|
||||
commit_message = '{attrPath}: {oldVersion} → {newVersion}'.format(**change)
|
||||
if 'commitMessage' in change:
|
||||
commit_message = change['commitMessage']
|
||||
elif 'commitBody' in change:
|
||||
commit_message = commit_message + '\n\n' + change['commitBody']
|
||||
await check_subprocess('git', 'commit', '--quiet', '-m', commit_message, cwd=worktree)
|
||||
await check_subprocess('git', 'cherry-pick', branch)
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@ with lib.maintainers; {
|
|||
DianaOlympos
|
||||
gleber
|
||||
happysalada
|
||||
minijackson
|
||||
yurrriq
|
||||
];
|
||||
scope = "Maintain BEAM-related packages and modules.";
|
||||
|
|
|
@ -145,26 +145,26 @@ As an example, we will take the case of display managers. There is a
|
|||
central display manager module for generic display manager options and a
|
||||
module file per display manager backend (sddm, gdm \...).
|
||||
|
||||
There are two approach to this module structure:
|
||||
There are two approaches we could take with this module structure:
|
||||
|
||||
- Managing the display managers independently by adding an enable
|
||||
- Configuring the display managers independently by adding an enable
|
||||
option to every display manager module backend. (NixOS)
|
||||
|
||||
- Managing the display managers in the central module by adding an
|
||||
option to select which display manager backend to use.
|
||||
- Configuring the display managers in the central module by adding
|
||||
an option to select which display manager backend to use.
|
||||
|
||||
Both approaches have problems.
|
||||
|
||||
Making backends independent can quickly become hard to manage. For
|
||||
display managers, there can be only one enabled at a time, but the type
|
||||
system can not enforce this restriction as there is no relation between
|
||||
each backend `enable` option. As a result, this restriction has to be
|
||||
done explicitely by adding assertions in each display manager backend
|
||||
module.
|
||||
display managers, there can only be one enabled at a time, but the
|
||||
type system cannot enforce this restriction as there is no relation
|
||||
between each backend's `enable` option. As a result, this restriction
|
||||
has to be done explicitly by adding assertions in each display manager
|
||||
backend module.
|
||||
|
||||
On the other hand, managing the display managers backends in the central
|
||||
module will require to change the central module option every time a new
|
||||
backend is added or removed.
|
||||
On the other hand, managing the display manager backends in the
|
||||
central module will require changing the central module option every
|
||||
time a new backend is added or removed.
|
||||
|
||||
By using extensible option types, it is possible to create a placeholder
|
||||
option in the central module
|
||||
|
@ -175,7 +175,7 @@ and to extend it in each backend module
|
|||
|
||||
As a result, `displayManager.enable` option values can be added without
|
||||
changing the main service module file and the type system automatically
|
||||
enforce that there can only be a single display manager enabled.
|
||||
enforces that there can only be a single display manager enabled.
|
||||
|
||||
::: {#ex-option-declaration-eot-service .example}
|
||||
::: {.title}
|
||||
|
|
|
@ -16,9 +16,9 @@ merging is handled.
|
|||
|
||||
`types.path`
|
||||
|
||||
: A filesystem path, defined as anything that when coerced to a string
|
||||
starts with a slash. Even if derivations can be considered as path,
|
||||
the more specific `types.package` should be preferred.
|
||||
: A filesystem path is anything that starts with a slash when
|
||||
coerced to a string. Even if derivations can be considered as
|
||||
paths, the more specific `types.package` should be preferred.
|
||||
|
||||
`types.package`
|
||||
|
||||
|
@ -63,6 +63,24 @@ merging is handled.
|
|||
```
|
||||
:::
|
||||
|
||||
`types.raw`
|
||||
|
||||
: A type which doesn't do any checking, merging or nested evaluation. It
|
||||
accepts a single arbitrary value that is not recursed into, making it
|
||||
useful for values coming from outside the module system, such as package
|
||||
sets or arbitrary data. Options of this type are still evaluated according
|
||||
to priorities and conditionals, so `mkForce`, `mkIf` and co. still work on
|
||||
the option value itself, but not for any value nested within it. This type
|
||||
should only be used when checking, merging and nested evaluation are not
|
||||
desirable.
|
||||
|
||||
`types.optionType`
|
||||
|
||||
: The type of an option's type. Its merging operation ensures that nested
|
||||
options have the correct file location annotated, and that if possible,
|
||||
multiple option definitions are correctly merged together. The main use
|
||||
case is as the type of the `_module.freeformType` option.
|
||||
|
||||
`types.attrs`
|
||||
|
||||
: A free-form attribute set.
|
||||
|
|
|
@ -66,6 +66,45 @@ have a predefined type and string generator already declared under
|
|||
and returning a set with TOML-specific attributes `type` and
|
||||
`generate` as specified [below](#pkgs-formats-result).
|
||||
|
||||
`pkgs.formats.elixirConf { elixir ? pkgs.elixir }`
|
||||
|
||||
: A function taking an attribute set with values
|
||||
|
||||
`elixir`
|
||||
|
||||
: The Elixir package which will be used to format the generated output
|
||||
|
||||
It returns a set with Elixir-Config-specific attributes `type`, `lib`, and
|
||||
`generate` as specified [below](#pkgs-formats-result).
|
||||
|
||||
The `lib` attribute contains functions to be used in settings, for
|
||||
generating special Elixir values:
|
||||
|
||||
`mkRaw elixirCode`
|
||||
|
||||
: Outputs the given string as raw Elixir code
|
||||
|
||||
`mkGetEnv { envVariable, fallback ? null }`
|
||||
|
||||
: Makes the configuration fetch an environment variable at runtime
|
||||
|
||||
`mkAtom atom`
|
||||
|
||||
: Outputs the given string as an Elixir atom, instead of the default
|
||||
Elixir binary string. Note: lowercase atoms still needs to be prefixed
|
||||
with `:`
|
||||
|
||||
`mkTuple array`
|
||||
|
||||
: Outputs the given array as an Elixir tuple, instead of the default
|
||||
Elixir list
|
||||
|
||||
`mkMap attrset`
|
||||
|
||||
: Outputs the given attribute set as an Elixir map, instead of the
|
||||
default Elixir keyword list
|
||||
|
||||
|
||||
::: {#pkgs-formats-result}
|
||||
These functions all return an attribute set with these values:
|
||||
:::
|
||||
|
@ -74,6 +113,12 @@ These functions all return an attribute set with these values:
|
|||
|
||||
: A module system type representing a value of the format
|
||||
|
||||
`lib`
|
||||
|
||||
: Utility functions for convenience, or special interactions with the format.
|
||||
This attribute is optional. It may contain inside a `types` attribute
|
||||
containing types specific to this format.
|
||||
|
||||
`generate` *`filename jsonValue`*
|
||||
|
||||
: A function that can render a value of the format to a file. Returns
|
||||
|
|
|
@ -41,17 +41,18 @@ checks:
|
|||
`RefuseManualStop` in the `[Unit]` section, and `X-OnlyManualStart` in the
|
||||
`[Unit]` section.
|
||||
|
||||
- The rest of the behavior is decided whether the unit has `X-StopIfChanged`
|
||||
in the `[Service]` section set (exposed via
|
||||
- Further behavior depends on the unit having `X-StopIfChanged` in the
|
||||
`[Service]` section set to `true` (exposed via
|
||||
[systemd.services.\<name\>.stopIfChanged](#opt-systemd.services)). This is
|
||||
set to `true` by default and must be explicitly turned off if not wanted.
|
||||
If the flag is enabled, the unit is **stop**ped and then **start**ed. If
|
||||
not, the unit is **restart**ed. The goal of the flag is to make sure that
|
||||
the new unit never runs in the old environment which is still in place
|
||||
before the activation script is run.
|
||||
before the activation script is run. This behavior is different when the
|
||||
service is socket-activated, as outlined in the following steps.
|
||||
|
||||
- The last thing that is taken into account is whether the unit is a service
|
||||
and socket-activated. Due to a bug, this is currently only done when
|
||||
`X-StopIfChanged` is set. If the unit is socket-activated, the socket is
|
||||
stopped and started, and the service is stopped and to be started by socket
|
||||
activation.
|
||||
and socket-activated. If `X-StopIfChanged` is **not** set, the service
|
||||
is **restart**ed with the others. If it is set, both the service and the
|
||||
socket are **stop**ped and the socket is **start**ed, leaving socket
|
||||
activation to start the service when it's needed.
|
||||
|
|
|
@ -215,21 +215,22 @@ lib.mkOption {
|
|||
manager backend (sddm, gdm ...).
|
||||
</para>
|
||||
<para>
|
||||
There are two approach to this module structure:
|
||||
There are two approaches we could take with this module
|
||||
structure:
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
Managing the display managers independently by adding an
|
||||
enable option to every display manager module backend.
|
||||
(NixOS)
|
||||
Configuring the display managers independently by adding
|
||||
an enable option to every display manager module
|
||||
backend. (NixOS)
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Managing the display managers in the central module by
|
||||
adding an option to select which display manager backend
|
||||
to use.
|
||||
Configuring the display managers in the central module
|
||||
by adding an option to select which display manager
|
||||
backend to use.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
@ -238,16 +239,16 @@ lib.mkOption {
|
|||
</para>
|
||||
<para>
|
||||
Making backends independent can quickly become hard to
|
||||
manage. For display managers, there can be only one enabled
|
||||
at a time, but the type system can not enforce this
|
||||
restriction as there is no relation between each backend
|
||||
manage. For display managers, there can only be one enabled
|
||||
at a time, but the type system cannot enforce this
|
||||
restriction as there is no relation between each backend’s
|
||||
<literal>enable</literal> option. As a result, this
|
||||
restriction has to be done explicitely by adding assertions
|
||||
restriction has to be done explicitly by adding assertions
|
||||
in each display manager backend module.
|
||||
</para>
|
||||
<para>
|
||||
On the other hand, managing the display managers backends in
|
||||
the central module will require to change the central module
|
||||
On the other hand, managing the display manager backends in
|
||||
the central module will require changing the central module
|
||||
option every time a new backend is added or removed.
|
||||
</para>
|
||||
<para>
|
||||
|
@ -268,7 +269,7 @@ lib.mkOption {
|
|||
<para>
|
||||
As a result, <literal>displayManager.enable</literal> option
|
||||
values can be added without changing the main service module
|
||||
file and the type system automatically enforce that there
|
||||
file and the type system automatically enforces that there
|
||||
can only be a single display manager enabled.
|
||||
</para>
|
||||
<anchor xml:id="ex-option-declaration-eot-service" />
|
||||
|
|
|
@ -30,10 +30,10 @@
|
|||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
A filesystem path, defined as anything that when coerced to
|
||||
a string starts with a slash. Even if derivations can be
|
||||
considered as path, the more specific
|
||||
<literal>types.package</literal> should be preferred.
|
||||
A filesystem path is anything that starts with a slash when
|
||||
coerced to a string. Even if derivations can be considered
|
||||
as paths, the more specific <literal>types.package</literal>
|
||||
should be preferred.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
@ -92,6 +92,39 @@
|
|||
</programlisting>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>types.raw</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
A type which doesn’t do any checking, merging or nested
|
||||
evaluation. It accepts a single arbitrary value that is not
|
||||
recursed into, making it useful for values coming from
|
||||
outside the module system, such as package sets or arbitrary
|
||||
data. Options of this type are still evaluated according to
|
||||
priorities and conditionals, so <literal>mkForce</literal>,
|
||||
<literal>mkIf</literal> and co. still work on the option
|
||||
value itself, but not for any value nested within it. This
|
||||
type should only be used when checking, merging and nested
|
||||
evaluation are not desirable.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>types.optionType</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The type of an option’s type. Its merging operation ensures
|
||||
that nested options have the correct file location
|
||||
annotated, and that if possible, multiple option definitions
|
||||
are correctly merged together. The main use case is as the
|
||||
type of the <literal>_module.freeformType</literal> option.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>types.attrs</literal>
|
||||
|
|
|
@ -137,6 +137,97 @@
|
|||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>pkgs.formats.elixirConf { elixir ? pkgs.elixir }</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
A function taking an attribute set with values
|
||||
</para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>elixir</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The Elixir package which will be used to format the
|
||||
generated output
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<para>
|
||||
It returns a set with Elixir-Config-specific attributes
|
||||
<literal>type</literal>, <literal>lib</literal>, and
|
||||
<literal>generate</literal> as specified
|
||||
<link linkend="pkgs-formats-result">below</link>.
|
||||
</para>
|
||||
<para>
|
||||
The <literal>lib</literal> attribute contains functions to
|
||||
be used in settings, for generating special Elixir values:
|
||||
</para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>mkRaw elixirCode</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Outputs the given string as raw Elixir code
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>mkGetEnv { envVariable, fallback ? null }</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Makes the configuration fetch an environment variable
|
||||
at runtime
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>mkAtom atom</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Outputs the given string as an Elixir atom, instead of
|
||||
the default Elixir binary string. Note: lowercase
|
||||
atoms still needs to be prefixed with
|
||||
<literal>:</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>mkTuple array</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Outputs the given array as an Elixir tuple, instead of
|
||||
the default Elixir list
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>mkMap attrset</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Outputs the given attribute set as an Elixir map,
|
||||
instead of the default Elixir keyword list
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<para xml:id="pkgs-formats-result">
|
||||
These functions all return an attribute set with these values:
|
||||
|
@ -152,6 +243,19 @@
|
|||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>lib</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Utility functions for convenience, or special interactions
|
||||
with the format. This attribute is optional. It may contain
|
||||
inside a <literal>types</literal> attribute containing types
|
||||
specific to this format.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>generate</literal>
|
||||
|
|
|
@ -88,9 +88,10 @@
|
|||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The rest of the behavior is decided whether the unit has
|
||||
Further behavior depends on the unit having
|
||||
<literal>X-StopIfChanged</literal> in the
|
||||
<literal>[Service]</literal> section set (exposed via
|
||||
<literal>[Service]</literal> section set to
|
||||
<literal>true</literal> (exposed via
|
||||
<link linkend="opt-systemd.services">systemd.services.<name>.stopIfChanged</link>).
|
||||
This is set to <literal>true</literal> by default and must
|
||||
be explicitly turned off if not wanted. If the flag is
|
||||
|
@ -100,17 +101,22 @@
|
|||
is <emphasis role="strong">restart</emphasis>ed. The goal of
|
||||
the flag is to make sure that the new unit never runs in the
|
||||
old environment which is still in place before the
|
||||
activation script is run.
|
||||
activation script is run. This behavior is different when
|
||||
the service is socket-activated, as outlined in the
|
||||
following steps.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The last thing that is taken into account is whether the
|
||||
unit is a service and socket-activated. Due to a bug, this
|
||||
is currently only done when
|
||||
<literal>X-StopIfChanged</literal> is set. If the unit is
|
||||
socket-activated, the socket is stopped and started, and the
|
||||
service is stopped and to be started by socket activation.
|
||||
unit is a service and socket-activated. If
|
||||
<literal>X-StopIfChanged</literal> is
|
||||
<emphasis role="strong">not</emphasis> set, the service is
|
||||
<emphasis role="strong">restart</emphasis>ed with the
|
||||
others. If it is set, both the service and the socket are
|
||||
<emphasis role="strong">stop</emphasis>ped and the socket is
|
||||
<emphasis role="strong">start</emphasis>ed, leaving socket
|
||||
activation to start the service when it’s needed.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
|
|
@ -26,8 +26,26 @@
|
|||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>iptables</literal> now uses
|
||||
<literal>nf_tables</literal> backend.
|
||||
<literal>iptables</literal> is now using
|
||||
<literal>nf_tables</literal> under the hood, by using
|
||||
<literal>iptables-nft</literal>, similar to
|
||||
<link xlink:href="https://wiki.debian.org/nftables#Current_status">Debian</link>
|
||||
and
|
||||
<link xlink:href="https://fedoraproject.org/wiki/Changes/iptables-nft-default">Fedora</link>.
|
||||
This means, <literal>ip[6]tables</literal>,
|
||||
<literal>arptables</literal> and <literal>ebtables</literal>
|
||||
commands will actually show rules from some specific tables in
|
||||
the <literal>nf_tables</literal> kernel subsystem.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
systemd got an <literal>nftables</literal> backend, and
|
||||
configures (networkd) rules in their own
|
||||
<literal>io.systemd.*</literal> tables. Check
|
||||
<literal>nft list ruleset</literal> to see these rules, not
|
||||
<literal>iptables-save</literal> (which only shows
|
||||
<literal>iptables</literal>-created rules.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
|
@ -1429,6 +1447,17 @@ Superuser created successfully.
|
|||
knob.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>/usr</literal> will always be included in the initial
|
||||
ramdisk. See the
|
||||
<literal>fileSystems.<name>.neededForBoot</literal>
|
||||
option. If any files exist under <literal>/usr</literal>
|
||||
(which is not typical for NixOS), they will be included in the
|
||||
initial ramdisk, increasing its size to a possibly problematic
|
||||
extent.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
<section xml:id="sec-release-21.11-notable-changes">
|
||||
|
|
|
@ -50,6 +50,18 @@
|
|||
granular distinction between reloads and restarts.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<link xlink:href="https://kops.sigs.k8s.io"><literal>kops</literal></link>
|
||||
defaults to 1.22.4, which will enable
|
||||
<link xlink:href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html">Instance
|
||||
Metadata Service Version 2</link> and require tokens on new
|
||||
clusters with Kubernetes 1.22. This will increase security by
|
||||
default, but may break some types of workloads. See the
|
||||
<link xlink:href="https://kops.sigs.k8s.io/releases/1.22-notes/">release
|
||||
notes</link> for details.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
<section xml:id="sec-release-22.05-new-services">
|
||||
|
@ -98,7 +110,7 @@
|
|||
<link xlink:href="https://frrouting.org/">FRRouting</link>, a
|
||||
popular suite of Internet routing protocol daemons (BGP, BFD,
|
||||
OSPF, IS-IS, VVRP and others). Available as
|
||||
<link linkend="opt-services.ffr.babel.enable">services.frr</link>
|
||||
<link linkend="opt-services.frr.babel.enable">services.frr</link>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
|
@ -108,6 +120,13 @@
|
|||
<link xlink:href="options.html#opt-services.heisenbridge.enable">services.heisenbridge</link>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<link xlink:href="https://snowflake.torproject.org/">snowflake-proxy</link>,
|
||||
a system to defeat internet censorship. Available as
|
||||
<link xlink:href="options.html#opt-services.snowflake-proxy.enable">services.snowflake-proxy</link>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<link xlink:href="https://ergo.chat">ergochat</link>, a modern
|
||||
|
@ -122,6 +141,13 @@
|
|||
<link xlink:href="options.html#opt-services.powerdns-admin.enable">services.powerdns-admin</link>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<link xlink:href="https://github.com/postgres/pgadmin4">pgadmin4</link>,
|
||||
an admin interface for the PostgreSQL database. Available at
|
||||
<link xlink:href="options.html#opt-services.pgadmin.enable">services.pgadmin</link>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<link xlink:href="https://github.com/sezanzeb/input-remapper">input-remapper</link>,
|
||||
|
@ -145,6 +171,15 @@
|
|||
<link xlink:href="options.html#opt-services.maddy.enable">services.maddy</link>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<link xlink:href="https://www.scorchworks.com/K40whisperer/k40whisperer.html">K40-Whisperer</link>,
|
||||
a program to control cheap Chinese laser cutters. Available as
|
||||
<link xlink:href="options.html#opt-programs.k4-whisperer.enable">programs.k40-whisperer.enable</link>.
|
||||
Users must add themselves to the <literal>k40</literal> group
|
||||
to be able to access the device.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<link xlink:href="https://github.com/mgumz/mtr-exporter">mtr-exporter</link>,
|
||||
|
@ -196,7 +231,7 @@
|
|||
<para>
|
||||
<link xlink:href="https://moosefs.com">moosefs</link>, fault
|
||||
tolerant petabyte distributed file system. Available as
|
||||
<link linkend="opt-services.moosefs">moosefs</link>.
|
||||
<link linkend="opt-services.moosefs.client.enable">moosefs</link>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
|
@ -353,6 +388,116 @@
|
|||
its reliance on python2.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The <literal>matrix-synapse</literal> service
|
||||
(<literal>services.matrix-synapse</literal>) has been
|
||||
converted to use the <literal>settings</literal> option
|
||||
defined in RFC42. This means that options that are part of
|
||||
your <literal>homeserver.yaml</literal> configuration, and
|
||||
that were specified at the top-level of the module
|
||||
(<literal>services.matrix-synapse</literal>) now need to be
|
||||
moved into
|
||||
<literal>services.matrix-synapse.settings</literal>. And while
|
||||
not all options you may use are defined in there, they are
|
||||
still supported, because you can set arbitrary values in this
|
||||
freeform type.
|
||||
</para>
|
||||
<para>
|
||||
An example to make the required migration clearer:
|
||||
</para>
|
||||
<para>
|
||||
Before:
|
||||
</para>
|
||||
<programlisting language="bash">
|
||||
{
|
||||
services.matrix-synapse = {
|
||||
enable = true;
|
||||
|
||||
server_name = "example.com";
|
||||
public_baseurl = "https://example.com:8448";
|
||||
|
||||
enable_registration = false;
|
||||
registration_shared_secret = "xohshaeyui8jic7uutuDogahkee3aehuaf6ei3Xouz4iicie5thie6nohNahceut";
|
||||
macaroon_secret_key = "xoo8eder9seivukaiPh1cheikohquuw8Yooreid0The4aifahth3Ou0aiShaiz4l";
|
||||
|
||||
tls_certificate_path = "/var/lib/acme/example.com/fullchain.pem";
|
||||
tls_certificate_path = "/var/lib/acme/example.com/fullchain.pem";
|
||||
|
||||
listeners = [ {
|
||||
port = 8448;
|
||||
bind_address = "";
|
||||
type = "http";
|
||||
tls = true;
|
||||
resources = [ {
|
||||
names = [ "client" ];
|
||||
compress = true;
|
||||
} {
|
||||
names = [ "federation" ];
|
||||
compress = false;
|
||||
} ];
|
||||
} ];
|
||||
|
||||
};
|
||||
}
|
||||
</programlisting>
|
||||
<para>
|
||||
After:
|
||||
</para>
|
||||
<programlisting language="bash">
|
||||
{
|
||||
services.matrix-synapse = {
|
||||
enable = true;
|
||||
|
||||
# this attribute set holds all values that go into your homeserver.yaml configuration
|
||||
# See https://github.com/matrix-org/synapse/blob/develop/docs/sample_config.yaml for
|
||||
# possible values.
|
||||
settings = {
|
||||
server_name = "example.com";
|
||||
public_baseurl = "https://example.com:8448";
|
||||
|
||||
enable_registration = false;
|
||||
# pass `registration_shared_secret` and `macaroon_secret_key` via `extraConfigFiles` instead
|
||||
|
||||
tls_certificate_path = "/var/lib/acme/example.com/fullchain.pem";
|
||||
tls_certificate_path = "/var/lib/acme/example.com/fullchain.pem";
|
||||
|
||||
listeners = [ {
|
||||
port = 8448;
|
||||
bind_address = [
|
||||
"::"
|
||||
"0.0.0.0"
|
||||
];
|
||||
type = "http";
|
||||
tls = true;
|
||||
resources = [ {
|
||||
names = [ "client" ];
|
||||
compress = true;
|
||||
} {
|
||||
names = [ "federation" ];
|
||||
compress = false;
|
||||
} ];
|
||||
} ];
|
||||
};
|
||||
|
||||
extraConfigFiles = [
|
||||
/run/keys/matrix-synapse/secrets.yaml
|
||||
];
|
||||
};
|
||||
}
|
||||
</programlisting>
|
||||
<para>
|
||||
The secrets in your original config should be migrated into a
|
||||
YAML file that is included via
|
||||
<literal>extraConfigFiles</literal>.
|
||||
</para>
|
||||
<para>
|
||||
Additionally a few option defaults have been synced up with
|
||||
upstream default values, for example the
|
||||
<literal>max_upload_size</literal> grew from
|
||||
<literal>10M</literal> to <literal>50M</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The MoinMoin wiki engine
|
||||
|
@ -444,6 +589,13 @@
|
|||
support due to python2 deprecation in nixpkgs
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>services.miniflux.adminCredentialFiles</literal> is
|
||||
now required, instead of defaulting to
|
||||
<literal>admin</literal> and <literal>password</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The <literal>autorestic</literal> package has been upgraded
|
||||
|
@ -530,6 +682,21 @@
|
|||
<literal>tilp2</literal> was removed together with its module
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The F-PROT antivirus (<literal>fprot</literal> package) and
|
||||
its service module were removed because it reached
|
||||
<link xlink:href="https://kb.cyren.com/av-support/index.php?/Knowledgebase/Article/View/434/0/end-of-sale--end-of-life-for-f-prot-and-csam">end-of-life</link>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>bird1</literal> and its modules
|
||||
<literal>services.bird</literal> as well as
|
||||
<literal>services.bird6</literal> have been removed. Upgrade
|
||||
to <literal>services.bird2</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The options
|
||||
|
@ -558,6 +725,15 @@
|
|||
<literal>~/.local/share/polymc/polymc.cfg</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>systemd-nspawn@.service</literal> settings have been
|
||||
reverted to the default systemd behaviour. User namespaces are
|
||||
now activated by default. If you want to keep running nspawn
|
||||
containers without user namespaces you need to set
|
||||
<literal>systemd.nspawn.<name>.execConfig.PrivateUsers = false</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The terraform 0.12 compatibility has been removed and the
|
||||
|
@ -590,6 +766,13 @@
|
|||
<literal>otelcorecol</literal> and enjoy a 7x smaller binary.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>pkgs.pgadmin</literal> now refers to
|
||||
<literal>pkgs.pgadmin4</literal>. If you still need pgadmin3,
|
||||
use <literal>pkgs.pgadmin3</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>pkgs.noto-fonts-cjk</literal> is now deprecated in
|
||||
|
@ -700,6 +883,83 @@
|
|||
<link xlink:href="https://github.com/olimorris/onedarkpro.nvim">olimorris/onedarkpro.nvim</link>).
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>services.pipewire.enable</literal> will default to
|
||||
enabling the WirePlumber session manager instead of
|
||||
pipewire-media-session. pipewire-media-session is deprecated
|
||||
by upstream and not recommended, but can still be manually
|
||||
enabled by setting
|
||||
<literal>services.pipewire.media-session.enable</literal> to
|
||||
<literal>true</literal> and
|
||||
<literal>services.pipewire.wireplumber.enable</literal> to
|
||||
<literal>false</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>pkgs.makeDesktopItem</literal> has been refactored to
|
||||
provide a more idiomatic API. Specifically:
|
||||
</para>
|
||||
<itemizedlist spacing="compact">
|
||||
<listitem>
|
||||
<para>
|
||||
All valid options as of FDO Desktop Entry specification
|
||||
version 1.4 can now be passed in as explicit arguments
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>exec</literal> can now be null, for entries that
|
||||
are not of type Application
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>mimeType</literal> argument is renamed to
|
||||
<literal>mimeTypes</literal> for consistency
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>mimeTypes</literal>,
|
||||
<literal>categories</literal>,
|
||||
<literal>implements</literal>,
|
||||
<literal>keywords</literal>, <literal>onlyShowIn</literal>
|
||||
and <literal>notShowIn</literal> take lists of strings
|
||||
instead of one string with semicolon separators
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>extraDesktopEntries</literal> renamed to
|
||||
<literal>extraConfig</literal> for consistency
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Actions should now be provided as an attrset
|
||||
<literal>actions</literal>, the <literal>Actions</literal>
|
||||
line will be autogenerated.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>extraEntries</literal> is removed.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Additional validation is added both at eval time and at
|
||||
build time.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<para>
|
||||
See the <literal>vscode</literal> package for a more detailed
|
||||
example.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
<section xml:id="sec-release-22.05-notable-changes">
|
||||
|
@ -901,6 +1161,16 @@
|
|||
<literal>true</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The <literal>element-desktop</literal> package now has an
|
||||
<literal>useKeytar</literal> option (defaults to
|
||||
<literal>true</literal>), which allows disabling
|
||||
<literal>keytar</literal> and in turn
|
||||
<literal>libsecret</literal> usage (which binds to native
|
||||
credential managers / keychain libraries).
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The option <literal>services.thelounge.plugins</literal> has
|
||||
|
@ -916,6 +1186,14 @@
|
|||
renamed to <literal>linux-firmware</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
It is now possible to specify wordlists to include as handy to
|
||||
access environment variables using the
|
||||
<literal>config.environment.wordlist</literal> configuration
|
||||
options.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The <literal>services.mbpfan</literal> module was converted to
|
||||
|
@ -954,6 +1232,13 @@
|
|||
Plugins are automatically repackaged using autoPatchelf.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>services.logrotate.enable</literal> now defaults to
|
||||
true if any rotate path has been defined, and some paths have
|
||||
been added by default.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The <literal>zrepl</literal> package has been updated from
|
||||
|
@ -990,10 +1275,20 @@
|
|||
warning.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The <literal>pomerium-cli</literal> command has been moved out
|
||||
of the <literal>pomerium</literal> package into the
|
||||
<literal>pomerium-cli</literal> package, following upstream’s
|
||||
repository split. If you are using the
|
||||
<literal>pomerium-cli</literal> command, you should now
|
||||
install the <literal>pomerium-cli</literal> package.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The option
|
||||
<link linkend="opt-services.networking.networkmanager.enableFccUnlock">services.networking.networkmanager.enableFccUnlock</link>
|
||||
<link linkend="opt-networking.networkmanager.enableFccUnlock">services.networking.networkmanager.enableFccUnlock</link>
|
||||
was added to support FCC unlock procedures. Since release
|
||||
1.18.4, the ModemManager daemon no longer automatically
|
||||
performs the FCC unlock procedure by default. See
|
||||
|
@ -1010,6 +1305,14 @@
|
|||
<literal>tmux</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The polkit service, available at
|
||||
<literal>security.polkit.enable</literal>, is now disabled by
|
||||
default. It will automatically be enabled through services and
|
||||
desktop environments as needed.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
</section>
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
This section lists the release notes for each stable version of NixOS and
|
||||
current unstable revision.
|
||||
</para>
|
||||
<xi:include href="../from_md/release-notes/rl-2205.section.xml" />
|
||||
<xi:include href="../from_md/release-notes/rl-2111.section.xml" />
|
||||
<xi:include href="../from_md/release-notes/rl-2105.section.xml" />
|
||||
<xi:include href="../from_md/release-notes/rl-2009.section.xml" />
|
||||
|
|
|
@ -8,7 +8,15 @@ In addition to numerous new and upgraded packages, this release has the followin
|
|||
|
||||
- Nix has been updated to version 2.4, reference its [release notes](https://discourse.nixos.org/t/nix-2-4-released/15822) for more information on what has changed. The previous version of Nix, 2.3.16, remains available for the time being in the `nix_2_3` package.
|
||||
|
||||
- `iptables` now uses `nf_tables` backend.
|
||||
- `iptables` is now using `nf_tables` under the hood, by using `iptables-nft`,
|
||||
similar to [Debian](https://wiki.debian.org/nftables#Current_status) and
|
||||
[Fedora](https://fedoraproject.org/wiki/Changes/iptables-nft-default).
|
||||
This means, `ip[6]tables`, `arptables` and `ebtables` commands will actually
|
||||
show rules from some specific tables in the `nf_tables` kernel subsystem.
|
||||
|
||||
- systemd got an `nftables` backend, and configures (networkd) rules in their
|
||||
own `io.systemd.*` tables. Check `nft list ruleset` to see these rules, not
|
||||
`iptables-save` (which only shows `iptables`-created rules.
|
||||
|
||||
- PHP now defaults to PHP 8.0, updated from 7.4.
|
||||
|
||||
|
@ -419,6 +427,9 @@ In addition to numerous new and upgraded packages, this release has the followin
|
|||
|
||||
- The Linux kernel for security reasons now restricts access to BPF syscalls via `BPF_UNPRIV_DEFAULT_OFF=y`. Unprivileged access can be reenabled via the `kernel.unprivileged_bpf_disabled` sysctl knob.
|
||||
|
||||
- `/usr` will always be included in the initial ramdisk. See the `fileSystems.<name>.neededForBoot` option.
|
||||
If any files exist under `/usr` (which is not typical for NixOS), they will be included in the initial ramdisk, increasing its size to a possibly problematic extent.
|
||||
|
||||
## Other Notable Changes {#sec-release-21.11-notable-changes}
|
||||
|
||||
|
||||
|
|
|
@ -19,6 +19,8 @@ In addition to numerous new and upgraded packages, this release has the followin
|
|||
|
||||
- systemd services can now set [systemd.services.\<name\>.reloadTriggers](#opt-systemd.services) instead of `reloadIfChanged` for a more granular distinction between reloads and restarts.
|
||||
|
||||
- [`kops`](https://kops.sigs.k8s.io) defaults to 1.22.4, which will enable [Instance Metadata Service Version 2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html) and require tokens on new clusters with Kubernetes 1.22. This will increase security by default, but may break some types of workloads. See the [release notes](https://kops.sigs.k8s.io/releases/1.22-notes/) for details.
|
||||
|
||||
## New Services {#sec-release-22.05-new-services}
|
||||
|
||||
- [aesmd](https://github.com/intel/linux-sgx#install-the-intelr-sgx-psw), the Intel SGX Architectural Enclave Service Manager. Available as [services.aesmd](#opt-services.aesmd.enable).
|
||||
|
@ -31,20 +33,26 @@ In addition to numerous new and upgraded packages, this release has the followin
|
|||
|
||||
- [apfs](https://github.com/linux-apfs/linux-apfs-rw), a kernel module for mounting the Apple File System (APFS).
|
||||
|
||||
- [FRRouting](https://frrouting.org/), a popular suite of Internet routing protocol daemons (BGP, BFD, OSPF, IS-IS, VVRP and others). Available as [services.frr](#opt-services.ffr.babel.enable)
|
||||
- [FRRouting](https://frrouting.org/), a popular suite of Internet routing protocol daemons (BGP, BFD, OSPF, IS-IS, VVRP and others). Available as [services.frr](#opt-services.frr.babel.enable)
|
||||
|
||||
- [heisenbridge](https://github.com/hifi/heisenbridge), a bouncer-style Matrix IRC bridge. Available as [services.heisenbridge](options.html#opt-services.heisenbridge.enable).
|
||||
|
||||
- [snowflake-proxy](https://snowflake.torproject.org/), a system to defeat internet censorship. Available as [services.snowflake-proxy](options.html#opt-services.snowflake-proxy.enable).
|
||||
|
||||
- [ergochat](https://ergo.chat), a modern IRC with IRCv3 features. Available as [services.ergochat](options.html#opt-services.ergochat.enable).
|
||||
|
||||
- [PowerDNS-Admin](https://github.com/ngoduykhanh/PowerDNS-Admin), a web interface for the PowerDNS server. Available at [services.powerdns-admin](options.html#opt-services.powerdns-admin.enable).
|
||||
|
||||
- [pgadmin4](https://github.com/postgres/pgadmin4), an admin interface for the PostgreSQL database. Available at [services.pgadmin](options.html#opt-services.pgadmin.enable).
|
||||
|
||||
- [input-remapper](https://github.com/sezanzeb/input-remapper), an easy to use tool to change the mapping of your input device buttons. Available at [services.input-remapper](options.html#opt-services.input-remapper.enable).
|
||||
|
||||
- [InvoicePlane](https://invoiceplane.com), web application for managing and creating invoices. Available at [services.invoiceplane](options.html#opt-services.invoiceplane.enable).
|
||||
|
||||
- [maddy](https://maddy.email), a composable all-in-one mail server. Available as [services.maddy](options.html#opt-services.maddy.enable).
|
||||
|
||||
- [K40-Whisperer](https://www.scorchworks.com/K40whisperer/k40whisperer.html), a program to control cheap Chinese laser cutters. Available as [programs.k40-whisperer.enable](options.html#opt-programs.k4-whisperer.enable). Users must add themselves to the `k40` group to be able to access the device.
|
||||
|
||||
- [mtr-exporter](https://github.com/mgumz/mtr-exporter), a Prometheus exporter for mtr metrics. Available as [services.mtr-exporter](options.html#opt-services.mtr-exporter.enable).
|
||||
|
||||
- [tetrd](https://tetrd.app), share your internet connection from your device to your PC and vice versa through a USB cable. Available at [services.tetrd](#opt-services.tetrd.enable).
|
||||
|
@ -58,7 +66,7 @@ In addition to numerous new and upgraded packages, this release has the followin
|
|||
- [BaGet](https://loic-sharma.github.io/BaGet/), a lightweight NuGet and symbol server. Available at [services.baget](#opt-services.baget.enable).
|
||||
|
||||
- [moosefs](https://moosefs.com), fault tolerant petabyte distributed file system.
|
||||
Available as [moosefs](#opt-services.moosefs).
|
||||
Available as [moosefs](#opt-services.moosefs.client.enable).
|
||||
|
||||
- [prosody-filer](https://github.com/ThomasLeister/prosody-filer), a server for handling XMPP HTTP Upload requests. Available at [services.prosody-filer](#opt-services.prosody-filer.enable).
|
||||
|
||||
|
@ -120,6 +128,95 @@ In addition to numerous new and upgraded packages, this release has the followin
|
|||
|
||||
- The `mailpile` email webclient (`services.mailpile`) has been removed due to its reliance on python2.
|
||||
|
||||
- The `matrix-synapse` service (`services.matrix-synapse`) has been converted to use the `settings` option defined in RFC42.
|
||||
This means that options that are part of your `homeserver.yaml` configuration, and that were specified at the top-level of the
|
||||
module (`services.matrix-synapse`) now need to be moved into `services.matrix-synapse.settings`. And while not all options you
|
||||
may use are defined in there, they are still supported, because you can set arbitrary values in this freeform type.
|
||||
|
||||
An example to make the required migration clearer:
|
||||
|
||||
Before:
|
||||
```nix
|
||||
{
|
||||
services.matrix-synapse = {
|
||||
enable = true;
|
||||
|
||||
server_name = "example.com";
|
||||
public_baseurl = "https://example.com:8448";
|
||||
|
||||
enable_registration = false;
|
||||
registration_shared_secret = "xohshaeyui8jic7uutuDogahkee3aehuaf6ei3Xouz4iicie5thie6nohNahceut";
|
||||
macaroon_secret_key = "xoo8eder9seivukaiPh1cheikohquuw8Yooreid0The4aifahth3Ou0aiShaiz4l";
|
||||
|
||||
tls_certificate_path = "/var/lib/acme/example.com/fullchain.pem";
|
||||
tls_certificate_path = "/var/lib/acme/example.com/fullchain.pem";
|
||||
|
||||
listeners = [ {
|
||||
port = 8448;
|
||||
bind_address = "";
|
||||
type = "http";
|
||||
tls = true;
|
||||
resources = [ {
|
||||
names = [ "client" ];
|
||||
compress = true;
|
||||
} {
|
||||
names = [ "federation" ];
|
||||
compress = false;
|
||||
} ];
|
||||
} ];
|
||||
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
After:
|
||||
```nix
|
||||
{
|
||||
services.matrix-synapse = {
|
||||
enable = true;
|
||||
|
||||
# this attribute set holds all values that go into your homeserver.yaml configuration
|
||||
# See https://github.com/matrix-org/synapse/blob/develop/docs/sample_config.yaml for
|
||||
# possible values.
|
||||
settings = {
|
||||
server_name = "example.com";
|
||||
public_baseurl = "https://example.com:8448";
|
||||
|
||||
enable_registration = false;
|
||||
# pass `registration_shared_secret` and `macaroon_secret_key` via `extraConfigFiles` instead
|
||||
|
||||
tls_certificate_path = "/var/lib/acme/example.com/fullchain.pem";
|
||||
tls_certificate_path = "/var/lib/acme/example.com/fullchain.pem";
|
||||
|
||||
listeners = [ {
|
||||
port = 8448;
|
||||
bind_address = [
|
||||
"::"
|
||||
"0.0.0.0"
|
||||
];
|
||||
type = "http";
|
||||
tls = true;
|
||||
resources = [ {
|
||||
names = [ "client" ];
|
||||
compress = true;
|
||||
} {
|
||||
names = [ "federation" ];
|
||||
compress = false;
|
||||
} ];
|
||||
} ];
|
||||
};
|
||||
|
||||
extraConfigFiles = [
|
||||
/run/keys/matrix-synapse/secrets.yaml
|
||||
];
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
The secrets in your original config should be migrated into a YAML file that is included via `extraConfigFiles`.
|
||||
|
||||
Additionally a few option defaults have been synced up with upstream default values, for example the `max_upload_size` grew from `10M` to `50M`.
|
||||
|
||||
- The MoinMoin wiki engine (`services.moinmoin`) has been removed, because Python 2 is being retired from nixpkgs.
|
||||
|
||||
- The `wafHook` hook now honors `NIX_BUILD_CORES` when `enableParallelBuilding` is not set explicitly. Packages can restore the old behaviour by setting `enableParallelBuilding=false`.
|
||||
|
@ -147,6 +244,8 @@ In addition to numerous new and upgraded packages, this release has the followin
|
|||
|
||||
- opensmtpd-extras is no longer build with python2 scripting support due to python2 deprecation in nixpkgs
|
||||
|
||||
- `services.miniflux.adminCredentialFiles` is now required, instead of defaulting to `admin` and `password`.
|
||||
|
||||
- The `autorestic` package has been upgraded from 1.3.0 to 1.5.0 which introduces breaking changes in config file, check [their migration guide](https://autorestic.vercel.app/migration/1.4_1.5) for more details.
|
||||
|
||||
- For `pkgs.python3.pkgs.ipython`, its direct dependency `pkgs.python3.pkgs.matplotlib-inline`
|
||||
|
@ -174,10 +273,16 @@ In addition to numerous new and upgraded packages, this release has the followin
|
|||
|
||||
- `tilp2` was removed together with its module
|
||||
|
||||
- The F-PROT antivirus (`fprot` package) and its service module were removed because it
|
||||
reached [end-of-life](https://kb.cyren.com/av-support/index.php?/Knowledgebase/Article/View/434/0/end-of-sale--end-of-life-for-f-prot-and-csam).
|
||||
|
||||
- `bird1` and its modules `services.bird` as well as `services.bird6` have been removed. Upgrade to `services.bird2`.
|
||||
|
||||
- The options `networking.interfaces.<name>.ipv4.routes` and `networking.interfaces.<name>.ipv6.routes` are no longer ignored when using networkd instead of the default scripted network backend by setting `networking.useNetworkd` to `true`.
|
||||
|
||||
- MultiMC has been replaced with the fork PolyMC due to upstream developers being hostile to 3rd party package maintainers. PolyMC removes all MultiMC branding and is aimed at providing proper 3rd party packages like the one contained in Nixpkgs. This change affects the data folder where game instances and other save and configuration files are stored. Users with existing installations should rename `~/.local/share/multimc` to `~/.local/share/polymc`. The main config file's path has also moved from `~/.local/share/multimc/multimc.cfg` to `~/.local/share/polymc/polymc.cfg`.
|
||||
|
||||
- `systemd-nspawn@.service` settings have been reverted to the default systemd behaviour. User namespaces are now activated by default. If you want to keep running nspawn containers without user namespaces you need to set `systemd.nspawn.<name>.execConfig.PrivateUsers = false`
|
||||
|
||||
- The terraform 0.12 compatibility has been removed and the `terraform.withPlugins` and `terraform-providers.mkProvider` implementations simplified. Providers now need to be stored under
|
||||
`$out/libexec/terraform-providers/<registry>/<owner>/<name>/<version>/<os>_<arch>/terraform-provider-<name>_v<version>` (which mkProvider does).
|
||||
|
@ -191,6 +296,8 @@ In addition to numerous new and upgraded packages, this release has the followin
|
|||
you should change the package you refer to. If you don't need them update your
|
||||
commands from `otelcontribcol` to `otelcorecol` and enjoy a 7x smaller binary.
|
||||
|
||||
- `pkgs.pgadmin` now refers to `pkgs.pgadmin4`.
|
||||
If you still need pgadmin3, use `pkgs.pgadmin3`.
|
||||
|
||||
- `pkgs.noto-fonts-cjk` is now deprecated in favor of `pkgs.noto-fonts-cjk-sans`
|
||||
and `pkgs.noto-fonts-cjk-serif` because they each have different release
|
||||
|
@ -220,6 +327,22 @@ In addition to numerous new and upgraded packages, this release has the followin
|
|||
- `pkgs.vimPlugins.onedark-nvim` now refers to [navarasu/onedark.nvim](https://github.com/navarasu/onedark.nvim)
|
||||
(formerly refers to [olimorris/onedarkpro.nvim](https://github.com/olimorris/onedarkpro.nvim)).
|
||||
|
||||
- `services.pipewire.enable` will default to enabling the WirePlumber session manager instead of pipewire-media-session.
|
||||
pipewire-media-session is deprecated by upstream and not recommended, but can still be manually enabled by setting
|
||||
`services.pipewire.media-session.enable` to `true` and `services.pipewire.wireplumber.enable` to `false`.
|
||||
|
||||
- `pkgs.makeDesktopItem` has been refactored to provide a more idiomatic API. Specifically:
|
||||
- All valid options as of FDO Desktop Entry specification version 1.4 can now be passed in as explicit arguments
|
||||
- `exec` can now be null, for entries that are not of type Application
|
||||
- `mimeType` argument is renamed to `mimeTypes` for consistency
|
||||
- `mimeTypes`, `categories`, `implements`, `keywords`, `onlyShowIn` and `notShowIn` take lists of strings instead of one string with semicolon separators
|
||||
- `extraDesktopEntries` renamed to `extraConfig` for consistency
|
||||
- Actions should now be provided as an attrset `actions`, the `Actions` line will be autogenerated.
|
||||
- `extraEntries` is removed.
|
||||
- Additional validation is added both at eval time and at build time.
|
||||
|
||||
See the `vscode` package for a more detailed example.
|
||||
|
||||
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
|
||||
|
||||
## Other Notable Changes {#sec-release-22.05-notable-changes}
|
||||
|
@ -304,10 +427,16 @@ In addition to numerous new and upgraded packages, this release has the followin
|
|||
using `fetchgit` or `fetchhg` if the argument `fetchSubmodules`
|
||||
is set to `true`.
|
||||
|
||||
- The `element-desktop` package now has an `useKeytar` option (defaults to `true`),
|
||||
which allows disabling `keytar` and in turn `libsecret` usage
|
||||
(which binds to native credential managers / keychain libraries).
|
||||
|
||||
- The option `services.thelounge.plugins` has been added to allow installing plugins for The Lounge. Plugins can be found in `pkgs.theLoungePlugins.plugins` and `pkgs.theLoungePlugins.themes`.
|
||||
|
||||
- The `firmwareLinuxNonfree` package has been renamed to `linux-firmware`.
|
||||
|
||||
- It is now possible to specify wordlists to include as handy to access environment variables using the `config.environment.wordlist` configuration options.
|
||||
|
||||
- The `services.mbpfan` module was converted to a [RFC 0042](https://github.com/NixOS/rfcs/blob/master/rfcs/0042-config-option.md) configuration.
|
||||
|
||||
- The default value for `programs.spacefm.settings.graphical_su` got unset. It previously pointed to `gksu` which has been removed.
|
||||
|
@ -320,6 +449,9 @@ In addition to numerous new and upgraded packages, this release has the followin
|
|||
- `services.mattermost.plugins` has been added to allow the declarative installation of Mattermost plugins.
|
||||
Plugins are automatically repackaged using autoPatchelf.
|
||||
|
||||
- `services.logrotate.enable` now defaults to true if any rotate path has
|
||||
been defined, and some paths have been added by default.
|
||||
|
||||
- The `zrepl` package has been updated from 0.4.0 to 0.5:
|
||||
|
||||
- The RPC protocol version was bumped; all zrepl daemons in a setup must be updated and restarted before replication can resume.
|
||||
|
@ -329,12 +461,19 @@ In addition to numerous new and upgraded packages, this release has the followin
|
|||
Reason is that the old name has been deprecated upstream.
|
||||
Using the old option name will still work, but produce a warning.
|
||||
|
||||
- The `pomerium-cli` command has been moved out of the `pomerium` package into
|
||||
the `pomerium-cli` package, following upstream's repository split. If you are
|
||||
using the `pomerium-cli` command, you should now install the `pomerium-cli`
|
||||
package.
|
||||
|
||||
- The option
|
||||
[services.networking.networkmanager.enableFccUnlock](#opt-services.networking.networkmanager.enableFccUnlock)
|
||||
[services.networking.networkmanager.enableFccUnlock](#opt-networking.networkmanager.enableFccUnlock)
|
||||
was added to support FCC unlock procedures. Since release 1.18.4, the ModemManager
|
||||
daemon no longer automatically performs the FCC unlock procedure by default. See
|
||||
[the docs](https://modemmanager.org/docs/modemmanager/fcc-unlock/) for more details.
|
||||
|
||||
- `programs.tmux` has a new option `plugins` that accepts a list of packages from the `tmuxPlugins` group. The specified packages are added to the system and loaded by `tmux`.
|
||||
|
||||
- The polkit service, available at `security.polkit.enable`, is now disabled by default. It will automatically be enabled through services and desktop environments as needed.
|
||||
|
||||
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
|
||||
|
|
5
third_party/nixpkgs/nixos/lib/utils.nix
vendored
5
third_party/nixpkgs/nixos/lib/utils.nix
vendored
|
@ -150,7 +150,8 @@ rec {
|
|||
rm '${output}'
|
||||
fi
|
||||
|
||||
inherit_errexit_restore=$(shopt -p inherit_errexit)
|
||||
inherit_errexit_enabled=0
|
||||
shopt -pq inherit_errexit && inherit_errexit_enabled=1
|
||||
shopt -s inherit_errexit
|
||||
''
|
||||
+ concatStringsSep
|
||||
|
@ -170,7 +171,7 @@ rec {
|
|||
' <<'EOF'
|
||||
${builtins.toJSON set}
|
||||
EOF
|
||||
$inherit_errexit_restore
|
||||
(( ! $inherit_errexit_enabled )) && shopt -u inherit_errexit
|
||||
'';
|
||||
|
||||
systemdUtils = {
|
||||
|
|
|
@ -83,6 +83,7 @@ in {
|
|||
b43Firmware_5_1_138
|
||||
b43Firmware_6_30_163_46
|
||||
b43FirmwareCutter
|
||||
xow_dongle-firmware
|
||||
] ++ optional pkgs.stdenv.hostPlatform.isx86 facetimehd-firmware;
|
||||
})
|
||||
(mkIf cfg.wirelessRegulatoryDatabase {
|
||||
|
|
23
third_party/nixpkgs/nixos/modules/hardware/xone.nix
vendored
Normal file
23
third_party/nixpkgs/nixos/modules/hardware/xone.nix
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
cfg = config.hardware.xone;
|
||||
in
|
||||
{
|
||||
options.hardware.xone = {
|
||||
enable = mkEnableOption "the xone driver for Xbox One and Xbobx Series X|S accessories";
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
boot = {
|
||||
blacklistedKernelModules = [ "xpad" "mt76x2u" ];
|
||||
extraModulePackages = with config.boot.kernelPackages; [ xone ];
|
||||
};
|
||||
hardware.firmware = [ pkgs.xow_dongle-firmware ];
|
||||
};
|
||||
|
||||
meta = {
|
||||
maintainers = with maintainers; [ rhysmdnz ];
|
||||
};
|
||||
}
|
|
@ -24,6 +24,9 @@
|
|||
[pi3]
|
||||
kernel=u-boot-rpi3.bin
|
||||
|
||||
[pi02]
|
||||
kernel=u-boot-rpi3.bin
|
||||
|
||||
[pi4]
|
||||
kernel=u-boot-rpi4.bin
|
||||
enable_gic=1
|
||||
|
@ -33,6 +36,9 @@
|
|||
# what the pi3 firmware does by default.
|
||||
disable_overscan=1
|
||||
|
||||
# Supported in newer board revisions
|
||||
arm_boost=1
|
||||
|
||||
[all]
|
||||
# Boot in 64-bit mode.
|
||||
arm_64bit=1
|
||||
|
|
|
@ -129,7 +129,7 @@ let
|
|||
genericName = "View NixOS documentation in a web browser";
|
||||
icon = "nix-snowflake";
|
||||
exec = "nixos-help";
|
||||
categories = "System";
|
||||
categories = ["System"];
|
||||
};
|
||||
|
||||
in pkgs.symlinkJoin {
|
||||
|
|
|
@ -82,14 +82,14 @@ in
|
|||
git = 41;
|
||||
#fourstore = 42; # dropped in 20.03
|
||||
#fourstorehttp = 43; # dropped in 20.03
|
||||
virtuoso = 44;
|
||||
#virtuoso = 44; dropped module
|
||||
#rtkit = 45; # dynamically allocated 2021-09-03
|
||||
dovecot2 = 46;
|
||||
dovenull2 = 47;
|
||||
prayer = 49;
|
||||
mpd = 50;
|
||||
clamav = 51;
|
||||
fprot = 52;
|
||||
#fprot = 52; # unused
|
||||
# bind = 53; #dynamically allocated as of 2021-09-03
|
||||
wwwrun = 54;
|
||||
#adm = 55; # unused
|
||||
|
@ -412,7 +412,7 @@ in
|
|||
prayer = 49;
|
||||
mpd = 50;
|
||||
clamav = 51;
|
||||
fprot = 52;
|
||||
#fprot = 52; # unused
|
||||
#bind = 53; # unused
|
||||
wwwrun = 54;
|
||||
adm = 55;
|
||||
|
|
|
@ -1,12 +1,17 @@
|
|||
{ config, lib, options, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.system.nixos;
|
||||
opt = options.system.nixos;
|
||||
in
|
||||
|
||||
inherit (lib)
|
||||
concatStringsSep mapAttrsToList toLower
|
||||
literalExpression mkRenamedOptionModule mkDefault mkOption trivial types;
|
||||
|
||||
attrsToText = attrs:
|
||||
concatStringsSep "\n" (mapAttrsToList (n: v: ''${n}="${toString v}"'') attrs);
|
||||
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
(mkRenamedOptionModule [ "system" "nixosVersion" ] [ "system" "nixos" "version" ])
|
||||
|
@ -101,22 +106,30 @@ in
|
|||
# Generate /etc/os-release. See
|
||||
# https://www.freedesktop.org/software/systemd/man/os-release.html for the
|
||||
# format.
|
||||
environment.etc.os-release.text =
|
||||
''
|
||||
NAME=NixOS
|
||||
ID=nixos
|
||||
VERSION="${cfg.release} (${cfg.codeName})"
|
||||
VERSION_CODENAME=${toLower cfg.codeName}
|
||||
VERSION_ID="${cfg.release}"
|
||||
BUILD_ID="${cfg.version}"
|
||||
PRETTY_NAME="NixOS ${cfg.release} (${cfg.codeName})"
|
||||
LOGO="nix-snowflake"
|
||||
HOME_URL="https://nixos.org/"
|
||||
DOCUMENTATION_URL="https://nixos.org/learn.html"
|
||||
SUPPORT_URL="https://nixos.org/community.html"
|
||||
BUG_REPORT_URL="https://github.com/NixOS/nixpkgs/issues"
|
||||
'';
|
||||
environment.etc = {
|
||||
"lsb-release".text = attrsToText {
|
||||
LSB_VERSION = "${cfg.release} (${cfg.codeName})";
|
||||
DISTRIB_ID = "nixos";
|
||||
DISTRIB_RELEASE = cfg.release;
|
||||
DISTRIB_CODENAME = toLower cfg.codeName;
|
||||
DISTRIB_DESCRIPTION = "NixOS ${cfg.release} (${cfg.codeName})";
|
||||
};
|
||||
|
||||
"os-release".text = attrsToText {
|
||||
NAME = "NixOS";
|
||||
ID = "nixos";
|
||||
VERSION = "${cfg.release} (${cfg.codeName})";
|
||||
VERSION_CODENAME = toLower cfg.codeName;
|
||||
VERSION_ID = cfg.release;
|
||||
BUILD_ID = cfg.version;
|
||||
PRETTY_NAME = "NixOS ${cfg.release} (${cfg.codeName})";
|
||||
LOGO = "nix-snowflake";
|
||||
HOME_URL = "https://nixos.org/";
|
||||
DOCUMENTATION_URL = "https://nixos.org/learn.html";
|
||||
SUPPORT_URL = "https://nixos.org/community.html";
|
||||
BUG_REPORT_URL = "https://github.com/NixOS/nixpkgs/issues";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# uses version info nixpkgs, which requires a full nixpkgs path
|
||||
|
|
59
third_party/nixpkgs/nixos/modules/misc/wordlist.nix
vendored
Normal file
59
third_party/nixpkgs/nixos/modules/misc/wordlist.nix
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
with lib;
|
||||
let
|
||||
concatAndSort = name: files: pkgs.runCommand name {} ''
|
||||
awk 1 ${lib.escapeShellArgs files} | sed '{ /^\s*$/d; s/^\s\+//; s/\s\+$// }' | sort | uniq > $out
|
||||
'';
|
||||
in
|
||||
{
|
||||
options = {
|
||||
environment.wordlist = {
|
||||
enable = mkEnableOption "environment variables for lists of words";
|
||||
|
||||
lists = mkOption {
|
||||
type = types.attrsOf (types.nonEmptyListOf types.path);
|
||||
|
||||
default = {
|
||||
WORDLIST = [ "${pkgs.scowl}/share/dict/words.txt" ];
|
||||
};
|
||||
|
||||
defaultText = literalExpression ''
|
||||
{
|
||||
WORDLIST = [ "''${pkgs.scowl}/share/dict/words.txt" ];
|
||||
}
|
||||
'';
|
||||
|
||||
description = ''
|
||||
A set with the key names being the environment variable you'd like to
|
||||
set and the values being a list of paths to text documents containing
|
||||
lists of words. The various files will be merged, sorted, duplicates
|
||||
removed, and extraneous spacing removed.
|
||||
|
||||
If you have a handful of words that you want to add to an already
|
||||
existing wordlist, you may find `builtins.toFile` useful for this
|
||||
task.
|
||||
'';
|
||||
|
||||
example = literalExpression ''
|
||||
{
|
||||
WORDLIST = [ "''${pkgs.scowl}/share/dict/words.txt" ];
|
||||
AUGMENTED_WORDLIST = [
|
||||
"''${pkgs.scowl}/share/dict/words.txt"
|
||||
"''${pkgs.scowl}/share/dict/words.variants.txt"
|
||||
(builtins.toFile "extra-words" '''
|
||||
desynchonization
|
||||
oobleck''')
|
||||
];
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf config.environment.wordlist.enable {
|
||||
environment.variables =
|
||||
lib.mapAttrs
|
||||
(name: value: "${concatAndSort "wordlist-${name}" value}")
|
||||
config.environment.wordlist.lists;
|
||||
};
|
||||
}
|
|
@ -91,6 +91,7 @@
|
|||
./hardware/video/switcheroo-control.nix
|
||||
./hardware/video/uvcvideo/default.nix
|
||||
./hardware/video/webcam/facetimehd.nix
|
||||
./hardware/xone.nix
|
||||
./hardware/xpadneo.nix
|
||||
./i18n/input-method/default.nix
|
||||
./i18n/input-method/fcitx.nix
|
||||
|
@ -115,6 +116,7 @@
|
|||
./misc/nixpkgs.nix
|
||||
./misc/passthru.nix
|
||||
./misc/version.nix
|
||||
./misc/wordlist.nix
|
||||
./misc/nixops-autoluks.nix
|
||||
./programs/adb.nix
|
||||
./programs/appgate-sdp.nix
|
||||
|
@ -166,6 +168,7 @@
|
|||
./programs/iftop.nix
|
||||
./programs/iotop.nix
|
||||
./programs/java.nix
|
||||
./programs/k40-whisperer.nix
|
||||
./programs/kdeconnect.nix
|
||||
./programs/kbdlight.nix
|
||||
./programs/less.nix
|
||||
|
@ -252,6 +255,7 @@
|
|||
./security/tpm2.nix
|
||||
./services/admin/meshcentral.nix
|
||||
./services/admin/oxidized.nix
|
||||
./services/admin/pgadmin.nix
|
||||
./services/admin/salt/master.nix
|
||||
./services/admin/salt/minion.nix
|
||||
./services/amqp/activemq/default.nix
|
||||
|
@ -349,7 +353,6 @@
|
|||
./services/databases/redis.nix
|
||||
./services/databases/riak.nix
|
||||
./services/databases/victoriametrics.nix
|
||||
./services/databases/virtuoso.nix
|
||||
./services/desktops/accountsservice.nix
|
||||
./services/desktops/bamf.nix
|
||||
./services/desktops/blueman.nix
|
||||
|
@ -394,6 +397,7 @@
|
|||
./services/development/jupyterhub/default.nix
|
||||
./services/development/rstudio-server/default.nix
|
||||
./services/development/lorri.nix
|
||||
./services/development/zammad.nix
|
||||
./services/display-managers/greetd.nix
|
||||
./services/editors/emacs.nix
|
||||
./services/editors/infinoted.nix
|
||||
|
@ -451,6 +455,7 @@
|
|||
./services/hardware/vdr.nix
|
||||
./services/hardware/xow.nix
|
||||
./services/home-automation/home-assistant.nix
|
||||
./services/home-automation/zigbee2mqtt.nix
|
||||
./services/logging/SystemdJournal2Gelf.nix
|
||||
./services/logging/awstats.nix
|
||||
./services/logging/filebeat.nix
|
||||
|
@ -495,6 +500,7 @@
|
|||
./services/mail/roundcube.nix
|
||||
./services/mail/sympa.nix
|
||||
./services/mail/nullmailer.nix
|
||||
./services/matrix/matrix-synapse.nix
|
||||
./services/matrix/mjolnir.nix
|
||||
./services/matrix/pantalaimon.nix
|
||||
./services/misc/ananicy.nix
|
||||
|
@ -561,7 +567,6 @@
|
|||
./services/misc/matrix-appservice-discord.nix
|
||||
./services/misc/matrix-appservice-irc.nix
|
||||
./services/misc/matrix-conduit.nix
|
||||
./services/misc/matrix-synapse.nix
|
||||
./services/misc/mautrix-facebook.nix
|
||||
./services/misc/mautrix-telegram.nix
|
||||
./services/misc/mbpfan.nix
|
||||
|
@ -622,7 +627,6 @@
|
|||
./services/misc/weechat.nix
|
||||
./services/misc/xmr-stak.nix
|
||||
./services/misc/xmrig.nix
|
||||
./services/misc/zigbee2mqtt.nix
|
||||
./services/misc/zoneminder.nix
|
||||
./services/misc/zookeeper.nix
|
||||
./services/monitoring/alerta.nix
|
||||
|
@ -873,6 +877,7 @@
|
|||
./services/networking/shorewall6.nix
|
||||
./services/networking/shout.nix
|
||||
./services/networking/sniproxy.nix
|
||||
./services/networking/snowflake-proxy.nix
|
||||
./services/networking/smartdns.nix
|
||||
./services/networking/smokeping.nix
|
||||
./services/networking/softether.nix
|
||||
|
@ -897,6 +902,7 @@
|
|||
./services/networking/tcpcrypt.nix
|
||||
./services/networking/teamspeak3.nix
|
||||
./services/networking/tedicross.nix
|
||||
./services/networking/tetrd.nix
|
||||
./services/networking/teleport.nix
|
||||
./services/networking/thelounge.nix
|
||||
./services/networking/tinc.nix
|
||||
|
@ -946,7 +952,6 @@
|
|||
./services/security/clamav.nix
|
||||
./services/security/fail2ban.nix
|
||||
./services/security/fprintd.nix
|
||||
./services/security/fprot.nix
|
||||
./services/security/haka.nix
|
||||
./services/security/haveged.nix
|
||||
./services/security/hockeypuck.nix
|
||||
|
|
|
@ -17,8 +17,8 @@ let
|
|||
then value
|
||||
else { executable = value; profile = null; extraArgs = []; };
|
||||
args = lib.escapeShellArgs (
|
||||
(optional (opts.profile != null) "--profile=${toString opts.profile}")
|
||||
++ opts.extraArgs
|
||||
opts.extraArgs
|
||||
++ (optional (opts.profile != null) "--profile=${toString opts.profile}")
|
||||
);
|
||||
in
|
||||
''
|
||||
|
|
40
third_party/nixpkgs/nixos/modules/programs/k40-whisperer.nix
vendored
Normal file
40
third_party/nixpkgs/nixos/modules/programs/k40-whisperer.nix
vendored
Normal file
|
@ -0,0 +1,40 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.programs.k40-whisperer;
|
||||
pkg = cfg.package.override {
|
||||
udevGroup = cfg.group;
|
||||
};
|
||||
in
|
||||
{
|
||||
options.programs.k40-whisperer = {
|
||||
enable = mkEnableOption "K40-Whisperer";
|
||||
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
Group assigned to the device when connected.
|
||||
'';
|
||||
default = "k40";
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.k40-whisperer;
|
||||
defaultText = literalExpression "pkgs.k40-whisperer";
|
||||
example = literalExpression "pkgs.k40-whisperer";
|
||||
description = ''
|
||||
K40 Whisperer package to use.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
users.groups.${cfg.group} = {};
|
||||
|
||||
environment.systemPackages = [ pkg ];
|
||||
services.udev.packages = [ pkg ];
|
||||
};
|
||||
}
|
|
@ -8,18 +8,17 @@ let
|
|||
# Based on https://source.puri.sm/Librem5/librem5-base/-/blob/4596c1056dd75ac7f043aede07887990fd46f572/default/sm.puri.OSK0.desktop
|
||||
oskItem = pkgs.makeDesktopItem {
|
||||
name = "sm.puri.OSK0";
|
||||
type = "Application";
|
||||
desktopName = "On-screen keyboard";
|
||||
exec = "${pkgs.squeekboard}/bin/squeekboard";
|
||||
categories = "GNOME;Core;";
|
||||
extraEntries = ''
|
||||
OnlyShowIn=GNOME;
|
||||
NoDisplay=true
|
||||
X-GNOME-Autostart-Phase=Panel
|
||||
X-GNOME-Provides=inputmethod
|
||||
X-GNOME-Autostart-Notify=true
|
||||
X-GNOME-AutoRestart=true
|
||||
'';
|
||||
categories = [ "GNOME" "Core" ];
|
||||
onlyShowIn = [ "GNOME" ];
|
||||
noDisplay = true;
|
||||
extraConfig = {
|
||||
X-GNOME-Autostart-Phase = "Panel";
|
||||
X-GNOME-Provides = "inputmethod";
|
||||
X-GNOME-Autostart-Notify = "true";
|
||||
X-GNOME-AutoRestart = "true";
|
||||
};
|
||||
};
|
||||
|
||||
phocConfigType = types.submodule {
|
||||
|
|
|
@ -134,6 +134,7 @@ in {
|
|||
'';
|
||||
};
|
||||
};
|
||||
security.polkit.enable = true;
|
||||
security.pam.services.swaylock = {};
|
||||
hardware.opengl.enable = mkDefault true;
|
||||
fonts.enableDefaultFonts = mkDefault true;
|
||||
|
|
4
third_party/nixpkgs/nixos/modules/rename.nix
vendored
4
third_party/nixpkgs/nixos/modules/rename.nix
vendored
|
@ -50,6 +50,7 @@ with lib;
|
|||
(mkRemovedOptionModule [ "services" "flashpolicyd" ] "The flashpolicyd module has been removed. Adobe Flash Player is deprecated.")
|
||||
(mkRemovedOptionModule [ "services" "fourStore" ] "The fourStore module has been removed")
|
||||
(mkRemovedOptionModule [ "services" "fourStoreEndpoint" ] "The fourStoreEndpoint module has been removed")
|
||||
(mkRemovedOptionModule [ "services" "fprot" ] "The corresponding package was removed from nixpkgs.")
|
||||
(mkRemovedOptionModule [ "services" "frab" ] "The frab module has been removed")
|
||||
(mkRemovedOptionModule [ "services" "kippo" ] "The corresponding package was removed from nixpkgs.")
|
||||
(mkRemovedOptionModule [ "services" "mailpile" ] "The corresponding package was removed from nixpkgs.")
|
||||
|
@ -87,10 +88,9 @@ with lib;
|
|||
(mkRemovedOptionModule [ "services" "racoon" ] ''
|
||||
The racoon module has been removed, because the software project was abandoned upstream.
|
||||
'')
|
||||
|
||||
(mkRemovedOptionModule [ "services" "shellinabox" ] "The corresponding package was removed from nixpkgs.")
|
||||
|
||||
(mkRemovedOptionModule [ "services" "gogoclient" ] "The corresponding package was removed from nixpkgs.")
|
||||
(mkRemovedOptionModule [ "services" "virtuoso" ] "The corresponding package was removed from nixpkgs.")
|
||||
|
||||
# Do NOT add any option renames here, see top of the file
|
||||
];
|
||||
|
|
|
@ -518,7 +518,7 @@ let
|
|||
auth optional ${pkgs.pam_gnupg}/lib/security/pam_gnupg.so ${optionalString cfg.gnupg.storeOnly " store-only"}
|
||||
'' +
|
||||
optionalString cfg.googleAuthenticator.enable ''
|
||||
auth required ${pkgs.googleAuthenticator}/lib/security/pam_google_authenticator.so no_increment_hotp
|
||||
auth required ${pkgs.google-authenticator}/lib/security/pam_google_authenticator.so no_increment_hotp
|
||||
'' +
|
||||
optionalString cfg.duoSecurity.enable ''
|
||||
auth required ${pkgs.duo-unix}/lib/security/pam_duo.so
|
||||
|
|
|
@ -12,11 +12,7 @@ in
|
|||
|
||||
options = {
|
||||
|
||||
security.polkit.enable = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Whether to enable PolKit.";
|
||||
};
|
||||
security.polkit.enable = mkEnableOption "polkit";
|
||||
|
||||
security.polkit.extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
|
|
|
@ -175,8 +175,8 @@ in {
|
|||
serviceName = "${name}.service";
|
||||
excludedPath = rootPaths;
|
||||
} ''
|
||||
mkdir -p "$out/lib/systemd/system"
|
||||
serviceFile="$out/lib/systemd/system/$serviceName"
|
||||
mkdir -p "$out/lib/systemd/system/$serviceName.d"
|
||||
serviceFile="$out/lib/systemd/system/$serviceName.d/confinement.conf"
|
||||
|
||||
echo '[Service]' > "$serviceFile"
|
||||
|
||||
|
|
127
third_party/nixpkgs/nixos/modules/services/admin/pgadmin.nix
vendored
Normal file
127
third_party/nixpkgs/nixos/modules/services/admin/pgadmin.nix
vendored
Normal file
|
@ -0,0 +1,127 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
pkg = pkgs.pgadmin4;
|
||||
cfg = config.services.pgadmin;
|
||||
|
||||
_base = with types; [ int bool str ];
|
||||
base = with types; oneOf ([ (listOf (oneOf _base)) (attrsOf (oneOf _base)) ] ++ _base);
|
||||
|
||||
formatAttrset = attr:
|
||||
"{${concatStringsSep "\n" (mapAttrsToList (key: value: "${builtins.toJSON key}: ${formatPyValue value},") attr)}}";
|
||||
|
||||
formatPyValue = value:
|
||||
if builtins.isString value then builtins.toJSON value
|
||||
else if value ? _expr then value._expr
|
||||
else if builtins.isInt value then toString value
|
||||
else if builtins.isBool value then (if value then "True" else "False")
|
||||
else if builtins.isAttrs value then (formatAttrset value)
|
||||
else if builtins.isList value then "[${concatStringsSep "\n" (map (v: "${formatPyValue v},") value)}]"
|
||||
else throw "Unrecognized type";
|
||||
|
||||
formatPy = attrs:
|
||||
concatStringsSep "\n" (mapAttrsToList (key: value: "${key} = ${formatPyValue value}") attrs);
|
||||
|
||||
pyType = with types; attrsOf (oneOf [ (attrsOf base) (listOf base) base ]);
|
||||
in
|
||||
{
|
||||
options.services.pgadmin = {
|
||||
enable = mkEnableOption "PostgreSQL Admin 4";
|
||||
|
||||
port = mkOption {
|
||||
description = "Port for pgadmin4 to run on";
|
||||
type = types.port;
|
||||
default = 5050;
|
||||
};
|
||||
|
||||
initialEmail = mkOption {
|
||||
description = "Initial email for the pgAdmin account.";
|
||||
type = types.str;
|
||||
};
|
||||
|
||||
initialPasswordFile = mkOption {
|
||||
description = ''
|
||||
Initial password file for the pgAdmin account.
|
||||
NOTE: Should be string not a store path, to prevent the password from being world readable.
|
||||
'';
|
||||
type = types.path;
|
||||
};
|
||||
|
||||
openFirewall = mkEnableOption "firewall passthrough for pgadmin4";
|
||||
|
||||
settings = mkOption {
|
||||
description = ''
|
||||
Settings for pgadmin4.
|
||||
<link xlink:href="https://www.pgadmin.org/docs/pgadmin4/development/config_py.html">Documentation</link>.
|
||||
'';
|
||||
type = pyType;
|
||||
default= {};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf (cfg.enable) {
|
||||
networking.firewall.allowedTCPPorts = mkIf (cfg.openFirewall) [ cfg.port ];
|
||||
|
||||
services.pgadmin.settings = {
|
||||
DEFAULT_SERVER_PORT = cfg.port;
|
||||
SERVER_MODE = true;
|
||||
} // (optionalAttrs cfg.openFirewall {
|
||||
DEFAULT_SERVER = mkDefault "::";
|
||||
});
|
||||
|
||||
systemd.services.pgadmin = {
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
requires = [ "network.target" ];
|
||||
# we're adding this optionally so just in case there's any race it'll be caught
|
||||
# in case postgres doesn't start, pgadmin will just start normally
|
||||
wants = [ "postgresql.service" ];
|
||||
|
||||
path = [ config.services.postgresql.package pkgs.coreutils pkgs.bash ];
|
||||
|
||||
preStart = ''
|
||||
# NOTE: this is idempotent (aka running it twice has no effect)
|
||||
(
|
||||
# Email address:
|
||||
echo ${escapeShellArg cfg.initialEmail}
|
||||
|
||||
# file might not contain newline. echo hack fixes that.
|
||||
PW=$(cat ${escapeShellArg cfg.initialPasswordFile})
|
||||
|
||||
# Password:
|
||||
echo "$PW"
|
||||
# Retype password:
|
||||
echo "$PW"
|
||||
) | ${pkg}/bin/pgadmin4-setup
|
||||
'';
|
||||
|
||||
restartTriggers = [
|
||||
"/etc/pgadmin/config_system.py"
|
||||
];
|
||||
|
||||
serviceConfig = {
|
||||
User = "pgadmin";
|
||||
DynamicUser = true;
|
||||
LogsDirectory = "pgadmin";
|
||||
StateDirectory = "pgadmin";
|
||||
ExecStart = "${pkg}/bin/pgadmin4";
|
||||
};
|
||||
};
|
||||
|
||||
users.users.pgadmin = {
|
||||
isSystemUser = true;
|
||||
group = "pgadmin";
|
||||
};
|
||||
|
||||
users.groups.pgadmin = {};
|
||||
|
||||
environment.etc."pgadmin/config_system.py" = {
|
||||
text = formatPy cfg.settings;
|
||||
mode = "0600";
|
||||
user = "pgadmin";
|
||||
group = "pgadmin";
|
||||
};
|
||||
};
|
||||
}
|
|
@ -44,24 +44,24 @@ let
|
|||
|
||||
optionString = concatStringsSep " " (mapAttrsToList streamToOption cfg.streams
|
||||
# global options
|
||||
++ [ "--stream.bind_to_address ${cfg.listenAddress}" ]
|
||||
++ [ "--stream.port ${toString cfg.port}" ]
|
||||
++ optionalNull cfg.sampleFormat "--stream.sampleformat ${cfg.sampleFormat}"
|
||||
++ optionalNull cfg.codec "--stream.codec ${cfg.codec}"
|
||||
++ optionalNull cfg.streamBuffer "--stream.stream_buffer ${toString cfg.streamBuffer}"
|
||||
++ optionalNull cfg.buffer "--stream.buffer ${toString cfg.buffer}"
|
||||
++ [ "--stream.bind_to_address=${cfg.listenAddress}" ]
|
||||
++ [ "--stream.port=${toString cfg.port}" ]
|
||||
++ optionalNull cfg.sampleFormat "--stream.sampleformat=${cfg.sampleFormat}"
|
||||
++ optionalNull cfg.codec "--stream.codec=${cfg.codec}"
|
||||
++ optionalNull cfg.streamBuffer "--stream.stream_buffer=${toString cfg.streamBuffer}"
|
||||
++ optionalNull cfg.buffer "--stream.buffer=${toString cfg.buffer}"
|
||||
++ optional cfg.sendToMuted "--stream.send_to_muted"
|
||||
# tcp json rpc
|
||||
++ [ "--tcp.enabled ${toString cfg.tcp.enable}" ]
|
||||
++ [ "--tcp.enabled=${toString cfg.tcp.enable}" ]
|
||||
++ optionals cfg.tcp.enable [
|
||||
"--tcp.bind_to_address ${cfg.tcp.listenAddress}"
|
||||
"--tcp.port ${toString cfg.tcp.port}" ]
|
||||
"--tcp.bind_to_address=${cfg.tcp.listenAddress}"
|
||||
"--tcp.port=${toString cfg.tcp.port}" ]
|
||||
# http json rpc
|
||||
++ [ "--http.enabled ${toString cfg.http.enable}" ]
|
||||
++ [ "--http.enabled=${toString cfg.http.enable}" ]
|
||||
++ optionals cfg.http.enable [
|
||||
"--http.bind_to_address ${cfg.http.listenAddress}"
|
||||
"--http.port ${toString cfg.http.port}"
|
||||
] ++ optional (cfg.http.docRoot != null) "--http.doc_root \"${toString cfg.http.docRoot}\"");
|
||||
"--http.bind_to_address=${cfg.http.listenAddress}"
|
||||
"--http.port=${toString cfg.http.port}"
|
||||
] ++ optional (cfg.http.docRoot != null) "--http.doc_root=\"${toString cfg.http.docRoot}\"");
|
||||
|
||||
in {
|
||||
imports = [
|
||||
|
|
|
@ -266,7 +266,7 @@ in
|
|||
in
|
||||
''
|
||||
export KUBECONFIG=${clusterAdminKubeconfig}
|
||||
${kubectl}/bin/kubectl apply -f ${concatStringsSep " \\\n -f " files}
|
||||
${kubernetes}/bin/kubectl apply -f ${concatStringsSep " \\\n -f " files}
|
||||
'';
|
||||
})]);
|
||||
|
||||
|
|
|
@ -1,99 +0,0 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
let
|
||||
cfg = config.services.virtuoso;
|
||||
virtuosoUser = "virtuoso";
|
||||
stateDir = "/var/lib/virtuoso";
|
||||
in
|
||||
with lib;
|
||||
{
|
||||
|
||||
###### interface
|
||||
|
||||
options = {
|
||||
|
||||
services.virtuoso = {
|
||||
|
||||
enable = mkEnableOption "Virtuoso Opensource database server";
|
||||
|
||||
config = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = "Extra options to put into Virtuoso configuration file.";
|
||||
};
|
||||
|
||||
parameters = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = "Extra options to put into [Parameters] section of Virtuoso configuration file.";
|
||||
};
|
||||
|
||||
listenAddress = mkOption {
|
||||
type = types.str;
|
||||
default = "1111";
|
||||
example = "myserver:1323";
|
||||
description = "ip:port or port to listen on.";
|
||||
};
|
||||
|
||||
httpListenAddress = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "myserver:8080";
|
||||
description = "ip:port or port for Virtuoso HTTP server to listen on.";
|
||||
};
|
||||
|
||||
dirsAllowed = mkOption {
|
||||
type = types.nullOr types.str; # XXX Maybe use a list in the future?
|
||||
default = null;
|
||||
example = "/www, /home/";
|
||||
description = "A list of directories Virtuoso is allowed to access";
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
users.users.${virtuosoUser} =
|
||||
{ uid = config.ids.uids.virtuoso;
|
||||
description = "virtuoso user";
|
||||
home = stateDir;
|
||||
};
|
||||
|
||||
systemd.services.virtuoso = {
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
preStart = ''
|
||||
mkdir -p ${stateDir}
|
||||
chown ${virtuosoUser} ${stateDir}
|
||||
'';
|
||||
|
||||
script = ''
|
||||
cd ${stateDir}
|
||||
${pkgs.virtuoso}/bin/virtuoso-t +foreground +configfile ${pkgs.writeText "virtuoso.ini" cfg.config}
|
||||
'';
|
||||
};
|
||||
|
||||
services.virtuoso.config = ''
|
||||
[Database]
|
||||
DatabaseFile=${stateDir}/x-virtuoso.db
|
||||
TransactionFile=${stateDir}/x-virtuoso.trx
|
||||
ErrorLogFile=${stateDir}/x-virtuoso.log
|
||||
xa_persistent_file=${stateDir}/x-virtuoso.pxa
|
||||
|
||||
[Parameters]
|
||||
ServerPort=${cfg.listenAddress}
|
||||
RunAs=${virtuosoUser}
|
||||
${optionalString (cfg.dirsAllowed != null) "DirsAllowed=${cfg.dirsAllowed}"}
|
||||
${cfg.parameters}
|
||||
|
||||
[HTTPServer]
|
||||
${optionalString (cfg.httpListenAddress != null) "ServerPort=${cfg.httpListenAddress}"}
|
||||
'';
|
||||
|
||||
};
|
||||
|
||||
}
|
|
@ -30,6 +30,8 @@ in {
|
|||
|
||||
environment.systemPackages = [ pkgs.flatpak ];
|
||||
|
||||
security.polkit.enable = true;
|
||||
|
||||
services.dbus.packages = [ pkgs.flatpak ];
|
||||
|
||||
systemd.packages = [ pkgs.flatpak ];
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
},
|
||||
"context.modules": [
|
||||
{
|
||||
"name": "libpipewire-module-rtkit",
|
||||
"name": "libpipewire-module-rt",
|
||||
"args": {},
|
||||
"flags": [
|
||||
"ifexists",
|
||||
|
|
118
third_party/nixpkgs/nixos/modules/services/desktops/pipewire/daemon/minimal.conf.json
vendored
Normal file
118
third_party/nixpkgs/nixos/modules/services/desktops/pipewire/daemon/minimal.conf.json
vendored
Normal file
|
@ -0,0 +1,118 @@
|
|||
{
|
||||
"context.properties": {
|
||||
"link.max-buffers": 16,
|
||||
"core.daemon": true,
|
||||
"core.name": "pipewire-0",
|
||||
"settings.check-quantum": true,
|
||||
"settings.check-rate": true,
|
||||
"vm.overrides": {
|
||||
"default.clock.min-quantum": 1024
|
||||
}
|
||||
},
|
||||
"context.spa-libs": {
|
||||
"audio.convert.*": "audioconvert/libspa-audioconvert",
|
||||
"api.alsa.*": "alsa/libspa-alsa",
|
||||
"support.*": "support/libspa-support"
|
||||
},
|
||||
"context.modules": [
|
||||
{
|
||||
"name": "libpipewire-module-rt",
|
||||
"args": {
|
||||
"nice.level": -11
|
||||
},
|
||||
"flags": [
|
||||
"ifexists",
|
||||
"nofail"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "libpipewire-module-protocol-native"
|
||||
},
|
||||
{
|
||||
"name": "libpipewire-module-profiler"
|
||||
},
|
||||
{
|
||||
"name": "libpipewire-module-metadata"
|
||||
},
|
||||
{
|
||||
"name": "libpipewire-module-spa-node-factory"
|
||||
},
|
||||
{
|
||||
"name": "libpipewire-module-client-node"
|
||||
},
|
||||
{
|
||||
"name": "libpipewire-module-access",
|
||||
"args": {}
|
||||
},
|
||||
{
|
||||
"name": "libpipewire-module-adapter"
|
||||
},
|
||||
{
|
||||
"name": "libpipewire-module-link-factory"
|
||||
}
|
||||
],
|
||||
"context.objects": [
|
||||
{
|
||||
"factory": "metadata",
|
||||
"args": {
|
||||
"metadata.name": "default"
|
||||
}
|
||||
},
|
||||
{
|
||||
"factory": "spa-node-factory",
|
||||
"args": {
|
||||
"factory.name": "support.node.driver",
|
||||
"node.name": "Dummy-Driver",
|
||||
"node.group": "pipewire.dummy",
|
||||
"priority.driver": 20000
|
||||
}
|
||||
},
|
||||
{
|
||||
"factory": "spa-node-factory",
|
||||
"args": {
|
||||
"factory.name": "support.node.driver",
|
||||
"node.name": "Freewheel-Driver",
|
||||
"priority.driver": 19000,
|
||||
"node.group": "pipewire.freewheel",
|
||||
"node.freewheel": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"factory": "adapter",
|
||||
"args": {
|
||||
"factory.name": "api.alsa.pcm.source",
|
||||
"node.name": "system",
|
||||
"node.description": "system",
|
||||
"media.class": "Audio/Source",
|
||||
"api.alsa.path": "hw:0",
|
||||
"node.suspend-on-idle": true,
|
||||
"resample.disable": true,
|
||||
"channelmix.disable": true,
|
||||
"adapter.auto-port-config": {
|
||||
"mode": "dsp",
|
||||
"monitor": false,
|
||||
"position": "unknown"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"factory": "adapter",
|
||||
"args": {
|
||||
"factory.name": "api.alsa.pcm.sink",
|
||||
"node.name": "system",
|
||||
"node.description": "system",
|
||||
"media.class": "Audio/Sink",
|
||||
"api.alsa.path": "hw:0",
|
||||
"node.suspend-on-idle": true,
|
||||
"resample.disable": true,
|
||||
"channelmix.disable": true,
|
||||
"adapter.auto-port-config": {
|
||||
"mode": "dsp",
|
||||
"monitor": false,
|
||||
"position": "unknown"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"context.exec": []
|
||||
}
|
|
@ -6,8 +6,10 @@
|
|||
},
|
||||
"context.modules": [
|
||||
{
|
||||
"name": "libpipewire-module-rtkit",
|
||||
"args": {},
|
||||
"name": "libpipewire-module-rt",
|
||||
"args": {
|
||||
"nice.level": -11
|
||||
},
|
||||
"flags": [
|
||||
"ifexists",
|
||||
"nofail"
|
||||
|
@ -37,6 +39,61 @@
|
|||
}
|
||||
}
|
||||
],
|
||||
"context.exec": [],
|
||||
"stream.properties": {}
|
||||
"context.exec": [
|
||||
{
|
||||
"path": "pactl",
|
||||
"args": "load-module module-always-sink"
|
||||
}
|
||||
],
|
||||
"stream.properties": {},
|
||||
"pulse.rules": [
|
||||
{
|
||||
"matches": [
|
||||
{}
|
||||
],
|
||||
"actions": {
|
||||
"update-props": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
"matches": [
|
||||
{
|
||||
"application.process.binary": "teams"
|
||||
},
|
||||
{
|
||||
"application.process.binary": "skypeforlinux"
|
||||
}
|
||||
],
|
||||
"actions": {
|
||||
"quirks": [
|
||||
"force-s16-info"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"matches": [
|
||||
{
|
||||
"application.process.binary": "firefox"
|
||||
}
|
||||
],
|
||||
"actions": {
|
||||
"quirks": [
|
||||
"remove-capture-dont-move"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"matches": [
|
||||
{
|
||||
"application.name": "~speech-dispatcher*"
|
||||
}
|
||||
],
|
||||
"actions": {
|
||||
"update-props": {
|
||||
"pulse.min.req": "1024/48000",
|
||||
"pulse.min.quantum": "1024/48000"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
"link.max-buffers": 16,
|
||||
"core.daemon": true,
|
||||
"core.name": "pipewire-0",
|
||||
"default.clock.min-quantum": 16,
|
||||
"vm.overrides": {
|
||||
"default.clock.min-quantum": 1024
|
||||
}
|
||||
|
@ -19,8 +20,10 @@
|
|||
},
|
||||
"context.modules": [
|
||||
{
|
||||
"name": "libpipewire-module-rtkit",
|
||||
"args": {},
|
||||
"name": "libpipewire-module-rt",
|
||||
"args": {
|
||||
"nice.level": -11
|
||||
},
|
||||
"flags": [
|
||||
"ifexists",
|
||||
"nofail"
|
||||
|
|
|
@ -38,9 +38,8 @@ in {
|
|||
services.pipewire.media-session = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = config.services.pipewire.enable;
|
||||
defaultText = literalExpression "config.services.pipewire.enable";
|
||||
description = "Example pipewire session manager";
|
||||
default = false;
|
||||
description = "Whether to enable the deprecated example Pipewire session manager";
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
|
|
|
@ -25,15 +25,18 @@ let
|
|||
client = lib.importJSON ./daemon/client.conf.json;
|
||||
client-rt = lib.importJSON ./daemon/client-rt.conf.json;
|
||||
jack = lib.importJSON ./daemon/jack.conf.json;
|
||||
minimal = lib.importJSON ./daemon/minimal.conf.json;
|
||||
pipewire = lib.importJSON ./daemon/pipewire.conf.json;
|
||||
pipewire-pulse = lib.importJSON ./daemon/pipewire-pulse.conf.json;
|
||||
};
|
||||
|
||||
useSessionManager = cfg.wireplumber.enable || cfg.media-session.enable;
|
||||
|
||||
configs = {
|
||||
client = recursiveUpdate defaults.client cfg.config.client;
|
||||
client-rt = recursiveUpdate defaults.client-rt cfg.config.client-rt;
|
||||
jack = recursiveUpdate defaults.jack cfg.config.jack;
|
||||
pipewire = recursiveUpdate defaults.pipewire cfg.config.pipewire;
|
||||
pipewire = recursiveUpdate (if useSessionManager then defaults.pipewire else defaults.minimal) cfg.config.pipewire;
|
||||
pipewire-pulse = recursiveUpdate defaults.pipewire-pulse cfg.config.pipewire-pulse;
|
||||
};
|
||||
in {
|
||||
|
|
|
@ -8,15 +8,18 @@ in
|
|||
|
||||
options = {
|
||||
services.pipewire.wireplumber = {
|
||||
enable = lib.mkEnableOption "A modular session / policy manager for PipeWire";
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = config.services.pipewire.enable;
|
||||
defaultText = lib.literalExpression "config.services.pipewire.enable";
|
||||
description = "Whether to enable Wireplumber, a modular session / policy manager for PipeWire";
|
||||
};
|
||||
|
||||
package = lib.mkOption {
|
||||
type = lib.types.package;
|
||||
default = pkgs.wireplumber;
|
||||
defaultText = lib.literalExpression "pkgs.wireplumber";
|
||||
description = ''
|
||||
The wireplumber derivation to use.
|
||||
'';
|
||||
description = "The wireplumber derivation to use.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
323
third_party/nixpkgs/nixos/modules/services/development/zammad.nix
vendored
Normal file
323
third_party/nixpkgs/nixos/modules/services/development/zammad.nix
vendored
Normal file
|
@ -0,0 +1,323 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.zammad;
|
||||
settingsFormat = pkgs.formats.yaml { };
|
||||
filterNull = filterAttrs (_: v: v != null);
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
Restart = "always";
|
||||
|
||||
User = "zammad";
|
||||
Group = "zammad";
|
||||
PrivateTmp = true;
|
||||
StateDirectory = "zammad";
|
||||
WorkingDirectory = cfg.dataDir;
|
||||
};
|
||||
environment = {
|
||||
RAILS_ENV = "production";
|
||||
NODE_ENV = "production";
|
||||
RAILS_SERVE_STATIC_FILES = "true";
|
||||
RAILS_LOG_TO_STDOUT = "true";
|
||||
};
|
||||
databaseConfig = settingsFormat.generate "database.yml" cfg.database.settings;
|
||||
in
|
||||
{
|
||||
|
||||
options = {
|
||||
services.zammad = {
|
||||
enable = mkEnableOption "Zammad, a web-based, open source user support/ticketing solution.";
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.zammad;
|
||||
defaultText = literalExpression "pkgs.zammad";
|
||||
description = "Zammad package to use.";
|
||||
};
|
||||
|
||||
dataDir = mkOption {
|
||||
type = types.path;
|
||||
default = "/var/lib/zammad";
|
||||
description = ''
|
||||
Path to a folder that will contain Zammad working directory.
|
||||
'';
|
||||
};
|
||||
|
||||
host = mkOption {
|
||||
type = types.str;
|
||||
default = "127.0.0.1";
|
||||
example = "192.168.23.42";
|
||||
description = "Host address.";
|
||||
};
|
||||
|
||||
openPorts = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Whether to open firewall ports for Zammad";
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
default = 3000;
|
||||
description = "Web service port.";
|
||||
};
|
||||
|
||||
websocketPort = mkOption {
|
||||
type = types.port;
|
||||
default = 6042;
|
||||
description = "Websocket service port.";
|
||||
};
|
||||
|
||||
database = {
|
||||
type = mkOption {
|
||||
type = types.enum [ "PostgreSQL" "MySQL" ];
|
||||
default = "PostgreSQL";
|
||||
example = "MySQL";
|
||||
description = "Database engine to use.";
|
||||
};
|
||||
|
||||
host = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = {
|
||||
PostgreSQL = "/run/postgresql";
|
||||
MySQL = "localhost";
|
||||
}.${cfg.database.type};
|
||||
defaultText = literalExpression ''
|
||||
{
|
||||
PostgreSQL = "/run/postgresql";
|
||||
MySQL = "localhost";
|
||||
}.''${config.services.zammad.database.type};
|
||||
'';
|
||||
description = ''
|
||||
Database host address.
|
||||
'';
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.nullOr types.port;
|
||||
default = null;
|
||||
description = "Database port. Use <literal>null</literal> for default port.";
|
||||
};
|
||||
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
default = "zammad";
|
||||
description = ''
|
||||
Database name.
|
||||
'';
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = "zammad";
|
||||
description = "Database user.";
|
||||
};
|
||||
|
||||
passwordFile = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
default = null;
|
||||
example = "/run/keys/zammad-dbpassword";
|
||||
description = ''
|
||||
A file containing the password for <option>services.zammad.database.user</option>.
|
||||
'';
|
||||
};
|
||||
|
||||
createLocally = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Whether to create a local database automatically.";
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
type = settingsFormat.type;
|
||||
default = { };
|
||||
example = literalExpression ''
|
||||
{
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
The <filename>database.yml</filename> configuration file as key value set.
|
||||
See <link xlink:href='TODO' />
|
||||
for list of configuration parameters.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
secretKeyBaseFile = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
default = null;
|
||||
example = "/run/keys/secret_key_base";
|
||||
description = ''
|
||||
The path to a file containing the
|
||||
<literal>secret_key_base</literal> secret.
|
||||
|
||||
Zammad uses <literal>secret_key_base</literal> to encrypt
|
||||
the cookie store, which contains session data, and to digest
|
||||
user auth tokens.
|
||||
|
||||
Needs to be a 64 byte long string of hexadecimal
|
||||
characters. You can generate one by running
|
||||
|
||||
<screen>
|
||||
<prompt>$ </prompt>openssl rand -hex 64 >/path/to/secret_key_base_file
|
||||
</screen>
|
||||
|
||||
This should be a string, not a nix path, since nix paths are
|
||||
copied into the world-readable nix store.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
services.zammad.database.settings = {
|
||||
production = mapAttrs (_: v: mkDefault v) (filterNull {
|
||||
adapter = {
|
||||
PostgreSQL = "postgresql";
|
||||
MySQL = "mysql2";
|
||||
}.${cfg.database.type};
|
||||
database = cfg.database.name;
|
||||
pool = 50;
|
||||
timeout = 5000;
|
||||
encoding = "utf8";
|
||||
username = cfg.database.user;
|
||||
host = cfg.database.host;
|
||||
port = cfg.database.port;
|
||||
});
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = mkIf cfg.openPorts [
|
||||
config.services.zammad.port
|
||||
config.services.zammad.websocketPort
|
||||
];
|
||||
|
||||
users.users.zammad = {
|
||||
isSystemUser = true;
|
||||
home = cfg.dataDir;
|
||||
group = "zammad";
|
||||
};
|
||||
|
||||
users.groups.zammad = { };
|
||||
|
||||
assertions = [
|
||||
{
|
||||
assertion = cfg.database.createLocally -> cfg.database.user == "zammad";
|
||||
message = "services.zammad.database.user must be set to \"zammad\" if services.zammad.database.createLocally is set to true";
|
||||
}
|
||||
{
|
||||
assertion = cfg.database.createLocally -> cfg.database.passwordFile == null;
|
||||
message = "a password cannot be specified if services.zammad.database.createLocally is set to true";
|
||||
}
|
||||
];
|
||||
|
||||
services.mysql = optionalAttrs (cfg.database.createLocally && cfg.database.type == "MySQL") {
|
||||
enable = true;
|
||||
package = mkDefault pkgs.mariadb;
|
||||
ensureDatabases = [ cfg.database.name ];
|
||||
ensureUsers = [
|
||||
{
|
||||
name = cfg.database.user;
|
||||
ensurePermissions = { "${cfg.database.name}.*" = "ALL PRIVILEGES"; };
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
services.postgresql = optionalAttrs (cfg.database.createLocally && cfg.database.type == "PostgreSQL") {
|
||||
enable = true;
|
||||
ensureDatabases = [ cfg.database.name ];
|
||||
ensureUsers = [
|
||||
{
|
||||
name = cfg.database.user;
|
||||
ensurePermissions = { "DATABASE ${cfg.database.name}" = "ALL PRIVILEGES"; };
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
systemd.services.zammad-web = {
|
||||
inherit environment;
|
||||
serviceConfig = serviceConfig // {
|
||||
# loading all the gems takes time
|
||||
TimeoutStartSec = 1200;
|
||||
};
|
||||
after = [
|
||||
"network.target"
|
||||
"postgresql.service"
|
||||
];
|
||||
requires = [
|
||||
"postgresql.service"
|
||||
];
|
||||
description = "Zammad web";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
preStart = ''
|
||||
# Blindly copy the whole project here.
|
||||
chmod -R +w .
|
||||
rm -rf ./public/assets/*
|
||||
rm -rf ./tmp/*
|
||||
rm -rf ./log/*
|
||||
cp -r --no-preserve=owner ${cfg.package}/* .
|
||||
chmod -R +w .
|
||||
# config file
|
||||
cp ${databaseConfig} ./config/database.yml
|
||||
chmod -R +w .
|
||||
${optionalString (cfg.database.passwordFile != null) ''
|
||||
{
|
||||
echo -n " password: "
|
||||
cat ${cfg.database.passwordFile}
|
||||
} >> ./config/database.yml
|
||||
''}
|
||||
${optionalString (cfg.secretKeyBaseFile != null) ''
|
||||
{
|
||||
echo "production: "
|
||||
echo -n " secret_key_base: "
|
||||
cat ${cfg.secretKeyBaseFile}
|
||||
} > ./config/secrets.yml
|
||||
''}
|
||||
|
||||
if [ `${config.services.postgresql.package}/bin/psql \
|
||||
--host ${cfg.database.host} \
|
||||
${optionalString
|
||||
(cfg.database.port != null)
|
||||
"--port ${toString cfg.database.port}"} \
|
||||
--username ${cfg.database.user} \
|
||||
--dbname ${cfg.database.name} \
|
||||
--command "SELECT COUNT(*) FROM pg_class c \
|
||||
JOIN pg_namespace s ON s.oid = c.relnamespace \
|
||||
WHERE s.nspname NOT IN ('pg_catalog', 'pg_toast', 'information_schema') \
|
||||
AND s.nspname NOT LIKE 'pg_temp%';" | sed -n 3p` -eq 0 ]; then
|
||||
echo "Initialize database"
|
||||
./bin/rake --no-system db:migrate
|
||||
./bin/rake --no-system db:seed
|
||||
else
|
||||
echo "Migrate database"
|
||||
./bin/rake --no-system db:migrate
|
||||
fi
|
||||
echo "Done"
|
||||
'';
|
||||
script = "./script/rails server -b ${cfg.host} -p ${toString cfg.port}";
|
||||
};
|
||||
|
||||
systemd.services.zammad-websocket = {
|
||||
inherit serviceConfig environment;
|
||||
after = [ "zammad-web.service" ];
|
||||
requires = [ "zammad-web.service" ];
|
||||
description = "Zammad websocket";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
script = "./script/websocket-server.rb -b ${cfg.host} -p ${toString cfg.websocketPort} start";
|
||||
};
|
||||
|
||||
systemd.services.zammad-scheduler = {
|
||||
inherit environment;
|
||||
serviceConfig = serviceConfig // { Type = "forking"; };
|
||||
after = [ "zammad-web.service" ];
|
||||
requires = [ "zammad-web.service" ];
|
||||
description = "Zammad scheduler";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
script = "./script/scheduler.rb start";
|
||||
};
|
||||
};
|
||||
|
||||
meta.maintainers = with lib.maintainers; [ garbas taeer ];
|
||||
}
|
|
@ -32,6 +32,8 @@ with lib;
|
|||
|
||||
environment.systemPackages = [ pkgs.udisks2 ];
|
||||
|
||||
security.polkit.enable = true;
|
||||
|
||||
services.dbus.packages = [ pkgs.udisks2 ];
|
||||
|
||||
systemd.tmpfiles.rules = [ "d /var/lib/udisks2 0755 root root -" ];
|
||||
|
|
|
@ -135,7 +135,7 @@ in {
|
|||
};
|
||||
|
||||
config = mkOption {
|
||||
type = types.submodule {
|
||||
type = types.nullOr (types.submodule {
|
||||
freeformType = format.type;
|
||||
options = {
|
||||
# This is a partial selection of the most common options, so new users can quickly
|
||||
|
@ -244,7 +244,7 @@ in {
|
|||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
});
|
||||
example = literalExpression ''
|
||||
{
|
||||
homeassistant = {
|
||||
|
@ -349,10 +349,6 @@ in {
|
|||
'';
|
||||
description = ''
|
||||
The Home Assistant package to use.
|
||||
Override <literal>extraPackages</literal> or <literal>extraComponents</literal> in order to add additional dependencies.
|
||||
If you specify <option>config</option> and do not set <option>autoExtraComponents</option>
|
||||
to <literal>false</literal>, overriding <literal>extraComponents</literal> will have no effect.
|
||||
Avoid <literal>home-assistant.overridePythonAttrs</literal> if you use <literal>autoExtraComponents</literal>.
|
||||
'';
|
||||
};
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ with lib;
|
|||
|
||||
let
|
||||
cfg = config.services.logrotate;
|
||||
inherit (config.users) groups;
|
||||
|
||||
pathOpts = { name, ... }: {
|
||||
options = {
|
||||
|
@ -85,10 +84,6 @@ let
|
|||
};
|
||||
|
||||
config.name = name;
|
||||
config.extraConfig = ''
|
||||
missingok
|
||||
notifempty
|
||||
'';
|
||||
};
|
||||
|
||||
mkConf = pathOpts: ''
|
||||
|
@ -102,7 +97,11 @@ let
|
|||
'';
|
||||
|
||||
paths = sortProperties (attrValues (filterAttrs (_: pathOpts: pathOpts.enable) cfg.paths));
|
||||
configFile = pkgs.writeText "logrotate.conf" (concatStringsSep "\n" ((map mkConf paths) ++ [ cfg.extraConfig ]));
|
||||
configFile = pkgs.writeText "logrotate.conf" (
|
||||
concatStringsSep "\n" (
|
||||
[ "missingok" "notifempty" cfg.extraConfig ] ++ (map mkConf paths)
|
||||
)
|
||||
);
|
||||
|
||||
in
|
||||
{
|
||||
|
@ -112,7 +111,10 @@ in
|
|||
|
||||
options = {
|
||||
services.logrotate = {
|
||||
enable = mkEnableOption "the logrotate systemd service";
|
||||
enable = mkEnableOption "the logrotate systemd service" // {
|
||||
default = foldr (n: a: a || n.enable) false (attrValues cfg.paths);
|
||||
defaultText = literalExpression "cfg.paths != {}";
|
||||
};
|
||||
|
||||
paths = mkOption {
|
||||
type = with types; attrsOf (submodule pathOpts);
|
||||
|
@ -163,28 +165,8 @@ in
|
|||
}
|
||||
) cfg.paths;
|
||||
|
||||
services.logrotate = {
|
||||
paths = {
|
||||
"/var/log/btmp" = {
|
||||
frequency = mkDefault "monthly";
|
||||
keep = mkDefault 1;
|
||||
extraConfig = ''
|
||||
create 0660 root ${groups.utmp.name}
|
||||
'';
|
||||
};
|
||||
"/var/log/wtmp" = {
|
||||
frequency = mkDefault "monthly";
|
||||
keep = mkDefault 1;
|
||||
extraConfig = ''
|
||||
create 0664 root ${groups.utmp.name}
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.logrotate = {
|
||||
description = "Logrotate Service";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
startAt = "hourly";
|
||||
|
||||
serviceConfig = {
|
||||
|
|
773
third_party/nixpkgs/nixos/modules/services/matrix/matrix-synapse.nix
vendored
Normal file
773
third_party/nixpkgs/nixos/modules/services/matrix/matrix-synapse.nix
vendored
Normal file
|
@ -0,0 +1,773 @@
|
|||
{ config, lib, options, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.matrix-synapse;
|
||||
format = pkgs.formats.yaml {};
|
||||
|
||||
# remove null values from the final configuration
|
||||
finalSettings = lib.filterAttrsRecursive (_: v: v != null) cfg.settings;
|
||||
configFile = format.generate "homeserver.yaml" finalSettings;
|
||||
logConfigFile = format.generate "log_config.yaml" cfg.logConfig;
|
||||
|
||||
pluginsEnv = cfg.package.python.buildEnv.override {
|
||||
extraLibs = cfg.plugins;
|
||||
};
|
||||
|
||||
usePostgresql = cfg.settings.database.name == "psycopg2";
|
||||
hasLocalPostgresDB = let args = cfg.settings.database.args; in
|
||||
usePostgresql && (!(args ? host) || (elem args.host [ "localhost" "127.0.0.1" "::1" ]));
|
||||
|
||||
registerNewMatrixUser =
|
||||
let
|
||||
isIpv6 = x: lib.length (lib.splitString ":" x) > 1;
|
||||
listener =
|
||||
lib.findFirst (
|
||||
listener: lib.any (
|
||||
resource: lib.any (
|
||||
name: name == "client"
|
||||
) resource.names
|
||||
) listener.resources
|
||||
) (lib.last cfg.settings.listeners) cfg.settings.listeners;
|
||||
# FIXME: Handle cases with missing client listener properly,
|
||||
# don't rely on lib.last, this will not work.
|
||||
|
||||
# add a tail, so that without any bind_addresses we still have a useable address
|
||||
bindAddress = head (listener.bind_addresses ++ [ "127.0.0.1" ]);
|
||||
listenerProtocol = if listener.tls
|
||||
then "https"
|
||||
else "http";
|
||||
in
|
||||
pkgs.writeShellScriptBin "matrix-synapse-register_new_matrix_user" ''
|
||||
exec ${cfg.package}/bin/register_new_matrix_user \
|
||||
$@ \
|
||||
${lib.concatMapStringsSep " " (x: "-c ${x}") ([ configFile ] ++ cfg.extraConfigFiles)} \
|
||||
"${listenerProtocol}://${
|
||||
if (isIpv6 bindAddress) then
|
||||
"[${bindAddress}]"
|
||||
else
|
||||
"${bindAddress}"
|
||||
}:${builtins.toString listener.port}/"
|
||||
'';
|
||||
in {
|
||||
|
||||
imports = [
|
||||
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "trusted_third_party_id_servers" ] ''
|
||||
The `trusted_third_party_id_servers` option as been removed in `matrix-synapse` v1.4.0
|
||||
as the behavior is now obsolete.
|
||||
'')
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "create_local_database" ] ''
|
||||
Database configuration must be done manually. An exemplary setup is demonstrated in
|
||||
<nixpkgs/nixos/tests/matrix-synapse.nix>
|
||||
'')
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "web_client" ] "")
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "room_invite_state_types" ] ''
|
||||
You may add additional event types via
|
||||
`services.matrix-synapse.room_prejoin_state.additional_event_types` and
|
||||
disable the default events via
|
||||
`services.matrix-synapse.room_prejoin_state.disable_default_event_types`.
|
||||
'')
|
||||
|
||||
# options that don't exist in synapse anymore
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "bind_host" ] "Use listener settings instead." )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "bind_port" ] "Use listener settings instead." )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "expire_access_tokens" ] "" )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "no_tls" ] "It is no longer supported by synapse." )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "tls_dh_param_path" ] "It was removed from synapse." )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "unsecure_port" ] "Use settings.listeners instead." )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "user_creation_max_duration" ] "It is no longer supported by synapse." )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "verbose" ] "Use a log config instead." )
|
||||
|
||||
# options that were moved into rfc42 style settigns
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "app_service_config_files" ] "Use settings.app_service_config_Files instead" )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "database_args" ] "Use settings.database.args instead" )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "database_name" ] "Use settings.database.args.database instead" )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "database_type" ] "Use settings.database.name instead" )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "database_user" ] "Use settings.database.args.user instead" )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "dynamic_thumbnails" ] "Use settings.dynamic_thumbnails instead" )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "enable_metrics" ] "Use settings.enable_metrics instead" )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "enable_registration" ] "Use settings.enable_registration instead" )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "extraConfig" ] "Use settings instead." )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "listeners" ] "Use settings.listeners instead" )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "logConfig" ] "Use settings.log_config instead" )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "max_image_pixels" ] "Use settings.max_image_pixels instead" )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "max_upload_size" ] "Use settings.max_upload_size instead" )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "presence" "enabled" ] "Use settings.presence.enabled instead" )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "public_baseurl" ] "Use settings.public_baseurl instead" )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "report_stats" ] "Use settings.report_stats instead" )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "server_name" ] "Use settings.server_name instead" )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "servers" ] "Use settings.trusted_key_servers instead." )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "tls_certificate_path" ] "Use settings.tls_certificate_path instead" )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "tls_private_key_path" ] "Use settings.tls_private_key_path instead" )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "turn_shared_secret" ] "Use settings.turn_shared_secret instead" )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "turn_uris" ] "Use settings.turn_uris instead" )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "turn_user_lifetime" ] "Use settings.turn_user_lifetime instead" )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "url_preview_enabled" ] "Use settings.url_preview_enabled instead" )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "url_preview_ip_range_blacklist" ] "Use settings.url_preview_ip_range_blacklist instead" )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "url_preview_ip_range_whitelist" ] "Use settings.url_preview_ip_range_whitelist instead" )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "url_preview_url_blacklist" ] "Use settings.url_preview_url_blacklist instead" )
|
||||
|
||||
# options that are too specific to mention them explicitly in settings
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "account_threepid_delegates" "email" ] "Use settings.account_threepid_delegates.email instead" )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "account_threepid_delegates" "msisdn" ] "Use settings.account_threepid_delegates.msisdn instead" )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "allow_guest_access" ] "Use settings.allow_guest_access instead" )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "bcrypt_rounds" ] "Use settings.bcrypt_rounds instead" )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "enable_registration_captcha" ] "Use settings.enable_registration_captcha instead" )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "event_cache_size" ] "Use settings.event_cache_size instead" )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "federation_rc_concurrent" ] "Use settings.rc_federation.concurrent instead" )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "federation_rc_reject_limit" ] "Use settings.rc_federation.reject_limit instead" )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "federation_rc_sleep_delay" ] "Use settings.rc_federation.sleep_delay instead" )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "federation_rc_sleep_limit" ] "Use settings.rc_federation.sleep_limit instead" )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "federation_rc_window_size" ] "Use settings.rc_federation.window_size instead" )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "key_refresh_interval" ] "Use settings.key_refresh_interval instead" )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "rc_messages_burst_count" ] "Use settings.rc_messages.burst_count instead" )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "rc_messages_per_second" ] "Use settings.rc_messages.per_second instead" )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "recaptcha_private_key" ] "Use settings.recaptcha_private_key instead" )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "recaptcha_public_key" ] "Use settings.recaptcha_public_key instead" )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "redaction_retention_period" ] "Use settings.redaction_retention_period instead" )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "room_prejoin_state" "additional_event_types" ] "Use settings.room_prejoin_state.additional_event_types instead" )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "room_prejoin_state" "disable_default_event_types" ] "Use settings.room_prejoin-state.disable_default_event_types instead" )
|
||||
|
||||
# Options that should be passed via extraConfigFiles, so they are not persisted into the nix store
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "macaroon_secret_key" ] "Pass this value via extraConfigFiles instead" )
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "registration_shared_secret" ] "Pass this value via extraConfigFiles instead" )
|
||||
|
||||
];
|
||||
|
||||
options = {
|
||||
services.matrix-synapse = {
|
||||
enable = mkEnableOption "matrix.org synapse";
|
||||
|
||||
configFile = mkOption {
|
||||
type = types.str;
|
||||
readOnly = true;
|
||||
description = ''
|
||||
Path to the configuration file on the target system. Useful to configure e.g. workers
|
||||
that also need this.
|
||||
'';
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.matrix-synapse;
|
||||
defaultText = literalExpression "pkgs.matrix-synapse";
|
||||
description = ''
|
||||
Overridable attribute of the matrix synapse server package to use.
|
||||
'';
|
||||
};
|
||||
|
||||
plugins = mkOption {
|
||||
type = types.listOf types.package;
|
||||
default = [ ];
|
||||
example = literalExpression ''
|
||||
with config.services.matrix-synapse.package.plugins; [
|
||||
matrix-synapse-ldap3
|
||||
matrix-synapse-pam
|
||||
];
|
||||
'';
|
||||
description = ''
|
||||
List of additional Matrix plugins to make available.
|
||||
'';
|
||||
};
|
||||
|
||||
withJemalloc = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to preload jemalloc to reduce memory fragmentation and overall usage.
|
||||
'';
|
||||
};
|
||||
|
||||
dataDir = mkOption {
|
||||
type = types.str;
|
||||
default = "/var/lib/matrix-synapse";
|
||||
description = ''
|
||||
The directory where matrix-synapse stores its stateful data such as
|
||||
certificates, media and uploads.
|
||||
'';
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
default = {};
|
||||
description = ''
|
||||
The primary synapse configuration. See the
|
||||
<link xlink:href="https://github.com/matrix-org/synapse/blob/v${cfg.package.version}/docs/sample_config.yaml">sample configuration</link>
|
||||
for possible values.
|
||||
|
||||
Secrets should be passed in by using the <literal>extraConfigFiles</literal> option.
|
||||
'';
|
||||
type = with types; submodule {
|
||||
freeformType = format.type;
|
||||
options = {
|
||||
# This is a reduced set of popular options and defaults
|
||||
# Do not add every available option here, they can be specified
|
||||
# by the user at their own discretion. This is a freeform type!
|
||||
|
||||
server_name = mkOption {
|
||||
type = types.str;
|
||||
example = "example.com";
|
||||
default = config.networking.hostName;
|
||||
defaultText = literalExpression "config.networking.hostName";
|
||||
description = ''
|
||||
The domain name of the server, with optional explicit port.
|
||||
This is used by remote servers to look up the server address.
|
||||
This is also the last part of your UserID.
|
||||
|
||||
The server_name cannot be changed later so it is important to configure this correctly before you start Synapse.
|
||||
'';
|
||||
};
|
||||
|
||||
enable_registration = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Enable registration for new users.
|
||||
'';
|
||||
};
|
||||
|
||||
registration_shared_secret = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
If set, allows registration by anyone who also has the shared
|
||||
secret, even if registration is otherwise disabled.
|
||||
|
||||
Secrets should be passed in via <literal>extraConfigFiles</literal>!
|
||||
'';
|
||||
};
|
||||
|
||||
macaroon_secret_key = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Secret key for authentication tokens. If none is specified,
|
||||
the registration_shared_secret is used, if one is given; otherwise,
|
||||
a secret key is derived from the signing key.
|
||||
|
||||
Secrets should be passed in via <literal>extraConfigFiles</literal>!
|
||||
'';
|
||||
};
|
||||
|
||||
enable_metrics = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Enable collection and rendering of performance metrics
|
||||
'';
|
||||
};
|
||||
|
||||
report_stats = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether or not to report anonymized homeserver usage statistics.
|
||||
'';
|
||||
};
|
||||
|
||||
signing_key_path = mkOption {
|
||||
type = types.path;
|
||||
default = "${cfg.dataDir}/homeserver.signing.key";
|
||||
description = ''
|
||||
Path to the signing key to sign messages with.
|
||||
'';
|
||||
};
|
||||
|
||||
pid_file = mkOption {
|
||||
type = types.path;
|
||||
default = "/run/matrix-synapse.pid";
|
||||
readOnly = true;
|
||||
description = ''
|
||||
The file to store the PID in.
|
||||
'';
|
||||
};
|
||||
|
||||
log_config = mkOption {
|
||||
type = types.path;
|
||||
default = ./matrix-synapse-log_config.yaml;
|
||||
description = ''
|
||||
The file that holds the logging configuration.
|
||||
'';
|
||||
};
|
||||
|
||||
media_store_path = mkOption {
|
||||
type = types.path;
|
||||
default = if lib.versionAtLeast config.system.stateVersion "22.05"
|
||||
then "${cfg.dataDir}/media_store"
|
||||
else "${cfg.dataDir}/media";
|
||||
description = ''
|
||||
Directory where uploaded images and attachments are stored.
|
||||
'';
|
||||
};
|
||||
|
||||
public_baseurl = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "https://example.com:8448/";
|
||||
description = ''
|
||||
The public-facing base URL for the client API (not including _matrix/...)
|
||||
'';
|
||||
};
|
||||
|
||||
tls_certificate_path = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "/var/lib/acme/example.com/fullchain.pem";
|
||||
description = ''
|
||||
PEM encoded X509 certificate for TLS.
|
||||
You can replace the self-signed certificate that synapse
|
||||
autogenerates on launch with your own SSL certificate + key pair
|
||||
if you like. Any required intermediary certificates can be
|
||||
appended after the primary certificate in hierarchical order.
|
||||
'';
|
||||
};
|
||||
|
||||
tls_private_key_path = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "/var/lib/acme/example.com/key.pem";
|
||||
description = ''
|
||||
PEM encoded private key for TLS. Specify null if synapse is not
|
||||
speaking TLS directly.
|
||||
'';
|
||||
};
|
||||
|
||||
presence.enabled = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
example = false;
|
||||
description = ''
|
||||
Whether to enable presence tracking.
|
||||
|
||||
Presence tracking allows users to see the state (e.g online/offline)
|
||||
of other local and remote users.
|
||||
'';
|
||||
};
|
||||
|
||||
listeners = mkOption {
|
||||
type = types.listOf (types.submodule {
|
||||
options = {
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
example = 8448;
|
||||
description = ''
|
||||
The port to listen for HTTP(S) requests on.
|
||||
'';
|
||||
};
|
||||
|
||||
bind_addresses = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [
|
||||
"::1"
|
||||
"127.0.0.1"
|
||||
];
|
||||
example = literalExpression ''
|
||||
[
|
||||
"::"
|
||||
"0.0.0.0"
|
||||
]
|
||||
'';
|
||||
description = ''
|
||||
IP addresses to bind the listener to.
|
||||
'';
|
||||
};
|
||||
|
||||
type = mkOption {
|
||||
type = types.enum [
|
||||
"http"
|
||||
"manhole"
|
||||
"metrics"
|
||||
"replication"
|
||||
];
|
||||
default = "http";
|
||||
example = "metrics";
|
||||
description = ''
|
||||
The type of the listener, usually http.
|
||||
'';
|
||||
};
|
||||
|
||||
tls = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
example = false;
|
||||
description = ''
|
||||
Whether to enable TLS on the listener socket.
|
||||
'';
|
||||
};
|
||||
|
||||
x_forwarded = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
example = true;
|
||||
description = ''
|
||||
Use the X-Forwarded-For (XFF) header as the client IP and not the
|
||||
actual client IP.
|
||||
'';
|
||||
};
|
||||
|
||||
resources = mkOption {
|
||||
type = types.listOf (types.submodule {
|
||||
options = {
|
||||
names = mkOption {
|
||||
type = types.listOf (types.enum [
|
||||
"client"
|
||||
"consent"
|
||||
"federation"
|
||||
"keys"
|
||||
"media"
|
||||
"metrics"
|
||||
"openid"
|
||||
"replication"
|
||||
"static"
|
||||
]);
|
||||
description = ''
|
||||
List of resources to host on this listener.
|
||||
'';
|
||||
example = [
|
||||
"client"
|
||||
];
|
||||
};
|
||||
compress = mkOption {
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Should synapse compress HTTP responses to clients that support it?
|
||||
This should be disabled if running synapse behind a load balancer
|
||||
that can do automatic compression.
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
description = ''
|
||||
List of HTTP resources to serve on this listener.
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
default = [ {
|
||||
port = 8008;
|
||||
bind_addresses = [ "127.0.0.1" ];
|
||||
type = "http";
|
||||
tls = false;
|
||||
x_forwarded = true;
|
||||
resources = [ {
|
||||
names = [ "client" ];
|
||||
compress = true;
|
||||
} {
|
||||
names = [ "federation" ];
|
||||
compress = false;
|
||||
} ];
|
||||
} ];
|
||||
description = ''
|
||||
List of ports that Synapse should listen on, their purpose and their configuration.
|
||||
'';
|
||||
};
|
||||
|
||||
database.name = mkOption {
|
||||
type = types.enum [
|
||||
"sqlite3"
|
||||
"psycopg2"
|
||||
];
|
||||
default = if versionAtLeast config.system.stateVersion "18.03"
|
||||
then "psycopg2"
|
||||
else "sqlite3";
|
||||
defaultText = literalExpression ''
|
||||
if versionAtLeast config.system.stateVersion "18.03"
|
||||
then "psycopg2"
|
||||
else "sqlite3"
|
||||
'';
|
||||
description = ''
|
||||
The database engine name. Can be sqlite3 or psycopg2.
|
||||
'';
|
||||
};
|
||||
|
||||
database.args.database = mkOption {
|
||||
type = types.str;
|
||||
default = {
|
||||
sqlite3 = "${cfg.dataDir}/homeserver.db";
|
||||
psycopg2 = "matrix-synapse";
|
||||
}.${cfg.settings.database.name};
|
||||
defaultText = literalExpression ''
|
||||
{
|
||||
sqlite3 = "''${${options.services.matrix-synapse.dataDir}}/homeserver.db";
|
||||
psycopg2 = "matrix-synapse";
|
||||
}.''${${options.services.matrix-synapse.settings}.database.name};
|
||||
'';
|
||||
description = ''
|
||||
Name of the database when using the psycopg2 backend,
|
||||
path to the database location when using sqlite3.
|
||||
'';
|
||||
};
|
||||
|
||||
database.args.user = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = {
|
||||
sqlite3 = null;
|
||||
psycopg2 = "matrix-synapse";
|
||||
}.${cfg.settings.database.name};
|
||||
description = ''
|
||||
Username to connect with psycopg2, set to null
|
||||
when using sqlite3.
|
||||
'';
|
||||
};
|
||||
|
||||
url_preview_enabled = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
example = false;
|
||||
description = ''
|
||||
Is the preview URL API enabled? If enabled, you *must* specify an
|
||||
explicit url_preview_ip_range_blacklist of IPs that the spider is
|
||||
denied from accessing.
|
||||
'';
|
||||
};
|
||||
|
||||
url_preview_ip_range_blacklist = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [
|
||||
"10.0.0.0/8"
|
||||
"100.64.0.0/10"
|
||||
"127.0.0.0/8"
|
||||
"169.254.0.0/16"
|
||||
"172.16.0.0/12"
|
||||
"192.0.0.0/24"
|
||||
"192.0.2.0/24"
|
||||
"192.168.0.0/16"
|
||||
"192.88.99.0/24"
|
||||
"198.18.0.0/15"
|
||||
"198.51.100.0/24"
|
||||
"2001:db8::/32"
|
||||
"203.0.113.0/24"
|
||||
"224.0.0.0/4"
|
||||
"::1/128"
|
||||
"fc00::/7"
|
||||
"fe80::/10"
|
||||
"fec0::/10"
|
||||
"ff00::/8"
|
||||
];
|
||||
description = ''
|
||||
List of IP address CIDR ranges that the URL preview spider is denied
|
||||
from accessing.
|
||||
'';
|
||||
};
|
||||
|
||||
url_preview_ip_range_whitelist = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
description = ''
|
||||
List of IP address CIDR ranges that the URL preview spider is allowed
|
||||
to access even if they are specified in url_preview_ip_range_blacklist.
|
||||
'';
|
||||
};
|
||||
|
||||
url_preview_url_blacklist = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
description = ''
|
||||
Optional list of URL matches that the URL preview spider is
|
||||
denied from accessing.
|
||||
'';
|
||||
};
|
||||
|
||||
max_upload_size = mkOption {
|
||||
type = types.str;
|
||||
default = "50M";
|
||||
example = "100M";
|
||||
description = ''
|
||||
The largest allowed upload size in bytes
|
||||
'';
|
||||
};
|
||||
|
||||
max_image_pixels = mkOption {
|
||||
type = types.str;
|
||||
default = "32M";
|
||||
example = "64M";
|
||||
description = ''
|
||||
Maximum number of pixels that will be thumbnailed
|
||||
'';
|
||||
};
|
||||
|
||||
dynamic_thumbnails = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
example = true;
|
||||
description = ''
|
||||
Whether to generate new thumbnails on the fly to precisely match
|
||||
the resolution requested by the client. If true then whenever
|
||||
a new resolution is requested by the client the server will
|
||||
generate a new thumbnail. If false the server will pick a thumbnail
|
||||
from a precalculated list.
|
||||
'';
|
||||
};
|
||||
|
||||
turn_uris = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
example = [
|
||||
"turn:turn.example.com:3487?transport=udp"
|
||||
"turn:turn.example.com:3487?transport=tcp"
|
||||
"turns:turn.example.com:5349?transport=udp"
|
||||
"turns:turn.example.com:5349?transport=tcp"
|
||||
];
|
||||
description = ''
|
||||
The public URIs of the TURN server to give to clients
|
||||
'';
|
||||
};
|
||||
turn_shared_secret = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
example = literalExpression ''
|
||||
config.services.coturn.static-auth-secret
|
||||
'';
|
||||
description = ''
|
||||
The shared secret used to compute passwords for the TURN server.
|
||||
|
||||
Secrets should be passed in via <literal>extraConfigFiles</literal>!
|
||||
'';
|
||||
};
|
||||
|
||||
trusted_key_servers = mkOption {
|
||||
type = types.listOf (types.submodule {
|
||||
options = {
|
||||
server_name = mkOption {
|
||||
type = types.str;
|
||||
example = "matrix.org";
|
||||
description = ''
|
||||
Hostname of the trusted server.
|
||||
'';
|
||||
};
|
||||
|
||||
verify_keys = mkOption {
|
||||
type = types.nullOr (types.attrsOf types.str);
|
||||
default = null;
|
||||
example = literalExpression ''
|
||||
{
|
||||
"ed25519:auto" = "Noi6WqcDj0QmPxCNQqgezwTlBKrfqehY1u2FyWP9uYw";
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Attribute set from key id to base64 encoded public key.
|
||||
|
||||
If specified synapse will check that the response is signed
|
||||
by at least one of the given keys.
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
default = [ {
|
||||
server_name = "matrix.org";
|
||||
verify_keys = {
|
||||
"ed25519:auto" = "Noi6WqcDj0QmPxCNQqgezwTlBKrfqehY1u2FyWP9uYw";
|
||||
};
|
||||
} ];
|
||||
description = ''
|
||||
The trusted servers to download signing keys from.
|
||||
'';
|
||||
};
|
||||
|
||||
app_service_config_files = mkOption {
|
||||
type = types.listOf types.path;
|
||||
default = [ ];
|
||||
description = ''
|
||||
A list of application service config file to use
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
extraConfigFiles = mkOption {
|
||||
type = types.listOf types.path;
|
||||
default = [];
|
||||
description = ''
|
||||
Extra config files to include.
|
||||
|
||||
The configuration files will be included based on the command line
|
||||
argument --config-path. This allows to configure secrets without
|
||||
having to go through the Nix store, e.g. based on deployment keys if
|
||||
NixOps is in use.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
assertions = [
|
||||
{ assertion = hasLocalPostgresDB -> config.services.postgresql.enable;
|
||||
message = ''
|
||||
Cannot deploy matrix-synapse with a configuration for a local postgresql database
|
||||
and a missing postgresql service. Since 20.03 it's mandatory to manually configure the
|
||||
database (please read the thread in https://github.com/NixOS/nixpkgs/pull/80447 for
|
||||
further reference).
|
||||
|
||||
If you
|
||||
- try to deploy a fresh synapse, you need to configure the database yourself. An example
|
||||
for this can be found in <nixpkgs/nixos/tests/matrix-synapse.nix>
|
||||
- update your existing matrix-synapse instance, you simply need to add `services.postgresql.enable = true`
|
||||
to your configuration.
|
||||
|
||||
For further information about this update, please read the release-notes of 20.03 carefully.
|
||||
'';
|
||||
}
|
||||
];
|
||||
|
||||
services.matrix-synapse.configFile = configFile;
|
||||
|
||||
users.users.matrix-synapse = {
|
||||
group = "matrix-synapse";
|
||||
home = cfg.dataDir;
|
||||
createHome = true;
|
||||
shell = "${pkgs.bash}/bin/bash";
|
||||
uid = config.ids.uids.matrix-synapse;
|
||||
};
|
||||
|
||||
users.groups.matrix-synapse = {
|
||||
gid = config.ids.gids.matrix-synapse;
|
||||
};
|
||||
|
||||
systemd.services.matrix-synapse = {
|
||||
description = "Synapse Matrix homeserver";
|
||||
after = [ "network.target" ] ++ optional hasLocalPostgresDB "postgresql.service";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
preStart = ''
|
||||
${cfg.package}/bin/synapse_homeserver \
|
||||
--config-path ${configFile} \
|
||||
--keys-directory ${cfg.dataDir} \
|
||||
--generate-keys
|
||||
'';
|
||||
environment = {
|
||||
PYTHONPATH = makeSearchPathOutput "lib" cfg.package.python.sitePackages [ pluginsEnv ];
|
||||
} // optionalAttrs (cfg.withJemalloc) {
|
||||
LD_PRELOAD = "${pkgs.jemalloc}/lib/libjemalloc.so";
|
||||
};
|
||||
serviceConfig = {
|
||||
Type = "notify";
|
||||
User = "matrix-synapse";
|
||||
Group = "matrix-synapse";
|
||||
WorkingDirectory = cfg.dataDir;
|
||||
ExecStartPre = [ ("+" + (pkgs.writeShellScript "matrix-synapse-fix-permissions" ''
|
||||
chown matrix-synapse:matrix-synapse ${cfg.dataDir}/homeserver.signing.key
|
||||
chmod 0600 ${cfg.dataDir}/homeserver.signing.key
|
||||
'')) ];
|
||||
ExecStart = ''
|
||||
${cfg.package}/bin/synapse_homeserver \
|
||||
${ concatMapStringsSep "\n " (x: "--config-path ${x} \\") ([ configFile ] ++ cfg.extraConfigFiles) }
|
||||
--keys-directory ${cfg.dataDir}
|
||||
'';
|
||||
ExecReload = "${pkgs.util-linux}/bin/kill -HUP $MAINPID";
|
||||
Restart = "on-failure";
|
||||
UMask = "0077";
|
||||
};
|
||||
};
|
||||
|
||||
environment.systemPackages = [ registerNewMatrixUser ];
|
||||
};
|
||||
|
||||
meta = {
|
||||
buildDocsInSandbox = false;
|
||||
doc = ./matrix-synapse.xml;
|
||||
maintainers = teams.matrix.members;
|
||||
};
|
||||
|
||||
}
|
|
@ -115,20 +115,21 @@ in {
|
|||
};
|
||||
services.matrix-synapse = {
|
||||
<link linkend="opt-services.matrix-synapse.enable">enable</link> = true;
|
||||
<link linkend="opt-services.matrix-synapse.server_name">server_name</link> = config.networking.domain;
|
||||
<link linkend="opt-services.matrix-synapse.listeners">listeners</link> = [
|
||||
<link linkend="opt-services.matrix-synapse.settings.server_name">server_name</link> = config.networking.domain;
|
||||
<link linkend="opt-services.matrix-synapse.settings.listeners">listeners</link> = [
|
||||
{
|
||||
<link linkend="opt-services.matrix-synapse.listeners._.port">port</link> = 8008;
|
||||
<link linkend="opt-services.matrix-synapse.listeners._.bind_address">bind_address</link> = "::1";
|
||||
<link linkend="opt-services.matrix-synapse.listeners._.type">type</link> = "http";
|
||||
<link linkend="opt-services.matrix-synapse.listeners._.tls">tls</link> = false;
|
||||
<link linkend="opt-services.matrix-synapse.listeners._.x_forwarded">x_forwarded</link> = true;
|
||||
<link linkend="opt-services.matrix-synapse.listeners._.resources">resources</link> = [
|
||||
{
|
||||
<link linkend="opt-services.matrix-synapse.listeners._.resources._.names">names</link> = [ "client" "federation" ];
|
||||
<link linkend="opt-services.matrix-synapse.listeners._.resources._.compress">compress</link> = false;
|
||||
}
|
||||
];
|
||||
<link linkend="opt-services.matrix-synapse.settings.listeners._.port">port</link> = 8008;
|
||||
<link linkend="opt-services.matrix-synapse.settings.listeners._.bind_addresses">bind_address</link> = [ "::1" ];
|
||||
<link linkend="opt-services.matrix-synapse.settings.listeners._.type">type</link> = "http";
|
||||
<link linkend="opt-services.matrix-synapse.settings.listeners._.tls">tls</link> = false;
|
||||
<link linkend="opt-services.matrix-synapse.settings.listeners._.x_forwarded">x_forwarded</link> = true;
|
||||
<link linkend="opt-services.matrix-synapse.settings.listeners._.resources">resources</link> = [ {
|
||||
<link linkend="opt-services.matrix-synapse.settings.listeners._.resources._.names">names</link> = [ "client" ];
|
||||
<link linkend="opt-services.matrix-synapse.settings.listeners._.resources._.compress">compress</link> = true;
|
||||
} {
|
||||
<link linkend="opt-services.matrix-synapse.settings.listeners._.resources._.names">names</link> = [ "federation" ];
|
||||
<link linkend="opt-services.matrix-synapse.settings.listeners._.resources._.compress">compress</link> = false;
|
||||
} ];
|
||||
}
|
||||
];
|
||||
};
|
||||
|
@ -151,11 +152,11 @@ in {
|
|||
|
||||
<para>
|
||||
If you want to run a server with public registration by anybody, you can
|
||||
then enable <literal><link linkend="opt-services.matrix-synapse.enable_registration">services.matrix-synapse.enable_registration</link> =
|
||||
then enable <literal><link linkend="opt-services.matrix-synapse.settings.enable_registration">services.matrix-synapse.enable_registration</link> =
|
||||
true;</literal>. Otherwise, or you can generate a registration secret with
|
||||
<command>pwgen -s 64 1</command> and set it with
|
||||
<option><link linkend="opt-services.matrix-synapse.registration_shared_secret">services.matrix-synapse.registration_shared_secret</link></option>. To
|
||||
create a new user or admin, run the following after you have set the secret
|
||||
<option><link linkend="opt-services.matrix-synapse.settings.registration_shared_secret">services.matrix-synapse.registration_shared_secret</link></option>.
|
||||
To create a new user or admin, run the following after you have set the secret
|
||||
and have rebuilt NixOS:
|
||||
<screen>
|
||||
<prompt>$ </prompt>nix run nixpkgs.matrix-synapse
|
||||
|
@ -170,7 +171,7 @@ Success!
|
|||
<literal>@your-username:example.org</literal>. Note that the registration
|
||||
secret ends up in the nix store and therefore is world-readable by any user
|
||||
on your machine, so it makes sense to only temporarily activate the
|
||||
<link linkend="opt-services.matrix-synapse.registration_shared_secret">registration_shared_secret</link>
|
||||
<link linkend="opt-services.matrix-synapse.settings.registration_shared_secret">registration_shared_secret</link>
|
||||
option until a better solution for NixOS is in place.
|
||||
</para>
|
||||
</section>
|
|
@ -1,844 +0,0 @@
|
|||
{ config, lib, options, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.matrix-synapse;
|
||||
opt = options.services.matrix-synapse;
|
||||
pg = config.services.postgresql;
|
||||
usePostgresql = cfg.database_type == "psycopg2";
|
||||
logConfigFile = pkgs.writeText "log_config.yaml" cfg.logConfig;
|
||||
mkResource = r: ''{names: ${builtins.toJSON r.names}, compress: ${boolToString r.compress}}'';
|
||||
mkListener = l: ''{port: ${toString l.port}, bind_address: "${l.bind_address}", type: ${l.type}, tls: ${boolToString l.tls}, x_forwarded: ${boolToString l.x_forwarded}, resources: [${concatStringsSep "," (map mkResource l.resources)}]}'';
|
||||
pluginsEnv = cfg.package.python.buildEnv.override {
|
||||
extraLibs = cfg.plugins;
|
||||
};
|
||||
configFile = pkgs.writeText "homeserver.yaml" ''
|
||||
${optionalString (cfg.tls_certificate_path != null) ''
|
||||
tls_certificate_path: "${cfg.tls_certificate_path}"
|
||||
''}
|
||||
${optionalString (cfg.tls_private_key_path != null) ''
|
||||
tls_private_key_path: "${cfg.tls_private_key_path}"
|
||||
''}
|
||||
${optionalString (cfg.tls_dh_params_path != null) ''
|
||||
tls_dh_params_path: "${cfg.tls_dh_params_path}"
|
||||
''}
|
||||
no_tls: ${boolToString cfg.no_tls}
|
||||
${optionalString (cfg.bind_port != null) ''
|
||||
bind_port: ${toString cfg.bind_port}
|
||||
''}
|
||||
${optionalString (cfg.unsecure_port != null) ''
|
||||
unsecure_port: ${toString cfg.unsecure_port}
|
||||
''}
|
||||
${optionalString (cfg.bind_host != null) ''
|
||||
bind_host: "${cfg.bind_host}"
|
||||
''}
|
||||
server_name: "${cfg.server_name}"
|
||||
pid_file: "/run/matrix-synapse.pid"
|
||||
${optionalString (cfg.public_baseurl != null) ''
|
||||
public_baseurl: "${cfg.public_baseurl}"
|
||||
''}
|
||||
listeners: [${concatStringsSep "," (map mkListener cfg.listeners)}]
|
||||
database: {
|
||||
name: "${cfg.database_type}",
|
||||
args: {
|
||||
${concatStringsSep ",\n " (
|
||||
mapAttrsToList (n: v: "\"${n}\": ${builtins.toJSON v}") cfg.database_args
|
||||
)}
|
||||
}
|
||||
}
|
||||
event_cache_size: "${cfg.event_cache_size}"
|
||||
verbose: ${cfg.verbose}
|
||||
log_config: "${logConfigFile}"
|
||||
rc_messages_per_second: ${cfg.rc_messages_per_second}
|
||||
rc_message_burst_count: ${cfg.rc_message_burst_count}
|
||||
federation_rc_window_size: ${cfg.federation_rc_window_size}
|
||||
federation_rc_sleep_limit: ${cfg.federation_rc_sleep_limit}
|
||||
federation_rc_sleep_delay: ${cfg.federation_rc_sleep_delay}
|
||||
federation_rc_reject_limit: ${cfg.federation_rc_reject_limit}
|
||||
federation_rc_concurrent: ${cfg.federation_rc_concurrent}
|
||||
media_store_path: "${cfg.dataDir}/media"
|
||||
uploads_path: "${cfg.dataDir}/uploads"
|
||||
max_upload_size: "${cfg.max_upload_size}"
|
||||
max_image_pixels: "${cfg.max_image_pixels}"
|
||||
dynamic_thumbnails: ${boolToString cfg.dynamic_thumbnails}
|
||||
url_preview_enabled: ${boolToString cfg.url_preview_enabled}
|
||||
${optionalString (cfg.url_preview_enabled == true) ''
|
||||
url_preview_ip_range_blacklist: ${builtins.toJSON cfg.url_preview_ip_range_blacklist}
|
||||
url_preview_ip_range_whitelist: ${builtins.toJSON cfg.url_preview_ip_range_whitelist}
|
||||
url_preview_url_blacklist: ${builtins.toJSON cfg.url_preview_url_blacklist}
|
||||
''}
|
||||
recaptcha_private_key: "${cfg.recaptcha_private_key}"
|
||||
recaptcha_public_key: "${cfg.recaptcha_public_key}"
|
||||
enable_registration_captcha: ${boolToString cfg.enable_registration_captcha}
|
||||
turn_uris: ${builtins.toJSON cfg.turn_uris}
|
||||
turn_shared_secret: "${cfg.turn_shared_secret}"
|
||||
enable_registration: ${boolToString cfg.enable_registration}
|
||||
${optionalString (cfg.registration_shared_secret != null) ''
|
||||
registration_shared_secret: "${cfg.registration_shared_secret}"
|
||||
''}
|
||||
recaptcha_siteverify_api: "https://www.google.com/recaptcha/api/siteverify"
|
||||
turn_user_lifetime: "${cfg.turn_user_lifetime}"
|
||||
user_creation_max_duration: ${cfg.user_creation_max_duration}
|
||||
bcrypt_rounds: ${cfg.bcrypt_rounds}
|
||||
allow_guest_access: ${boolToString cfg.allow_guest_access}
|
||||
|
||||
account_threepid_delegates:
|
||||
${optionalString (cfg.account_threepid_delegates.email != null) "email: ${cfg.account_threepid_delegates.email}"}
|
||||
${optionalString (cfg.account_threepid_delegates.msisdn != null) "msisdn: ${cfg.account_threepid_delegates.msisdn}"}
|
||||
|
||||
room_prejoin_state:
|
||||
disable_default_event_types: ${boolToString cfg.room_prejoin_state.disable_default_event_types}
|
||||
additional_event_types: ${builtins.toJSON cfg.room_prejoin_state.additional_event_types}
|
||||
${optionalString (cfg.macaroon_secret_key != null) ''
|
||||
macaroon_secret_key: "${cfg.macaroon_secret_key}"
|
||||
''}
|
||||
expire_access_token: ${boolToString cfg.expire_access_token}
|
||||
enable_metrics: ${boolToString cfg.enable_metrics}
|
||||
report_stats: ${boolToString cfg.report_stats}
|
||||
signing_key_path: "${cfg.dataDir}/homeserver.signing.key"
|
||||
key_refresh_interval: "${cfg.key_refresh_interval}"
|
||||
perspectives:
|
||||
servers: {
|
||||
${concatStringsSep "},\n" (mapAttrsToList (n: v: ''
|
||||
"${n}": {
|
||||
"verify_keys": {
|
||||
${concatStringsSep "},\n" (mapAttrsToList (n: v: ''
|
||||
"${n}": {
|
||||
"key": "${v}"
|
||||
}'') v)}
|
||||
}
|
||||
'') cfg.servers)}
|
||||
}
|
||||
}
|
||||
redaction_retention_period: ${toString cfg.redaction_retention_period}
|
||||
app_service_config_files: ${builtins.toJSON cfg.app_service_config_files}
|
||||
|
||||
${cfg.extraConfig}
|
||||
'';
|
||||
|
||||
hasLocalPostgresDB = let args = cfg.database_args; in
|
||||
usePostgresql && (!(args ? host) || (elem args.host [ "localhost" "127.0.0.1" "::1" ]));
|
||||
|
||||
registerNewMatrixUser =
|
||||
let
|
||||
isIpv6 = x: lib.length (lib.splitString ":" x) > 1;
|
||||
listener =
|
||||
lib.findFirst (
|
||||
listener: lib.any (
|
||||
resource: lib.any (
|
||||
name: name == "client"
|
||||
) resource.names
|
||||
) listener.resources
|
||||
) (lib.last cfg.listeners) cfg.listeners;
|
||||
in
|
||||
pkgs.writeShellScriptBin "matrix-synapse-register_new_matrix_user" ''
|
||||
exec ${cfg.package}/bin/register_new_matrix_user \
|
||||
$@ \
|
||||
${lib.concatMapStringsSep " " (x: "-c ${x}") ([ configFile ] ++ cfg.extraConfigFiles)} \
|
||||
"${listener.type}://${
|
||||
if (isIpv6 listener.bind_address) then
|
||||
"[${listener.bind_address}]"
|
||||
else
|
||||
"${listener.bind_address}"
|
||||
}:${builtins.toString listener.port}/"
|
||||
'';
|
||||
in {
|
||||
options = {
|
||||
services.matrix-synapse = {
|
||||
enable = mkEnableOption "matrix.org synapse";
|
||||
configFile = mkOption {
|
||||
type = types.str;
|
||||
readOnly = true;
|
||||
description = ''
|
||||
Path to the configuration file on the target system. Useful to configure e.g. workers
|
||||
that also need this.
|
||||
'';
|
||||
};
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.matrix-synapse;
|
||||
defaultText = literalExpression "pkgs.matrix-synapse";
|
||||
description = ''
|
||||
Overridable attribute of the matrix synapse server package to use.
|
||||
'';
|
||||
};
|
||||
plugins = mkOption {
|
||||
type = types.listOf types.package;
|
||||
default = [ ];
|
||||
example = literalExpression ''
|
||||
with config.services.matrix-synapse.package.plugins; [
|
||||
matrix-synapse-ldap3
|
||||
matrix-synapse-pam
|
||||
];
|
||||
'';
|
||||
description = ''
|
||||
List of additional Matrix plugins to make available.
|
||||
'';
|
||||
};
|
||||
withJemalloc = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to preload jemalloc to reduce memory fragmentation and overall usage.
|
||||
'';
|
||||
};
|
||||
no_tls = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Don't bind to the https port
|
||||
'';
|
||||
};
|
||||
bind_port = mkOption {
|
||||
type = types.nullOr types.int;
|
||||
default = null;
|
||||
example = 8448;
|
||||
description = ''
|
||||
DEPRECATED: Use listeners instead.
|
||||
The port to listen for HTTPS requests on.
|
||||
For when matrix traffic is sent directly to synapse.
|
||||
'';
|
||||
};
|
||||
unsecure_port = mkOption {
|
||||
type = types.nullOr types.int;
|
||||
default = null;
|
||||
example = 8008;
|
||||
description = ''
|
||||
DEPRECATED: Use listeners instead.
|
||||
The port to listen for HTTP requests on.
|
||||
For when matrix traffic passes through loadbalancer that unwraps TLS.
|
||||
'';
|
||||
};
|
||||
bind_host = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
DEPRECATED: Use listeners instead.
|
||||
Local interface to listen on.
|
||||
The empty string will cause synapse to listen on all interfaces.
|
||||
'';
|
||||
};
|
||||
tls_certificate_path = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "/var/lib/matrix-synapse/homeserver.tls.crt";
|
||||
description = ''
|
||||
PEM encoded X509 certificate for TLS.
|
||||
You can replace the self-signed certificate that synapse
|
||||
autogenerates on launch with your own SSL certificate + key pair
|
||||
if you like. Any required intermediary certificates can be
|
||||
appended after the primary certificate in hierarchical order.
|
||||
'';
|
||||
};
|
||||
tls_private_key_path = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "/var/lib/matrix-synapse/homeserver.tls.key";
|
||||
description = ''
|
||||
PEM encoded private key for TLS. Specify null if synapse is not
|
||||
speaking TLS directly.
|
||||
'';
|
||||
};
|
||||
tls_dh_params_path = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "/var/lib/matrix-synapse/homeserver.tls.dh";
|
||||
description = ''
|
||||
PEM dh parameters for ephemeral keys
|
||||
'';
|
||||
};
|
||||
server_name = mkOption {
|
||||
type = types.str;
|
||||
example = "example.com";
|
||||
default = config.networking.hostName;
|
||||
defaultText = literalExpression "config.networking.hostName";
|
||||
description = ''
|
||||
The domain name of the server, with optional explicit port.
|
||||
This is used by remote servers to look up the server address.
|
||||
This is also the last part of your UserID.
|
||||
|
||||
The server_name cannot be changed later so it is important to configure this correctly before you start Synapse.
|
||||
'';
|
||||
};
|
||||
public_baseurl = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "https://example.com:8448/";
|
||||
description = ''
|
||||
The public-facing base URL for the client API (not including _matrix/...)
|
||||
'';
|
||||
};
|
||||
listeners = mkOption {
|
||||
type = types.listOf (types.submodule {
|
||||
options = {
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
example = 8448;
|
||||
description = ''
|
||||
The port to listen for HTTP(S) requests on.
|
||||
'';
|
||||
};
|
||||
bind_address = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
example = "203.0.113.42";
|
||||
description = ''
|
||||
Local interface to listen on.
|
||||
The empty string will cause synapse to listen on all interfaces.
|
||||
'';
|
||||
};
|
||||
type = mkOption {
|
||||
type = types.str;
|
||||
default = "http";
|
||||
description = ''
|
||||
Type of listener.
|
||||
'';
|
||||
};
|
||||
tls = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to listen for HTTPS connections rather than HTTP.
|
||||
'';
|
||||
};
|
||||
x_forwarded = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Use the X-Forwarded-For (XFF) header as the client IP and not the
|
||||
actual client IP.
|
||||
'';
|
||||
};
|
||||
resources = mkOption {
|
||||
type = types.listOf (types.submodule {
|
||||
options = {
|
||||
names = mkOption {
|
||||
type = types.listOf types.str;
|
||||
description = ''
|
||||
List of resources to host on this listener.
|
||||
'';
|
||||
example = ["client" "federation"];
|
||||
};
|
||||
compress = mkOption {
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Should synapse compress HTTP responses to clients that support it?
|
||||
This should be disabled if running synapse behind a load balancer
|
||||
that can do automatic compression.
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
description = ''
|
||||
List of HTTP resources to serve on this listener.
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
default = [{
|
||||
port = 8448;
|
||||
bind_address = "";
|
||||
type = "http";
|
||||
tls = true;
|
||||
x_forwarded = false;
|
||||
resources = [
|
||||
{ names = ["client"]; compress = true; }
|
||||
{ names = ["federation"]; compress = false; }
|
||||
];
|
||||
}];
|
||||
description = ''
|
||||
List of ports that Synapse should listen on, their purpose and their configuration.
|
||||
'';
|
||||
};
|
||||
verbose = mkOption {
|
||||
type = types.str;
|
||||
default = "0";
|
||||
description = "Logging verbosity level.";
|
||||
};
|
||||
rc_messages_per_second = mkOption {
|
||||
type = types.str;
|
||||
default = "0.2";
|
||||
description = "Number of messages a client can send per second";
|
||||
};
|
||||
rc_message_burst_count = mkOption {
|
||||
type = types.str;
|
||||
default = "10.0";
|
||||
description = "Number of message a client can send before being throttled";
|
||||
};
|
||||
federation_rc_window_size = mkOption {
|
||||
type = types.str;
|
||||
default = "1000";
|
||||
description = "The federation window size in milliseconds";
|
||||
};
|
||||
federation_rc_sleep_limit = mkOption {
|
||||
type = types.str;
|
||||
default = "10";
|
||||
description = ''
|
||||
The number of federation requests from a single server in a window
|
||||
before the server will delay processing the request.
|
||||
'';
|
||||
};
|
||||
federation_rc_sleep_delay = mkOption {
|
||||
type = types.str;
|
||||
default = "500";
|
||||
description = ''
|
||||
The duration in milliseconds to delay processing events from
|
||||
remote servers by if they go over the sleep limit.
|
||||
'';
|
||||
};
|
||||
federation_rc_reject_limit = mkOption {
|
||||
type = types.str;
|
||||
default = "50";
|
||||
description = ''
|
||||
The maximum number of concurrent federation requests allowed
|
||||
from a single server
|
||||
'';
|
||||
};
|
||||
federation_rc_concurrent = mkOption {
|
||||
type = types.str;
|
||||
default = "3";
|
||||
description = "The number of federation requests to concurrently process from a single server";
|
||||
};
|
||||
database_type = mkOption {
|
||||
type = types.enum [ "sqlite3" "psycopg2" ];
|
||||
default = if versionAtLeast config.system.stateVersion "18.03"
|
||||
then "psycopg2"
|
||||
else "sqlite3";
|
||||
defaultText = literalExpression ''
|
||||
if versionAtLeast config.system.stateVersion "18.03"
|
||||
then "psycopg2"
|
||||
else "sqlite3"
|
||||
'';
|
||||
description = ''
|
||||
The database engine name. Can be sqlite or psycopg2.
|
||||
'';
|
||||
};
|
||||
database_name = mkOption {
|
||||
type = types.str;
|
||||
default = "matrix-synapse";
|
||||
description = "Database name.";
|
||||
};
|
||||
database_user = mkOption {
|
||||
type = types.str;
|
||||
default = "matrix-synapse";
|
||||
description = "Database user name.";
|
||||
};
|
||||
database_args = mkOption {
|
||||
type = types.attrs;
|
||||
default = {
|
||||
sqlite3 = { database = "${cfg.dataDir}/homeserver.db"; };
|
||||
psycopg2 = {
|
||||
user = cfg.database_user;
|
||||
database = cfg.database_name;
|
||||
};
|
||||
}.${cfg.database_type};
|
||||
defaultText = literalDocBook ''
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>using sqlite3</term>
|
||||
<listitem>
|
||||
<programlisting>
|
||||
{ database = "''${config.${opt.dataDir}}/homeserver.db"; }
|
||||
</programlisting>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>using psycopg2</term>
|
||||
<listitem>
|
||||
<programlisting>
|
||||
psycopg2 = {
|
||||
user = config.${opt.database_user};
|
||||
database = config.${opt.database_name};
|
||||
}
|
||||
</programlisting>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
'';
|
||||
description = ''
|
||||
Arguments to pass to the engine.
|
||||
'';
|
||||
};
|
||||
event_cache_size = mkOption {
|
||||
type = types.str;
|
||||
default = "10K";
|
||||
description = "Number of events to cache in memory.";
|
||||
};
|
||||
url_preview_enabled = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Is the preview URL API enabled? If enabled, you *must* specify an
|
||||
explicit url_preview_ip_range_blacklist of IPs that the spider is
|
||||
denied from accessing.
|
||||
'';
|
||||
};
|
||||
url_preview_ip_range_blacklist = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [
|
||||
"127.0.0.0/8"
|
||||
"10.0.0.0/8"
|
||||
"172.16.0.0/12"
|
||||
"192.168.0.0/16"
|
||||
"100.64.0.0/10"
|
||||
"169.254.0.0/16"
|
||||
"::1/128"
|
||||
"fe80::/64"
|
||||
"fc00::/7"
|
||||
];
|
||||
description = ''
|
||||
List of IP address CIDR ranges that the URL preview spider is denied
|
||||
from accessing.
|
||||
'';
|
||||
};
|
||||
url_preview_ip_range_whitelist = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
description = ''
|
||||
List of IP address CIDR ranges that the URL preview spider is allowed
|
||||
to access even if they are specified in
|
||||
url_preview_ip_range_blacklist.
|
||||
'';
|
||||
};
|
||||
url_preview_url_blacklist = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
description = ''
|
||||
Optional list of URL matches that the URL preview spider is
|
||||
denied from accessing.
|
||||
'';
|
||||
};
|
||||
recaptcha_private_key = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
This Home Server's ReCAPTCHA private key.
|
||||
'';
|
||||
};
|
||||
recaptcha_public_key = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
This Home Server's ReCAPTCHA public key.
|
||||
'';
|
||||
};
|
||||
enable_registration_captcha = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Enables ReCaptcha checks when registering, preventing signup
|
||||
unless a captcha is answered. Requires a valid ReCaptcha
|
||||
public/private key.
|
||||
'';
|
||||
};
|
||||
turn_uris = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
description = ''
|
||||
The public URIs of the TURN server to give to clients
|
||||
'';
|
||||
};
|
||||
turn_shared_secret = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
The shared secret used to compute passwords for the TURN server
|
||||
'';
|
||||
};
|
||||
turn_user_lifetime = mkOption {
|
||||
type = types.str;
|
||||
default = "1h";
|
||||
description = "How long generated TURN credentials last";
|
||||
};
|
||||
enable_registration = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Enable registration for new users.
|
||||
'';
|
||||
};
|
||||
registration_shared_secret = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
If set, allows registration by anyone who also has the shared
|
||||
secret, even if registration is otherwise disabled.
|
||||
'';
|
||||
};
|
||||
enable_metrics = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Enable collection and rendering of performance metrics
|
||||
'';
|
||||
};
|
||||
report_stats = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "";
|
||||
};
|
||||
servers = mkOption {
|
||||
type = types.attrsOf (types.attrsOf types.str);
|
||||
default = {
|
||||
"matrix.org" = {
|
||||
"ed25519:auto" = "Noi6WqcDj0QmPxCNQqgezwTlBKrfqehY1u2FyWP9uYw";
|
||||
};
|
||||
};
|
||||
description = ''
|
||||
The trusted servers to download signing keys from.
|
||||
'';
|
||||
};
|
||||
max_upload_size = mkOption {
|
||||
type = types.str;
|
||||
default = "10M";
|
||||
description = "The largest allowed upload size in bytes";
|
||||
};
|
||||
max_image_pixels = mkOption {
|
||||
type = types.str;
|
||||
default = "32M";
|
||||
description = "Maximum number of pixels that will be thumbnailed";
|
||||
};
|
||||
dynamic_thumbnails = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to generate new thumbnails on the fly to precisely match
|
||||
the resolution requested by the client. If true then whenever
|
||||
a new resolution is requested by the client the server will
|
||||
generate a new thumbnail. If false the server will pick a thumbnail
|
||||
from a precalculated list.
|
||||
'';
|
||||
};
|
||||
user_creation_max_duration = mkOption {
|
||||
type = types.str;
|
||||
default = "1209600000";
|
||||
description = ''
|
||||
Sets the expiry for the short term user creation in
|
||||
milliseconds. The default value is two weeks.
|
||||
'';
|
||||
};
|
||||
bcrypt_rounds = mkOption {
|
||||
type = types.str;
|
||||
default = "12";
|
||||
description = ''
|
||||
Set the number of bcrypt rounds used to generate password hash.
|
||||
Larger numbers increase the work factor needed to generate the hash.
|
||||
'';
|
||||
};
|
||||
allow_guest_access = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Allows users to register as guests without a password/email/etc, and
|
||||
participate in rooms hosted on this server which have been made
|
||||
accessible to anonymous users.
|
||||
'';
|
||||
};
|
||||
account_threepid_delegates.email = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Delegate email sending to https://example.org
|
||||
'';
|
||||
};
|
||||
account_threepid_delegates.msisdn = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Delegate SMS sending to this local process (https://localhost:8090)
|
||||
'';
|
||||
};
|
||||
room_prejoin_state.additional_event_types = mkOption {
|
||||
default = [];
|
||||
type = types.listOf types.str;
|
||||
description = ''
|
||||
Additional events to share with users who received an invite.
|
||||
'';
|
||||
};
|
||||
room_prejoin_state.disable_default_event_types = mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Whether to disable the default state-event types for users invited to a room.
|
||||
These are:
|
||||
|
||||
<itemizedlist>
|
||||
<listitem><para>m.room.join_rules</para></listitem>
|
||||
<listitem><para>m.room.canonical_alias</para></listitem>
|
||||
<listitem><para>m.room.avatar</para></listitem>
|
||||
<listitem><para>m.room.encryption</para></listitem>
|
||||
<listitem><para>m.room.name</para></listitem>
|
||||
<listitem><para>m.room.create</para></listitem>
|
||||
</itemizedlist>
|
||||
'';
|
||||
};
|
||||
macaroon_secret_key = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Secret key for authentication tokens
|
||||
'';
|
||||
};
|
||||
expire_access_token = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to enable access token expiration.
|
||||
'';
|
||||
};
|
||||
key_refresh_interval = mkOption {
|
||||
type = types.str;
|
||||
default = "1d";
|
||||
description = ''
|
||||
How long key response published by this server is valid for.
|
||||
Used to set the valid_until_ts in /key/v2 APIs.
|
||||
Determines how quickly servers will query to check which keys
|
||||
are still valid.
|
||||
'';
|
||||
};
|
||||
app_service_config_files = mkOption {
|
||||
type = types.listOf types.path;
|
||||
default = [ ];
|
||||
description = ''
|
||||
A list of application service config file to use
|
||||
'';
|
||||
};
|
||||
redaction_retention_period = mkOption {
|
||||
type = types.int;
|
||||
default = 7;
|
||||
description = ''
|
||||
How long to keep redacted events in unredacted form in the database.
|
||||
'';
|
||||
};
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = ''
|
||||
Extra config options for matrix-synapse.
|
||||
'';
|
||||
};
|
||||
extraConfigFiles = mkOption {
|
||||
type = types.listOf types.path;
|
||||
default = [];
|
||||
description = ''
|
||||
Extra config files to include.
|
||||
|
||||
The configuration files will be included based on the command line
|
||||
argument --config-path. This allows to configure secrets without
|
||||
having to go through the Nix store, e.g. based on deployment keys if
|
||||
NixOPS is in use.
|
||||
'';
|
||||
};
|
||||
logConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = readFile ./matrix-synapse-log_config.yaml;
|
||||
description = ''
|
||||
A yaml python logging config file
|
||||
'';
|
||||
};
|
||||
dataDir = mkOption {
|
||||
type = types.str;
|
||||
default = "/var/lib/matrix-synapse";
|
||||
description = ''
|
||||
The directory where matrix-synapse stores its stateful data such as
|
||||
certificates, media and uploads.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
assertions = [
|
||||
{ assertion = hasLocalPostgresDB -> config.services.postgresql.enable;
|
||||
message = ''
|
||||
Cannot deploy matrix-synapse with a configuration for a local postgresql database
|
||||
and a missing postgresql service. Since 20.03 it's mandatory to manually configure the
|
||||
database (please read the thread in https://github.com/NixOS/nixpkgs/pull/80447 for
|
||||
further reference).
|
||||
|
||||
If you
|
||||
- try to deploy a fresh synapse, you need to configure the database yourself. An example
|
||||
for this can be found in <nixpkgs/nixos/tests/matrix-synapse.nix>
|
||||
- update your existing matrix-synapse instance, you simply need to add `services.postgresql.enable = true`
|
||||
to your configuration.
|
||||
|
||||
For further information about this update, please read the release-notes of 20.03 carefully.
|
||||
'';
|
||||
}
|
||||
];
|
||||
|
||||
services.matrix-synapse.configFile = "${configFile}";
|
||||
|
||||
users.users.matrix-synapse = {
|
||||
group = "matrix-synapse";
|
||||
home = cfg.dataDir;
|
||||
createHome = true;
|
||||
shell = "${pkgs.bash}/bin/bash";
|
||||
uid = config.ids.uids.matrix-synapse;
|
||||
};
|
||||
|
||||
users.groups.matrix-synapse = {
|
||||
gid = config.ids.gids.matrix-synapse;
|
||||
};
|
||||
|
||||
systemd.services.matrix-synapse = {
|
||||
description = "Synapse Matrix homeserver";
|
||||
after = [ "network.target" ] ++ optional hasLocalPostgresDB "postgresql.service";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
preStart = ''
|
||||
${cfg.package}/bin/synapse_homeserver \
|
||||
--config-path ${configFile} \
|
||||
--keys-directory ${cfg.dataDir} \
|
||||
--generate-keys
|
||||
'';
|
||||
environment = {
|
||||
PYTHONPATH = makeSearchPathOutput "lib" cfg.package.python.sitePackages [ pluginsEnv ];
|
||||
} // optionalAttrs (cfg.withJemalloc) {
|
||||
LD_PRELOAD = "${pkgs.jemalloc}/lib/libjemalloc.so";
|
||||
};
|
||||
serviceConfig = {
|
||||
Type = "notify";
|
||||
User = "matrix-synapse";
|
||||
Group = "matrix-synapse";
|
||||
WorkingDirectory = cfg.dataDir;
|
||||
ExecStartPre = [ ("+" + (pkgs.writeShellScript "matrix-synapse-fix-permissions" ''
|
||||
chown matrix-synapse:matrix-synapse ${cfg.dataDir}/homeserver.signing.key
|
||||
chmod 0600 ${cfg.dataDir}/homeserver.signing.key
|
||||
'')) ];
|
||||
ExecStart = ''
|
||||
${cfg.package}/bin/synapse_homeserver \
|
||||
${ concatMapStringsSep "\n " (x: "--config-path ${x} \\") ([ configFile ] ++ cfg.extraConfigFiles) }
|
||||
--keys-directory ${cfg.dataDir}
|
||||
'';
|
||||
ExecReload = "${pkgs.util-linux}/bin/kill -HUP $MAINPID";
|
||||
Restart = "on-failure";
|
||||
UMask = "0077";
|
||||
};
|
||||
};
|
||||
|
||||
environment.systemPackages = [ registerNewMatrixUser ];
|
||||
};
|
||||
|
||||
imports = [
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "trusted_third_party_id_servers" ] ''
|
||||
The `trusted_third_party_id_servers` option as been removed in `matrix-synapse` v1.4.0
|
||||
as the behavior is now obsolete.
|
||||
'')
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "create_local_database" ] ''
|
||||
Database configuration must be done manually. An exemplary setup is demonstrated in
|
||||
<nixpkgs/nixos/tests/matrix-synapse.nix>
|
||||
'')
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "web_client" ] "")
|
||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "room_invite_state_types" ] ''
|
||||
You may add additional event types via
|
||||
`services.matrix-synapse.room_prejoin_state.additional_event_types` and
|
||||
disable the default events via
|
||||
`services.matrix-synapse.room_prejoin_state.disable_default_event_types`.
|
||||
'')
|
||||
];
|
||||
|
||||
meta.doc = ./matrix-synapse.xml;
|
||||
meta.maintainers = teams.matrix.members;
|
||||
|
||||
}
|
|
@ -730,6 +730,40 @@ in
|
|||
};
|
||||
|
||||
restartTriggers = [ nixConf ];
|
||||
|
||||
# `stopIfChanged = false` changes to switch behavior
|
||||
# from stop -> update units -> start
|
||||
# to update units -> restart
|
||||
#
|
||||
# The `stopIfChanged` setting therefore controls a trade-off between a
|
||||
# more predictable lifecycle, which runs the correct "version" of
|
||||
# the `ExecStop` line, and on the other hand the availability of
|
||||
# sockets during the switch, as the effectiveness of the stop operation
|
||||
# depends on the socket being stopped as well.
|
||||
#
|
||||
# As `nix-daemon.service` does not make use of `ExecStop`, we prefer
|
||||
# to keep the socket up and available. This is important for machines
|
||||
# that run Nix-based services, such as automated build, test, and deploy
|
||||
# services, that expect the daemon socket to be available at all times.
|
||||
#
|
||||
# Notably, the Nix client does not retry on failure to connect to the
|
||||
# daemon socket, and the in-process RemoteStore instance will disable
|
||||
# itself. This makes retries infeasible even for services that are
|
||||
# aware of the issue. Failure to connect can affect not only new client
|
||||
# processes, but also new RemoteStore instances in existing processes,
|
||||
# as well as existing RemoteStore instances that have not saturated
|
||||
# their connection pool.
|
||||
#
|
||||
# Also note that `stopIfChanged = true` does not kill existing
|
||||
# connection handling daemons, as one might wish to happen before a
|
||||
# breaking Nix upgrade (which is rare). The daemon forks that handle
|
||||
# the individual connections split off into their own sessions, causing
|
||||
# them not to be stopped by systemd.
|
||||
# If a Nix upgrade does require all existing daemon processes to stop,
|
||||
# nix-daemon must do so on its own accord, and only when the new version
|
||||
# starts and detects that Nix's persistent state needs an upgrade.
|
||||
stopIfChanged = false;
|
||||
|
||||
};
|
||||
|
||||
# Set up the environment variables for running Nix.
|
||||
|
|
|
@ -55,6 +55,19 @@ in
|
|||
symlinks in Plex's plugin directory will be cleared and this module
|
||||
will symlink all of the paths specified here to that directory.
|
||||
'';
|
||||
example = literalExpression ''
|
||||
[
|
||||
(builtins.path {
|
||||
name = "Audnexus.bundle";
|
||||
path = pkgs.fetchFromGitHub {
|
||||
owner = "djdembeck";
|
||||
repo = "Audnexus.bundle";
|
||||
rev = "v0.2.8";
|
||||
sha256 = "sha256-IWOSz3vYL7zhdHan468xNc6C/eQ2C2BukQlaJNLXh7E=";
|
||||
};
|
||||
})
|
||||
]
|
||||
'';
|
||||
};
|
||||
|
||||
extraScanners = mkOption {
|
||||
|
|
|
@ -259,7 +259,7 @@ in
|
|||
ipfs --offline config Mounts.IPFS ${cfg.ipfsMountDir}
|
||||
ipfs --offline config Mounts.IPNS ${cfg.ipnsMountDir}
|
||||
'' + optionalString cfg.autoMigrate ''
|
||||
${pkgs.ipfs-migrator}/bin/fs-repo-migrations -y
|
||||
${pkgs.ipfs-migrator}/bin/fs-repo-migrations -to '${cfg.package.repoVersion}' -y
|
||||
'' + ''
|
||||
ipfs --offline config show \
|
||||
| ${pkgs.jq}/bin/jq '. * $extraConfig' --argjson extraConfig ${
|
||||
|
|
|
@ -3,103 +3,101 @@
|
|||
let
|
||||
inherit (lib) mkEnableOption mkIf mkOption optionalString types;
|
||||
|
||||
generic = variant:
|
||||
let
|
||||
cfg = config.services.${variant};
|
||||
pkg = pkgs.${variant};
|
||||
birdBin = if variant == "bird6" then "bird6" else "bird";
|
||||
birdc = if variant == "bird6" then "birdc6" else "birdc";
|
||||
descr =
|
||||
{ bird = "1.6.x with IPv4 support";
|
||||
bird6 = "1.6.x with IPv6 support";
|
||||
bird2 = "2.x";
|
||||
}.${variant};
|
||||
in {
|
||||
###### interface
|
||||
options = {
|
||||
services.${variant} = {
|
||||
enable = mkEnableOption "BIRD Internet Routing Daemon (${descr})";
|
||||
config = mkOption {
|
||||
type = types.lines;
|
||||
description = ''
|
||||
BIRD Internet Routing Daemon configuration file.
|
||||
<link xlink:href='http://bird.network.cz/'/>
|
||||
'';
|
||||
};
|
||||
checkConfig = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether the config should be checked at build time.
|
||||
When the config can't be checked during build time, for example when it includes
|
||||
other files, either disable this option or use <code>preCheckConfig</code> to create
|
||||
the included files before checking.
|
||||
'';
|
||||
};
|
||||
preCheckConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
example = ''
|
||||
echo "cost 100;" > include.conf
|
||||
'';
|
||||
description = ''
|
||||
Commands to execute before the config file check. The file to be checked will be
|
||||
available as <code>${variant}.conf</code> in the current directory.
|
||||
|
||||
Files created with this option will not be available at service runtime, only during
|
||||
build time checking.
|
||||
'';
|
||||
};
|
||||
};
|
||||
cfg = config.services.bird2;
|
||||
caps = [ "CAP_NET_ADMIN" "CAP_NET_BIND_SERVICE" "CAP_NET_RAW" ];
|
||||
in
|
||||
{
|
||||
###### interface
|
||||
options = {
|
||||
services.bird2 = {
|
||||
enable = mkEnableOption "BIRD Internet Routing Daemon";
|
||||
config = mkOption {
|
||||
type = types.lines;
|
||||
description = ''
|
||||
BIRD Internet Routing Daemon configuration file.
|
||||
<link xlink:href='http://bird.network.cz/'/>
|
||||
'';
|
||||
};
|
||||
checkConfig = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether the config should be checked at build time.
|
||||
When the config can't be checked during build time, for example when it includes
|
||||
other files, either disable this option or use <code>preCheckConfig</code> to create
|
||||
the included files before checking.
|
||||
'';
|
||||
};
|
||||
preCheckConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
example = ''
|
||||
echo "cost 100;" > include.conf
|
||||
'';
|
||||
description = ''
|
||||
Commands to execute before the config file check. The file to be checked will be
|
||||
available as <code>bird2.conf</code> in the current directory.
|
||||
|
||||
###### implementation
|
||||
config = mkIf cfg.enable {
|
||||
environment.systemPackages = [ pkg ];
|
||||
|
||||
environment.etc."bird/${variant}.conf".source = pkgs.writeTextFile {
|
||||
name = "${variant}.conf";
|
||||
text = cfg.config;
|
||||
checkPhase = optionalString cfg.checkConfig ''
|
||||
ln -s $out ${variant}.conf
|
||||
${cfg.preCheckConfig}
|
||||
${pkg}/bin/${birdBin} -d -p -c ${variant}.conf
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.services.${variant} = {
|
||||
description = "BIRD Internet Routing Daemon (${descr})";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
reloadIfChanged = true;
|
||||
restartTriggers = [ config.environment.etc."bird/${variant}.conf".source ];
|
||||
serviceConfig = {
|
||||
Type = "forking";
|
||||
Restart = "on-failure";
|
||||
ExecStart = "${pkg}/bin/${birdBin} -c /etc/bird/${variant}.conf -u ${variant} -g ${variant}";
|
||||
ExecReload = "/bin/sh -c '${pkg}/bin/${birdBin} -c /etc/bird/${variant}.conf -p && ${pkg}/bin/${birdc} configure'";
|
||||
ExecStop = "${pkg}/bin/${birdc} down";
|
||||
CapabilityBoundingSet = [ "CAP_CHOWN" "CAP_FOWNER" "CAP_DAC_OVERRIDE" "CAP_SETUID" "CAP_SETGID"
|
||||
# see bird/sysdep/linux/syspriv.h
|
||||
"CAP_NET_BIND_SERVICE" "CAP_NET_BROADCAST" "CAP_NET_ADMIN" "CAP_NET_RAW" ];
|
||||
ProtectSystem = "full";
|
||||
ProtectHome = "yes";
|
||||
SystemCallFilter="~@cpu-emulation @debug @keyring @module @mount @obsolete @raw-io";
|
||||
MemoryDenyWriteExecute = "yes";
|
||||
};
|
||||
};
|
||||
users = {
|
||||
users.${variant} = {
|
||||
description = "BIRD Internet Routing Daemon user";
|
||||
group = variant;
|
||||
isSystemUser = true;
|
||||
};
|
||||
groups.${variant} = {};
|
||||
};
|
||||
Files created with this option will not be available at service runtime, only during
|
||||
build time checking.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
imports = map generic [ "bird" "bird6" "bird2" ];
|
||||
imports = [
|
||||
(lib.mkRemovedOptionModule [ "services" "bird" ] "Use services.bird2 instead")
|
||||
(lib.mkRemovedOptionModule [ "services" "bird6" ] "Use services.bird2 instead")
|
||||
];
|
||||
|
||||
###### implementation
|
||||
config = mkIf cfg.enable {
|
||||
environment.systemPackages = [ pkgs.bird ];
|
||||
|
||||
environment.etc."bird/bird2.conf".source = pkgs.writeTextFile {
|
||||
name = "bird2";
|
||||
text = cfg.config;
|
||||
checkPhase = optionalString cfg.checkConfig ''
|
||||
ln -s $out bird2.conf
|
||||
${cfg.preCheckConfig}
|
||||
${pkgs.bird}/bin/bird -d -p -c bird2.conf
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.services.bird2 = {
|
||||
description = "BIRD Internet Routing Daemon";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
reloadIfChanged = true;
|
||||
restartTriggers = [ config.environment.etc."bird/bird2.conf".source ];
|
||||
serviceConfig = {
|
||||
Type = "forking";
|
||||
Restart = "on-failure";
|
||||
User = "bird2";
|
||||
Group = "bird2";
|
||||
ExecStart = "${pkgs.bird}/bin/bird -c /etc/bird/bird2.conf";
|
||||
ExecReload = "${pkgs.bird}/bin/birdc configure";
|
||||
ExecStop = "${pkgs.bird}/bin/birdc down";
|
||||
RuntimeDirectory = "bird";
|
||||
CapabilityBoundingSet = caps;
|
||||
AmbientCapabilities = caps;
|
||||
ProtectSystem = "full";
|
||||
ProtectHome = "yes";
|
||||
ProtectKernelTunables = true;
|
||||
ProtectControlGroups = true;
|
||||
PrivateTmp = true;
|
||||
PrivateDevices = true;
|
||||
SystemCallFilter = "~@cpu-emulation @debug @keyring @module @mount @obsolete @raw-io";
|
||||
MemoryDenyWriteExecute = "yes";
|
||||
};
|
||||
};
|
||||
users = {
|
||||
users.bird2 = {
|
||||
description = "BIRD Internet Routing Daemon user";
|
||||
group = "bird2";
|
||||
isSystemUser = true;
|
||||
};
|
||||
groups.bird2 = { };
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -306,7 +306,7 @@ in
|
|||
Type = if forking then "forking" else "simple";
|
||||
PIDFile = mkIf forking "/run/murmur/murmurd.pid";
|
||||
EnvironmentFile = mkIf (cfg.environmentFile != null) cfg.environmentFile;
|
||||
ExecStart = "${cfg.package}/bin/murmurd -ini /run/murmur/murmurd.ini";
|
||||
ExecStart = "${cfg.package}/bin/mumble-server -ini /run/murmur/murmurd.ini";
|
||||
Restart = "always";
|
||||
RuntimeDirectory = "murmur";
|
||||
RuntimeDirectoryMode = "0700";
|
||||
|
|
|
@ -556,6 +556,7 @@ in {
|
|||
|
||||
boot.kernelModules = [ "ctr" ];
|
||||
|
||||
security.polkit.enable = true;
|
||||
security.polkit.extraConfig = polkitConf;
|
||||
|
||||
services.dbus.packages = cfg.packages
|
||||
|
|
81
third_party/nixpkgs/nixos/modules/services/networking/snowflake-proxy.nix
vendored
Normal file
81
third_party/nixpkgs/nixos/modules/services/networking/snowflake-proxy.nix
vendored
Normal file
|
@ -0,0 +1,81 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.snowflake-proxy;
|
||||
in
|
||||
{
|
||||
options = {
|
||||
services.snowflake-proxy = {
|
||||
enable = mkEnableOption "System to defeat internet censorship";
|
||||
|
||||
broker = mkOption {
|
||||
description = "Broker URL (default \"https://snowflake-broker.torproject.net/\")";
|
||||
type = with types; nullOr str;
|
||||
default = null;
|
||||
};
|
||||
|
||||
capacity = mkOption {
|
||||
description = "Limits the amount of maximum concurrent clients allowed.";
|
||||
type = with types; nullOr int;
|
||||
default = null;
|
||||
};
|
||||
|
||||
relay = mkOption {
|
||||
description = "websocket relay URL (default \"wss://snowflake.bamsoftware.com/\")";
|
||||
type = with types; nullOr str;
|
||||
default = null;
|
||||
};
|
||||
|
||||
stun = mkOption {
|
||||
description = "STUN broker URL (default \"stun:stun.stunprotocol.org:3478\")";
|
||||
type = with types; nullOr str;
|
||||
default = null;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
systemd.services.snowflake-proxy = {
|
||||
wantedBy = [ "network-online.target" ];
|
||||
serviceConfig = {
|
||||
ExecStart =
|
||||
"${pkgs.snowflake}/bin/proxy " + concatStringsSep " " (
|
||||
optional (cfg.broker != null) "-broker ${cfg.broker}"
|
||||
++ optional (cfg.capacity != null) "-capacity ${builtins.toString cfg.capacity}"
|
||||
++ optional (cfg.relay != null) "-relay ${cfg.relay}"
|
||||
++ optional (cfg.stun != null) "-stun ${cfg.stun}"
|
||||
);
|
||||
|
||||
# Security Hardening
|
||||
# Refer to systemd.exec(5) for option descriptions.
|
||||
CapabilityBoundingSet = "";
|
||||
|
||||
# implies RemoveIPC=, PrivateTmp=, NoNewPrivileges=, RestrictSUIDSGID=,
|
||||
# ProtectSystem=strict, ProtectHome=read-only
|
||||
DynamicUser = true;
|
||||
LockPersonality = true;
|
||||
PrivateDevices = true;
|
||||
PrivateUsers = true;
|
||||
ProcSubset = "pid";
|
||||
ProtectClock = true;
|
||||
ProtectControlGroups = true;
|
||||
ProtectHome = true;
|
||||
ProtectHostname = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectProc = "invisible";
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
RestrictAddressFamilies = [ "AF_INET" "AF_INET6" "AF_UNIX" ];
|
||||
RestrictNamespaces = true;
|
||||
RestrictRealtime = true;
|
||||
SystemCallArchitectures = "native";
|
||||
SystemCallFilter = "~@clock @cpu-emulation @debug @mount @obsolete @reboot @swap @privileged @resources";
|
||||
UMask = "0077";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
meta.maintainers = with maintainers; [ yayayayaka ];
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
options.services.tetrd.enable = lib.mkEnableOption pkgs.tetrd.meta.description;
|
||||
options.services.tetrd.enable = lib.mkEnableOption "tetrd";
|
||||
|
||||
config = lib.mkIf config.services.tetrd.enable {
|
||||
environment = {
|
||||
|
|
|
@ -9,7 +9,7 @@ let
|
|||
pkg = pkgs.clamav;
|
||||
|
||||
toKeyValue = generators.toKeyValue {
|
||||
mkKeyValue = generators.mkKeyValueDefault {} " ";
|
||||
mkKeyValue = generators.mkKeyValueDefault { } " ";
|
||||
listsAsDuplicateKeys = true;
|
||||
};
|
||||
|
||||
|
@ -30,7 +30,7 @@ in
|
|||
|
||||
settings = mkOption {
|
||||
type = with types; attrsOf (oneOf [ bool int str (listOf str) ]);
|
||||
default = {};
|
||||
default = { };
|
||||
description = ''
|
||||
ClamAV configuration. Refer to <link xlink:href="https://linux.die.net/man/5/clamd.conf"/>,
|
||||
for details on supported values.
|
||||
|
@ -59,7 +59,7 @@ in
|
|||
|
||||
settings = mkOption {
|
||||
type = with types; attrsOf (oneOf [ bool int str (listOf str) ]);
|
||||
default = {};
|
||||
default = { };
|
||||
description = ''
|
||||
freshclam configuration. Refer to <link xlink:href="https://linux.die.net/man/5/freshclam.conf"/>,
|
||||
for details on supported values.
|
||||
|
@ -104,7 +104,6 @@ in
|
|||
systemd.services.clamav-daemon = mkIf cfg.daemon.enable {
|
||||
description = "ClamAV daemon (clamd)";
|
||||
after = optional cfg.updater.enable "clamav-freshclam.service";
|
||||
requires = optional cfg.updater.enable "clamav-freshclam.service";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
restartTriggers = [ clamdConfigFile ];
|
||||
|
||||
|
@ -134,7 +133,7 @@ in
|
|||
systemd.services.clamav-freshclam = mkIf cfg.updater.enable {
|
||||
description = "ClamAV virus database updater (freshclam)";
|
||||
restartTriggers = [ freshclamConfigFile ];
|
||||
|
||||
after = [ "network-online.target" ];
|
||||
preStart = ''
|
||||
mkdir -m 0755 -p ${stateDir}
|
||||
chown ${clamavUser}:${clamavGroup} ${stateDir}
|
||||
|
|
|
@ -1,82 +0,0 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
with lib;
|
||||
let
|
||||
fprotUser = "fprot";
|
||||
stateDir = "/var/lib/fprot";
|
||||
fprotGroup = fprotUser;
|
||||
cfg = config.services.fprot;
|
||||
in {
|
||||
options = {
|
||||
|
||||
services.fprot = {
|
||||
updater = {
|
||||
enable = mkEnableOption "automatic F-Prot virus definitions database updates";
|
||||
|
||||
productData = mkOption {
|
||||
description = ''
|
||||
product.data file. Defaults to the one supplied with installation package.
|
||||
'';
|
||||
type = types.path;
|
||||
};
|
||||
|
||||
frequency = mkOption {
|
||||
default = 30;
|
||||
type = types.int;
|
||||
description = ''
|
||||
Update virus definitions every X minutes.
|
||||
'';
|
||||
};
|
||||
|
||||
licenseKeyfile = mkOption {
|
||||
type = types.path;
|
||||
description = ''
|
||||
License keyfile. Defaults to the one supplied with installation package.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf cfg.updater.enable {
|
||||
|
||||
services.fprot.updater.productData = mkDefault "${pkgs.fprot}/opt/f-prot/product.data";
|
||||
services.fprot.updater.licenseKeyfile = mkDefault "${pkgs.fprot}/opt/f-prot/license.key";
|
||||
|
||||
environment.systemPackages = [ pkgs.fprot ];
|
||||
environment.etc."f-prot.conf" = {
|
||||
source = "${pkgs.fprot}/opt/f-prot/f-prot.conf";
|
||||
};
|
||||
|
||||
users.users.${fprotUser} =
|
||||
{ uid = config.ids.uids.fprot;
|
||||
description = "F-Prot daemon user";
|
||||
home = stateDir;
|
||||
};
|
||||
|
||||
users.groups.${fprotGroup} =
|
||||
{ gid = config.ids.gids.fprot; };
|
||||
|
||||
services.cron.systemCronJobs = [ "*/${toString cfg.updater.frequency} * * * * root start fprot-updater" ];
|
||||
|
||||
systemd.services.fprot-updater = {
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = false;
|
||||
};
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
# have to copy fpupdate executable because it insists on storing the virus database in the same dir
|
||||
preStart = ''
|
||||
mkdir -m 0755 -p ${stateDir}
|
||||
chown ${fprotUser}:${fprotGroup} ${stateDir}
|
||||
cp ${pkgs.fprot}/opt/f-prot/fpupdate ${stateDir}
|
||||
ln -sf ${cfg.updater.productData} ${stateDir}/product.data
|
||||
'';
|
||||
|
||||
script = "/var/lib/fprot/fpupdate --keyfile ${cfg.updater.licenseKeyfile}";
|
||||
};
|
||||
};
|
||||
}
|
|
@ -3,22 +3,123 @@
|
|||
with lib;
|
||||
|
||||
let
|
||||
name = "opensnitch";
|
||||
cfg = config.services.opensnitch;
|
||||
format = pkgs.formats.json {};
|
||||
in {
|
||||
options = {
|
||||
services.opensnitch = {
|
||||
enable = mkEnableOption "Opensnitch application firewall";
|
||||
settings = mkOption {
|
||||
type = types.submodule {
|
||||
freeformType = format.type;
|
||||
|
||||
options = {
|
||||
Server = {
|
||||
|
||||
Address = mkOption {
|
||||
type = 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;
|
||||
description = ''
|
||||
File to write logs to (use /dev/stdout to write logs to standard
|
||||
output).
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
DefaultAction = mkOption {
|
||||
type = types.enum [ "allow" "deny" ];
|
||||
description = ''
|
||||
Default action whether to block or allow application internet
|
||||
access.
|
||||
'';
|
||||
};
|
||||
|
||||
DefaultDuration = mkOption {
|
||||
type = types.enum [
|
||||
"once" "always" "until restart" "30s" "5m" "15m" "30m" "1h"
|
||||
];
|
||||
description = ''
|
||||
Default duration of firewall rule.
|
||||
'';
|
||||
};
|
||||
|
||||
InterceptUnknown = mkOption {
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Wheter to intercept spare connections.
|
||||
'';
|
||||
};
|
||||
|
||||
ProcMonitorMethod = mkOption {
|
||||
type = types.enum [ "ebpf" "proc" "ftrace" "audit" ];
|
||||
description = ''
|
||||
Which process monitoring method to use.
|
||||
'';
|
||||
};
|
||||
|
||||
LogLevel = mkOption {
|
||||
type = types.enum [ 0 1 2 3 4 ];
|
||||
description = ''
|
||||
Default log level from 0 to 4 (debug, info, important, warning,
|
||||
error).
|
||||
'';
|
||||
};
|
||||
|
||||
Firewall = mkOption {
|
||||
type = types.enum [ "iptables" "nftables" ];
|
||||
description = ''
|
||||
Which firewall backend to use.
|
||||
'';
|
||||
};
|
||||
|
||||
Stats = {
|
||||
|
||||
MaxEvents = mkOption {
|
||||
type = types.int;
|
||||
description = ''
|
||||
Max events to send to the GUI.
|
||||
'';
|
||||
};
|
||||
|
||||
MaxStats = mkOption {
|
||||
type = types.int;
|
||||
description = ''
|
||||
Max stats per item to keep in backlog.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
};
|
||||
description = ''
|
||||
opensnitchd configuration. Refer to
|
||||
<link xlink:href="https://github.com/evilsocket/opensnitch/wiki/Configurations"/>
|
||||
for details on supported values.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = 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) (builtins.fromJSON (builtins.unsafeDiscardStringContext (builtins.readFile "${pkgs.opensnitch}/etc/default-config.json")));
|
||||
|
||||
systemd = {
|
||||
packages = [ pkgs.opensnitch ];
|
||||
services.opensnitchd.wantedBy = [ "multi-user.target" ];
|
||||
};
|
||||
|
||||
environment.etc."opensnitchd/default-config.json".source = format.generate "default-config.json" cfg.settings;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -106,6 +106,9 @@ in
|
|||
ConditionFileNotEmpty = ""; # override upstream
|
||||
};
|
||||
serviceConfig = {
|
||||
User = "step-ca";
|
||||
Group = "step-ca";
|
||||
UMask = "0077";
|
||||
Environment = "HOME=%S/step-ca";
|
||||
WorkingDirectory = ""; # override upstream
|
||||
ReadWriteDirectories = ""; # override upstream
|
||||
|
@ -127,6 +130,14 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
users.users.step-ca = {
|
||||
home = "/var/lib/step-ca";
|
||||
group = "step-ca";
|
||||
isSystemUser = true;
|
||||
};
|
||||
|
||||
users.groups.step-ca = {};
|
||||
|
||||
networking.firewall = lib.mkIf cfg.openFirewall {
|
||||
allowedTCPPorts = [ cfg.port ];
|
||||
};
|
||||
|
|
|
@ -151,7 +151,7 @@ in {
|
|||
};
|
||||
|
||||
systemd.services.backup-vaultwarden = mkIf (cfg.backupDir != null) {
|
||||
aliases = [ "backup-bitwarden_rs" ];
|
||||
aliases = [ "backup-bitwarden_rs.service" ];
|
||||
description = "Backup vaultwarden";
|
||||
environment = {
|
||||
DATA_FOLDER = "/var/lib/bitwarden_rs";
|
||||
|
@ -169,7 +169,7 @@ in {
|
|||
};
|
||||
|
||||
systemd.timers.backup-vaultwarden = mkIf (cfg.backupDir != null) {
|
||||
aliases = [ "backup-bitwarden_rs" ];
|
||||
aliases = [ "backup-bitwarden_rs.service" ];
|
||||
description = "Backup vaultwarden on time";
|
||||
timerConfig = {
|
||||
OnCalendar = mkDefault "23:00";
|
||||
|
|
|
@ -39,20 +39,12 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
useKernelOOMKiller= mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Use kernel OOM killer instead of own user-space implementation.
|
||||
'';
|
||||
};
|
||||
|
||||
# TODO: remove or warn after 1.7 (https://github.com/rfjakob/earlyoom/commit/7ebc4554)
|
||||
ignoreOOMScoreAdjust = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Ignore oom_score_adjust values of processes.
|
||||
User-space implementation only.
|
||||
'';
|
||||
};
|
||||
|
||||
|
@ -87,16 +79,21 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
imports = [
|
||||
(mkRemovedOptionModule [ "services" "earlyoom" "useKernelOOMKiller" ] ''
|
||||
This option is deprecated and ignored by earlyoom since 1.2.
|
||||
'')
|
||||
];
|
||||
|
||||
config = mkIf ecfg.enable {
|
||||
assertions = [
|
||||
{ assertion = ecfg.freeMemThreshold > 0 && ecfg.freeMemThreshold <= 100;
|
||||
message = "Needs to be a positive percentage"; }
|
||||
{ assertion = ecfg.freeSwapThreshold > 0 && ecfg.freeSwapThreshold <= 100;
|
||||
message = "Needs to be a positive percentage"; }
|
||||
{ assertion = !ecfg.useKernelOOMKiller || !ecfg.ignoreOOMScoreAdjust;
|
||||
message = "Both options in conjunction do not make sense"; }
|
||||
];
|
||||
|
||||
# TODO: reimplement this option as -N after 1.7 (https://github.com/rfjakob/earlyoom/commit/afe03606)
|
||||
warnings = optional (ecfg.notificationsCommand != null)
|
||||
"`services.earlyoom.notificationsCommand` is deprecated and ignored by earlyoom since 1.6.";
|
||||
|
||||
|
@ -107,15 +104,13 @@ in
|
|||
serviceConfig = {
|
||||
StandardOutput = "null";
|
||||
StandardError = "journal";
|
||||
ExecStart = ''
|
||||
${pkgs.earlyoom}/bin/earlyoom \
|
||||
-m ${toString ecfg.freeMemThreshold} \
|
||||
-s ${toString ecfg.freeSwapThreshold} \
|
||||
${optionalString ecfg.useKernelOOMKiller "-k"} \
|
||||
${optionalString ecfg.ignoreOOMScoreAdjust "-i"} \
|
||||
${optionalString ecfg.enableDebugInfo "-d"} \
|
||||
${optionalString ecfg.enableNotifications "-n"}
|
||||
'';
|
||||
ExecStart = concatStringsSep " " ([
|
||||
"${pkgs.earlyoom}/bin/earlyoom"
|
||||
"-m ${toString ecfg.freeMemThreshold}"
|
||||
"-s ${toString ecfg.freeSwapThreshold}"
|
||||
] ++ optional ecfg.ignoreOOMScoreAdjust "-i"
|
||||
++ optional ecfg.enableDebugInfo "-d"
|
||||
++ optional ecfg.enableNotifications "-n");
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -81,6 +81,8 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
security.polkit.enable = true;
|
||||
|
||||
security.pam.services.cage.text = ''
|
||||
auth required pam_unix.so nullok
|
||||
account required pam_unix.so
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue