merge master
This commit is contained in:
commit
9a26e2dea9
7
.github/CODEOWNERS
vendored
7
.github/CODEOWNERS
vendored
@ -238,7 +238,7 @@ pkgs/development/python-modules/buildcatrust/ @ajs124 @lukegb @mweinelt
|
|||||||
|
|
||||||
# VsCode Extensions
|
# VsCode Extensions
|
||||||
/pkgs/applications/editors/vscode @superherointj
|
/pkgs/applications/editors/vscode @superherointj
|
||||||
/pkgs/applications/editors/vscode/extensions @jonringer
|
/pkgs/applications/editors/vscode/extensions @jonringer @superherointj
|
||||||
|
|
||||||
# Prometheus exporter modules and tests
|
# Prometheus exporter modules and tests
|
||||||
/nixos/modules/services/monitoring/prometheus/exporters.nix @WilliButz
|
/nixos/modules/services/monitoring/prometheus/exporters.nix @WilliButz
|
||||||
@ -310,3 +310,8 @@ pkgs/development/python-modules/buildcatrust/ @ajs124 @lukegb @mweinelt
|
|||||||
/pkgs/build-support/node/build-npm-package @winterqt
|
/pkgs/build-support/node/build-npm-package @winterqt
|
||||||
/pkgs/build-support/node/fetch-npm-deps @winterqt
|
/pkgs/build-support/node/fetch-npm-deps @winterqt
|
||||||
/doc/languages-frameworks/javascript.section.md @winterqt
|
/doc/languages-frameworks/javascript.section.md @winterqt
|
||||||
|
|
||||||
|
# OCaml
|
||||||
|
/pkgs/build-support/ocaml @romildo @superherointj @ulrikstrid
|
||||||
|
/pkgs/development/compilers/ocaml @romildo @superherointj @ulrikstrid
|
||||||
|
/pkgs/development/ocaml-modules @romildo @superherointj @ulrikstrid
|
||||||
|
24
.github/workflows/check-maintainers-sorted.yaml
vendored
Normal file
24
.github/workflows/check-maintainers-sorted.yaml
vendored
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
name: "Check that maintainer list is sorted"
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request_target:
|
||||||
|
paths:
|
||||||
|
- 'maintainers/maintainer-list.nix'
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
nixos:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: github.repository_owner == 'NixOS'
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
# pull_request_target checks out the base branch by default
|
||||||
|
ref: refs/pull/${{ github.event.pull_request.number }}/merge
|
||||||
|
- uses: cachix/install-nix-action@v20
|
||||||
|
with:
|
||||||
|
# explicitly enable sandbox
|
||||||
|
extra_nix_config: sandbox = true
|
||||||
|
- name: Check that maintainer-list.nix is sorted
|
||||||
|
run: nix-instantiate --eval maintainers/scripts/check-maintainers-sorted.nix
|
14
.github/workflows/update-terraform-providers.yml
vendored
14
.github/workflows/update-terraform-providers.yml
vendored
@ -12,7 +12,7 @@ jobs:
|
|||||||
tf-providers:
|
tf-providers:
|
||||||
permissions:
|
permissions:
|
||||||
contents: write # for peter-evans/create-pull-request to create branch
|
contents: write # for peter-evans/create-pull-request to create branch
|
||||||
pull-requests: write # for peter-evans/create-pull-request to create a PR, for peter-evans/create-or-update-comment to create or update comment
|
pull-requests: write # for peter-evans/create-pull-request to create a PR
|
||||||
if: github.repository_owner == 'NixOS' && github.ref == 'refs/heads/master' # ensure workflow_dispatch only runs on master
|
if: github.repository_owner == 'NixOS' && github.ref == 'refs/heads/master' # ensure workflow_dispatch only runs on master
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
@ -36,6 +36,12 @@ jobs:
|
|||||||
--argstr keep-going true \
|
--argstr keep-going true \
|
||||||
--argstr max-workers 2 \
|
--argstr max-workers 2 \
|
||||||
--argstr path terraform-providers
|
--argstr path terraform-providers
|
||||||
|
- name: get failed updates
|
||||||
|
run: |
|
||||||
|
echo 'FAILED<<EOF' >> $GITHUB_ENV
|
||||||
|
git ls-files --others >> $GITHUB_ENV
|
||||||
|
echo 'EOF' >> $GITHUB_ENV
|
||||||
|
# cleanup logs of failed updates so they aren't included in the PR
|
||||||
- name: clean repo
|
- name: clean repo
|
||||||
run: |
|
run: |
|
||||||
git clean -f
|
git clean -f
|
||||||
@ -47,10 +53,16 @@ jobs:
|
|||||||
|
|
||||||
https://github.com/NixOS/nixpkgs/actions/runs/${{ github.run_id }}
|
https://github.com/NixOS/nixpkgs/actions/runs/${{ github.run_id }}
|
||||||
|
|
||||||
|
These providers failed to update:
|
||||||
|
```
|
||||||
|
${{ env.FAILED }}
|
||||||
|
```
|
||||||
|
|
||||||
Check that all providers build with:
|
Check that all providers build with:
|
||||||
```
|
```
|
||||||
@ofborg build terraform.full
|
@ofborg build terraform.full
|
||||||
```
|
```
|
||||||
|
If there is more than ten commits in the PR `ofborg` won't build it automatically and you will need to use the above command.
|
||||||
branch: terraform-providers-update
|
branch: terraform-providers-update
|
||||||
delete-branch: false
|
delete-branch: false
|
||||||
title: ${{ steps.setup.outputs.title }}
|
title: ${{ steps.setup.outputs.title }}
|
||||||
|
@ -14,7 +14,7 @@ nixpkgs follows the [official elixir deprecation schedule](https://hexdocs.pm/el
|
|||||||
|
|
||||||
All BEAM-related expressions are available via the top-level `beam` attribute, which includes:
|
All BEAM-related expressions are available via the top-level `beam` attribute, which includes:
|
||||||
|
|
||||||
- `interpreters`: a set of compilers running on the BEAM, including multiple Erlang/OTP versions (`beam.interpreters.erlangR22`, etc), Elixir (`beam.interpreters.elixir`) and LFE (Lisp Flavoured Erlang) (`beam.interpreters.lfe`).
|
- `interpreters`: a set of compilers running on the BEAM, including multiple Erlang/OTP versions (`beam.interpreters.erlang_22`, etc), Elixir (`beam.interpreters.elixir`) and LFE (Lisp Flavoured Erlang) (`beam.interpreters.lfe`).
|
||||||
|
|
||||||
- `packages`: a set of package builders (Mix and rebar3), each compiled with a specific Erlang/OTP version, e.g. `beam.packages.erlang22`.
|
- `packages`: a set of package builders (Mix and rebar3), each compiled with a specific Erlang/OTP version, e.g. `beam.packages.erlang22`.
|
||||||
|
|
||||||
@ -22,7 +22,7 @@ The default Erlang compiler, defined by `beam.interpreters.erlang`, is aliased a
|
|||||||
|
|
||||||
To create a package builder built with a custom Erlang version, use the lambda, `beam.packagesWith`, which accepts an Erlang/OTP derivation and produces a package builder similar to `beam.packages.erlang`.
|
To create a package builder built with a custom Erlang version, use the lambda, `beam.packagesWith`, which accepts an Erlang/OTP derivation and produces a package builder similar to `beam.packages.erlang`.
|
||||||
|
|
||||||
Many Erlang/OTP distributions available in `beam.interpreters` have versions with ODBC and/or Java enabled or without wx (no observer support). For example, there's `beam.interpreters.erlangR22_odbc_javac`, which corresponds to `beam.interpreters.erlangR22` and `beam.interpreters.erlangR22_nox`, which corresponds to `beam.interpreters.erlangR22`.
|
Many Erlang/OTP distributions available in `beam.interpreters` have versions with ODBC and/or Java enabled or without wx (no observer support). For example, there's `beam.interpreters.erlang_22_odbc_javac`, which corresponds to `beam.interpreters.erlang_22` and `beam.interpreters.erlang_22_nox`, which corresponds to `beam.interpreters.erlang_22`.
|
||||||
|
|
||||||
## Build Tools {#build-tools}
|
## Build Tools {#build-tools}
|
||||||
|
|
||||||
@ -128,7 +128,7 @@ You will need to run the build process once to fix the hash to correspond to you
|
|||||||
|
|
||||||
###### FOD {#fixed-output-derivation}
|
###### FOD {#fixed-output-derivation}
|
||||||
|
|
||||||
A fixed output derivation will download mix dependencies from the internet. To ensure reproducibility, a hash will be supplied. Note that mix is relatively reproducible. An FOD generating a different hash on each run hasn't been observed (as opposed to npm where the chances are relatively high). See [elixir_ls](https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/beam-modules/elixir-ls/default.nix) for a usage example of FOD.
|
A fixed output derivation will download mix dependencies from the internet. To ensure reproducibility, a hash will be supplied. Note that mix is relatively reproducible. An FOD generating a different hash on each run hasn't been observed (as opposed to npm where the chances are relatively high). See [elixir-ls](https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/beam-modules/elixir-ls/default.nix) for a usage example of FOD.
|
||||||
|
|
||||||
Practical steps
|
Practical steps
|
||||||
|
|
||||||
@ -154,7 +154,7 @@ Here is how your `default.nix` file would look for a phoenix project.
|
|||||||
with import <nixpkgs> { };
|
with import <nixpkgs> { };
|
||||||
|
|
||||||
let
|
let
|
||||||
# beam.interpreters.erlangR23 is available if you need a particular version
|
# beam.interpreters.erlang_23 is available if you need a particular version
|
||||||
packages = beam.packagesWith beam.interpreters.erlang;
|
packages = beam.packagesWith beam.interpreters.erlang;
|
||||||
|
|
||||||
pname = "your_project";
|
pname = "your_project";
|
||||||
@ -274,7 +274,7 @@ Usually, we need to create a `shell.nix` file and do our development inside of t
|
|||||||
|
|
||||||
with pkgs;
|
with pkgs;
|
||||||
let
|
let
|
||||||
elixir = beam.packages.erlangR24.elixir_1_12;
|
elixir = beam.packages.erlang_24.elixir_1_12;
|
||||||
in
|
in
|
||||||
mkShell {
|
mkShell {
|
||||||
buildInputs = [ elixir ];
|
buildInputs = [ elixir ];
|
||||||
|
@ -88,7 +88,7 @@ To package Dotnet applications, you can use `buildDotnetModule`. This has simila
|
|||||||
* `runtimeDeps` is used to wrap libraries into `LD_LIBRARY_PATH`. This is how dotnet usually handles runtime dependencies.
|
* `runtimeDeps` is used to wrap libraries into `LD_LIBRARY_PATH`. This is how dotnet usually handles runtime dependencies.
|
||||||
* `buildType` is used to change the type of build. Possible values are `Release`, `Debug`, etc. By default, this is set to `Release`.
|
* `buildType` is used to change the type of build. Possible values are `Release`, `Debug`, etc. By default, this is set to `Release`.
|
||||||
* `selfContainedBuild` allows to enable the [self-contained](https://docs.microsoft.com/en-us/dotnet/core/deploying/#publish-self-contained) build flag. By default, it is set to false and generated applications have a dependency on the selected dotnet runtime. If enabled, the dotnet runtime is bundled into the executable and the built app has no dependency on Dotnet.
|
* `selfContainedBuild` allows to enable the [self-contained](https://docs.microsoft.com/en-us/dotnet/core/deploying/#publish-self-contained) build flag. By default, it is set to false and generated applications have a dependency on the selected dotnet runtime. If enabled, the dotnet runtime is bundled into the executable and the built app has no dependency on Dotnet.
|
||||||
* `dotnet-sdk` is useful in cases where you need to change what dotnet SDK is being used.
|
* `dotnet-sdk` is useful in cases where you need to change what dotnet SDK is being used. You can also set this to the result of `dotnetSdkPackages.combinePackages`, if the project uses multiple SDKs to build.
|
||||||
* `dotnet-runtime` is useful in cases where you need to change what dotnet runtime is being used. This can be either a regular dotnet runtime, or an aspnetcore.
|
* `dotnet-runtime` is useful in cases where you need to change what dotnet runtime is being used. This can be either a regular dotnet runtime, or an aspnetcore.
|
||||||
* `dotnet-test-sdk` is useful in cases where unit tests expect a different dotnet SDK. By default, this is set to the `dotnet-sdk` attribute.
|
* `dotnet-test-sdk` is useful in cases where unit tests expect a different dotnet SDK. By default, this is set to the `dotnet-sdk` attribute.
|
||||||
* `testProjectFile` is useful in cases where the regular project file does not contain the unit tests. It gets restored and build, but not installed. You may need to regenerate your nuget lockfile after setting this.
|
* `testProjectFile` is useful in cases where the regular project file does not contain the unit tests. It gets restored and build, but not installed. You may need to regenerate your nuget lockfile after setting this.
|
||||||
|
@ -116,10 +116,6 @@ For convenience, it also adds `dconf.lib` for a GIO module implementing a GSetti
|
|||||||
|
|
||||||
- []{#ssec-gnome-hooks-gobject-introspection} `gobject-introspection` setup hook populates `GI_TYPELIB_PATH` variable with `lib/girepository-1.0` directories of dependencies, which is then added to wrapper by `wrapGAppsHook`. It also adds `share` directories of dependencies to `XDG_DATA_DIRS`, which is intended to promote GIR files but it also [pollutes the closures](https://github.com/NixOS/nixpkgs/issues/32790) of packages using `wrapGAppsHook`.
|
- []{#ssec-gnome-hooks-gobject-introspection} `gobject-introspection` setup hook populates `GI_TYPELIB_PATH` variable with `lib/girepository-1.0` directories of dependencies, which is then added to wrapper by `wrapGAppsHook`. It also adds `share` directories of dependencies to `XDG_DATA_DIRS`, which is intended to promote GIR files but it also [pollutes the closures](https://github.com/NixOS/nixpkgs/issues/32790) of packages using `wrapGAppsHook`.
|
||||||
|
|
||||||
::: {.warning}
|
|
||||||
The setup hook [currently](https://github.com/NixOS/nixpkgs/issues/56943) does not work in expressions with `strictDeps` enabled, like Python packages. In those cases, you will need to disable it with `strictDeps = false;`.
|
|
||||||
:::
|
|
||||||
|
|
||||||
- []{#ssec-gnome-hooks-gst-grl-plugins} Setup hooks of `gst_all_1.gstreamer` and `grilo` will populate the `GST_PLUGIN_SYSTEM_PATH_1_0` and `GRL_PLUGIN_PATH` variables, respectively, which will then be added to the wrapper by `wrapGAppsHook`.
|
- []{#ssec-gnome-hooks-gst-grl-plugins} Setup hooks of `gst_all_1.gstreamer` and `grilo` will populate the `GST_PLUGIN_SYSTEM_PATH_1_0` and `GRL_PLUGIN_PATH` variables, respectively, which will then be added to the wrapper by `wrapGAppsHook`.
|
||||||
|
|
||||||
You can also pass additional arguments to `makeWrapper` using `gappsWrapperArgs` in `preFixup` hook:
|
You can also pass additional arguments to `makeWrapper` using `gappsWrapperArgs` in `preFixup` hook:
|
||||||
|
@ -50,6 +50,11 @@ package. `cargoHash256` is used for traditional Nix SHA-256 hashes,
|
|||||||
such as the one in the example above. `cargoHash` should instead be
|
such as the one in the example above. `cargoHash` should instead be
|
||||||
used for [SRI](https://www.w3.org/TR/SRI/) hashes. For example:
|
used for [SRI](https://www.w3.org/TR/SRI/) hashes. For example:
|
||||||
|
|
||||||
|
Exception: If the application has cargo `git` dependencies, the `cargoHash`/`cargoSha256`
|
||||||
|
approach will not work, and you will need to copy the `Cargo.lock` file of the application
|
||||||
|
to nixpkgs and continue with the next section for specifying the options of the`cargoLock`
|
||||||
|
section.
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
cargoHash = "sha256-l1vL2ZdtDRxSGvP0X/l3nMw8+6WF67KPutJEzUROjg8=";
|
cargoHash = "sha256-l1vL2ZdtDRxSGvP0X/l3nMw8+6WF67KPutJEzUROjg8=";
|
||||||
```
|
```
|
||||||
@ -411,13 +416,13 @@ rustPlatform.buildRustPackage rec {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Compiling non-Rust packages that include Rust code {#compiling-non-rust-packages-that-include-rust-code}
|
### Compiling non-Rust packages that include Rust code {#compiling-non-rust-packages-that-include-rust-code}
|
||||||
|
|
||||||
Several non-Rust packages incorporate Rust code for performance- or
|
Several non-Rust packages incorporate Rust code for performance- or
|
||||||
security-sensitive parts. `rustPlatform` exposes several functions and
|
security-sensitive parts. `rustPlatform` exposes several functions and
|
||||||
hooks that can be used to integrate Cargo in non-Rust packages.
|
hooks that can be used to integrate Cargo in non-Rust packages.
|
||||||
|
|
||||||
### Vendoring of dependencies {#vendoring-of-dependencies}
|
#### Vendoring of dependencies {#vendoring-of-dependencies}
|
||||||
|
|
||||||
Since network access is not allowed in sandboxed builds, Rust crate
|
Since network access is not allowed in sandboxed builds, Rust crate
|
||||||
dependencies need to be retrieved using a fetcher. `rustPlatform`
|
dependencies need to be retrieved using a fetcher. `rustPlatform`
|
||||||
@ -477,7 +482,7 @@ added. To find the correct hash, you can first use `lib.fakeSha256` or
|
|||||||
`lib.fakeHash` as a stub hash. Building `cargoDeps` will then inform
|
`lib.fakeHash` as a stub hash. Building `cargoDeps` will then inform
|
||||||
you of the correct hash.
|
you of the correct hash.
|
||||||
|
|
||||||
### Hooks {#hooks}
|
#### Hooks {#hooks}
|
||||||
|
|
||||||
`rustPlatform` provides the following hooks to automate Cargo builds:
|
`rustPlatform` provides the following hooks to automate Cargo builds:
|
||||||
|
|
||||||
@ -513,7 +518,7 @@ you of the correct hash.
|
|||||||
* `bindgenHook`: for crates which use `bindgen` as a build dependency, lets
|
* `bindgenHook`: for crates which use `bindgen` as a build dependency, lets
|
||||||
`bindgen` find `libclang` and `libclang` find the libraries in `buildInputs`.
|
`bindgen` find `libclang` and `libclang` find the libraries in `buildInputs`.
|
||||||
|
|
||||||
### Examples {#examples}
|
#### Examples {#examples}
|
||||||
|
|
||||||
#### Python package using `setuptools-rust` {#python-package-using-setuptools-rust}
|
#### Python package using `setuptools-rust` {#python-package-using-setuptools-rust}
|
||||||
|
|
||||||
@ -642,7 +647,127 @@ buildPythonPackage rec {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Setting Up `nix-shell` {#setting-up-nix-shell}
|
## `buildRustCrate`: Compiling Rust crates using Nix instead of Cargo {#compiling-rust-crates-using-nix-instead-of-cargo}
|
||||||
|
|
||||||
|
### Simple operation {#simple-operation}
|
||||||
|
|
||||||
|
When run, `cargo build` produces a file called `Cargo.lock`,
|
||||||
|
containing pinned versions of all dependencies. Nixpkgs contains a
|
||||||
|
tool called `crate2Nix` (`nix-shell -p crate2nix`), which can be
|
||||||
|
used to turn a `Cargo.lock` into a Nix expression. That Nix
|
||||||
|
expression calls `rustc` directly (hence bypassing Cargo), and can
|
||||||
|
be used to compile a crate and all its dependencies.
|
||||||
|
|
||||||
|
See [`crate2nix`'s documentation](https://github.com/kolloch/crate2nix#known-restrictions)
|
||||||
|
for instructions on how to use it.
|
||||||
|
|
||||||
|
### Handling external dependencies {#handling-external-dependencies}
|
||||||
|
|
||||||
|
Some crates require external libraries. For crates from
|
||||||
|
[crates.io](https://crates.io), such libraries can be specified in
|
||||||
|
`defaultCrateOverrides` package in nixpkgs itself.
|
||||||
|
|
||||||
|
Starting from that file, one can add more overrides, to add features
|
||||||
|
or build inputs by overriding the hello crate in a separate file.
|
||||||
|
|
||||||
|
```nix
|
||||||
|
with import <nixpkgs> {};
|
||||||
|
((import ./hello.nix).hello {}).override {
|
||||||
|
crateOverrides = defaultCrateOverrides // {
|
||||||
|
hello = attrs: { buildInputs = [ openssl ]; };
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Here, `crateOverrides` is expected to be a attribute set, where the
|
||||||
|
key is the crate name without version number and the value a function.
|
||||||
|
The function gets all attributes passed to `buildRustCrate` as first
|
||||||
|
argument and returns a set that contains all attribute that should be
|
||||||
|
overwritten.
|
||||||
|
|
||||||
|
For more complicated cases, such as when parts of the crate's
|
||||||
|
derivation depend on the crate's version, the `attrs` argument of
|
||||||
|
the override above can be read, as in the following example, which
|
||||||
|
patches the derivation:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
with import <nixpkgs> {};
|
||||||
|
((import ./hello.nix).hello {}).override {
|
||||||
|
crateOverrides = defaultCrateOverrides // {
|
||||||
|
hello = attrs: lib.optionalAttrs (lib.versionAtLeast attrs.version "1.0") {
|
||||||
|
postPatch = ''
|
||||||
|
substituteInPlace lib/zoneinfo.rs \
|
||||||
|
--replace "/usr/share/zoneinfo" "${tzdata}/share/zoneinfo"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Another situation is when we want to override a nested
|
||||||
|
dependency. This actually works in the exact same way, since the
|
||||||
|
`crateOverrides` parameter is forwarded to the crate's
|
||||||
|
dependencies. For instance, to override the build inputs for crate
|
||||||
|
`libc` in the example above, where `libc` is a dependency of the main
|
||||||
|
crate, we could do:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
with import <nixpkgs> {};
|
||||||
|
((import hello.nix).hello {}).override {
|
||||||
|
crateOverrides = defaultCrateOverrides // {
|
||||||
|
libc = attrs: { buildInputs = []; };
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Options and phases configuration {#options-and-phases-configuration}
|
||||||
|
|
||||||
|
Actually, the overrides introduced in the previous section are more
|
||||||
|
general. A number of other parameters can be overridden:
|
||||||
|
|
||||||
|
- The version of `rustc` used to compile the crate:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
(hello {}).override { rust = pkgs.rust; };
|
||||||
|
```
|
||||||
|
|
||||||
|
- Whether to build in release mode or debug mode (release mode by
|
||||||
|
default):
|
||||||
|
|
||||||
|
```nix
|
||||||
|
(hello {}).override { release = false; };
|
||||||
|
```
|
||||||
|
|
||||||
|
- Whether to print the commands sent to `rustc` when building
|
||||||
|
(equivalent to `--verbose` in cargo:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
(hello {}).override { verbose = false; };
|
||||||
|
```
|
||||||
|
|
||||||
|
- Extra arguments to be passed to `rustc`:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
(hello {}).override { extraRustcOpts = "-Z debuginfo=2"; };
|
||||||
|
```
|
||||||
|
|
||||||
|
- Phases, just like in any other derivation, can be specified using
|
||||||
|
the following attributes: `preUnpack`, `postUnpack`, `prePatch`,
|
||||||
|
`patches`, `postPatch`, `preConfigure` (in the case of a Rust crate,
|
||||||
|
this is run before calling the "build" script), `postConfigure`
|
||||||
|
(after the "build" script),`preBuild`, `postBuild`, `preInstall` and
|
||||||
|
`postInstall`. As an example, here is how to create a new module
|
||||||
|
before running the build script:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
(hello {}).override {
|
||||||
|
preConfigure = ''
|
||||||
|
echo "pub const PATH=\"${hi.out}\";" >> src/path.rs"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### Setting Up `nix-shell` {#setting-up-nix-shell}
|
||||||
|
|
||||||
Oftentimes you want to develop code from within `nix-shell`. Unfortunately
|
Oftentimes you want to develop code from within `nix-shell`. Unfortunately
|
||||||
`buildRustCrate` does not support common `nix-shell` operations directly
|
`buildRustCrate` does not support common `nix-shell` operations directly
|
||||||
|
@ -101,11 +101,11 @@ To build a `stdenv` package in a [`nix-shell`](https://nixos.org/manual/nix/unst
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
nix-shell '<nixpkgs>' -A some_package
|
nix-shell '<nixpkgs>' -A some_package
|
||||||
eval ${unpackPhase:-unpackPhase}
|
eval "${unpackPhase:-unpackPhase}"
|
||||||
cd $sourceRoot
|
cd $sourceRoot
|
||||||
eval ${patchPhase:-patchPhase}
|
eval "${patchPhase:-patchPhase}"
|
||||||
eval ${configurePhase:-configurePhase}
|
eval "${configurePhase:-configurePhase}"
|
||||||
eval ${buildPhase:-buildPhase}
|
eval "${buildPhase:-buildPhase}"
|
||||||
```
|
```
|
||||||
|
|
||||||
To modify a [phase](#sec-stdenv-phases), first print it with
|
To modify a [phase](#sec-stdenv-phases), first print it with
|
||||||
@ -380,39 +380,107 @@ Values inside it are not passed to the builder, so you can change them without t
|
|||||||
|
|
||||||
#### `passthru.updateScript` {#var-passthru-updateScript}
|
#### `passthru.updateScript` {#var-passthru-updateScript}
|
||||||
|
|
||||||
A script to be run by `maintainers/scripts/update.nix` when the package is matched. It needs to be an executable file, either on the file system:
|
A script to be run by `maintainers/scripts/update.nix` when the package is matched. The attribute can contain one of the following:
|
||||||
|
|
||||||
```nix
|
- []{#var-passthru-updateScript-command} an executable file, either on the file system:
|
||||||
passthru.updateScript = ./update.sh;
|
|
||||||
```
|
|
||||||
|
|
||||||
or inside the expression itself:
|
```nix
|
||||||
|
passthru.updateScript = ./update.sh;
|
||||||
|
```
|
||||||
|
|
||||||
```nix
|
or inside the expression itself:
|
||||||
passthru.updateScript = writeScript "update-zoom-us" ''
|
|
||||||
#!/usr/bin/env nix-shell
|
|
||||||
#!nix-shell -i bash -p curl pcre common-updater-scripts
|
|
||||||
|
|
||||||
set -eu -o pipefail
|
```nix
|
||||||
|
passthru.updateScript = writeScript "update-zoom-us" ''
|
||||||
|
#!/usr/bin/env nix-shell
|
||||||
|
#!nix-shell -i bash -p curl pcre common-updater-scripts
|
||||||
|
|
||||||
version="$(curl -sI https://zoom.us/client/latest/zoom_x86_64.tar.xz | grep -Fi 'Location:' | pcregrep -o1 '/(([0-9]\.?)+)/')"
|
set -eu -o pipefail
|
||||||
update-source-version zoom-us "$version"
|
|
||||||
'';
|
|
||||||
```
|
|
||||||
|
|
||||||
The attribute can also contain a list, a script followed by arguments to be passed to it:
|
version="$(curl -sI https://zoom.us/client/latest/zoom_x86_64.tar.xz | grep -Fi 'Location:' | pcregrep -o1 '/(([0-9]\.?)+)/')"
|
||||||
|
update-source-version zoom-us "$version"
|
||||||
|
'';
|
||||||
|
```
|
||||||
|
|
||||||
```nix
|
- a list, a script followed by arguments to be passed to it:
|
||||||
passthru.updateScript = [ ../../update.sh pname "--requested-release=unstable" ];
|
|
||||||
```
|
|
||||||
|
|
||||||
The script will be run with the `UPDATE_NIX_NAME`, `UPDATE_NIX_PNAME`, `UPDATE_NIX_OLD_VERSION` and `UPDATE_NIX_ATTR_PATH` environment variables set respectively to the name, pname, old version and attribute path of the package it is supposed to update.
|
```nix
|
||||||
|
passthru.updateScript = [ ../../update.sh pname "--requested-release=unstable" ];
|
||||||
|
```
|
||||||
|
|
||||||
|
- an attribute set containing:
|
||||||
|
- [`command`]{#var-passthru-updateScript-set-command} – a string or list in the [format expected by `passthru.updateScript`](#var-passthru-updateScript-command).
|
||||||
|
- [`attrPath`]{#var-passthru-updateScript-set-attrPath} (optional) – a string containing the canonical attribute path for the package. If present, it will be passed to the update script instead of the attribute path on which the package was discovered during Nixpkgs traversal.
|
||||||
|
- [`supportedFeatures`]{#var-passthru-updateScript-set-supportedFeatures} (optional) – a list of the [extra features](#var-passthru-updateScript-supported-features) the script supports.
|
||||||
|
|
||||||
|
```nix
|
||||||
|
passthru.updateScript = {
|
||||||
|
command = [ ../../update.sh pname ];
|
||||||
|
attrPath = pname;
|
||||||
|
supportedFeatures = [ … ];
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
##### How update scripts are executed? {#var-passthru-updateScript-execution}
|
||||||
|
|
||||||
|
Update scripts are to be invoked by `maintainers/scripts/update.nix` script. You can run `nix-shell maintainers/scripts/update.nix` in the root of Nixpkgs repository for information on how to use it. `update.nix` offers several modes for selecting packages to update (e.g. select by attribute path, traverse Nixpkgs and filter by maintainer, etc.), and it will execute update scripts for all matched packages that have an `updateScript` attribute.
|
||||||
|
|
||||||
|
Each update script will be passed the following environment variables:
|
||||||
|
|
||||||
|
- [`UPDATE_NIX_NAME`]{#var-passthru-updateScript-env-UPDATE_NIX_NAME} – content of the `name` attribute of the updated package.
|
||||||
|
- [`UPDATE_NIX_PNAME`]{#var-passthru-updateScript-env-UPDATE_NIX_PNAME} – content of the `pname` attribute of the updated package.
|
||||||
|
- [`UPDATE_NIX_OLD_VERSION`]{#var-passthru-updateScript-env-UPDATE_NIX_OLD_VERSION} – content of the `version` attribute of the updated package.
|
||||||
|
- [`UPDATE_NIX_ATTR_PATH`]{#var-passthru-updateScript-env-UPDATE_NIX_ATTR_PATH} – attribute path the `update.nix` discovered the package on (or the [canonical `attrPath`](#var-passthru-updateScript-set-attrPath) when available). Example: `pantheon.elementary-terminal`
|
||||||
|
|
||||||
::: {.note}
|
::: {.note}
|
||||||
The script will be usually run from the root of the Nixpkgs repository but you should not rely on that. Also note that the update scripts will be run in parallel by default; you should avoid running `git commit` or any other commands that cannot handle that.
|
An update script will be usually run from the root of the Nixpkgs repository but you should not rely on that. Also note that `update.nix` executes update scripts in parallel by default so you should avoid running `git commit` or any other commands that cannot handle that.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
For information about how to run the updates, execute `nix-shell maintainers/scripts/update.nix`.
|
::: {.tip}
|
||||||
|
While update scripts should not create commits themselves, `maintainers/scripts/update.nix` supports automatically creating commits when running it with `--argstr commit true`. If you need to customize commit message, you can have the update script implement [`commit`](#var-passthru-updateScript-commit) feature.
|
||||||
|
:::
|
||||||
|
|
||||||
|
##### Supported features {#var-passthru-updateScript-supported-features}
|
||||||
|
###### `commit` {#var-passthru-updateScript-commit}
|
||||||
|
|
||||||
|
This feature allows update scripts to *ask* `update.nix` to create Git commits.
|
||||||
|
|
||||||
|
When support of this feature is declared, whenever the update script exits with `0` return status, it is expected to print a JSON list containing an object described below for each updated attribute to standard output.
|
||||||
|
|
||||||
|
When `update.nix` is run with `--argstr commit true` arguments, it will create a separate commit for each of the objects. An empty list can be returned when the script did not update any files, for example, when the package is already at the latest version.
|
||||||
|
|
||||||
|
The commit object contains the following values:
|
||||||
|
|
||||||
|
- [`attrPath`]{#var-passthru-updateScript-commit-attrPath} – a string containing attribute path.
|
||||||
|
- [`oldVersion`]{#var-passthru-updateScript-commit-oldVersion} – a string containing old version.
|
||||||
|
- [`newVersion`]{#var-passthru-updateScript-commit-newVersion} – a string containing new version.
|
||||||
|
- [`files`]{#var-passthru-updateScript-commit-files} – a non-empty list of file paths (as strings) to add to the commit.
|
||||||
|
- [`commitBody`]{#var-passthru-updateScript-commit-commitBody} (optional) – a string with extra content to be appended to the default commit message (useful for adding changelog links).
|
||||||
|
- [`commitMessage`]{#var-passthru-updateScript-commit-commitMessage} (optional) – a string to use instead of the default commit message.
|
||||||
|
|
||||||
|
If the returned array contains exactly one object (e.g. `[{}]`), all values are optional and will be determined automatically.
|
||||||
|
|
||||||
|
```{=docbook}
|
||||||
|
<example>
|
||||||
|
<title>Standard output of an update script using commit feature</title>
|
||||||
|
```
|
||||||
|
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"attrPath": "volume_key",
|
||||||
|
"oldVersion": "0.3.11",
|
||||||
|
"newVersion": "0.3.12",
|
||||||
|
"files": [
|
||||||
|
"/path/to/nixpkgs/pkgs/development/libraries/volume-key/default.nix"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
```{=docbook}
|
||||||
|
</example>
|
||||||
|
```
|
||||||
|
|
||||||
### Recursive attributes in `mkDerivation` {#mkderivation-recursive-attributes}
|
### Recursive attributes in `mkDerivation` {#mkderivation-recursive-attributes}
|
||||||
|
|
||||||
|
@ -176,7 +176,7 @@ rec {
|
|||||||
# Only show the error for the first missing argument
|
# Only show the error for the first missing argument
|
||||||
error = errorForArg (lib.head missingArgs);
|
error = errorForArg (lib.head missingArgs);
|
||||||
|
|
||||||
in if missingArgs == [] then makeOverridable f allArgs else throw error;
|
in if missingArgs == [] then makeOverridable f allArgs else abort error;
|
||||||
|
|
||||||
|
|
||||||
/* Like callPackage, but for a function that returns an attribute
|
/* Like callPackage, but for a function that returns an attribute
|
||||||
|
@ -422,7 +422,7 @@ ${expr "" v}
|
|||||||
(if v then "True" else "False")
|
(if v then "True" else "False")
|
||||||
else if isFunction v then
|
else if isFunction v then
|
||||||
abort "generators.toDhall: cannot convert a function to Dhall"
|
abort "generators.toDhall: cannot convert a function to Dhall"
|
||||||
else if isNull v then
|
else if v == null then
|
||||||
abort "generators.toDhall: cannot convert a null to Dhall"
|
abort "generators.toDhall: cannot convert a null to Dhall"
|
||||||
else
|
else
|
||||||
builtins.toJSON v;
|
builtins.toJSON v;
|
||||||
|
@ -15,6 +15,9 @@ let
|
|||||||
last
|
last
|
||||||
genList
|
genList
|
||||||
elemAt
|
elemAt
|
||||||
|
all
|
||||||
|
concatMap
|
||||||
|
foldl'
|
||||||
;
|
;
|
||||||
|
|
||||||
inherit (lib.strings)
|
inherit (lib.strings)
|
||||||
@ -190,6 +193,80 @@ in /* No rec! Add dependencies on this file at the top. */ {
|
|||||||
subpathInvalidReason value == null;
|
subpathInvalidReason value == null;
|
||||||
|
|
||||||
|
|
||||||
|
/* Join subpath strings together using `/`, returning a normalised subpath string.
|
||||||
|
|
||||||
|
Like `concatStringsSep "/"` but safer, specifically:
|
||||||
|
|
||||||
|
- All elements must be valid subpath strings, see `lib.path.subpath.isValid`
|
||||||
|
|
||||||
|
- The result gets normalised, see `lib.path.subpath.normalise`
|
||||||
|
|
||||||
|
- The edge case of an empty list gets properly handled by returning the neutral subpath `"./."`
|
||||||
|
|
||||||
|
Laws:
|
||||||
|
|
||||||
|
- Associativity:
|
||||||
|
|
||||||
|
subpath.join [ x (subpath.join [ y z ]) ] == subpath.join [ (subpath.join [ x y ]) z ]
|
||||||
|
|
||||||
|
- Identity - `"./."` is the neutral element for normalised paths:
|
||||||
|
|
||||||
|
subpath.join [ ] == "./."
|
||||||
|
subpath.join [ (subpath.normalise p) "./." ] == subpath.normalise p
|
||||||
|
subpath.join [ "./." (subpath.normalise p) ] == subpath.normalise p
|
||||||
|
|
||||||
|
- Normalisation - the result is normalised according to `lib.path.subpath.normalise`:
|
||||||
|
|
||||||
|
subpath.join ps == subpath.normalise (subpath.join ps)
|
||||||
|
|
||||||
|
- For non-empty lists, the implementation is equivalent to normalising the result of `concatStringsSep "/"`.
|
||||||
|
Note that the above laws can be derived from this one.
|
||||||
|
|
||||||
|
ps != [] -> subpath.join ps == subpath.normalise (concatStringsSep "/" ps)
|
||||||
|
|
||||||
|
Type:
|
||||||
|
subpath.join :: [ String ] -> String
|
||||||
|
|
||||||
|
Example:
|
||||||
|
subpath.join [ "foo" "bar/baz" ]
|
||||||
|
=> "./foo/bar/baz"
|
||||||
|
|
||||||
|
# normalise the result
|
||||||
|
subpath.join [ "./foo" "." "bar//./baz/" ]
|
||||||
|
=> "./foo/bar/baz"
|
||||||
|
|
||||||
|
# passing an empty list results in the current directory
|
||||||
|
subpath.join [ ]
|
||||||
|
=> "./."
|
||||||
|
|
||||||
|
# elements must be valid subpath strings
|
||||||
|
subpath.join [ /foo ]
|
||||||
|
=> <error>
|
||||||
|
subpath.join [ "" ]
|
||||||
|
=> <error>
|
||||||
|
subpath.join [ "/foo" ]
|
||||||
|
=> <error>
|
||||||
|
subpath.join [ "../foo" ]
|
||||||
|
=> <error>
|
||||||
|
*/
|
||||||
|
subpath.join =
|
||||||
|
# The list of subpaths to join together
|
||||||
|
subpaths:
|
||||||
|
# Fast in case all paths are valid
|
||||||
|
if all isValid subpaths
|
||||||
|
then joinRelPath (concatMap splitRelPath subpaths)
|
||||||
|
else
|
||||||
|
# Otherwise we take our time to gather more info for a better error message
|
||||||
|
# Strictly go through each path, throwing on the first invalid one
|
||||||
|
# Tracks the list index in the fold accumulator
|
||||||
|
foldl' (i: path:
|
||||||
|
if isValid path
|
||||||
|
then i + 1
|
||||||
|
else throw ''
|
||||||
|
lib.path.subpath.join: Element at index ${toString i} is not a valid subpath string:
|
||||||
|
${subpathInvalidReason path}''
|
||||||
|
) 0 subpaths;
|
||||||
|
|
||||||
/* Normalise a subpath. Throw an error if the subpath isn't valid, see
|
/* Normalise a subpath. Throw an error if the subpath isn't valid, see
|
||||||
`lib.path.subpath.isValid`
|
`lib.path.subpath.isValid`
|
||||||
|
|
||||||
|
@ -107,6 +107,36 @@ let
|
|||||||
expected = true;
|
expected = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# Test examples from the lib.path.subpath.join documentation
|
||||||
|
testSubpathJoinExample1 = {
|
||||||
|
expr = subpath.join [ "foo" "bar/baz" ];
|
||||||
|
expected = "./foo/bar/baz";
|
||||||
|
};
|
||||||
|
testSubpathJoinExample2 = {
|
||||||
|
expr = subpath.join [ "./foo" "." "bar//./baz/" ];
|
||||||
|
expected = "./foo/bar/baz";
|
||||||
|
};
|
||||||
|
testSubpathJoinExample3 = {
|
||||||
|
expr = subpath.join [ ];
|
||||||
|
expected = "./.";
|
||||||
|
};
|
||||||
|
testSubpathJoinExample4 = {
|
||||||
|
expr = (builtins.tryEval (subpath.join [ /foo ])).success;
|
||||||
|
expected = false;
|
||||||
|
};
|
||||||
|
testSubpathJoinExample5 = {
|
||||||
|
expr = (builtins.tryEval (subpath.join [ "" ])).success;
|
||||||
|
expected = false;
|
||||||
|
};
|
||||||
|
testSubpathJoinExample6 = {
|
||||||
|
expr = (builtins.tryEval (subpath.join [ "/foo" ])).success;
|
||||||
|
expected = false;
|
||||||
|
};
|
||||||
|
testSubpathJoinExample7 = {
|
||||||
|
expr = (builtins.tryEval (subpath.join [ "../foo" ])).success;
|
||||||
|
expected = false;
|
||||||
|
};
|
||||||
|
|
||||||
# Test examples from the lib.path.subpath.normalise documentation
|
# Test examples from the lib.path.subpath.normalise documentation
|
||||||
testSubpathNormaliseExample1 = {
|
testSubpathNormaliseExample1 = {
|
||||||
expr = subpath.normalise "foo//bar";
|
expr = subpath.normalise "foo//bar";
|
||||||
|
File diff suppressed because it is too large
Load Diff
57
maintainers/scripts/check-maintainers-sorted.nix
Normal file
57
maintainers/scripts/check-maintainers-sorted.nix
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
let
|
||||||
|
lib = import ../../lib;
|
||||||
|
inherit (lib)
|
||||||
|
add attrNames elemAt foldl' genList length replaceStrings sort toLower trace;
|
||||||
|
|
||||||
|
maintainers = import ../maintainer-list.nix;
|
||||||
|
simplify = replaceStrings [ "-" "_" ] [ "" "" ];
|
||||||
|
compare = a: b: simplify (toLower a) < simplify (toLower b);
|
||||||
|
namesSorted =
|
||||||
|
sort
|
||||||
|
(a: b: a.key < b.key)
|
||||||
|
(map
|
||||||
|
(n: let pos = builtins.unsafeGetAttrPos n maintainers;
|
||||||
|
in assert pos == null -> throw "maintainers entry ${n} is malformed";
|
||||||
|
{ name = n; line = pos.line; key = toLower (simplify n); })
|
||||||
|
(attrNames maintainers));
|
||||||
|
before = { name, line, key }:
|
||||||
|
foldl'
|
||||||
|
(acc: n: if n.key < key && (acc == null || n.key > acc.key) then n else acc)
|
||||||
|
null
|
||||||
|
namesSorted;
|
||||||
|
errors = foldl' add 0
|
||||||
|
(map
|
||||||
|
(i: let a = elemAt namesSorted i;
|
||||||
|
b = elemAt namesSorted (i + 1);
|
||||||
|
lim = let t = before a; in if t == null then "the initial {" else t.name;
|
||||||
|
in if a.line >= b.line
|
||||||
|
then trace
|
||||||
|
("maintainer ${a.name} (line ${toString a.line}) should be listed "
|
||||||
|
+ "after ${lim}, not after ${b.name} (line ${toString b.line})")
|
||||||
|
1
|
||||||
|
else 0)
|
||||||
|
(genList (i: i) (length namesSorted - 1)));
|
||||||
|
in
|
||||||
|
assert errors == 0; "all good!"
|
||||||
|
|
||||||
|
# generate edit commands to sort the list.
|
||||||
|
# may everything following the last current entry (closing } ff) in the wrong place
|
||||||
|
# with lib;
|
||||||
|
# concatStringsSep
|
||||||
|
# "\n"
|
||||||
|
# (let first = foldl' (acc: n: if n.line < acc then n.line else acc) 999999999 namesSorted;
|
||||||
|
# commands = map
|
||||||
|
# (i: let e = elemAt namesSorted i;
|
||||||
|
# begin = foldl'
|
||||||
|
# (acc: n: if n.line < e.line && n.line > acc then n.line else acc)
|
||||||
|
# 1
|
||||||
|
# namesSorted;
|
||||||
|
# end =
|
||||||
|
# foldl' (acc: n: if n.line > e.line && n.line < acc then n.line else acc)
|
||||||
|
# 999999999
|
||||||
|
# namesSorted;
|
||||||
|
# in "${toString e.line},${toString (end - 1)} p")
|
||||||
|
# (genList (i: i) (length namesSorted));
|
||||||
|
# in map
|
||||||
|
# (c: "sed -ne '${c}' maintainers/maintainer-list.nix")
|
||||||
|
# ([ "1,${toString (first - 1)} p" ] ++ commands))
|
4
maintainers/scripts/convert-to-import-cargo-lock.sh
Executable file
4
maintainers/scripts/convert-to-import-cargo-lock.sh
Executable file
@ -0,0 +1,4 @@
|
|||||||
|
#!/usr/bin/env nix-shell
|
||||||
|
#!nix-shell -I nixpkgs=. -i bash -p "import ./maintainers/scripts/convert-to-import-cargo-lock" nix-prefetch-git
|
||||||
|
|
||||||
|
convert-to-import-cargo-lock "$@"
|
1
maintainers/scripts/convert-to-import-cargo-lock/.gitignore
vendored
Normal file
1
maintainers/scripts/convert-to-import-cargo-lock/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/target
|
106
maintainers/scripts/convert-to-import-cargo-lock/Cargo.lock
generated
Normal file
106
maintainers/scripts/convert-to-import-cargo-lock/Cargo.lock
generated
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anyhow"
|
||||||
|
version = "1.0.69"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "224afbd727c3d6e4b90103ece64b8d1b67fbb1973b1046c2281eed3f3803f800"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "basic-toml"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2e819b667739967cd44d308b8c7b71305d8bb0729ac44a248aa08f33d01950b4"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "convert-to-import-cargo-lock"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"basic-toml",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "1.0.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.51"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.23"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ryu"
|
||||||
|
version = "1.0.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde"
|
||||||
|
version = "1.0.152"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb"
|
||||||
|
dependencies = [
|
||||||
|
"serde_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_derive"
|
||||||
|
version = "1.0.152"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_json"
|
||||||
|
version = "1.0.93"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cad406b69c91885b5107daf2c29572f6c8cdb3c66826821e286c533490c0bc76"
|
||||||
|
dependencies = [
|
||||||
|
"itoa",
|
||||||
|
"ryu",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "1.0.107"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"
|
12
maintainers/scripts/convert-to-import-cargo-lock/Cargo.toml
Normal file
12
maintainers/scripts/convert-to-import-cargo-lock/Cargo.toml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
[package]
|
||||||
|
name = "convert-to-import-cargo-lock"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
anyhow = { version = "1.0.69" }
|
||||||
|
basic-toml = "0.1.1"
|
||||||
|
serde = { version = "1.0.152", features = ["derive"] }
|
||||||
|
serde_json = "1.0.93"
|
16
maintainers/scripts/convert-to-import-cargo-lock/default.nix
Normal file
16
maintainers/scripts/convert-to-import-cargo-lock/default.nix
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
with import ../../../. { };
|
||||||
|
|
||||||
|
rustPlatform.buildRustPackage {
|
||||||
|
name = "convert-to-import-cargo-lock";
|
||||||
|
|
||||||
|
src = lib.cleanSourceWith {
|
||||||
|
src = ./.;
|
||||||
|
filter = name: type:
|
||||||
|
let
|
||||||
|
name' = builtins.baseNameOf name;
|
||||||
|
in
|
||||||
|
name' != "default.nix" && name' != "target";
|
||||||
|
};
|
||||||
|
|
||||||
|
cargoLock.lockFile = ./Cargo.lock;
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
with import ../../../. { };
|
||||||
|
|
||||||
|
mkShell {
|
||||||
|
packages = [ rustc cargo clippy rustfmt ] ++ lib.optional stdenv.isDarwin libiconv;
|
||||||
|
}
|
241
maintainers/scripts/convert-to-import-cargo-lock/src/main.rs
Normal file
241
maintainers/scripts/convert-to-import-cargo-lock/src/main.rs
Normal file
@ -0,0 +1,241 @@
|
|||||||
|
#![warn(clippy::pedantic)]
|
||||||
|
#![allow(clippy::too_many_lines)]
|
||||||
|
|
||||||
|
use anyhow::anyhow;
|
||||||
|
use serde::Deserialize;
|
||||||
|
use std::{collections::HashMap, env, fs, path::PathBuf, process::Command};
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct CargoLock<'a> {
|
||||||
|
#[serde(rename = "package", borrow)]
|
||||||
|
packages: Vec<Package<'a>>,
|
||||||
|
metadata: Option<HashMap<&'a str, &'a str>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct Package<'a> {
|
||||||
|
name: &'a str,
|
||||||
|
version: &'a str,
|
||||||
|
source: Option<&'a str>,
|
||||||
|
checksum: Option<&'a str>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct PrefetchOutput {
|
||||||
|
sha256: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> anyhow::Result<()> {
|
||||||
|
let mut hashes = HashMap::new();
|
||||||
|
|
||||||
|
let attr_count = env::args().len() - 1;
|
||||||
|
|
||||||
|
for (i, attr) in env::args().skip(1).enumerate() {
|
||||||
|
println!("converting {attr} ({}/{attr_count})", i + 1);
|
||||||
|
|
||||||
|
convert(&attr, &mut hashes)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn convert(attr: &str, hashes: &mut HashMap<String, String>) -> anyhow::Result<()> {
|
||||||
|
let package_path = nix_eval(format!("{attr}.meta.position"))?
|
||||||
|
.and_then(|p| p.split_once(':').map(|(f, _)| PathBuf::from(f)));
|
||||||
|
|
||||||
|
if package_path.is_none() {
|
||||||
|
eprintln!("can't automatically convert {attr}: doesn't exist");
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let package_path = package_path.unwrap();
|
||||||
|
|
||||||
|
if package_path.with_file_name("Cargo.lock").exists() {
|
||||||
|
eprintln!("skipping {attr}: already has a vendored Cargo.lock");
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut src = PathBuf::from(
|
||||||
|
String::from_utf8(
|
||||||
|
Command::new("nix-build")
|
||||||
|
.arg("-A")
|
||||||
|
.arg(format!("{attr}.src"))
|
||||||
|
.output()?
|
||||||
|
.stdout,
|
||||||
|
)?
|
||||||
|
.trim(),
|
||||||
|
);
|
||||||
|
|
||||||
|
if !src.exists() {
|
||||||
|
eprintln!("can't automatically convert {attr}: src doesn't exist (bad attr?)");
|
||||||
|
return Ok(());
|
||||||
|
} else if !src.metadata()?.is_dir() {
|
||||||
|
eprintln!("can't automatically convert {attr}: src isn't a directory");
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(mut source_root) = nix_eval(format!("{attr}.sourceRoot"))?.map(PathBuf::from) {
|
||||||
|
source_root = source_root.components().skip(1).collect();
|
||||||
|
src.push(source_root);
|
||||||
|
}
|
||||||
|
|
||||||
|
let cargo_lock_path = src.join("Cargo.lock");
|
||||||
|
|
||||||
|
if !cargo_lock_path.exists() {
|
||||||
|
eprintln!("can't automatically convert {attr}: src doesn't contain Cargo.lock");
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let cargo_lock_content = fs::read_to_string(cargo_lock_path)?;
|
||||||
|
|
||||||
|
let cargo_lock: CargoLock = basic_toml::from_str(&cargo_lock_content)?;
|
||||||
|
|
||||||
|
let mut git_dependencies = Vec::new();
|
||||||
|
|
||||||
|
for package in cargo_lock.packages.iter().filter(|p| {
|
||||||
|
p.source.is_some()
|
||||||
|
&& p.checksum
|
||||||
|
.or_else(|| {
|
||||||
|
cargo_lock
|
||||||
|
.metadata
|
||||||
|
.as_ref()?
|
||||||
|
.get(
|
||||||
|
format!("checksum {} {} ({})", p.name, p.version, p.source.unwrap())
|
||||||
|
.as_str(),
|
||||||
|
)
|
||||||
|
.copied()
|
||||||
|
})
|
||||||
|
.is_none()
|
||||||
|
}) {
|
||||||
|
let (typ, original_url) = package
|
||||||
|
.source
|
||||||
|
.unwrap()
|
||||||
|
.split_once('+')
|
||||||
|
.expect("dependency should have well-formed source url");
|
||||||
|
|
||||||
|
if let Some(hash) = hashes.get(original_url) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
typ, "git",
|
||||||
|
"packages without checksums should be git dependencies"
|
||||||
|
);
|
||||||
|
|
||||||
|
let (mut url, rev) = original_url
|
||||||
|
.split_once('#')
|
||||||
|
.expect("git dependency should have commit");
|
||||||
|
|
||||||
|
// TODO: improve
|
||||||
|
if let Some((u, _)) = url.split_once('?') {
|
||||||
|
url = u;
|
||||||
|
}
|
||||||
|
|
||||||
|
let prefetch_output: PrefetchOutput = serde_json::from_slice(
|
||||||
|
&Command::new("nix-prefetch-git")
|
||||||
|
.args(["--url", url, "--rev", rev, "--quiet", "--fetch-submodules"])
|
||||||
|
.output()?
|
||||||
|
.stdout,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let output_hash = String::from_utf8(
|
||||||
|
Command::new("nix")
|
||||||
|
.args([
|
||||||
|
"--extra-experimental-features",
|
||||||
|
"nix-command",
|
||||||
|
"hash",
|
||||||
|
"to-sri",
|
||||||
|
"--type",
|
||||||
|
"sha256",
|
||||||
|
&prefetch_output.sha256,
|
||||||
|
])
|
||||||
|
.output()?
|
||||||
|
.stdout,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let hash = output_hash.trim().to_string();
|
||||||
|
|
||||||
|
git_dependencies.push((
|
||||||
|
format!("{}-{}", package.name, package.version),
|
||||||
|
output_hash.trim().to_string().clone(),
|
||||||
|
));
|
||||||
|
|
||||||
|
hashes.insert(original_url.to_string(), hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
fs::write(
|
||||||
|
package_path.with_file_name("Cargo.lock"),
|
||||||
|
cargo_lock_content,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let mut package_lines: Vec<_> = fs::read_to_string(&package_path)?
|
||||||
|
.lines()
|
||||||
|
.map(String::from)
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let (cargo_deps_line_index, cargo_deps_line) = package_lines
|
||||||
|
.iter_mut()
|
||||||
|
.enumerate()
|
||||||
|
.find(|(_, l)| {
|
||||||
|
l.trim_start().starts_with("cargoHash") || l.trim_start().starts_with("cargoSha256")
|
||||||
|
})
|
||||||
|
.expect("package should contain cargoHash/cargoSha256");
|
||||||
|
|
||||||
|
let spaces = " ".repeat(cargo_deps_line.len() - cargo_deps_line.trim_start().len());
|
||||||
|
|
||||||
|
if git_dependencies.is_empty() {
|
||||||
|
*cargo_deps_line = format!("{spaces}cargoLock.lockFile = ./Cargo.lock;");
|
||||||
|
} else {
|
||||||
|
*cargo_deps_line = format!("{spaces}cargoLock = {{");
|
||||||
|
|
||||||
|
let mut index_iter = cargo_deps_line_index + 1..;
|
||||||
|
|
||||||
|
package_lines.insert(
|
||||||
|
index_iter.next().unwrap(),
|
||||||
|
format!("{spaces} lockFile = ./Cargo.lock;"),
|
||||||
|
);
|
||||||
|
|
||||||
|
package_lines.insert(
|
||||||
|
index_iter.next().unwrap(),
|
||||||
|
format!("{spaces} outputHashes = {{"),
|
||||||
|
);
|
||||||
|
|
||||||
|
for ((dep, hash), index) in git_dependencies.drain(..).zip(&mut index_iter) {
|
||||||
|
package_lines.insert(index, format!("{spaces} {dep:?} = {hash:?};"));
|
||||||
|
}
|
||||||
|
|
||||||
|
package_lines.insert(index_iter.next().unwrap(), format!("{spaces} }};"));
|
||||||
|
package_lines.insert(index_iter.next().unwrap(), format!("{spaces}}};"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if package_lines.last().map(String::as_str) != Some("") {
|
||||||
|
package_lines.push(String::new());
|
||||||
|
}
|
||||||
|
|
||||||
|
fs::write(package_path, package_lines.join("\n"))?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn nix_eval(attr: impl AsRef<str>) -> anyhow::Result<Option<String>> {
|
||||||
|
let output = String::from_utf8(
|
||||||
|
Command::new("nix-instantiate")
|
||||||
|
.args(["--eval", "-A", attr.as_ref()])
|
||||||
|
.output()?
|
||||||
|
.stdout,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let trimmed = output.trim();
|
||||||
|
|
||||||
|
if trimmed.is_empty() || trimmed == "null" {
|
||||||
|
Ok(None)
|
||||||
|
} else {
|
||||||
|
Ok(Some(
|
||||||
|
trimmed
|
||||||
|
.strip_prefix('"')
|
||||||
|
.and_then(|p| p.strip_suffix('"'))
|
||||||
|
.ok_or_else(|| anyhow!("couldn't parse nix-instantiate output: {output:?}"))?
|
||||||
|
.to_string(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
@ -127,8 +127,7 @@ echo "$urllist" | xargs wget $wgetargs -nH -r -c --no-parent && {
|
|||||||
|
|
||||||
# TODO fetch only missing tar.xz files
|
# TODO fetch only missing tar.xz files
|
||||||
echo "fetching $filecount tar.xz files ..."
|
echo "fetching $filecount tar.xz files ..."
|
||||||
urllist="$(echo "$filelist" | while read file; do echo "$BASE_URL/$file"; done)"
|
echo "$filelist" | xargs wget $wgetargs -nH -r -c --no-parent
|
||||||
echo "$urllist" | xargs wget $wgetargs -nH -r -c --no-parent
|
|
||||||
|
|
||||||
echo "generating sha256 files ..."
|
echo "generating sha256 files ..."
|
||||||
find . -type f -name '*.tar.xz' | while read src; do
|
find . -type f -name '*.tar.xz' | while read src; do
|
||||||
|
@ -3,7 +3,7 @@ let
|
|||||||
pkgs = import ../../.. {};
|
pkgs = import ../../.. {};
|
||||||
inherit (pkgs) lib;
|
inherit (pkgs) lib;
|
||||||
getDeps = _: pkg: {
|
getDeps = _: pkg: {
|
||||||
deps = builtins.filter (x: !isNull x) (map (x: x.pname or null) (pkg.propagatedBuildInputs or []));
|
deps = builtins.filter (x: x != null) (map (x: x.pname or null) (pkg.propagatedBuildInputs or []));
|
||||||
broken = (pkg.meta.hydraPlatforms or [null]) == [];
|
broken = (pkg.meta.hydraPlatforms or [null]) == [];
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
|
468
maintainers/scripts/update-octave-packages
Executable file
468
maintainers/scripts/update-octave-packages
Executable file
@ -0,0 +1,468 @@
|
|||||||
|
#!/usr/bin/env nix-shell
|
||||||
|
#!nix-shell update-octave-shell.nix -i python3
|
||||||
|
|
||||||
|
"""
|
||||||
|
Update a Octave package expression by passing in the `.nix` file, or the directory containing it.
|
||||||
|
You can pass in multiple files or paths.
|
||||||
|
|
||||||
|
You'll likely want to use
|
||||||
|
``
|
||||||
|
$ ./update-octave-libraries ../../pkgs/development/octave-modules/**/default.nix
|
||||||
|
``
|
||||||
|
to update all non-pinned libraries in that folder.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
import pathlib
|
||||||
|
import re
|
||||||
|
import requests
|
||||||
|
import yaml
|
||||||
|
from concurrent.futures import ThreadPoolExecutor as Pool
|
||||||
|
from packaging.version import Version as _Version
|
||||||
|
from packaging.version import InvalidVersion
|
||||||
|
from packaging.specifiers import SpecifierSet
|
||||||
|
import collections
|
||||||
|
import subprocess
|
||||||
|
import tempfile
|
||||||
|
|
||||||
|
INDEX = "https://raw.githubusercontent.com/gnu-octave/packages/main/packages"
|
||||||
|
"""url of Octave packages' source on GitHub"""
|
||||||
|
|
||||||
|
EXTENSIONS = ['tar.gz', 'tar.bz2', 'tar', 'zip']
|
||||||
|
"""Permitted file extensions. These are evaluated from left to right and the first occurance is returned."""
|
||||||
|
|
||||||
|
PRERELEASES = False
|
||||||
|
|
||||||
|
GIT = "git"
|
||||||
|
|
||||||
|
NIXPGKS_ROOT = subprocess.check_output(["git", "rev-parse", "--show-toplevel"]).decode('utf-8').strip()
|
||||||
|
|
||||||
|
import logging
|
||||||
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
|
||||||
|
|
||||||
|
class Version(_Version, collections.abc.Sequence):
|
||||||
|
|
||||||
|
def __init__(self, version):
|
||||||
|
super().__init__(version)
|
||||||
|
# We cannot use `str(Version(0.04.21))` because that becomes `0.4.21`
|
||||||
|
# https://github.com/avian2/unidecode/issues/13#issuecomment-354538882
|
||||||
|
self.raw_version = version
|
||||||
|
|
||||||
|
def __getitem__(self, i):
|
||||||
|
return self._version.release[i]
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return len(self._version.release)
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
yield from self._version.release
|
||||||
|
|
||||||
|
|
||||||
|
def _get_values(attribute, text):
|
||||||
|
"""Match attribute in text and return all matches.
|
||||||
|
|
||||||
|
:returns: List of matches.
|
||||||
|
"""
|
||||||
|
regex = '{}\s+=\s+"(.*)";'.format(attribute)
|
||||||
|
regex = re.compile(regex)
|
||||||
|
values = regex.findall(text)
|
||||||
|
return values
|
||||||
|
|
||||||
|
def _get_unique_value(attribute, text):
|
||||||
|
"""Match attribute in text and return unique match.
|
||||||
|
|
||||||
|
:returns: Single match.
|
||||||
|
"""
|
||||||
|
values = _get_values(attribute, text)
|
||||||
|
n = len(values)
|
||||||
|
if n > 1:
|
||||||
|
raise ValueError("found too many values for {}".format(attribute))
|
||||||
|
elif n == 1:
|
||||||
|
return values[0]
|
||||||
|
else:
|
||||||
|
raise ValueError("no value found for {}".format(attribute))
|
||||||
|
|
||||||
|
def _get_line_and_value(attribute, text):
|
||||||
|
"""Match attribute in text. Return the line and the value of the attribute."""
|
||||||
|
regex = '({}\s+=\s+"(.*)";)'.format(attribute)
|
||||||
|
regex = re.compile(regex)
|
||||||
|
value = regex.findall(text)
|
||||||
|
n = len(value)
|
||||||
|
if n > 1:
|
||||||
|
raise ValueError("found too many values for {}".format(attribute))
|
||||||
|
elif n == 1:
|
||||||
|
return value[0]
|
||||||
|
else:
|
||||||
|
raise ValueError("no value found for {}".format(attribute))
|
||||||
|
|
||||||
|
|
||||||
|
def _replace_value(attribute, value, text):
|
||||||
|
"""Search and replace value of attribute in text."""
|
||||||
|
old_line, old_value = _get_line_and_value(attribute, text)
|
||||||
|
new_line = old_line.replace(old_value, value)
|
||||||
|
new_text = text.replace(old_line, new_line)
|
||||||
|
return new_text
|
||||||
|
|
||||||
|
|
||||||
|
def _fetch_page(url):
|
||||||
|
r = requests.get(url)
|
||||||
|
if r.status_code == requests.codes.ok:
|
||||||
|
return list(yaml.safe_load_all(r.content))[0]
|
||||||
|
else:
|
||||||
|
raise ValueError("request for {} failed".format(url))
|
||||||
|
|
||||||
|
|
||||||
|
def _fetch_github(url):
|
||||||
|
headers = {}
|
||||||
|
token = os.environ.get('GITHUB_API_TOKEN')
|
||||||
|
if token:
|
||||||
|
headers["Authorization"] = f"token {token}"
|
||||||
|
r = requests.get(url, headers=headers)
|
||||||
|
|
||||||
|
if r.status_code == requests.codes.ok:
|
||||||
|
return r.json()
|
||||||
|
else:
|
||||||
|
raise ValueError("request for {} failed".format(url))
|
||||||
|
|
||||||
|
|
||||||
|
SEMVER = {
|
||||||
|
'major' : 0,
|
||||||
|
'minor' : 1,
|
||||||
|
'patch' : 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _determine_latest_version(current_version, target, versions):
|
||||||
|
"""Determine latest version, given `target`, returning the more recent version.
|
||||||
|
"""
|
||||||
|
current_version = Version(current_version)
|
||||||
|
|
||||||
|
def _parse_versions(versions):
|
||||||
|
for v in versions:
|
||||||
|
try:
|
||||||
|
yield Version(v)
|
||||||
|
except InvalidVersion:
|
||||||
|
pass
|
||||||
|
|
||||||
|
versions = _parse_versions(versions)
|
||||||
|
|
||||||
|
index = SEMVER[target]
|
||||||
|
|
||||||
|
ceiling = list(current_version[0:index])
|
||||||
|
if len(ceiling) == 0:
|
||||||
|
ceiling = None
|
||||||
|
else:
|
||||||
|
ceiling[-1]+=1
|
||||||
|
ceiling = Version(".".join(map(str, ceiling)))
|
||||||
|
|
||||||
|
# We do not want prereleases
|
||||||
|
versions = SpecifierSet(prereleases=PRERELEASES).filter(versions)
|
||||||
|
|
||||||
|
if ceiling is not None:
|
||||||
|
versions = SpecifierSet(f"<{ceiling}").filter(versions)
|
||||||
|
|
||||||
|
return (max(sorted(versions))).raw_version
|
||||||
|
|
||||||
|
|
||||||
|
def _get_latest_version_octave_packages(package, extension, current_version, target):
|
||||||
|
"""Get latest version and hash from Octave Packages."""
|
||||||
|
url = "{}/{}.yaml".format(INDEX, package)
|
||||||
|
yaml = _fetch_page(url)
|
||||||
|
|
||||||
|
versions = list(map(lambda pv: pv['id'], yaml['versions']))
|
||||||
|
version = _determine_latest_version(current_version, target, versions)
|
||||||
|
|
||||||
|
try:
|
||||||
|
releases = [v if v['id'] == version else None for v in yaml['versions']]
|
||||||
|
except KeyError as e:
|
||||||
|
raise KeyError('Could not find version {} for {}'.format(version, package)) from e
|
||||||
|
for release in releases:
|
||||||
|
if release['url'].endswith(extension):
|
||||||
|
sha256 = release['sha256']
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
sha256 = None
|
||||||
|
return version, sha256, None
|
||||||
|
|
||||||
|
|
||||||
|
def _get_latest_version_github(package, extension, current_version, target):
|
||||||
|
def strip_prefix(tag):
|
||||||
|
return re.sub("^[^0-9]*", "", tag)
|
||||||
|
|
||||||
|
def get_prefix(string):
|
||||||
|
matches = re.findall(r"^([^0-9]*)", string)
|
||||||
|
return next(iter(matches), "")
|
||||||
|
|
||||||
|
# when invoked as an updateScript, UPDATE_NIX_ATTR_PATH will be set
|
||||||
|
# this allows us to work with packages which live outside of octave-modules
|
||||||
|
attr_path = os.environ.get("UPDATE_NIX_ATTR_PATH", f"octavePackages.{package}")
|
||||||
|
try:
|
||||||
|
homepage = subprocess.check_output(
|
||||||
|
["nix", "eval", "-f", f"{NIXPGKS_ROOT}/default.nix", "--raw", f"{attr_path}.src.meta.homepage"])\
|
||||||
|
.decode('utf-8')
|
||||||
|
except Exception as e:
|
||||||
|
raise ValueError(f"Unable to determine homepage: {e}")
|
||||||
|
owner_repo = homepage[len("https://github.com/"):] # remove prefix
|
||||||
|
owner, repo = owner_repo.split("/")
|
||||||
|
|
||||||
|
url = f"https://api.github.com/repos/{owner}/{repo}/releases"
|
||||||
|
all_releases = _fetch_github(url)
|
||||||
|
releases = list(filter(lambda x: not x['prerelease'], all_releases))
|
||||||
|
|
||||||
|
if len(releases) == 0:
|
||||||
|
raise ValueError(f"{homepage} does not contain any stable releases")
|
||||||
|
|
||||||
|
versions = map(lambda x: strip_prefix(x['tag_name']), releases)
|
||||||
|
version = _determine_latest_version(current_version, target, versions)
|
||||||
|
|
||||||
|
release = next(filter(lambda x: strip_prefix(x['tag_name']) == version, releases))
|
||||||
|
prefix = get_prefix(release['tag_name'])
|
||||||
|
try:
|
||||||
|
sha256 = subprocess.check_output(["nix-prefetch-url", "--type", "sha256", "--unpack", f"{release['tarball_url']}"], stderr=subprocess.DEVNULL)\
|
||||||
|
.decode('utf-8').strip()
|
||||||
|
except:
|
||||||
|
# this may fail if they have both a branch and a tag of the same name, attempt tag name
|
||||||
|
tag_url = str(release['tarball_url']).replace("tarball","tarball/refs/tags")
|
||||||
|
sha256 = subprocess.check_output(["nix-prefetch-url", "--type", "sha256", "--unpack", tag_url], stderr=subprocess.DEVNULL)\
|
||||||
|
.decode('utf-8').strip()
|
||||||
|
|
||||||
|
|
||||||
|
return version, sha256, prefix
|
||||||
|
|
||||||
|
def _get_latest_version_git(package, extension, current_version, target):
|
||||||
|
"""NOTE: Unimplemented!"""
|
||||||
|
# attr_path = os.environ.get("UPDATE_NIX_ATTR_PATH", f"octavePackages.{package}")
|
||||||
|
# try:
|
||||||
|
# download_url = subprocess.check_output(
|
||||||
|
# ["nix", "--extra-experimental-features", "nix-command", "eval", "-f", f"{NIXPGKS_ROOT}/default.nix", "--raw", f"{attr_path}.src.url"])\
|
||||||
|
# .decode('utf-8')
|
||||||
|
# except Exception as e:
|
||||||
|
# raise ValueError(f"Unable to determine download link: {e}")
|
||||||
|
|
||||||
|
# with tempfile.TemporaryDirectory(prefix=attr_path) as new_clone_location:
|
||||||
|
# subprocess.run(["git", "clone", download_url, new_clone_location])
|
||||||
|
# newest_commit = subprocess.check_output(
|
||||||
|
# ["git" "rev-parse" "$(git branch -r)" "|" "tail" "-n" "1"]).decode('utf-8')
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
FETCHERS = {
|
||||||
|
'fetchFromGitHub' : _get_latest_version_github,
|
||||||
|
'fetchurl' : _get_latest_version_octave_packages,
|
||||||
|
'fetchgit' : _get_latest_version_git,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DEFAULT_SETUPTOOLS_EXTENSION = 'tar.gz'
|
||||||
|
|
||||||
|
|
||||||
|
FORMATS = {
|
||||||
|
'setuptools' : DEFAULT_SETUPTOOLS_EXTENSION,
|
||||||
|
}
|
||||||
|
|
||||||
|
def _determine_fetcher(text):
|
||||||
|
# Count occurrences of fetchers.
|
||||||
|
nfetchers = sum(text.count('src = {}'.format(fetcher)) for fetcher in FETCHERS.keys())
|
||||||
|
if nfetchers == 0:
|
||||||
|
raise ValueError("no fetcher.")
|
||||||
|
elif nfetchers > 1:
|
||||||
|
raise ValueError("multiple fetchers.")
|
||||||
|
else:
|
||||||
|
# Then we check which fetcher to use.
|
||||||
|
for fetcher in FETCHERS.keys():
|
||||||
|
if 'src = {}'.format(fetcher) in text:
|
||||||
|
return fetcher
|
||||||
|
|
||||||
|
|
||||||
|
def _determine_extension(text, fetcher):
|
||||||
|
"""Determine what extension is used in the expression.
|
||||||
|
|
||||||
|
If we use:
|
||||||
|
- fetchPypi, we check if format is specified.
|
||||||
|
- fetchurl, we determine the extension from the url.
|
||||||
|
- fetchFromGitHub we simply use `.tar.gz`.
|
||||||
|
"""
|
||||||
|
if fetcher == 'fetchurl':
|
||||||
|
url = _get_unique_value('url', text)
|
||||||
|
extension = os.path.splitext(url)[1]
|
||||||
|
|
||||||
|
elif fetcher == 'fetchFromGitHub' or fetcher == 'fetchgit':
|
||||||
|
if "fetchSubmodules" in text:
|
||||||
|
raise ValueError("fetchFromGitHub fetcher doesn't support submodules")
|
||||||
|
extension = "tar.gz"
|
||||||
|
|
||||||
|
return extension
|
||||||
|
|
||||||
|
|
||||||
|
def _update_package(path, target):
|
||||||
|
|
||||||
|
# Read the expression
|
||||||
|
with open(path, 'r') as f:
|
||||||
|
text = f.read()
|
||||||
|
|
||||||
|
# Determine pname. Many files have more than one pname
|
||||||
|
pnames = _get_values('pname', text)
|
||||||
|
|
||||||
|
# Determine version.
|
||||||
|
version = _get_unique_value('version', text)
|
||||||
|
|
||||||
|
# First we check how many fetchers are mentioned.
|
||||||
|
fetcher = _determine_fetcher(text)
|
||||||
|
|
||||||
|
extension = _determine_extension(text, fetcher)
|
||||||
|
|
||||||
|
# Attempt a fetch using each pname, e.g. backports-zoneinfo vs backports.zoneinfo
|
||||||
|
successful_fetch = False
|
||||||
|
for pname in pnames:
|
||||||
|
if fetcher == "fetchgit":
|
||||||
|
logging.warning(f"You must update {pname} MANUALLY!")
|
||||||
|
return { 'path': path, 'target': target, 'pname': pname,
|
||||||
|
'old_version': version, 'new_version': version }
|
||||||
|
try:
|
||||||
|
new_version, new_sha256, prefix = FETCHERS[fetcher](pname, extension, version, target)
|
||||||
|
successful_fetch = True
|
||||||
|
break
|
||||||
|
except ValueError:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if not successful_fetch:
|
||||||
|
raise ValueError(f"Unable to find correct package using these pnames: {pnames}")
|
||||||
|
|
||||||
|
if new_version == version:
|
||||||
|
logging.info("Path {}: no update available for {}.".format(path, pname))
|
||||||
|
return False
|
||||||
|
elif Version(new_version) <= Version(version):
|
||||||
|
raise ValueError("downgrade for {}.".format(pname))
|
||||||
|
if not new_sha256:
|
||||||
|
raise ValueError("no file available for {}.".format(pname))
|
||||||
|
|
||||||
|
text = _replace_value('version', new_version, text)
|
||||||
|
# hashes from pypi are 16-bit encoded sha256's, normalize it to sri to avoid merge conflicts
|
||||||
|
# sri hashes have been the default format since nix 2.4+
|
||||||
|
sri_hash = subprocess.check_output(["nix", "--extra-experimental-features", "nix-command", "hash", "to-sri", "--type", "sha256", new_sha256]).decode('utf-8').strip()
|
||||||
|
|
||||||
|
|
||||||
|
# fetchers can specify a sha256, or a sri hash
|
||||||
|
try:
|
||||||
|
text = _replace_value('sha256', sri_hash, text)
|
||||||
|
except ValueError:
|
||||||
|
text = _replace_value('hash', sri_hash, text)
|
||||||
|
|
||||||
|
if fetcher == 'fetchFromGitHub':
|
||||||
|
# in the case of fetchFromGitHub, it's common to see `rev = version;` or `rev = "v${version}";`
|
||||||
|
# in which no string value is meant to be substituted. However, we can just overwrite the previous value.
|
||||||
|
regex = '(rev\s+=\s+[^;]*;)'
|
||||||
|
regex = re.compile(regex)
|
||||||
|
matches = regex.findall(text)
|
||||||
|
n = len(matches)
|
||||||
|
|
||||||
|
if n == 0:
|
||||||
|
raise ValueError("Unable to find rev value for {}.".format(pname))
|
||||||
|
else:
|
||||||
|
# forcefully rewrite rev, incase tagging conventions changed for a release
|
||||||
|
match = matches[0]
|
||||||
|
text = text.replace(match, f'rev = "refs/tags/{prefix}${{version}}";')
|
||||||
|
# incase there's no prefix, just rewrite without interpolation
|
||||||
|
text = text.replace('"${version}";', 'version;')
|
||||||
|
|
||||||
|
with open(path, 'w') as f:
|
||||||
|
f.write(text)
|
||||||
|
|
||||||
|
logging.info("Path {}: updated {} from {} to {}".format(path, pname, version, new_version))
|
||||||
|
|
||||||
|
result = {
|
||||||
|
'path' : path,
|
||||||
|
'target': target,
|
||||||
|
'pname': pname,
|
||||||
|
'old_version' : version,
|
||||||
|
'new_version' : new_version,
|
||||||
|
#'fetcher' : fetcher,
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def _update(path, target):
|
||||||
|
|
||||||
|
# We need to read and modify a Nix expression.
|
||||||
|
if os.path.isdir(path):
|
||||||
|
path = os.path.join(path, 'default.nix')
|
||||||
|
|
||||||
|
# If a default.nix does not exist, we quit.
|
||||||
|
if not os.path.isfile(path):
|
||||||
|
logging.info("Path {}: does not exist.".format(path))
|
||||||
|
return False
|
||||||
|
|
||||||
|
# If file is not a Nix expression, we quit.
|
||||||
|
if not path.endswith(".nix"):
|
||||||
|
logging.info("Path {}: does not end with `.nix`.".format(path))
|
||||||
|
return False
|
||||||
|
|
||||||
|
try:
|
||||||
|
return _update_package(path, target)
|
||||||
|
except ValueError as e:
|
||||||
|
logging.warning("Path {}: {}".format(path, e))
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def _commit(path, pname, old_version, new_version, pkgs_prefix="octave: ", **kwargs):
|
||||||
|
"""Commit result.
|
||||||
|
"""
|
||||||
|
|
||||||
|
msg = f'{pkgs_prefix}{pname}: {old_version} -> {new_version}'
|
||||||
|
|
||||||
|
try:
|
||||||
|
subprocess.check_call([GIT, 'add', path])
|
||||||
|
subprocess.check_call([GIT, 'commit', '-m', msg])
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
subprocess.check_call([GIT, 'checkout', path])
|
||||||
|
raise subprocess.CalledProcessError(f'Could not commit {path}') from e
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
|
||||||
|
epilog = """
|
||||||
|
environment variables:
|
||||||
|
GITHUB_API_TOKEN\tGitHub API token used when updating github packages
|
||||||
|
"""
|
||||||
|
parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter, epilog=epilog)
|
||||||
|
parser.add_argument('package', type=str, nargs='+')
|
||||||
|
parser.add_argument('--target', type=str, choices=SEMVER.keys(), default='major')
|
||||||
|
parser.add_argument('--commit', action='store_true', help='Create a commit for each package update')
|
||||||
|
parser.add_argument('--use-pkgs-prefix', action='store_true', help='Use octavePackages.${pname}: instead of octave: ${pname}: when making commits')
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
target = args.target
|
||||||
|
|
||||||
|
packages = list(map(os.path.abspath, args.package))
|
||||||
|
|
||||||
|
logging.info("Updating packages...")
|
||||||
|
|
||||||
|
# Use threads to update packages concurrently
|
||||||
|
with Pool() as p:
|
||||||
|
results = list(filter(bool, p.map(lambda pkg: _update(pkg, target), packages)))
|
||||||
|
|
||||||
|
logging.info("Finished updating packages.")
|
||||||
|
|
||||||
|
commit_options = {}
|
||||||
|
if args.use_pkgs_prefix:
|
||||||
|
logging.info("Using octavePackages. prefix for commits")
|
||||||
|
commit_options["pkgs_prefix"] = "octavePackages."
|
||||||
|
|
||||||
|
# Commits are created sequentially.
|
||||||
|
if args.commit:
|
||||||
|
logging.info("Committing updates...")
|
||||||
|
# list forces evaluation
|
||||||
|
list(map(lambda x: _commit(**x, **commit_options), results))
|
||||||
|
logging.info("Finished committing updates")
|
||||||
|
|
||||||
|
count = len(results)
|
||||||
|
logging.info("{} package(s) updated".format(count))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
12
maintainers/scripts/update-octave-shell.nix
Normal file
12
maintainers/scripts/update-octave-shell.nix
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{ nixpkgs ? import ../.. { }
|
||||||
|
}:
|
||||||
|
with nixpkgs;
|
||||||
|
let
|
||||||
|
pyEnv = python3.withPackages(ps: with ps; [ packaging requests toolz pyyaml ]);
|
||||||
|
in
|
||||||
|
mkShell {
|
||||||
|
packages = [
|
||||||
|
pyEnv
|
||||||
|
nix-prefetch-scripts
|
||||||
|
];
|
||||||
|
}
|
@ -221,6 +221,7 @@ with lib.maintainers; {
|
|||||||
|
|
||||||
docs = {
|
docs = {
|
||||||
members = [
|
members = [
|
||||||
|
asymmetric
|
||||||
ryantm
|
ryantm
|
||||||
];
|
];
|
||||||
scope = "Maintain nixpkgs/NixOS documentation and tools for building it.";
|
scope = "Maintain nixpkgs/NixOS documentation and tools for building it.";
|
||||||
@ -424,11 +425,14 @@ with lib.maintainers; {
|
|||||||
|
|
||||||
llvm = {
|
llvm = {
|
||||||
members = [
|
members = [
|
||||||
ericson2314
|
|
||||||
sternenseemann
|
|
||||||
lovek323
|
|
||||||
dtzWill
|
dtzWill
|
||||||
|
ericson2314
|
||||||
|
lovek323
|
||||||
primeos
|
primeos
|
||||||
|
qyliss
|
||||||
|
raitobezarius
|
||||||
|
rrbutani
|
||||||
|
sternenseemann
|
||||||
];
|
];
|
||||||
scope = "Maintain LLVM package sets and related packages";
|
scope = "Maintain LLVM package sets and related packages";
|
||||||
shortName = "LLVM";
|
shortName = "LLVM";
|
||||||
|
@ -166,7 +166,11 @@ let
|
|||||||
--manpage-urls ${manpageUrls} \
|
--manpage-urls ${manpageUrls} \
|
||||||
--revision ${lib.escapeShellArg revision} \
|
--revision ${lib.escapeShellArg revision} \
|
||||||
./manual.md \
|
./manual.md \
|
||||||
./manual-combined.xml
|
./manual-combined-pre.xml
|
||||||
|
|
||||||
|
${pkgs.libxslt.bin}/bin/xsltproc \
|
||||||
|
-o manual-combined.xml ${./../../lib/make-options-doc/postprocess-option-descriptions.xsl} \
|
||||||
|
manual-combined-pre.xml
|
||||||
|
|
||||||
${linterFunctions}
|
${linterFunctions}
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ In addition to numerous new and upgraded packages, this release has the followin
|
|||||||
|
|
||||||
- [ArchiSteamFarm](https://github.com/JustArchiNET/ArchiSteamFarm), a C# application with primary purpose of idling Steam cards from multiple accounts simultaneously. Available as [services.archisteamfarm](#opt-services.archisteamfarm.enable).
|
- [ArchiSteamFarm](https://github.com/JustArchiNET/ArchiSteamFarm), a C# application with primary purpose of idling Steam cards from multiple accounts simultaneously. Available as [services.archisteamfarm](#opt-services.archisteamfarm.enable).
|
||||||
|
|
||||||
- [BaGet](https://loic-sharma.github.io/BaGet/), a lightweight NuGet and symbol server. Available at [services.baget](#opt-services.baget.enable).
|
- [BaGet](https://loic-sharma.github.io/BaGet/), a lightweight NuGet and symbol server. Available at services.baget.
|
||||||
|
|
||||||
- [bird-lg](https://github.com/xddxdd/bird-lg-go), a BGP looking glass for Bird Routing. Available as [services.bird-lg](#opt-services.bird-lg.package).
|
- [bird-lg](https://github.com/xddxdd/bird-lg-go), a BGP looking glass for Bird Routing. Available as [services.bird-lg](#opt-services.bird-lg.package).
|
||||||
|
|
||||||
|
@ -12,12 +12,18 @@ In addition to numerous new and upgraded packages, this release has the followin
|
|||||||
|
|
||||||
- default linux: 5.15 -\> 6.1, all supported kernels available
|
- default linux: 5.15 -\> 6.1, all supported kernels available
|
||||||
|
|
||||||
|
- systemd has been updated to v253.1, see [the pull request](https://github.com/NixOS/nixpkgs/pull/216826) for more info.
|
||||||
|
It's recommended to use `nixos-rebuild boot` and `reboot`, rather than `nixos-rebuild switch` - since in some rare cases
|
||||||
|
the switch of a live system might fail.
|
||||||
|
|
||||||
- Cinnamon has been updated to 5.6, see [the pull request](https://github.com/NixOS/nixpkgs/pull/201328#issue-1449910204) for what is changed.
|
- Cinnamon has been updated to 5.6, see [the pull request](https://github.com/NixOS/nixpkgs/pull/201328#issue-1449910204) for what is changed.
|
||||||
|
|
||||||
- KDE Plasma has been updated to v5.27, see [the release notes](https://kde.org/announcements/plasma/5/5.27.0/) for what is changed.
|
- KDE Plasma has been updated to v5.27, see [the release notes](https://kde.org/announcements/plasma/5/5.27.0/) for what is changed.
|
||||||
|
|
||||||
- `nixos-rebuild` now supports an extra `--specialisation` option that can be used to change specialisation for `switch` and `test` commands.
|
- `nixos-rebuild` now supports an extra `--specialisation` option that can be used to change specialisation for `switch` and `test` commands.
|
||||||
|
|
||||||
|
- `libxcrypt`, the library providing the `crypt(3)` password hashing function, is now built without support for algorithms not flagged [`strong`](https://github.com/besser82/libxcrypt/blob/v4.4.33/lib/hashes.conf#L48). This affects the availability of password hashing algorithms used for system login (`login(1)`, `passwd(1)`), but also Apache2 Basic-Auth, Samba, OpenLDAP, Dovecot, and [many other packages](https://github.com/search?q=repo%3ANixOS%2Fnixpkgs%20libxcrypt&type=code).
|
||||||
|
|
||||||
## New Services {#sec-release-23.05-new-services}
|
## New Services {#sec-release-23.05-new-services}
|
||||||
|
|
||||||
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
|
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
|
||||||
@ -45,8 +51,12 @@ In addition to numerous new and upgraded packages, this release has the followin
|
|||||||
|
|
||||||
- [opensearch](https://opensearch.org), a search server alternative to Elasticsearch. Available as [services.opensearch](options.html#opt-services.opensearch.enable).
|
- [opensearch](https://opensearch.org), a search server alternative to Elasticsearch. Available as [services.opensearch](options.html#opt-services.opensearch.enable).
|
||||||
|
|
||||||
|
- [authelia](https://www.authelia.com/), is an open-source authentication and authorization server. Available under [services.authelia](options.html#opt-services.authelia.enable).
|
||||||
|
|
||||||
- [goeland](https://github.com/slurdge/goeland), an alternative to rss2email written in golang with many filters. Available as [services.goeland](#opt-services.goeland.enable).
|
- [goeland](https://github.com/slurdge/goeland), an alternative to rss2email written in golang with many filters. Available as [services.goeland](#opt-services.goeland.enable).
|
||||||
|
|
||||||
|
- [alertmanager-irc-relay](https://github.com/google/alertmanager-irc-relay), a Prometheus Alertmanager IRC Relay. Available as [services.prometheus.alertmanagerIrcRelay](options.html#opt-services.prometheus.alertmanagerIrcRelay.enable).
|
||||||
|
|
||||||
- [tts](https://github.com/coqui-ai/TTS), a battle-tested deep learning toolkit for Text-to-Speech. Mutiple servers may be configured below [services.tts.servers](#opt-services.tts.servers).
|
- [tts](https://github.com/coqui-ai/TTS), a battle-tested deep learning toolkit for Text-to-Speech. Mutiple servers may be configured below [services.tts.servers](#opt-services.tts.servers).
|
||||||
|
|
||||||
- [atuin](https://github.com/ellie/atuin), a sync server for shell history. Available as [services.atuin](#opt-services.atuin.enable).
|
- [atuin](https://github.com/ellie/atuin), a sync server for shell history. Available as [services.atuin](#opt-services.atuin.enable).
|
||||||
@ -57,6 +67,8 @@ In addition to numerous new and upgraded packages, this release has the followin
|
|||||||
|
|
||||||
- [QDMR](https://dm3mat.darc.de/qdmr/), a GUI application and command line tool for programming DMR radios [programs.qdmr](#opt-programs.qdmr.enable)
|
- [QDMR](https://dm3mat.darc.de/qdmr/), a GUI application and command line tool for programming DMR radios [programs.qdmr](#opt-programs.qdmr.enable)
|
||||||
|
|
||||||
|
- [keyd](https://github.com/rvaiya/keyd), a key remapping daemon for linux. Available as [services.keyd](#opt-services.keyd.enable).
|
||||||
|
|
||||||
- [v2rayA](https://v2raya.org), a Linux web GUI client of Project V which supports V2Ray, Xray, SS, SSR, Trojan and Pingtunnel. Available as [services.v2raya](options.html#opt-services.v2raya.enable).
|
- [v2rayA](https://v2raya.org), a Linux web GUI client of Project V which supports V2Ray, Xray, SS, SSR, Trojan and Pingtunnel. Available as [services.v2raya](options.html#opt-services.v2raya.enable).
|
||||||
|
|
||||||
- [ulogd](https://www.netfilter.org/projects/ulogd/index.html), a userspace logging daemon for netfilter/iptables related logging. Available as [services.ulogd](options.html#opt-services.ulogd.enable).
|
- [ulogd](https://www.netfilter.org/projects/ulogd/index.html), a userspace logging daemon for netfilter/iptables related logging. Available as [services.ulogd](options.html#opt-services.ulogd.enable).
|
||||||
@ -65,12 +77,20 @@ In addition to numerous new and upgraded packages, this release has the followin
|
|||||||
|
|
||||||
- [photoprism](https://photoprism.app/), a AI-Powered Photos App for the Decentralized Web. Available as [services.photoprism](options.html#opt-services.photoprism.enable).
|
- [photoprism](https://photoprism.app/), a AI-Powered Photos App for the Decentralized Web. Available as [services.photoprism](options.html#opt-services.photoprism.enable).
|
||||||
|
|
||||||
|
- [peroxide](https://github.com/ljanyst/peroxide), a fork of the official [ProtonMail bridge](https://github.com/ProtonMail/proton-bridge) that aims to be similar to [Hydroxide](https://github.com/emersion/hydroxide). Available as [services.peroxide](#opt-services.peroxide.enable).
|
||||||
|
|
||||||
- [autosuspend](https://github.com/languitar/autosuspend), a python daemon that suspends a system if certain conditions are met, or not met.
|
- [autosuspend](https://github.com/languitar/autosuspend), a python daemon that suspends a system if certain conditions are met, or not met.
|
||||||
|
|
||||||
- [sharing](https://github.com/parvardegr/sharing), a command-line tool to share directories and files from the CLI to iOS and Android devices without the need of an extra client app. Available as [programs.sharing](#opt-programs.sharing.enable).
|
- [sharing](https://github.com/parvardegr/sharing), a command-line tool to share directories and files from the CLI to iOS and Android devices without the need of an extra client app. Available as [programs.sharing](#opt-programs.sharing.enable).
|
||||||
|
|
||||||
- [nimdow](https://github.com/avahe-kellenberger/nimdow), a window manager written in Nim, inspired by dwm.
|
- [nimdow](https://github.com/avahe-kellenberger/nimdow), a window manager written in Nim, inspired by dwm.
|
||||||
|
|
||||||
|
- [woodpecker-agents](https://woodpecker-ci.org/), a simple CI engine with great extensibility. Available as [services.woodpecker-agents](#opt-services.woodpecker-agents.agents._name_.enable).
|
||||||
|
|
||||||
|
- [woodpecker-server](https://woodpecker-ci.org/), a simple CI engine with great extensibility. Available as [services.woodpecker-server](#opt-services.woodpecker-server.enable).
|
||||||
|
|
||||||
|
- [ReGreet](https://github.com/rharish101/ReGreet), a clean and customizable greeter for greetd. Available as [programs.regreet](#opt-programs.regreet.enable).
|
||||||
|
|
||||||
## Backward Incompatibilities {#sec-release-23.05-incompatibilities}
|
## Backward Incompatibilities {#sec-release-23.05-incompatibilities}
|
||||||
|
|
||||||
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
|
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
|
||||||
@ -89,6 +109,8 @@ In addition to numerous new and upgraded packages, this release has the followin
|
|||||||
|
|
||||||
- `git-bug` has been updated to at least version 0.8.0, which includes backwards incompatible changes. The `git-bug-migration` package can be used to upgrade existing repositories.
|
- `git-bug` has been updated to at least version 0.8.0, which includes backwards incompatible changes. The `git-bug-migration` package can be used to upgrade existing repositories.
|
||||||
|
|
||||||
|
- `nushell` has been updated to at least version 0.77.0, which includes potential breaking changes in aliases. The old aliases are now available as `old-alias` but it is recommended you migrate to the new format. See [Reworked aliases](https://www.nushell.sh/blog/2023-03-14-nushell_0_77.html#reworked-aliases-breaking-changes-kubouch).
|
||||||
|
|
||||||
- `keepassx` and `keepassx2` have been removed, due to upstream [stopping development](https://www.keepassx.org/index.html%3Fp=636.html). Consider [KeePassXC](https://keepassxc.org) as a maintained alternative.
|
- `keepassx` and `keepassx2` have been removed, due to upstream [stopping development](https://www.keepassx.org/index.html%3Fp=636.html). Consider [KeePassXC](https://keepassxc.org) as a maintained alternative.
|
||||||
|
|
||||||
- The `services.kubo.settings` option is now no longer stateful. If you changed any of the options in `services.kubo.settings` in the past and then removed them from your NixOS configuration again, those changes are still in your Kubo configuration file but will now be reset to the default. If you're unsure, you may want to make a backup of your configuration file (probably /var/lib/ipfs/config) and compare after the update.
|
- The `services.kubo.settings` option is now no longer stateful. If you changed any of the options in `services.kubo.settings` in the past and then removed them from your NixOS configuration again, those changes are still in your Kubo configuration file but will now be reset to the default. If you're unsure, you may want to make a backup of your configuration file (probably /var/lib/ipfs/config) and compare after the update.
|
||||||
@ -110,16 +132,22 @@ In addition to numerous new and upgraded packages, this release has the followin
|
|||||||
|
|
||||||
- `tut` has been updated from 1.0.34 to 2.0.0, and now uses the TOML format for the configuration file instead of INI. Additional information can be found [here](https://github.com/RasmusLindroth/tut/releases/tag/2.0.0).
|
- `tut` has been updated from 1.0.34 to 2.0.0, and now uses the TOML format for the configuration file instead of INI. Additional information can be found [here](https://github.com/RasmusLindroth/tut/releases/tag/2.0.0).
|
||||||
|
|
||||||
|
- `i3status-rust` has been updated from 0.22.0 to 0.30.5, and this brings many changes to its configuration format. Additional information can be found [here](https://github.com/greshake/i3status-rust/blob/v0.30.0/NEWS.md).
|
||||||
|
|
||||||
- The `wordpress` derivation no longer contains any builtin plugins or themes. If you need them you have to add them back to prevent your site from breaking. You can find them in `wordpressPackages.{plugins,themes}`.
|
- The `wordpress` derivation no longer contains any builtin plugins or themes. If you need them you have to add them back to prevent your site from breaking. You can find them in `wordpressPackages.{plugins,themes}`.
|
||||||
|
|
||||||
- `llvmPackages_rocm.llvm` will not contain `clang` or `compiler-rt`. `llvmPackages_rocm.clang` will not contain `llvm`. `llvmPackages_rocm.clangNoCompilerRt` has been removed in favor of using `llvmPackages_rocm.clang-unwrapped`.
|
- `llvmPackages_rocm.llvm` will not contain `clang` or `compiler-rt`. `llvmPackages_rocm.clang` will not contain `llvm`. `llvmPackages_rocm.clangNoCompilerRt` has been removed in favor of using `llvmPackages_rocm.clang-unwrapped`.
|
||||||
|
|
||||||
|
- `services.xserver.desktopManager.plasma5.excludePackages` has been moved to `environment.plasma5.excludePackages`, for consistency with other Desktop Environments
|
||||||
|
|
||||||
- The EC2 image module previously detected and automatically mounted ext3-formatted instance store devices and partitions in stage-1 (initramfs), storing `/tmp` on the first discovered device. This behaviour, which only catered to very specific use cases and could not be disabled, has been removed. Users relying on this should provide their own implementation, and probably use ext4 and perform the mount in stage-2.
|
- The EC2 image module previously detected and automatically mounted ext3-formatted instance store devices and partitions in stage-1 (initramfs), storing `/tmp` on the first discovered device. This behaviour, which only catered to very specific use cases and could not be disabled, has been removed. Users relying on this should provide their own implementation, and probably use ext4 and perform the mount in stage-2.
|
||||||
|
|
||||||
- `teleport` has been upgraded from major version 10 to major version 12. Please see upstream [upgrade instructions](https://goteleport.com/docs/setup/operations/upgrading/) and release notes for versions [11](https://goteleport.com/docs/changelog/#1100) and [12](https://goteleport.com/docs/changelog/#1201). Note that Teleport does not officially support upgrades across more than one major version at a time. If you're running Teleport server components, it is recommended to first upgrade to an intermediate 11.x version by setting `services.teleport.package = pkgs.teleport_11`. Afterwards, this option can be removed to upgrade to the default version (12).
|
- `teleport` has been upgraded from major version 10 to major version 12. Please see upstream [upgrade instructions](https://goteleport.com/docs/setup/operations/upgrading/) and release notes for versions [11](https://goteleport.com/docs/changelog/#1100) and [12](https://goteleport.com/docs/changelog/#1201). Note that Teleport does not officially support upgrades across more than one major version at a time. If you're running Teleport server components, it is recommended to first upgrade to an intermediate 11.x version by setting `services.teleport.package = pkgs.teleport_11`. Afterwards, this option can be removed to upgrade to the default version (12).
|
||||||
|
|
||||||
- The EC2 image module previously detected and activated swap-formatted instance store devices and partitions in stage-1 (initramfs). This behaviour has been removed. Users relying on this should provide their own implementation.
|
- The EC2 image module previously detected and activated swap-formatted instance store devices and partitions in stage-1 (initramfs). This behaviour has been removed. Users relying on this should provide their own implementation.
|
||||||
|
|
||||||
|
- `fail2ban` has been updated to 1.0.2, which has a few breaking changes compared to 0.11.2 ([changelog for 1.0.1](https://github.com/fail2ban/fail2ban/blob/1.0.1/ChangeLog), [changelog for 1.0.2](https://github.com/fail2ban/fail2ban/blob/1.0.2/ChangeLog))
|
||||||
|
|
||||||
- Calling `makeSetupHook` without passing a `name` argument is deprecated.
|
- Calling `makeSetupHook` without passing a `name` argument is deprecated.
|
||||||
|
|
||||||
- `lib.systems.examples.ghcjs` and consequently `pkgsCross.ghcjs` now use the target triplet `javascript-unknown-ghcjs` instead of `js-unknown-ghcjs`. This has been done to match an [upstream decision](https://gitlab.haskell.org/ghc/ghc/-/commit/6636b670233522f01d002c9b97827d00289dbf5c) to follow Cabal's platform naming more closely. Nixpkgs will also reject `js` as an architecture name.
|
- `lib.systems.examples.ghcjs` and consequently `pkgsCross.ghcjs` now use the target triplet `javascript-unknown-ghcjs` instead of `js-unknown-ghcjs`. This has been done to match an [upstream decision](https://gitlab.haskell.org/ghc/ghc/-/commit/6636b670233522f01d002c9b97827d00289dbf5c) to follow Cabal's platform naming more closely. Nixpkgs will also reject `js` as an architecture name.
|
||||||
@ -130,10 +158,12 @@ In addition to numerous new and upgraded packages, this release has the followin
|
|||||||
|
|
||||||
- The [services.wordpress.sites.<name>.plugins](#opt-services.wordpress.sites._name_.plugins) and [services.wordpress.sites.<name>.themes](#opt-services.wordpress.sites._name_.themes) options have been converted from sets to attribute sets to allow for consumers to specify explicit install paths via attribute name.
|
- The [services.wordpress.sites.<name>.plugins](#opt-services.wordpress.sites._name_.plugins) and [services.wordpress.sites.<name>.themes](#opt-services.wordpress.sites._name_.themes) options have been converted from sets to attribute sets to allow for consumers to specify explicit install paths via attribute name.
|
||||||
|
|
||||||
- `protonmail-bridge` package has been updated to v3.0 and the CLI executable is now named bridge instead of protonmail-bridge to be more in line with upstream.
|
- `protonmail-bridge` package has been updated to major version 3.
|
||||||
|
|
||||||
- Nebula now runs as a system user and group created for each nebula network, using the `CAP_NET_ADMIN` ambient capability on launch rather than starting as root. Ensure that any files each Nebula instance needs to access are owned by the correct user and group, by default `nebula-${networkName}`.
|
- Nebula now runs as a system user and group created for each nebula network, using the `CAP_NET_ADMIN` ambient capability on launch rather than starting as root. Ensure that any files each Nebula instance needs to access are owned by the correct user and group, by default `nebula-${networkName}`.
|
||||||
|
|
||||||
|
- The `i18n.inputMethod.fcitx` option has been replaced with `i18n.inputMethod.fcitx5` because fcitx 4 `pkgs.fcitx` has been removed.
|
||||||
|
|
||||||
- In `mastodon` it is now necessary to specify location of file with `PostgreSQL` database password. In `services.mastodon.database.passwordFile` parameter default value `/var/lib/mastodon/secrets/db-password` has been changed to `null`.
|
- In `mastodon` it is now necessary to specify location of file with `PostgreSQL` database password. In `services.mastodon.database.passwordFile` parameter default value `/var/lib/mastodon/secrets/db-password` has been changed to `null`.
|
||||||
|
|
||||||
- The `--target-host` and `--build-host` options of `nixos-rebuild` no longer treat the `localhost` value specially – to build on/deploy to local machine, omit the relevant flag.
|
- The `--target-host` and `--build-host` options of `nixos-rebuild` no longer treat the `localhost` value specially – to build on/deploy to local machine, omit the relevant flag.
|
||||||
@ -142,6 +172,12 @@ In addition to numerous new and upgraded packages, this release has the followin
|
|||||||
|
|
||||||
- Deprecated `xlibsWrapper` transitional package has been removed in favour of direct use of its constitutents: `xorg.libX11`, `freetype` and others.
|
- Deprecated `xlibsWrapper` transitional package has been removed in favour of direct use of its constitutents: `xorg.libX11`, `freetype` and others.
|
||||||
|
|
||||||
|
- The latest available version of Nextcloud is v26 (available as `pkgs.nextcloud26`) which uses PHP 8.2 as interpreter by default. The installation logic is as follows:
|
||||||
|
- If `system.stateVersion` is >=23.05, `pkgs.nextcloud26` will be installed by default.
|
||||||
|
- If `system.stateVersion` is >=22.11, `pkgs.nextcloud25` will be installed by default.
|
||||||
|
- Please note that an upgrade from v24 (or older) to v26 directly is not possible. Please upgrade to `nextcloud25` (or earlier) first. Nextcloud prohibits skipping major versions while upgrading. You can upgrade by declaring [`services.nextcloud.package = pkgs.nextcloud25;`](options.html#opt-services.nextcloud.package).
|
||||||
|
- It's recommended to use the latest version available (i.e. v26) and to specify that using `services.nextcloud.package`.
|
||||||
|
|
||||||
- .NET 5.0 was removed due to being end-of-life, use a newer, supported .NET version - https://dotnet.microsoft.com/en-us/platform/support/policy/dotnet-core
|
- .NET 5.0 was removed due to being end-of-life, use a newer, supported .NET version - https://dotnet.microsoft.com/en-us/platform/support/policy/dotnet-core
|
||||||
|
|
||||||
- The iputils package, which is installed by default, no longer provides the
|
- The iputils package, which is installed by default, no longer provides the
|
||||||
@ -153,6 +189,18 @@ In addition to numerous new and upgraded packages, this release has the followin
|
|||||||
|
|
||||||
- conntrack helper autodetection has been removed from kernels 6.0 and up upstream, and an assertion was added to ensure things don't silently stop working. Migrate your configuration to assign helpers explicitly or use an older LTS kernel branch as a temporary workaround.
|
- conntrack helper autodetection has been removed from kernels 6.0 and up upstream, and an assertion was added to ensure things don't silently stop working. Migrate your configuration to assign helpers explicitly or use an older LTS kernel branch as a temporary workaround.
|
||||||
|
|
||||||
|
- The `services.pipewire.config` options have been removed, as they have basically never worked correctly. All behavior defined by the default configuration can be overridden with drop-in files as necessary - see [below](#sec-release-23.05-migration-pipewire) for details.
|
||||||
|
|
||||||
|
- The catch-all `hardware.video.hidpi.enable` option was removed. Users on high density displays may want to:
|
||||||
|
|
||||||
|
- Set `services.xserver.upscaleDefaultCursor` to upscale the default X11 cursor for higher resolutions
|
||||||
|
- Adjust settings under `fonts.fontconfig` according to preference
|
||||||
|
- Adjust `console.font` according to preference, though the kernel will generally choose a reasonably sized font
|
||||||
|
|
||||||
|
- `services.pipewire.media-session` and the `pipewire-media-session` package have been removed, as they are no longer supported upstream. Users are encouraged to use `services.pipewire.wireplumber` instead.
|
||||||
|
|
||||||
|
- The `baget` package and module was removed due to being unmaintained.
|
||||||
|
|
||||||
## Other Notable Changes {#sec-release-23.05-notable-changes}
|
## Other Notable Changes {#sec-release-23.05-notable-changes}
|
||||||
|
|
||||||
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
|
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
|
||||||
@ -196,10 +244,14 @@ In addition to numerous new and upgraded packages, this release has the followin
|
|||||||
The `{aclUse,superUser,disableActions}` attributes have been renamed, `pluginsConfig` now also accepts an attribute set of booleans, passing plain PHP is deprecated.
|
The `{aclUse,superUser,disableActions}` attributes have been renamed, `pluginsConfig` now also accepts an attribute set of booleans, passing plain PHP is deprecated.
|
||||||
Same applies to `acl` which now also accepts structured settings.
|
Same applies to `acl` which now also accepts structured settings.
|
||||||
|
|
||||||
|
- The `zsh` package changes the way to set environment variables on NixOS systems where `programs.zsh.enable` equals `false`. It now sources `/etc/set-environment` when reading the system-level `zshenv` file. Before, it sourced `/etc/profile` when reading the system-level `zprofile` file.
|
||||||
|
|
||||||
- The `wordpress` service now takes configuration via the `services.wordpress.sites.<name>.settings` attribute set, `extraConfig` is still available to append additional text to `wp-config.php`.
|
- The `wordpress` service now takes configuration via the `services.wordpress.sites.<name>.settings` attribute set, `extraConfig` is still available to append additional text to `wp-config.php`.
|
||||||
|
|
||||||
- To reduce closure size in `nixos/modules/profiles/minimal.nix` profile disabled installation documentations and manuals. Also disabled `logrotate` and `udisks2` services.
|
- To reduce closure size in `nixos/modules/profiles/minimal.nix` profile disabled installation documentations and manuals. Also disabled `logrotate` and `udisks2` services.
|
||||||
|
|
||||||
|
- To reduce closure size in `nixos/modules/installer/netboot/netboot-minimal.nix` profile disabled load linux firmwares, pre-installing the complete stdenv and `networking.wireless` service.
|
||||||
|
|
||||||
- The minimal ISO image now uses the `nixos/modules/profiles/minimal.nix` profile.
|
- The minimal ISO image now uses the `nixos/modules/profiles/minimal.nix` profile.
|
||||||
|
|
||||||
- The `ghcWithPackages` and `ghcWithHoogle` wrappers will now also symlink GHC's
|
- The `ghcWithPackages` and `ghcWithHoogle` wrappers will now also symlink GHC's
|
||||||
@ -207,8 +259,12 @@ In addition to numerous new and upgraded packages, this release has the followin
|
|||||||
If undesired, the old behavior can be restored by overriding the builders with
|
If undesired, the old behavior can be restored by overriding the builders with
|
||||||
`{ installDocumentation = false; }`.
|
`{ installDocumentation = false; }`.
|
||||||
|
|
||||||
|
- The new option `networking.nftables.checkRuleset` controls whether the ruleset is checked for syntax or not during build. It is `true` by default. The check might fail because it is in a sandbox environment. To circumvent this, the ruleset file can be edited using the `networking.nftables.preCheckRuleset` option.
|
||||||
|
|
||||||
- `mastodon` now supports connection to a remote `PostgreSQL` database.
|
- `mastodon` now supports connection to a remote `PostgreSQL` database.
|
||||||
|
|
||||||
|
- `nextcloud` has an option to enable SSE-C in S3.
|
||||||
|
|
||||||
- `services.peertube` now requires you to specify the secret file `secrets.secretsFile`. It can be generated by running `openssl rand -hex 32`.
|
- `services.peertube` now requires you to specify the secret file `secrets.secretsFile`. It can be generated by running `openssl rand -hex 32`.
|
||||||
Before upgrading, read the release notes for PeerTube:
|
Before upgrading, read the release notes for PeerTube:
|
||||||
- [Release v5.0.0](https://github.com/Chocobozzz/PeerTube/releases/tag/v5.0.0)
|
- [Release v5.0.0](https://github.com/Chocobozzz/PeerTube/releases/tag/v5.0.0)
|
||||||
@ -280,16 +336,12 @@ In addition to numerous new and upgraded packages, this release has the followin
|
|||||||
|
|
||||||
- The `unifi-poller` package and corresponding NixOS module have been renamed to `unpoller` to match upstream.
|
- The `unifi-poller` package and corresponding NixOS module have been renamed to `unpoller` to match upstream.
|
||||||
|
|
||||||
- `protonmail-bridge` package has been updated to v3.0 and the CLI executable is now named bridge instead of protonmail-bridge to be more in line with upstream.
|
|
||||||
|
|
||||||
- The new option `services.tailscale.useRoutingFeatures` controls various settings for using Tailscale features like exit nodes and subnet routers. If you wish to use your machine as an exit node, you can set this setting to `server`, otherwise if you wish to use an exit node you can set this setting to `client`. The strict RPF warning has been removed as the RPF will be loosened automatically based on the value of this setting.
|
- The new option `services.tailscale.useRoutingFeatures` controls various settings for using Tailscale features like exit nodes and subnet routers. If you wish to use your machine as an exit node, you can set this setting to `server`, otherwise if you wish to use an exit node you can set this setting to `client`. The strict RPF warning has been removed as the RPF will be loosened automatically based on the value of this setting.
|
||||||
|
|
||||||
- `openjdk` from version 11 and above is not build with `openjfx` (i.e.: JavaFX) support by default anymore. You can re-enable it by overriding, e.g.: `openjdk11.override { enableJavaFX = true; };`.
|
- `openjdk` from version 11 and above is not build with `openjfx` (i.e.: JavaFX) support by default anymore. You can re-enable it by overriding, e.g.: `openjdk11.override { enableJavaFX = true; };`.
|
||||||
|
|
||||||
- [Xastir](https://xastir.org/index.php/Main_Page) can now access AX.25 interfaces via the `libax25` package.
|
- [Xastir](https://xastir.org/index.php/Main_Page) can now access AX.25 interfaces via the `libax25` package.
|
||||||
|
|
||||||
- `tvbrowser-bin` was removed, and now `tvbrowser` is built from source.
|
|
||||||
|
|
||||||
- `nixos-version` now accepts `--configuration-revision` to display more information about the current generation revision
|
- `nixos-version` now accepts `--configuration-revision` to display more information about the current generation revision
|
||||||
|
|
||||||
- The option `services.nomad.extraSettingsPlugins` has been fixed to allow more than one plugin in the path.
|
- The option `services.nomad.extraSettingsPlugins` has been fixed to allow more than one plugin in the path.
|
||||||
@ -297,3 +349,87 @@ In addition to numerous new and upgraded packages, this release has the followin
|
|||||||
- The option `services.prometheus.exporters.pihole.interval` does not exist anymore and has been removed.
|
- The option `services.prometheus.exporters.pihole.interval` does not exist anymore and has been removed.
|
||||||
|
|
||||||
- `k3s` can now be configured with an EnvironmentFile for its systemd service, allowing secrets to be provided without ending up in the Nix Store.
|
- `k3s` can now be configured with an EnvironmentFile for its systemd service, allowing secrets to be provided without ending up in the Nix Store.
|
||||||
|
|
||||||
|
- `boot.initrd.luks.device.<name>` has a new `tryEmptyPassphrase` option, this is useful for OEM's who need to install an encrypted disk with a future settable passphrase
|
||||||
|
|
||||||
|
## Detailed migration information {#sec-release-23.05-migration}
|
||||||
|
|
||||||
|
### Pipewire configuration overrides {#sec-release-23.05-migration-pipewire}
|
||||||
|
|
||||||
|
#### Why this change? {#sec-release-23.05-migration-pipewire-why}
|
||||||
|
|
||||||
|
The Pipewire config semantics don't really match the NixOS module semantics, so it's extremely awkward to override the default config, especially when lists are involved. Vendoring the configuration files in nixpkgs also creates unnecessary maintenance overhead.
|
||||||
|
|
||||||
|
Also, upstream added a lot of accomodations to allow doing most of the things you'd want to do with a config edit in better ways.
|
||||||
|
|
||||||
|
#### Migrating your configuration {#sec-release-23.05-migration-pipewire-how}
|
||||||
|
|
||||||
|
Compare your settings to [the defaults](https://gitlab.freedesktop.org/pipewire/pipewire/-/tree/master/src/daemon) and where your configuration differs from them.
|
||||||
|
|
||||||
|
Then, create a drop-in JSON file in `/etc/pipewire/<config file name>.d/99-custom.conf` (the actual filename can be anything) and migrate your changes to it according to the following sections.
|
||||||
|
|
||||||
|
Repeat for every file you've modified, changing the directory name accordingly.
|
||||||
|
|
||||||
|
#### Things you can just copy over {#sec-release-23.05-migration-pipewire-simple}
|
||||||
|
|
||||||
|
If you are:
|
||||||
|
|
||||||
|
- setting properties via `*.properties`
|
||||||
|
- loading a new module to `context.modules`
|
||||||
|
- creating new objects with `context.objects`
|
||||||
|
- declaring SPA libraries with `context.spa-libs`
|
||||||
|
- running custom commands with `context.exec`
|
||||||
|
- adding new rules with `*.rules`
|
||||||
|
- running custom PulseAudio commands with `pulse.cmd`
|
||||||
|
|
||||||
|
Simply move the definitions into the drop-in.
|
||||||
|
|
||||||
|
Note that the use of `context.exec` is not recommended and other methods of running your thing are likely a better option.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"context.properties": {
|
||||||
|
"your.property.name": "your.property.value"
|
||||||
|
},
|
||||||
|
"context.modules": [
|
||||||
|
{ "name": "libpipewire-module-my-cool-thing" }
|
||||||
|
],
|
||||||
|
"context.objects": [
|
||||||
|
{ "factory": { ... } }
|
||||||
|
],
|
||||||
|
"alsa.rules": [
|
||||||
|
{ "matches: { ... }, "actions": { ... } }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Removing a module from `context.modules` {#sec-release-23.05-migration-pipewire-removing-modules}
|
||||||
|
|
||||||
|
Look for an option to disable it via `context.properties` (`"module.x11.bell": "false"` is likely the most common use case here).
|
||||||
|
If one is not available, proceed to [Nuclear option](#sec-release-23.05-migration-pipewire).
|
||||||
|
|
||||||
|
#### Modifying a module's parameters in `context.modules` {#sec-release-23.05-migration-pipewire-modifying-modules}
|
||||||
|
|
||||||
|
For most modules (e.g. `libpipewire-module-rt`) it's enough to load the module again with the new arguments, e.g.:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"context.modules": [
|
||||||
|
{
|
||||||
|
"name": "libpipewire-module-rt",
|
||||||
|
"args": {
|
||||||
|
"rt.prio": 90
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that `module-rt` specifically will generally use the highest values available by default, so setting limits on the `pipewire` systemd service is preferable to reloading.
|
||||||
|
|
||||||
|
If reloading the module is not an option, proceed to [Nuclear option](#sec-release-23.05-migration-pipewire).
|
||||||
|
|
||||||
|
#### Nuclear option {#sec-release-23.05-migration-pipewire-nuclear}
|
||||||
|
If all else fails, you can still manually copy the contents of the default configuration file
|
||||||
|
from `${pkgs.pipewire.lib}/share/pipewire` to `/etc/pipewire` and edit it to fully override the default.
|
||||||
|
However, this should be done only as a last resort. Please talk to the Pipewire maintainers if you ever need to do this.
|
||||||
|
@ -24,7 +24,7 @@ in rec {
|
|||||||
}
|
}
|
||||||
''
|
''
|
||||||
name=${shellEscape name}
|
name=${shellEscape name}
|
||||||
mkdir -p "$out/$(dirname "$name")"
|
mkdir -p "$out/$(dirname -- "$name")"
|
||||||
echo -n "$text" > "$out/$name"
|
echo -n "$text" > "$out/$name"
|
||||||
''
|
''
|
||||||
else
|
else
|
||||||
|
@ -179,7 +179,6 @@ class Driver:
|
|||||||
start_command=cmd,
|
start_command=cmd,
|
||||||
name=name,
|
name=name,
|
||||||
keep_vm_state=args.get("keep_vm_state", False),
|
keep_vm_state=args.get("keep_vm_state", False),
|
||||||
allow_reboot=args.get("allow_reboot", False),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def serial_stdout_on(self) -> None:
|
def serial_stdout_on(self) -> None:
|
||||||
|
@ -144,7 +144,7 @@ class StartCommand:
|
|||||||
self,
|
self,
|
||||||
monitor_socket_path: Path,
|
monitor_socket_path: Path,
|
||||||
shell_socket_path: Path,
|
shell_socket_path: Path,
|
||||||
allow_reboot: bool = False, # TODO: unused, legacy?
|
allow_reboot: bool = False,
|
||||||
) -> str:
|
) -> str:
|
||||||
display_opts = ""
|
display_opts = ""
|
||||||
display_available = any(x in os.environ for x in ["DISPLAY", "WAYLAND_DISPLAY"])
|
display_available = any(x in os.environ for x in ["DISPLAY", "WAYLAND_DISPLAY"])
|
||||||
@ -152,16 +152,14 @@ class StartCommand:
|
|||||||
display_opts += " -nographic"
|
display_opts += " -nographic"
|
||||||
|
|
||||||
# qemu options
|
# qemu options
|
||||||
qemu_opts = ""
|
qemu_opts = (
|
||||||
qemu_opts += (
|
|
||||||
""
|
|
||||||
if allow_reboot
|
|
||||||
else " -no-reboot"
|
|
||||||
" -device virtio-serial"
|
" -device virtio-serial"
|
||||||
" -device virtconsole,chardev=shell"
|
" -device virtconsole,chardev=shell"
|
||||||
" -device virtio-rng-pci"
|
" -device virtio-rng-pci"
|
||||||
" -serial stdio"
|
" -serial stdio"
|
||||||
)
|
)
|
||||||
|
if not allow_reboot:
|
||||||
|
qemu_opts += " -no-reboot"
|
||||||
# TODO: qemu script already catpures this env variable, legacy?
|
# TODO: qemu script already catpures this env variable, legacy?
|
||||||
qemu_opts += " " + os.environ.get("QEMU_OPTS", "")
|
qemu_opts += " " + os.environ.get("QEMU_OPTS", "")
|
||||||
|
|
||||||
@ -195,9 +193,10 @@ class StartCommand:
|
|||||||
shared_dir: Path,
|
shared_dir: Path,
|
||||||
monitor_socket_path: Path,
|
monitor_socket_path: Path,
|
||||||
shell_socket_path: Path,
|
shell_socket_path: Path,
|
||||||
|
allow_reboot: bool,
|
||||||
) -> subprocess.Popen:
|
) -> subprocess.Popen:
|
||||||
return subprocess.Popen(
|
return subprocess.Popen(
|
||||||
self.cmd(monitor_socket_path, shell_socket_path),
|
self.cmd(monitor_socket_path, shell_socket_path, allow_reboot),
|
||||||
stdin=subprocess.PIPE,
|
stdin=subprocess.PIPE,
|
||||||
stdout=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
stderr=subprocess.STDOUT,
|
stderr=subprocess.STDOUT,
|
||||||
@ -312,7 +311,6 @@ class Machine:
|
|||||||
|
|
||||||
start_command: StartCommand
|
start_command: StartCommand
|
||||||
keep_vm_state: bool
|
keep_vm_state: bool
|
||||||
allow_reboot: bool
|
|
||||||
|
|
||||||
process: Optional[subprocess.Popen]
|
process: Optional[subprocess.Popen]
|
||||||
pid: Optional[int]
|
pid: Optional[int]
|
||||||
@ -337,13 +335,11 @@ class Machine:
|
|||||||
start_command: StartCommand,
|
start_command: StartCommand,
|
||||||
name: str = "machine",
|
name: str = "machine",
|
||||||
keep_vm_state: bool = False,
|
keep_vm_state: bool = False,
|
||||||
allow_reboot: bool = False,
|
|
||||||
callbacks: Optional[List[Callable]] = None,
|
callbacks: Optional[List[Callable]] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
self.out_dir = out_dir
|
self.out_dir = out_dir
|
||||||
self.tmp_dir = tmp_dir
|
self.tmp_dir = tmp_dir
|
||||||
self.keep_vm_state = keep_vm_state
|
self.keep_vm_state = keep_vm_state
|
||||||
self.allow_reboot = allow_reboot
|
|
||||||
self.name = name
|
self.name = name
|
||||||
self.start_command = start_command
|
self.start_command = start_command
|
||||||
self.callbacks = callbacks if callbacks is not None else []
|
self.callbacks = callbacks if callbacks is not None else []
|
||||||
@ -741,9 +737,10 @@ class Machine:
|
|||||||
self.connected = True
|
self.connected = True
|
||||||
|
|
||||||
def screenshot(self, filename: str) -> None:
|
def screenshot(self, filename: str) -> None:
|
||||||
word_pattern = re.compile(r"^\w+$")
|
if "." not in filename:
|
||||||
if word_pattern.match(filename):
|
filename += ".png"
|
||||||
filename = os.path.join(self.out_dir, f"{filename}.png")
|
if "/" not in filename:
|
||||||
|
filename = os.path.join(self.out_dir, filename)
|
||||||
tmp = f"{filename}.ppm"
|
tmp = f"{filename}.ppm"
|
||||||
|
|
||||||
with self.nested(
|
with self.nested(
|
||||||
@ -874,7 +871,7 @@ class Machine:
|
|||||||
self.process.stdin.write(chars.encode())
|
self.process.stdin.write(chars.encode())
|
||||||
self.process.stdin.flush()
|
self.process.stdin.flush()
|
||||||
|
|
||||||
def start(self) -> None:
|
def start(self, allow_reboot: bool = False) -> None:
|
||||||
if self.booted:
|
if self.booted:
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -898,6 +895,7 @@ class Machine:
|
|||||||
self.shared_dir,
|
self.shared_dir,
|
||||||
self.monitor_path,
|
self.monitor_path,
|
||||||
self.shell_path,
|
self.shell_path,
|
||||||
|
allow_reboot,
|
||||||
)
|
)
|
||||||
self.monitor, _ = monitor_socket.accept()
|
self.monitor, _ = monitor_socket.accept()
|
||||||
self.shell, _ = shell_socket.accept()
|
self.shell, _ = shell_socket.accept()
|
||||||
@ -946,6 +944,15 @@ class Machine:
|
|||||||
self.send_monitor_command("quit")
|
self.send_monitor_command("quit")
|
||||||
self.wait_for_shutdown()
|
self.wait_for_shutdown()
|
||||||
|
|
||||||
|
def reboot(self) -> None:
|
||||||
|
"""Press Ctrl+Alt+Delete in the guest.
|
||||||
|
|
||||||
|
Prepares the machine to be reconnected which is useful if the
|
||||||
|
machine was started with `allow_reboot = True`
|
||||||
|
"""
|
||||||
|
self.send_key(f"ctrl-alt-delete")
|
||||||
|
self.connected = False
|
||||||
|
|
||||||
def wait_for_x(self) -> None:
|
def wait_for_x(self) -> None:
|
||||||
"""Wait until it is possible to connect to the X server. Note that
|
"""Wait until it is possible to connect to the X server. Note that
|
||||||
testing the existence of /tmp/.X11-unix/X0 is insufficient.
|
testing the existence of /tmp/.X11-unix/X0 is insufficient.
|
||||||
|
@ -21,7 +21,7 @@ let
|
|||||||
# Sadly, systemd-vconsole-setup doesn't support binary keymaps.
|
# Sadly, systemd-vconsole-setup doesn't support binary keymaps.
|
||||||
vconsoleConf = pkgs.writeText "vconsole.conf" ''
|
vconsoleConf = pkgs.writeText "vconsole.conf" ''
|
||||||
KEYMAP=${cfg.keyMap}
|
KEYMAP=${cfg.keyMap}
|
||||||
FONT=${cfg.font}
|
${optionalString (cfg.font != null) "FONT=${cfg.font}"}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
consoleEnv = kbd: pkgs.buildEnv {
|
consoleEnv = kbd: pkgs.buildEnv {
|
||||||
@ -45,14 +45,19 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
font = mkOption {
|
font = mkOption {
|
||||||
type = with types; either str path;
|
type = with types; nullOr (either str path);
|
||||||
default = "Lat2-Terminus16";
|
default = null;
|
||||||
example = "LatArCyrHeb-16";
|
example = "LatArCyrHeb-16";
|
||||||
description = mdDoc ''
|
description = mdDoc ''
|
||||||
The font used for the virtual consoles. Leave empty to use
|
The font used for the virtual consoles.
|
||||||
whatever the {command}`setfont` program considers the
|
Can be `null`, a font name, or a path to a PSF font file.
|
||||||
default font.
|
|
||||||
Can be either a font name or a path to a PSF font file.
|
Use `null` to let the kernel choose a built-in font.
|
||||||
|
The default is 8x16, and, as of Linux 5.3, Terminus 32 bold for display
|
||||||
|
resolutions of 2560x1080 and higher.
|
||||||
|
These fonts cover the [IBM437][] character set.
|
||||||
|
|
||||||
|
[IBM437]: https://en.wikipedia.org/wiki/Code_page_437
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -151,7 +156,7 @@ in
|
|||||||
printf "\033%%${if isUnicode then "G" else "@"}" >> /dev/console
|
printf "\033%%${if isUnicode then "G" else "@"}" >> /dev/console
|
||||||
loadkmap < ${optimizedKeymap}
|
loadkmap < ${optimizedKeymap}
|
||||||
|
|
||||||
${optionalString cfg.earlySetup ''
|
${optionalString (cfg.earlySetup && cfg.font != null) ''
|
||||||
setfont -C /dev/console $extraUtils/share/consolefonts/font.psf
|
setfont -C /dev/console $extraUtils/share/consolefonts/font.psf
|
||||||
''}
|
''}
|
||||||
'');
|
'');
|
||||||
@ -168,7 +173,7 @@ in
|
|||||||
"${config.boot.initrd.systemd.package.kbd}/bin/setfont"
|
"${config.boot.initrd.systemd.package.kbd}/bin/setfont"
|
||||||
"${config.boot.initrd.systemd.package.kbd}/bin/loadkeys"
|
"${config.boot.initrd.systemd.package.kbd}/bin/loadkeys"
|
||||||
"${config.boot.initrd.systemd.package.kbd.gzip}/bin/gzip" # Fonts and keyboard layouts are compressed
|
"${config.boot.initrd.systemd.package.kbd.gzip}/bin/gzip" # Fonts and keyboard layouts are compressed
|
||||||
] ++ optionals (hasPrefix builtins.storeDir cfg.font) [
|
] ++ optionals (cfg.font != null && hasPrefix builtins.storeDir cfg.font) [
|
||||||
"${cfg.font}"
|
"${cfg.font}"
|
||||||
] ++ optionals (hasPrefix builtins.storeDir cfg.keyMap) [
|
] ++ optionals (hasPrefix builtins.storeDir cfg.keyMap) [
|
||||||
"${cfg.keyMap}"
|
"${cfg.keyMap}"
|
||||||
@ -195,7 +200,7 @@ in
|
|||||||
];
|
];
|
||||||
})
|
})
|
||||||
|
|
||||||
(mkIf (cfg.earlySetup && !config.boot.initrd.systemd.enable) {
|
(mkIf (cfg.earlySetup && cfg.font != null && !config.boot.initrd.systemd.enable) {
|
||||||
boot.initrd.extraUtilsCommands = ''
|
boot.initrd.extraUtilsCommands = ''
|
||||||
mkdir -p $out/share/consolefonts
|
mkdir -p $out/share/consolefonts
|
||||||
${if substring 0 1 cfg.font == "/" then ''
|
${if substring 0 1 cfg.font == "/" then ''
|
||||||
|
@ -7,6 +7,19 @@ This module generates a package containing configuration files and link it in /e
|
|||||||
Fontconfig reads files in folder name / file name order, so the number prepended to the configuration file name decide the order of parsing.
|
Fontconfig reads files in folder name / file name order, so the number prepended to the configuration file name decide the order of parsing.
|
||||||
Low number means high priority.
|
Low number means high priority.
|
||||||
|
|
||||||
|
NOTE: Please take extreme care when adjusting the default settings of this module.
|
||||||
|
People care a lot, and I mean A LOT, about their font rendering, and you will be
|
||||||
|
The Person That Broke It if it changes in a way people don't like.
|
||||||
|
|
||||||
|
See prior art:
|
||||||
|
- https://github.com/NixOS/nixpkgs/pull/194594
|
||||||
|
- https://github.com/NixOS/nixpkgs/pull/222236
|
||||||
|
- https://github.com/NixOS/nixpkgs/pull/222689
|
||||||
|
|
||||||
|
And do not repeat our mistakes.
|
||||||
|
|
||||||
|
- @K900, March 2023
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
{ config, pkgs, lib, ... }:
|
{ config, pkgs, lib, ... }:
|
||||||
@ -218,6 +231,8 @@ let
|
|||||||
paths = cfg.confPackages;
|
paths = cfg.confPackages;
|
||||||
ignoreCollisions = true;
|
ignoreCollisions = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
fontconfigNote = "Consider manually configuring fonts.fontconfig according to personal preference.";
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
@ -229,6 +244,8 @@ in
|
|||||||
(mkRemovedOptionModule [ "fonts" "fontconfig" "forceAutohint" ] "")
|
(mkRemovedOptionModule [ "fonts" "fontconfig" "forceAutohint" ] "")
|
||||||
(mkRemovedOptionModule [ "fonts" "fontconfig" "renderMonoTTFAsBitmap" ] "")
|
(mkRemovedOptionModule [ "fonts" "fontconfig" "renderMonoTTFAsBitmap" ] "")
|
||||||
(mkRemovedOptionModule [ "fonts" "fontconfig" "dpi" ] "Use display server-specific options")
|
(mkRemovedOptionModule [ "fonts" "fontconfig" "dpi" ] "Use display server-specific options")
|
||||||
|
(mkRemovedOptionModule [ "hardware" "video" "hidpi" "enable" ] fontconfigNote)
|
||||||
|
(mkRemovedOptionModule [ "fonts" "optimizeForVeryHighDPI" ] fontconfigNote)
|
||||||
] ++ lib.forEach [ "enable" "substitutions" "preset" ]
|
] ++ lib.forEach [ "enable" "substitutions" "preset" ]
|
||||||
(opt: lib.mkRemovedOptionModule [ "fonts" "fontconfig" "ultimate" "${opt}" ] ''
|
(opt: lib.mkRemovedOptionModule [ "fonts" "fontconfig" "ultimate" "${opt}" ] ''
|
||||||
The fonts.fontconfig.ultimate module and configuration is obsolete.
|
The fonts.fontconfig.ultimate module and configuration is obsolete.
|
||||||
|
@ -3,29 +3,7 @@
|
|||||||
with lib;
|
with lib;
|
||||||
|
|
||||||
let
|
let
|
||||||
# A scalable variant of the X11 "core" cursor
|
cfg = config.fonts;
|
||||||
#
|
|
||||||
# If not running a fancy desktop environment, the cursor is likely set to
|
|
||||||
# the default `cursor.pcf` bitmap font. This is 17px wide, so it's very
|
|
||||||
# small and almost invisible on 4K displays.
|
|
||||||
fontcursormisc_hidpi = pkgs.xorg.fontxfree86type1.overrideAttrs (old:
|
|
||||||
let
|
|
||||||
# The scaling constant is 230/96: the scalable `left_ptr` glyph at
|
|
||||||
# about 23 points is rendered as 17px, on a 96dpi display.
|
|
||||||
# Note: the XLFD font size is in decipoints.
|
|
||||||
size = 2.39583 * config.services.xserver.dpi;
|
|
||||||
sizeString = builtins.head (builtins.split "\\." (toString size));
|
|
||||||
in
|
|
||||||
{
|
|
||||||
postInstall = ''
|
|
||||||
alias='cursor -xfree86-cursor-medium-r-normal--0-${sizeString}-0-0-p-0-adobe-fontspecific'
|
|
||||||
echo "$alias" > $out/lib/X11/fonts/Type1/fonts.alias
|
|
||||||
'';
|
|
||||||
});
|
|
||||||
|
|
||||||
hasHidpi =
|
|
||||||
config.hardware.video.hidpi.enable &&
|
|
||||||
config.services.xserver.dpi != null;
|
|
||||||
|
|
||||||
defaultFonts =
|
defaultFonts =
|
||||||
[ pkgs.dejavu_fonts
|
[ pkgs.dejavu_fonts
|
||||||
@ -35,14 +13,7 @@ let
|
|||||||
pkgs.unifont
|
pkgs.unifont
|
||||||
pkgs.noto-fonts-emoji
|
pkgs.noto-fonts-emoji
|
||||||
];
|
];
|
||||||
|
|
||||||
defaultXFonts =
|
|
||||||
[ (if hasHidpi then fontcursormisc_hidpi else pkgs.xorg.fontcursormisc)
|
|
||||||
pkgs.xorg.fontmiscmisc
|
|
||||||
];
|
|
||||||
|
|
||||||
in
|
in
|
||||||
|
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
(mkRemovedOptionModule [ "fonts" "enableCoreFonts" ] "Use fonts.fonts = [ pkgs.corefonts ]; instead.")
|
(mkRemovedOptionModule [ "fonts" "enableCoreFonts" ] "Use fonts.fonts = [ pkgs.corefonts ]; instead.")
|
||||||
@ -68,14 +39,9 @@ in
|
|||||||
and families and reasonable coverage of Unicode.
|
and families and reasonable coverage of Unicode.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkMerge [
|
config = { fonts.fonts = mkIf cfg.enableDefaultFonts defaultFonts; };
|
||||||
{ fonts.fonts = mkIf config.fonts.enableDefaultFonts defaultFonts; }
|
|
||||||
{ fonts.fonts = mkIf config.services.xserver.enable defaultXFonts; }
|
|
||||||
];
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -539,7 +539,9 @@ in {
|
|||||||
|
|
||||||
###### implementation
|
###### implementation
|
||||||
|
|
||||||
config = {
|
config = let
|
||||||
|
cryptSchemeIdPatternGroup = "(${lib.concatStringsSep "|" pkgs.libxcrypt.enabledCryptSchemeIds})";
|
||||||
|
in {
|
||||||
|
|
||||||
users.users = {
|
users.users = {
|
||||||
root = {
|
root = {
|
||||||
@ -601,15 +603,16 @@ in {
|
|||||||
text = ''
|
text = ''
|
||||||
users=()
|
users=()
|
||||||
while IFS=: read -r user hash tail; do
|
while IFS=: read -r user hash tail; do
|
||||||
if [[ "$hash" = "$"* && ! "$hash" =~ ^\$(y|gy|7|2b|2y|2a|6)\$ ]]; then
|
if [[ "$hash" = "$"* && ! "$hash" =~ ^\''$${cryptSchemeIdPatternGroup}\$ ]]; then
|
||||||
users+=("$user")
|
users+=("$user")
|
||||||
fi
|
fi
|
||||||
done </etc/shadow
|
done </etc/shadow
|
||||||
|
|
||||||
if (( "''${#users[@]}" )); then
|
if (( "''${#users[@]}" )); then
|
||||||
echo "
|
echo "
|
||||||
WARNING: The following user accounts rely on password hashes that will
|
WARNING: The following user accounts rely on password hashing algorithms
|
||||||
be removed in NixOS 23.05. They should be renewed as soon as possible."
|
that have been removed. They need to be renewed as soon as possible, as
|
||||||
|
they do prevent their users from logging in."
|
||||||
printf ' - %s\n' "''${users[@]}"
|
printf ' - %s\n' "''${users[@]}"
|
||||||
fi
|
fi
|
||||||
'';
|
'';
|
||||||
@ -699,7 +702,20 @@ in {
|
|||||||
users.groups.${user.name} = {};
|
users.groups.${user.name} = {};
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
]
|
] ++ (map (shell: {
|
||||||
|
assertion = (user.shell == pkgs.${shell}) -> (config.programs.${shell}.enable == true);
|
||||||
|
message = ''
|
||||||
|
users.users.${user.name}.shell is set to ${shell}, but
|
||||||
|
programs.${shell}.enable is not true. This will cause the ${shell}
|
||||||
|
shell to lack the basic nix directories in its PATH and might make
|
||||||
|
logging in as that user impossible. You can fix it with:
|
||||||
|
programs.${shell}.enable = true;
|
||||||
|
'';
|
||||||
|
}) [
|
||||||
|
"fish"
|
||||||
|
"xonsh"
|
||||||
|
"zsh"
|
||||||
|
])
|
||||||
));
|
));
|
||||||
|
|
||||||
warnings =
|
warnings =
|
||||||
@ -716,7 +732,7 @@ in {
|
|||||||
let
|
let
|
||||||
sep = "\\$";
|
sep = "\\$";
|
||||||
base64 = "[a-zA-Z0-9./]+";
|
base64 = "[a-zA-Z0-9./]+";
|
||||||
id = "[a-z0-9-]+";
|
id = cryptSchemeIdPatternGroup;
|
||||||
value = "[a-zA-Z0-9/+.-]+";
|
value = "[a-zA-Z0-9/+.-]+";
|
||||||
options = "${id}(=${value})?(,${id}=${value})*";
|
options = "${id}(=${value})?(,${id}=${value})*";
|
||||||
scheme = "${id}(${sep}${options})?";
|
scheme = "${id}(${sep}${options})?";
|
||||||
|
@ -82,12 +82,30 @@ in
|
|||||||
{command}`cat /sys/class/block/zram*/comp_algorithm`
|
{command}`cat /sys/class/block/zram*/comp_algorithm`
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
writebackDevice = lib.mkOption {
|
||||||
|
default = null;
|
||||||
|
example = "/dev/zvol/tarta-zoot/swap-writeback";
|
||||||
|
type = lib.types.nullOr lib.types.path;
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Write incompressible pages to this device,
|
||||||
|
as there's no gain from keeping them in RAM.
|
||||||
|
'';
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
|
|
||||||
|
assertions = [
|
||||||
|
{
|
||||||
|
assertion = cfg.writebackDevice == null || cfg.swapDevices <= 1;
|
||||||
|
message = "A single writeback device cannot be shared among multiple zram devices";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
system.requiredKernelConfig = with config.lib.kernelConfig; [
|
system.requiredKernelConfig = with config.lib.kernelConfig; [
|
||||||
(isModule "ZRAM")
|
(isModule "ZRAM")
|
||||||
];
|
];
|
||||||
@ -112,6 +130,8 @@ in
|
|||||||
zram-size = if cfg.memoryMax != null then "min(${size}, ${toString cfg.memoryMax} / 1024 / 1024)" else size;
|
zram-size = if cfg.memoryMax != null then "min(${size}, ${toString cfg.memoryMax} / 1024 / 1024)" else size;
|
||||||
compression-algorithm = cfg.algorithm;
|
compression-algorithm = cfg.algorithm;
|
||||||
swap-priority = cfg.priority;
|
swap-priority = cfg.priority;
|
||||||
|
} // lib.optionalAttrs (cfg.writebackDevice != null) {
|
||||||
|
writeback-device = cfg.writebackDevice;
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
devices));
|
devices));
|
||||||
|
@ -65,7 +65,7 @@ let
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
filterDTBs = src: if isNull cfg.filter
|
filterDTBs = src: if cfg.filter == null
|
||||||
then "${src}/dtbs"
|
then "${src}/dtbs"
|
||||||
else
|
else
|
||||||
pkgs.runCommand "dtbs-filtered" {} ''
|
pkgs.runCommand "dtbs-filtered" {} ''
|
||||||
@ -93,8 +93,8 @@ let
|
|||||||
# Fill in `dtboFile` for each overlay if not set already.
|
# Fill in `dtboFile` for each overlay if not set already.
|
||||||
# Existence of one of these is guarded by assertion below
|
# Existence of one of these is guarded by assertion below
|
||||||
withDTBOs = xs: flip map xs (o: o // { dtboFile =
|
withDTBOs = xs: flip map xs (o: o // { dtboFile =
|
||||||
if isNull o.dtboFile then
|
if o.dtboFile == null then
|
||||||
if !isNull o.dtsFile then compileDTS o.name o.dtsFile
|
if o.dtsFile != null then compileDTS o.name o.dtsFile
|
||||||
else compileDTS o.name (pkgs.writeText "dts" o.dtsText)
|
else compileDTS o.name (pkgs.writeText "dts" o.dtsText)
|
||||||
else o.dtboFile; } );
|
else o.dtboFile; } );
|
||||||
|
|
||||||
@ -181,7 +181,7 @@ in
|
|||||||
config = mkIf (cfg.enable) {
|
config = mkIf (cfg.enable) {
|
||||||
|
|
||||||
assertions = let
|
assertions = let
|
||||||
invalidOverlay = o: isNull o.dtsFile && isNull o.dtsText && isNull o.dtboFile;
|
invalidOverlay = o: (o.dtsFile == null) && (o.dtsText == null) && (o.dtboFile == null);
|
||||||
in lib.singleton {
|
in lib.singleton {
|
||||||
assertion = lib.all (o: !invalidOverlay o) cfg.overlays;
|
assertion = lib.all (o: !invalidOverlay o) cfg.overlays;
|
||||||
message = ''
|
message = ''
|
||||||
|
@ -22,6 +22,6 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
services.udev.packages = [ pkgs.nitrokey-udev-rules ];
|
services.udev.packages = [ pkgs.libnitrokey ];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -69,21 +69,50 @@ in
|
|||||||
package = mkOption {
|
package = mkOption {
|
||||||
type = types.package;
|
type = types.package;
|
||||||
internal = true;
|
internal = true;
|
||||||
|
default = cfg.mesaPackage;
|
||||||
description = lib.mdDoc ''
|
description = lib.mdDoc ''
|
||||||
The package that provides the OpenGL implementation.
|
The package that provides the OpenGL implementation.
|
||||||
|
|
||||||
|
The default is Mesa's drivers which should cover all OpenGL-capable
|
||||||
|
hardware. If you want to use another Mesa version, adjust
|
||||||
|
{option}`mesaPackage`.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
package32 = mkOption {
|
package32 = mkOption {
|
||||||
type = types.package;
|
type = types.package;
|
||||||
internal = true;
|
internal = true;
|
||||||
|
default = cfg.mesaPackage32;
|
||||||
description = lib.mdDoc ''
|
description = lib.mdDoc ''
|
||||||
The package that provides the 32-bit OpenGL implementation on
|
Same as {option}`package` but for the 32-bit OpenGL implementation on
|
||||||
64-bit systems. Used when {option}`driSupport32Bit` is
|
64-bit systems. Used when {option}`driSupport32Bit` is set.
|
||||||
set.
|
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
mesaPackage = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
default = pkgs.mesa;
|
||||||
|
defaultText = literalExpression "pkgs.mesa";
|
||||||
|
example = literalExpression "pkgs.mesa_22";
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
The Mesa driver package used for rendering support on the system.
|
||||||
|
|
||||||
|
You should only need to adjust this if you require a newer Mesa
|
||||||
|
version for your hardware or because you need to patch a bug.
|
||||||
|
'';
|
||||||
|
apply = mesa: mesa.drivers or (throw "`mesa` package must have a `drivers` output.");
|
||||||
|
};
|
||||||
|
mesaPackage32 = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
default = pkgs.pkgsi686Linux.mesa;
|
||||||
|
defaultText = literalExpression "pkgs.pkgsi686Linux.mesa";
|
||||||
|
example = literalExpression "pkgs.pkgsi686Linux.mesa_22";
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Same as {option}`mesaPackage` but for the 32-bit Mesa on 64-bit
|
||||||
|
systems. Used when {option}`driSupport32Bit` is set.
|
||||||
|
'';
|
||||||
|
apply = mesa: mesa.drivers or (throw "`mesa` package must have a `drivers` output.");
|
||||||
|
};
|
||||||
|
|
||||||
extraPackages = mkOption {
|
extraPackages = mkOption {
|
||||||
type = types.listOf types.package;
|
type = types.listOf types.package;
|
||||||
default = [];
|
default = [];
|
||||||
@ -97,7 +126,6 @@ in
|
|||||||
:::
|
:::
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
extraPackages32 = mkOption {
|
extraPackages32 = mkOption {
|
||||||
type = types.listOf types.package;
|
type = types.listOf types.package;
|
||||||
default = [];
|
default = [];
|
||||||
@ -153,9 +181,6 @@ in
|
|||||||
environment.sessionVariables.LD_LIBRARY_PATH = mkIf cfg.setLdLibraryPath
|
environment.sessionVariables.LD_LIBRARY_PATH = mkIf cfg.setLdLibraryPath
|
||||||
([ "/run/opengl-driver/lib" ] ++ optional cfg.driSupport32Bit "/run/opengl-driver-32/lib");
|
([ "/run/opengl-driver/lib" ] ++ optional cfg.driSupport32Bit "/run/opengl-driver-32/lib");
|
||||||
|
|
||||||
hardware.opengl.package = mkDefault pkgs.mesa.drivers;
|
|
||||||
hardware.opengl.package32 = mkDefault pkgs.pkgsi686Linux.mesa.drivers;
|
|
||||||
|
|
||||||
boot.extraModulePackages = optional (elem "virtualbox" videoDrivers) kernelPackages.virtualboxGuestAdditions;
|
boot.extraModulePackages = optional (elem "virtualbox" videoDrivers) kernelPackages.virtualboxGuestAdditions;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
{ lib, pkgs, config, ...}:
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
{
|
|
||||||
options.hardware.video.hidpi.enable = mkEnableOption (lib.mdDoc "Font/DPI configuration optimized for HiDPI displays");
|
|
||||||
|
|
||||||
config = mkIf config.hardware.video.hidpi.enable {
|
|
||||||
console.font = lib.mkDefault "${pkgs.terminus_font}/share/consolefonts/ter-v32n.psf.gz";
|
|
||||||
|
|
||||||
# Needed when typing in passwords for full disk encryption
|
|
||||||
console.earlySetup = mkDefault true;
|
|
||||||
boot.loader.systemd-boot.consoleMode = mkDefault "1";
|
|
||||||
|
|
||||||
|
|
||||||
# Grayscale anti-aliasing for fonts
|
|
||||||
fonts.fontconfig.antialias = mkDefault true;
|
|
||||||
fonts.fontconfig.subpixel = {
|
|
||||||
rgba = mkDefault "none";
|
|
||||||
lcdfilter = mkDefault "none";
|
|
||||||
};
|
|
||||||
|
|
||||||
# TODO Find reasonable defaults X11 & wayland
|
|
||||||
};
|
|
||||||
}
|
|
@ -462,8 +462,7 @@ in
|
|||||||
boot.kernelParams = optional (offloadCfg.enable || cfg.modesetting.enable) "nvidia-drm.modeset=1"
|
boot.kernelParams = optional (offloadCfg.enable || cfg.modesetting.enable) "nvidia-drm.modeset=1"
|
||||||
++ optional cfg.powerManagement.enable "nvidia.NVreg_PreserveVideoMemoryAllocations=1"
|
++ optional cfg.powerManagement.enable "nvidia.NVreg_PreserveVideoMemoryAllocations=1"
|
||||||
++ optional cfg.open "nvidia.NVreg_OpenRmEnableUnsupportedGpus=1"
|
++ optional cfg.open "nvidia.NVreg_OpenRmEnableUnsupportedGpus=1"
|
||||||
# proprietary driver is not compiled with support for X86_KERNEL_IBT
|
++ optional (!cfg.open && config.boot.kernelPackages.kernel.kernelAtLeast "6.2" && lib.versionOlder nvidia_x11.version "530") "ibt=off";
|
||||||
++ optional (!cfg.open && config.boot.kernelPackages.kernel.kernelAtLeast "6.2") "ibt=off";
|
|
||||||
|
|
||||||
services.udev.extraRules =
|
services.udev.extraRules =
|
||||||
''
|
''
|
||||||
|
@ -9,7 +9,7 @@ than there are keys on the keyboard.
|
|||||||
The following input methods are available in NixOS:
|
The following input methods are available in NixOS:
|
||||||
|
|
||||||
- IBus: The intelligent input bus.
|
- IBus: The intelligent input bus.
|
||||||
- Fcitx: A customizable lightweight input method.
|
- Fcitx5: The next generation of fcitx, addons (including engines, dictionaries, skins) can be added using `i18n.inputMethod.fcitx5.addons`.
|
||||||
- Nabi: A Korean input method based on XIM.
|
- Nabi: A Korean input method based on XIM.
|
||||||
- Uim: The universal input method, is a library with a XIM bridge.
|
- Uim: The universal input method, is a library with a XIM bridge.
|
||||||
- Hime: An extremely easy-to-use input method framework.
|
- Hime: An extremely easy-to-use input method framework.
|
||||||
@ -67,38 +67,40 @@ application in the Nix store. The `glib` packages must
|
|||||||
match exactly. If they do not, uninstalling and reinstalling the
|
match exactly. If they do not, uninstalling and reinstalling the
|
||||||
application is a likely fix.
|
application is a likely fix.
|
||||||
|
|
||||||
## Fcitx {#module-services-input-methods-fcitx}
|
## Fcitx5 {#module-services-input-methods-fcitx}
|
||||||
|
|
||||||
Fcitx is an input method framework with extension support. It has three
|
Fcitx5 is an input method framework with extension support. It has three
|
||||||
built-in Input Method Engine, Pinyin, QuWei and Table-based input methods.
|
built-in Input Method Engine, Pinyin, QuWei and Table-based input methods.
|
||||||
|
|
||||||
The following snippet can be used to configure Fcitx:
|
The following snippet can be used to configure Fcitx:
|
||||||
|
|
||||||
```
|
```
|
||||||
i18n.inputMethod = {
|
i18n.inputMethod = {
|
||||||
enabled = "fcitx";
|
enabled = "fcitx5";
|
||||||
fcitx.engines = with pkgs.fcitx-engines; [ mozc hangul m17n ];
|
fcitx5.addons = with pkgs; [ fcitx5-mozc fcitx5-hangul fcitx5-m17n ];
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
`i18n.inputMethod.fcitx.engines` is optional and can be
|
`i18n.inputMethod.fcitx5.addons` is optional and can be
|
||||||
used to add extra Fcitx engines.
|
used to add extra Fcitx5 addons.
|
||||||
|
|
||||||
Available extra Fcitx engines are:
|
Available extra Fcitx5 addons are:
|
||||||
|
|
||||||
- Anthy (`fcitx-engines.anthy`): Anthy is a system for
|
- Anthy (`fcitx5-anthy`): Anthy is a system for
|
||||||
Japanese input method. It converts Hiragana text to Kana Kanji mixed text.
|
Japanese input method. It converts Hiragana text to Kana Kanji mixed text.
|
||||||
- Chewing (`fcitx-engines.chewing`): Chewing is an
|
- Chewing (`fcitx5-chewing`): Chewing is an
|
||||||
intelligent Zhuyin input method. It is one of the most popular input
|
intelligent Zhuyin input method. It is one of the most popular input
|
||||||
methods among Traditional Chinese Unix users.
|
methods among Traditional Chinese Unix users.
|
||||||
- Hangul (`fcitx-engines.hangul`): Korean input method.
|
- Hangul (`fcitx5-hangul`): Korean input method.
|
||||||
- Unikey (`fcitx-engines.unikey`): Vietnamese input method.
|
- Unikey (`fcitx5-unikey`): Vietnamese input method.
|
||||||
- m17n (`fcitx-engines.m17n`): m17n is an input method that
|
- m17n (`fcitx5-m17n`): m17n is an input method that
|
||||||
uses input methods and corresponding icons in the m17n database.
|
uses input methods and corresponding icons in the m17n database.
|
||||||
- mozc (`fcitx-engines.mozc`): A Japanese input method from
|
- mozc (`fcitx5-mozc`): A Japanese input method from
|
||||||
Google.
|
Google.
|
||||||
- table-others (`fcitx-engines.table-others`): Various
|
- table-others (`fcitx5-table-other`): Various
|
||||||
table-based input methods.
|
table-based input methods.
|
||||||
|
- chinese-addons (`fcitx5-chinese-addons`): Various chinese input methods.
|
||||||
|
- rime (`fcitx5-rime`): RIME support for fcitx5.
|
||||||
|
|
||||||
## Nabi {#module-services-input-methods-nabi}
|
## Nabi {#module-services-input-methods-nabi}
|
||||||
|
|
||||||
|
@ -29,9 +29,9 @@ in
|
|||||||
options.i18n = {
|
options.i18n = {
|
||||||
inputMethod = {
|
inputMethod = {
|
||||||
enabled = mkOption {
|
enabled = mkOption {
|
||||||
type = types.nullOr (types.enum [ "ibus" "fcitx" "fcitx5" "nabi" "uim" "hime" "kime" ]);
|
type = types.nullOr (types.enum [ "ibus" "fcitx5" "nabi" "uim" "hime" "kime" ]);
|
||||||
default = null;
|
default = null;
|
||||||
example = "fcitx";
|
example = "fcitx5";
|
||||||
description = lib.mdDoc ''
|
description = lib.mdDoc ''
|
||||||
Select the enabled input method. Input methods is a software to input symbols that are not available on standard input devices.
|
Select the enabled input method. Input methods is a software to input symbols that are not available on standard input devices.
|
||||||
|
|
||||||
@ -40,7 +40,6 @@ in
|
|||||||
Currently the following input methods are available in NixOS:
|
Currently the following input methods are available in NixOS:
|
||||||
|
|
||||||
- ibus: The intelligent input bus, extra input engines can be added using `i18n.inputMethod.ibus.engines`.
|
- ibus: The intelligent input bus, extra input engines can be added using `i18n.inputMethod.ibus.engines`.
|
||||||
- fcitx: A customizable lightweight input method, extra input engines can be added using `i18n.inputMethod.fcitx.engines`.
|
|
||||||
- fcitx5: The next generation of fcitx, addons (including engines, dictionaries, skins) can be added using `i18n.inputMethod.fcitx5.addons`.
|
- fcitx5: The next generation of fcitx, addons (including engines, dictionaries, skins) can be added using `i18n.inputMethod.fcitx5.addons`.
|
||||||
- nabi: A Korean input method based on XIM. Nabi doesn't support Qt 5.
|
- nabi: A Korean input method based on XIM. Nabi doesn't support Qt 5.
|
||||||
- uim: The universal input method, is a library with a XIM bridge. uim mainly support Chinese, Japanese and Korean.
|
- uim: The universal input method, is a library with a XIM bridge. uim mainly support Chinese, Japanese and Korean.
|
||||||
|
@ -1,46 +0,0 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
let
|
|
||||||
cfg = config.i18n.inputMethod.fcitx;
|
|
||||||
fcitxPackage = pkgs.fcitx.override { plugins = cfg.engines; };
|
|
||||||
fcitxEngine = types.package // {
|
|
||||||
name = "fcitx-engine";
|
|
||||||
check = x: (lib.types.package.check x) && (attrByPath ["meta" "isFcitxEngine"] false x);
|
|
||||||
};
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options = {
|
|
||||||
|
|
||||||
i18n.inputMethod.fcitx = {
|
|
||||||
engines = mkOption {
|
|
||||||
type = with types; listOf fcitxEngine;
|
|
||||||
default = [];
|
|
||||||
example = literalExpression "with pkgs.fcitx-engines; [ mozc hangul ]";
|
|
||||||
description =
|
|
||||||
let
|
|
||||||
enginesDrv = filterAttrs (const isDerivation) pkgs.fcitx-engines;
|
|
||||||
engines = concatStringsSep ", "
|
|
||||||
(map (name: "`${name}`") (attrNames enginesDrv));
|
|
||||||
in
|
|
||||||
lib.mdDoc "Enabled Fcitx engines. Available engines are: ${engines}.";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf (config.i18n.inputMethod.enabled == "fcitx") {
|
|
||||||
i18n.inputMethod.package = fcitxPackage;
|
|
||||||
|
|
||||||
environment.variables = {
|
|
||||||
GTK_IM_MODULE = "fcitx";
|
|
||||||
QT_IM_MODULE = "fcitx";
|
|
||||||
XMODIFIERS = "@im=fcitx";
|
|
||||||
};
|
|
||||||
services.xserver.displayManager.sessionCommands = "${fcitxPackage}/bin/fcitx";
|
|
||||||
};
|
|
||||||
|
|
||||||
# uses attributes of the linked package
|
|
||||||
meta.buildDocsInSandbox = false;
|
|
||||||
}
|
|
@ -21,6 +21,9 @@ with lib;
|
|||||||
# ISO naming.
|
# ISO naming.
|
||||||
isoImage.isoName = "${config.isoImage.isoBaseName}-${config.system.nixos.label}-${pkgs.stdenv.hostPlatform.system}.iso";
|
isoImage.isoName = "${config.isoImage.isoBaseName}-${config.system.nixos.label}-${pkgs.stdenv.hostPlatform.system}.iso";
|
||||||
|
|
||||||
|
# BIOS booting
|
||||||
|
isoImage.makeBiosBootable = true;
|
||||||
|
|
||||||
# EFI booting
|
# EFI booting
|
||||||
isoImage.makeEfiBootable = true;
|
isoImage.makeEfiBootable = true;
|
||||||
|
|
||||||
|
@ -535,10 +535,17 @@ in
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
isoImage.makeBiosBootable = mkOption {
|
||||||
|
default = false;
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Whether the ISO image should be a BIOS-bootable disk.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
isoImage.makeEfiBootable = mkOption {
|
isoImage.makeEfiBootable = mkOption {
|
||||||
default = false;
|
default = false;
|
||||||
description = lib.mdDoc ''
|
description = lib.mdDoc ''
|
||||||
Whether the ISO image should be an efi-bootable volume.
|
Whether the ISO image should be an EFI-bootable volume.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -693,7 +700,7 @@ in
|
|||||||
boot.loader.grub.enable = false;
|
boot.loader.grub.enable = false;
|
||||||
|
|
||||||
environment.systemPackages = [ grubPkgs.grub2 grubPkgs.grub2_efi ]
|
environment.systemPackages = [ grubPkgs.grub2 grubPkgs.grub2_efi ]
|
||||||
++ optional canx86BiosBoot pkgs.syslinux
|
++ optional (config.isoImage.makeBiosBootable && canx86BiosBoot) pkgs.syslinux
|
||||||
;
|
;
|
||||||
|
|
||||||
# In stage 1 of the boot, mount the CD as the root FS by label so
|
# In stage 1 of the boot, mount the CD as the root FS by label so
|
||||||
@ -744,7 +751,7 @@ in
|
|||||||
{ source = pkgs.writeText "version" config.system.nixos.label;
|
{ source = pkgs.writeText "version" config.system.nixos.label;
|
||||||
target = "/version.txt";
|
target = "/version.txt";
|
||||||
}
|
}
|
||||||
] ++ optionals canx86BiosBoot [
|
] ++ optionals (config.isoImage.makeBiosBootable && canx86BiosBoot) [
|
||||||
{ source = config.isoImage.splashImage;
|
{ source = config.isoImage.splashImage;
|
||||||
target = "/isolinux/background.png";
|
target = "/isolinux/background.png";
|
||||||
}
|
}
|
||||||
@ -771,7 +778,7 @@ in
|
|||||||
{ source = config.isoImage.efiSplashImage;
|
{ source = config.isoImage.efiSplashImage;
|
||||||
target = "/EFI/boot/efi-background.png";
|
target = "/EFI/boot/efi-background.png";
|
||||||
}
|
}
|
||||||
] ++ optionals (config.boot.loader.grub.memtest86.enable && canx86BiosBoot) [
|
] ++ optionals (config.boot.loader.grub.memtest86.enable && config.isoImage.makeBiosBootable && canx86BiosBoot) [
|
||||||
{ source = "${pkgs.memtest86plus}/memtest.bin";
|
{ source = "${pkgs.memtest86plus}/memtest.bin";
|
||||||
target = "/boot/memtest.bin";
|
target = "/boot/memtest.bin";
|
||||||
}
|
}
|
||||||
@ -786,10 +793,10 @@ in
|
|||||||
# Create the ISO image.
|
# Create the ISO image.
|
||||||
system.build.isoImage = pkgs.callPackage ../../../lib/make-iso9660-image.nix ({
|
system.build.isoImage = pkgs.callPackage ../../../lib/make-iso9660-image.nix ({
|
||||||
inherit (config.isoImage) isoName compressImage volumeID contents;
|
inherit (config.isoImage) isoName compressImage volumeID contents;
|
||||||
bootable = canx86BiosBoot;
|
bootable = config.isoImage.makeBiosBootable && canx86BiosBoot;
|
||||||
bootImage = "/isolinux/isolinux.bin";
|
bootImage = "/isolinux/isolinux.bin";
|
||||||
syslinux = if canx86BiosBoot then pkgs.syslinux else null;
|
syslinux = if config.isoImage.makeBiosBootable && canx86BiosBoot then pkgs.syslinux else null;
|
||||||
} // optionalAttrs (config.isoImage.makeUsbBootable && canx86BiosBoot) {
|
} // optionalAttrs (config.isoImage.makeUsbBootable && config.isoImage.makeBiosBootable && canx86BiosBoot) {
|
||||||
usbBootable = true;
|
usbBootable = true;
|
||||||
isohybridMbrImage = "${pkgs.syslinux}/share/syslinux/isohdpfx.bin";
|
isohybridMbrImage = "${pkgs.syslinux}/share/syslinux/isohdpfx.bin";
|
||||||
} // optionalAttrs config.isoImage.makeEfiBootable {
|
} // optionalAttrs config.isoImage.makeEfiBootable {
|
||||||
|
@ -9,4 +9,7 @@
|
|||||||
];
|
];
|
||||||
|
|
||||||
documentation.man.enable = lib.mkOverride 500 true;
|
documentation.man.enable = lib.mkOverride 500 true;
|
||||||
|
hardware.enableRedistributableFirmware = lib.mkOverride 70 false;
|
||||||
|
system.extraDependencies = lib.mkOverride 70 [];
|
||||||
|
networking.wireless.enable = lib.mkOverride 500 false;
|
||||||
}
|
}
|
||||||
|
@ -518,21 +518,6 @@ EOF
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# For lack of a better way to determine it, guess whether we should use a
|
|
||||||
# bigger font for the console from the display mode on the first
|
|
||||||
# framebuffer. A way based on the physical size/actual DPI reported by
|
|
||||||
# the monitor would be nice, but I don't know how to do this without X :)
|
|
||||||
my $fb_modes_file = "/sys/class/graphics/fb0/modes";
|
|
||||||
if (-f $fb_modes_file && -r $fb_modes_file) {
|
|
||||||
my $modes = read_file($fb_modes_file);
|
|
||||||
$modes =~ m/([0-9]+)x([0-9]+)/;
|
|
||||||
my $console_width = $1, my $console_height = $2;
|
|
||||||
if ($console_width > 1920) {
|
|
||||||
push @attrs, "# high-resolution display";
|
|
||||||
push @attrs, 'hardware.video.hidpi.enable = lib.mkDefault true;';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Generate the hardware configuration file.
|
# Generate the hardware configuration file.
|
||||||
|
|
||||||
|
@ -159,10 +159,7 @@ in
|
|||||||
$desktopConfiguration
|
$desktopConfiguration
|
||||||
# Configure keymap in X11
|
# Configure keymap in X11
|
||||||
# services.xserver.layout = "us";
|
# services.xserver.layout = "us";
|
||||||
# services.xserver.xkbOptions = {
|
# services.xserver.xkbOptions = "eurosign:e,caps:escape";
|
||||||
# "eurosign:e";
|
|
||||||
# "caps:escape" # map caps to escape.
|
|
||||||
# };
|
|
||||||
|
|
||||||
# Enable CUPS to print documents.
|
# Enable CUPS to print documents.
|
||||||
# services.printing.enable = true;
|
# services.printing.enable = true;
|
||||||
|
@ -338,7 +338,7 @@ in
|
|||||||
lidarr = 306;
|
lidarr = 306;
|
||||||
slurm = 307;
|
slurm = 307;
|
||||||
kapacitor = 308;
|
kapacitor = 308;
|
||||||
solr = 309;
|
# solr = 309; removed 2023-03-16
|
||||||
alerta = 310;
|
alerta = 310;
|
||||||
minetest = 311;
|
minetest = 311;
|
||||||
rss2email = 312;
|
rss2email = 312;
|
||||||
@ -648,7 +648,7 @@ in
|
|||||||
lidarr = 306;
|
lidarr = 306;
|
||||||
slurm = 307;
|
slurm = 307;
|
||||||
kapacitor = 308;
|
kapacitor = 308;
|
||||||
solr = 309;
|
# solr = 309; removed 2023-03-16
|
||||||
alerta = 310;
|
alerta = 310;
|
||||||
minetest = 311;
|
minetest = 311;
|
||||||
rss2email = 312;
|
rss2email = 312;
|
||||||
|
@ -95,7 +95,6 @@
|
|||||||
./hardware/video/bumblebee.nix
|
./hardware/video/bumblebee.nix
|
||||||
./hardware/video/capture/mwprocapture.nix
|
./hardware/video/capture/mwprocapture.nix
|
||||||
./hardware/video/displaylink.nix
|
./hardware/video/displaylink.nix
|
||||||
./hardware/video/hidpi.nix
|
|
||||||
./hardware/video/nvidia.nix
|
./hardware/video/nvidia.nix
|
||||||
./hardware/video/switcheroo-control.nix
|
./hardware/video/switcheroo-control.nix
|
||||||
./hardware/video/uvcvideo/default.nix
|
./hardware/video/uvcvideo/default.nix
|
||||||
@ -104,7 +103,6 @@
|
|||||||
./hardware/xone.nix
|
./hardware/xone.nix
|
||||||
./hardware/xpadneo.nix
|
./hardware/xpadneo.nix
|
||||||
./i18n/input-method/default.nix
|
./i18n/input-method/default.nix
|
||||||
./i18n/input-method/fcitx.nix
|
|
||||||
./i18n/input-method/fcitx5.nix
|
./i18n/input-method/fcitx5.nix
|
||||||
./i18n/input-method/hime.nix
|
./i18n/input-method/hime.nix
|
||||||
./i18n/input-method/ibus.nix
|
./i18n/input-method/ibus.nix
|
||||||
@ -220,6 +218,7 @@
|
|||||||
./programs/proxychains.nix
|
./programs/proxychains.nix
|
||||||
./programs/qdmr.nix
|
./programs/qdmr.nix
|
||||||
./programs/qt5ct.nix
|
./programs/qt5ct.nix
|
||||||
|
./programs/regreet.nix
|
||||||
./programs/rog-control-center.nix
|
./programs/rog-control-center.nix
|
||||||
./programs/rust-motd.nix
|
./programs/rust-motd.nix
|
||||||
./programs/screen.nix
|
./programs/screen.nix
|
||||||
@ -377,6 +376,8 @@
|
|||||||
./services/continuous-integration/jenkins/default.nix
|
./services/continuous-integration/jenkins/default.nix
|
||||||
./services/continuous-integration/jenkins/job-builder.nix
|
./services/continuous-integration/jenkins/job-builder.nix
|
||||||
./services/continuous-integration/jenkins/slave.nix
|
./services/continuous-integration/jenkins/slave.nix
|
||||||
|
./services/continuous-integration/woodpecker/agents.nix
|
||||||
|
./services/continuous-integration/woodpecker/server.nix
|
||||||
./services/databases/aerospike.nix
|
./services/databases/aerospike.nix
|
||||||
./services/databases/cassandra.nix
|
./services/databases/cassandra.nix
|
||||||
./services/databases/clickhouse.nix
|
./services/databases/clickhouse.nix
|
||||||
@ -429,7 +430,6 @@
|
|||||||
./services/desktops/gvfs.nix
|
./services/desktops/gvfs.nix
|
||||||
./services/desktops/malcontent.nix
|
./services/desktops/malcontent.nix
|
||||||
./services/desktops/neard.nix
|
./services/desktops/neard.nix
|
||||||
./services/desktops/pipewire/pipewire-media-session.nix
|
|
||||||
./services/desktops/pipewire/pipewire.nix
|
./services/desktops/pipewire/pipewire.nix
|
||||||
./services/desktops/pipewire/wireplumber.nix
|
./services/desktops/pipewire/wireplumber.nix
|
||||||
./services/desktops/profile-sync-daemon.nix
|
./services/desktops/profile-sync-daemon.nix
|
||||||
@ -509,6 +509,7 @@
|
|||||||
./services/hardware/usbmuxd.nix
|
./services/hardware/usbmuxd.nix
|
||||||
./services/hardware/usbrelayd.nix
|
./services/hardware/usbrelayd.nix
|
||||||
./services/hardware/vdr.nix
|
./services/hardware/vdr.nix
|
||||||
|
./services/hardware/keyd.nix
|
||||||
./services/home-automation/evcc.nix
|
./services/home-automation/evcc.nix
|
||||||
./services/home-automation/home-assistant.nix
|
./services/home-automation/home-assistant.nix
|
||||||
./services/home-automation/zigbee2mqtt.nix
|
./services/home-automation/zigbee2mqtt.nix
|
||||||
@ -732,6 +733,7 @@
|
|||||||
./services/monitoring/nagios.nix
|
./services/monitoring/nagios.nix
|
||||||
./services/monitoring/netdata.nix
|
./services/monitoring/netdata.nix
|
||||||
./services/monitoring/parsedmarc.nix
|
./services/monitoring/parsedmarc.nix
|
||||||
|
./services/monitoring/prometheus/alertmanager-irc-relay.nix
|
||||||
./services/monitoring/prometheus/alertmanager.nix
|
./services/monitoring/prometheus/alertmanager.nix
|
||||||
./services/monitoring/prometheus/default.nix
|
./services/monitoring/prometheus/default.nix
|
||||||
./services/monitoring/prometheus/exporters.nix
|
./services/monitoring/prometheus/exporters.nix
|
||||||
@ -948,6 +950,7 @@
|
|||||||
./services/networking/owamp.nix
|
./services/networking/owamp.nix
|
||||||
./services/networking/pdns-recursor.nix
|
./services/networking/pdns-recursor.nix
|
||||||
./services/networking/pdnsd.nix
|
./services/networking/pdnsd.nix
|
||||||
|
./services/networking/peroxide.nix
|
||||||
./services/networking/pixiecore.nix
|
./services/networking/pixiecore.nix
|
||||||
./services/networking/pleroma.nix
|
./services/networking/pleroma.nix
|
||||||
./services/networking/polipo.nix
|
./services/networking/polipo.nix
|
||||||
@ -1059,8 +1062,8 @@
|
|||||||
./services/search/meilisearch.nix
|
./services/search/meilisearch.nix
|
||||||
./services/search/opensearch.nix
|
./services/search/opensearch.nix
|
||||||
./services/search/qdrant.nix
|
./services/search/qdrant.nix
|
||||||
./services/search/solr.nix
|
|
||||||
./services/security/aesmd.nix
|
./services/security/aesmd.nix
|
||||||
|
./services/security/authelia.nix
|
||||||
./services/security/certmgr.nix
|
./services/security/certmgr.nix
|
||||||
./services/security/cfssl.nix
|
./services/security/cfssl.nix
|
||||||
./services/security/clamav.nix
|
./services/security/clamav.nix
|
||||||
@ -1130,7 +1133,6 @@
|
|||||||
./services/web-apps/atlassian/confluence.nix
|
./services/web-apps/atlassian/confluence.nix
|
||||||
./services/web-apps/atlassian/crowd.nix
|
./services/web-apps/atlassian/crowd.nix
|
||||||
./services/web-apps/atlassian/jira.nix
|
./services/web-apps/atlassian/jira.nix
|
||||||
./services/web-apps/baget.nix
|
|
||||||
./services/web-apps/bookstack.nix
|
./services/web-apps/bookstack.nix
|
||||||
./services/web-apps/calibre-web.nix
|
./services/web-apps/calibre-web.nix
|
||||||
./services/web-apps/coder.nix
|
./services/web-apps/coder.nix
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# This module defines the software packages included in the "minimal"
|
# This module defines the software packages included in the "minimal"
|
||||||
# installation CD. It might be useful elsewhere.
|
# installation CD. It might be useful elsewhere.
|
||||||
|
|
||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
@ -17,7 +17,6 @@
|
|||||||
pkgs.ddrescue
|
pkgs.ddrescue
|
||||||
pkgs.ccrypt
|
pkgs.ccrypt
|
||||||
pkgs.cryptsetup # needed for dm-crypt volumes
|
pkgs.cryptsetup # needed for dm-crypt volumes
|
||||||
pkgs.mkpasswd # for generating password files
|
|
||||||
|
|
||||||
# Some text editors.
|
# Some text editors.
|
||||||
(pkgs.vim.customize {
|
(pkgs.vim.customize {
|
||||||
@ -32,7 +31,6 @@
|
|||||||
pkgs.fuse
|
pkgs.fuse
|
||||||
pkgs.fuse3
|
pkgs.fuse3
|
||||||
pkgs.sshfs-fuse
|
pkgs.sshfs-fuse
|
||||||
pkgs.rsync
|
|
||||||
pkgs.socat
|
pkgs.socat
|
||||||
pkgs.screen
|
pkgs.screen
|
||||||
pkgs.tcpdump
|
pkgs.tcpdump
|
||||||
@ -45,22 +43,14 @@
|
|||||||
pkgs.usbutils
|
pkgs.usbutils
|
||||||
pkgs.nvme-cli
|
pkgs.nvme-cli
|
||||||
|
|
||||||
# Tools to create / manipulate filesystems.
|
|
||||||
pkgs.ntfsprogs # for resizing NTFS partitions
|
|
||||||
pkgs.dosfstools
|
|
||||||
pkgs.mtools
|
|
||||||
pkgs.xfsprogs.bin
|
|
||||||
pkgs.jfsutils
|
|
||||||
pkgs.f2fs-tools
|
|
||||||
|
|
||||||
# Some compression/archiver tools.
|
# Some compression/archiver tools.
|
||||||
pkgs.unzip
|
pkgs.unzip
|
||||||
pkgs.zip
|
pkgs.zip
|
||||||
];
|
];
|
||||||
|
|
||||||
# Include support for various filesystems.
|
# Include support for various filesystems and tools to create / manipulate them.
|
||||||
boot.supportedFilesystems =
|
boot.supportedFilesystems =
|
||||||
[ "btrfs" "reiserfs" "vfat" "f2fs" "xfs" "ntfs" "cifs" ] ++
|
[ "btrfs" "cifs" "f2fs" "jfs" "ntfs" "reiserfs" "vfat" "xfs" ] ++
|
||||||
lib.optional (lib.meta.availableOn pkgs.stdenv.hostPlatform config.boot.zfs.package) "zfs";
|
lib.optional (lib.meta.availableOn pkgs.stdenv.hostPlatform config.boot.zfs.package) "zfs";
|
||||||
|
|
||||||
# Configure host id for ZFS to work
|
# Configure host id for ZFS to work
|
||||||
|
@ -17,7 +17,7 @@ in {
|
|||||||
type = types.listOf types.str;
|
type = types.listOf types.str;
|
||||||
description = lib.mdDoc "Nix top-level packages to be compiled using CCache";
|
description = lib.mdDoc "Nix top-level packages to be compiled using CCache";
|
||||||
default = [];
|
default = [];
|
||||||
example = [ "wxGTK30" "ffmpeg" "libav_all" ];
|
example = [ "wxGTK32" "ffmpeg" "libav_all" ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
75
nixos/modules/programs/regreet.nix
Normal file
75
nixos/modules/programs/regreet.nix
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
{ lib
|
||||||
|
, pkgs
|
||||||
|
, config
|
||||||
|
, ...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
cfg = config.programs.regreet;
|
||||||
|
settingsFormat = pkgs.formats.toml { };
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.programs.regreet = {
|
||||||
|
enable = lib.mkEnableOption null // {
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Enable ReGreet, a clean and customizable greeter for greetd.
|
||||||
|
|
||||||
|
To use ReGreet, {option}`services.greetd` has to be enabled and
|
||||||
|
{option}`services.greetd.settings.default_session` should contain the
|
||||||
|
appropriate configuration to launch
|
||||||
|
{option}`config.programs.regreet.package`. For examples, see the
|
||||||
|
[ReGreet Readme](https://github.com/rharish101/ReGreet#set-as-default-session).
|
||||||
|
|
||||||
|
A minimal configuration that launches ReGreet in {command}`cage` is
|
||||||
|
enabled by this module by default.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
package = lib.mkPackageOptionMD pkgs [ "greetd" "regreet" ] { };
|
||||||
|
|
||||||
|
settings = lib.mkOption {
|
||||||
|
type = lib.types.either lib.types.path settingsFormat.type;
|
||||||
|
default = { };
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
ReGreet configuration file. Refer
|
||||||
|
<https://github.com/rharish101/ReGreet/blob/main/regreet.sample.toml>
|
||||||
|
for options.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
extraCss = lib.mkOption {
|
||||||
|
type = lib.types.either lib.types.path lib.types.lines;
|
||||||
|
default = "";
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Extra CSS rules to apply on top of the GTK theme. Refer to
|
||||||
|
[GTK CSS Properties](https://docs.gtk.org/gtk4/css-properties.html) for
|
||||||
|
modifiable properties.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
services.greetd = {
|
||||||
|
enable = lib.mkDefault true;
|
||||||
|
settings.default_session.command = lib.mkDefault "${lib.getExe pkgs.cage} -s -- ${lib.getExe cfg.package}";
|
||||||
|
};
|
||||||
|
|
||||||
|
environment.etc = {
|
||||||
|
"greetd/regreet.css" =
|
||||||
|
if lib.isPath cfg.extraCss
|
||||||
|
then {source = cfg.extraCss;}
|
||||||
|
else {text = cfg.extraCss;};
|
||||||
|
|
||||||
|
"greetd/regreet.toml".source =
|
||||||
|
if lib.isPath cfg.settings
|
||||||
|
then cfg.settings
|
||||||
|
else settingsFormat.generate "regreet.toml" cfg.settings;
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.tmpfiles.rules = let
|
||||||
|
user = config.services.greetd.settings.default_session.user;
|
||||||
|
in [
|
||||||
|
"d /var/log/regreet 0755 greeter ${user} - -"
|
||||||
|
"d /var/cache/regreet 0755 greeter ${user} - -"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
@ -240,7 +240,7 @@ in
|
|||||||
[
|
[
|
||||||
./known_hosts
|
./known_hosts
|
||||||
(writeText "github.keys" '''
|
(writeText "github.keys" '''
|
||||||
github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
|
github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk=
|
||||||
github.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg=
|
github.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg=
|
||||||
github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl
|
github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl
|
||||||
''')
|
''')
|
||||||
|
@ -9,10 +9,27 @@ let
|
|||||||
|
|
||||||
settingsFile = settingsFormat.generate "starship.toml" cfg.settings;
|
settingsFile = settingsFormat.generate "starship.toml" cfg.settings;
|
||||||
|
|
||||||
in {
|
initOption =
|
||||||
|
if cfg.interactiveOnly then
|
||||||
|
"promptInit"
|
||||||
|
else
|
||||||
|
"shellInit";
|
||||||
|
|
||||||
|
in
|
||||||
|
{
|
||||||
options.programs.starship = {
|
options.programs.starship = {
|
||||||
enable = mkEnableOption (lib.mdDoc "the Starship shell prompt");
|
enable = mkEnableOption (lib.mdDoc "the Starship shell prompt");
|
||||||
|
|
||||||
|
interactiveOnly = mkOption {
|
||||||
|
default = true;
|
||||||
|
example = false;
|
||||||
|
type = types.bool;
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Whether to enable starship only when the shell is interactive.
|
||||||
|
Some plugins require this to be set to false to function correctly.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
settings = mkOption {
|
settings = mkOption {
|
||||||
inherit (settingsFormat) type;
|
inherit (settingsFormat) type;
|
||||||
default = { };
|
default = { };
|
||||||
@ -25,21 +42,21 @@ in {
|
|||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
programs.bash.promptInit = ''
|
programs.bash.${initOption} = ''
|
||||||
if [[ $TERM != "dumb" && (-z $INSIDE_EMACS || $INSIDE_EMACS == "vterm") ]]; then
|
if [[ $TERM != "dumb" && (-z $INSIDE_EMACS || $INSIDE_EMACS == "vterm") ]]; then
|
||||||
export STARSHIP_CONFIG=${settingsFile}
|
export STARSHIP_CONFIG=${settingsFile}
|
||||||
eval "$(${pkgs.starship}/bin/starship init bash)"
|
eval "$(${pkgs.starship}/bin/starship init bash)"
|
||||||
fi
|
fi
|
||||||
'';
|
'';
|
||||||
|
|
||||||
programs.fish.promptInit = ''
|
programs.fish.${initOption} = ''
|
||||||
if test "$TERM" != "dumb" -a \( -z "$INSIDE_EMACS" -o "$INSIDE_EMACS" = "vterm" \)
|
if test "$TERM" != "dumb" -a \( -z "$INSIDE_EMACS" -o "$INSIDE_EMACS" = "vterm" \)
|
||||||
set -x STARSHIP_CONFIG ${settingsFile}
|
set -x STARSHIP_CONFIG ${settingsFile}
|
||||||
eval (${pkgs.starship}/bin/starship init fish)
|
eval (${pkgs.starship}/bin/starship init fish)
|
||||||
end
|
end
|
||||||
'';
|
'';
|
||||||
|
|
||||||
programs.zsh.promptInit = ''
|
programs.zsh.${initOption} = ''
|
||||||
if [[ $TERM != "dumb" && (-z $INSIDE_EMACS || $INSIDE_EMACS == "vterm") ]]; then
|
if [[ $TERM != "dumb" && (-z $INSIDE_EMACS || $INSIDE_EMACS == "vterm") ]]; then
|
||||||
export STARSHIP_CONFIG=${settingsFile}
|
export STARSHIP_CONFIG=${settingsFile}
|
||||||
eval "$(${pkgs.starship}/bin/starship init zsh)"
|
eval "$(${pkgs.starship}/bin/starship init zsh)"
|
||||||
|
@ -9,23 +9,36 @@ in {
|
|||||||
enable = mkEnableOption (lib.mdDoc "steam");
|
enable = mkEnableOption (lib.mdDoc "steam");
|
||||||
|
|
||||||
package = mkOption {
|
package = mkOption {
|
||||||
type = types.package;
|
type = types.package;
|
||||||
default = pkgs.steam.override {
|
default = pkgs.steam;
|
||||||
extraLibraries = pkgs: with config.hardware.opengl;
|
defaultText = literalExpression "pkgs.steam";
|
||||||
if pkgs.stdenv.hostPlatform.is64bit
|
example = literalExpression ''
|
||||||
then [ package ] ++ extraPackages
|
pkgs.steam-small.override {
|
||||||
else [ package32 ] ++ extraPackages32;
|
extraEnv = {
|
||||||
};
|
MANGOHUD = true;
|
||||||
defaultText = literalExpression ''
|
OBS_VKCAPTURE = true;
|
||||||
pkgs.steam.override {
|
RADV_TEX_ANISO = 16;
|
||||||
extraLibraries = pkgs: with config.hardware.opengl;
|
};
|
||||||
|
extraLibraries = p: with p; [
|
||||||
|
atk
|
||||||
|
];
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
apply = steam: steam.override (prev: {
|
||||||
|
extraLibraries = pkgs: let
|
||||||
|
prevLibs = if prev ? extraLibraries then prev.extraLibraries pkgs else [ ];
|
||||||
|
additionalLibs = with config.hardware.opengl;
|
||||||
if pkgs.stdenv.hostPlatform.is64bit
|
if pkgs.stdenv.hostPlatform.is64bit
|
||||||
then [ package ] ++ extraPackages
|
then [ package ] ++ extraPackages
|
||||||
else [ package32 ] ++ extraPackages32;
|
else [ package32 ] ++ extraPackages32;
|
||||||
}
|
in prevLibs ++ additionalLibs;
|
||||||
'';
|
});
|
||||||
description = lib.mdDoc ''
|
description = lib.mdDoc ''
|
||||||
steam package to use.
|
The Steam package to use. Additional libraries are added from the system
|
||||||
|
configuration to ensure graphics work properly.
|
||||||
|
|
||||||
|
Use this option to customise the Steam package rather than adding your
|
||||||
|
custom Steam to {option}`environment.systemPackages` yourself.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ in {
|
|||||||
|
|
||||||
security.wrappers.dumpcap = {
|
security.wrappers.dumpcap = {
|
||||||
source = "${wireshark}/bin/dumpcap";
|
source = "${wireshark}/bin/dumpcap";
|
||||||
capabilities = "cap_net_raw+p";
|
capabilities = "cap_net_raw,cap_net_admin+eip";
|
||||||
owner = "root";
|
owner = "root";
|
||||||
group = "wireshark";
|
group = "wireshark";
|
||||||
permissions = "u+rx,g+x";
|
permissions = "u+rx,g+x";
|
||||||
|
@ -44,6 +44,7 @@ with lib;
|
|||||||
The hidepid module was removed, since the underlying machinery
|
The hidepid module was removed, since the underlying machinery
|
||||||
is broken when using cgroups-v2.
|
is broken when using cgroups-v2.
|
||||||
'')
|
'')
|
||||||
|
(mkRemovedOptionModule [ "services" "baget" "enable" ] "The baget module was removed due to the upstream package being unmaintained.")
|
||||||
(mkRemovedOptionModule [ "services" "beegfs" ] "The BeeGFS module has been removed")
|
(mkRemovedOptionModule [ "services" "beegfs" ] "The BeeGFS module has been removed")
|
||||||
(mkRemovedOptionModule [ "services" "beegfsEnable" ] "The BeeGFS module has been removed")
|
(mkRemovedOptionModule [ "services" "beegfsEnable" ] "The BeeGFS module has been removed")
|
||||||
(mkRemovedOptionModule [ "services" "cgmanager" "enable"] "cgmanager was deprecated by lxc and therefore removed from nixpkgs.")
|
(mkRemovedOptionModule [ "services" "cgmanager" "enable"] "cgmanager was deprecated by lxc and therefore removed from nixpkgs.")
|
||||||
@ -106,6 +107,8 @@ with lib;
|
|||||||
(mkRemovedOptionModule [ "services" "riak" ] "The corresponding package was removed from nixpkgs.")
|
(mkRemovedOptionModule [ "services" "riak" ] "The corresponding package was removed from nixpkgs.")
|
||||||
(mkRemovedOptionModule [ "services" "cryptpad" ] "The corresponding package was removed from nixpkgs.")
|
(mkRemovedOptionModule [ "services" "cryptpad" ] "The corresponding package was removed from nixpkgs.")
|
||||||
|
|
||||||
|
(mkRemovedOptionModule [ "i18n" "inputMethod" "fcitx" ] "The fcitx module has been removed. Plesae use fcitx5 instead")
|
||||||
|
|
||||||
# Do NOT add any option renames here, see top of the file
|
# Do NOT add any option renames here, see top of the file
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ let
|
|||||||
];
|
];
|
||||||
|
|
||||||
mkArgs = rule:
|
mkArgs = rule:
|
||||||
if (isNull rule.args) then ""
|
if (rule.args == null) then ""
|
||||||
else if (length rule.args == 0) then "args"
|
else if (length rule.args == 0) then "args"
|
||||||
else "args ${concatStringsSep " " rule.args}";
|
else "args ${concatStringsSep " " rule.args}";
|
||||||
|
|
||||||
@ -27,9 +27,9 @@ let
|
|||||||
let
|
let
|
||||||
opts = mkOpts rule;
|
opts = mkOpts rule;
|
||||||
|
|
||||||
as = optionalString (!isNull rule.runAs) "as ${rule.runAs}";
|
as = optionalString (rule.runAs != null) "as ${rule.runAs}";
|
||||||
|
|
||||||
cmd = optionalString (!isNull rule.cmd) "cmd ${rule.cmd}";
|
cmd = optionalString (rule.cmd != null) "cmd ${rule.cmd}";
|
||||||
|
|
||||||
args = mkArgs rule;
|
args = mkArgs rule;
|
||||||
in
|
in
|
||||||
@ -75,7 +75,9 @@ in
|
|||||||
{file}`/etc/doas.conf` file. More specific rules should
|
{file}`/etc/doas.conf` file. More specific rules should
|
||||||
come after more general ones in order to yield the expected behavior.
|
come after more general ones in order to yield the expected behavior.
|
||||||
You can use `mkBefore` and/or `mkAfter` to ensure
|
You can use `mkBefore` and/or `mkAfter` to ensure
|
||||||
this is the case when configuration options are merged.
|
this is the case when configuration options are merged. Be aware that
|
||||||
|
this option cannot be used to override the behaviour allowing
|
||||||
|
passwordless operation for root.
|
||||||
'';
|
'';
|
||||||
example = literalExpression ''
|
example = literalExpression ''
|
||||||
[
|
[
|
||||||
@ -224,7 +226,9 @@ in
|
|||||||
type = with types; lines;
|
type = with types; lines;
|
||||||
default = "";
|
default = "";
|
||||||
description = lib.mdDoc ''
|
description = lib.mdDoc ''
|
||||||
Extra configuration text appended to {file}`doas.conf`.
|
Extra configuration text appended to {file}`doas.conf`. Be aware that
|
||||||
|
this option cannot be used to override the behaviour allowing
|
||||||
|
passwordless operation for root.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -266,14 +270,14 @@ in
|
|||||||
# completely replace the contents of this file, use
|
# completely replace the contents of this file, use
|
||||||
# `environment.etc."doas.conf"`.
|
# `environment.etc."doas.conf"`.
|
||||||
|
|
||||||
# "root" is allowed to do anything.
|
|
||||||
permit nopass keepenv root
|
|
||||||
|
|
||||||
# extraRules
|
# extraRules
|
||||||
${concatStringsSep "\n" (lists.flatten (map mkRule cfg.extraRules))}
|
${concatStringsSep "\n" (lists.flatten (map mkRule cfg.extraRules))}
|
||||||
|
|
||||||
# extraConfig
|
# extraConfig
|
||||||
${cfg.extraConfig}
|
${cfg.extraConfig}
|
||||||
|
|
||||||
|
# "root" is allowed to do anything.
|
||||||
|
permit nopass keepenv root
|
||||||
'';
|
'';
|
||||||
preferLocalBuild = true;
|
preferLocalBuild = true;
|
||||||
}
|
}
|
||||||
|
@ -620,7 +620,7 @@ let
|
|||||||
optionalString config.services.homed.enable ''
|
optionalString config.services.homed.enable ''
|
||||||
password sufficient ${config.systemd.package}/lib/security/pam_systemd_home.so
|
password sufficient ${config.systemd.package}/lib/security/pam_systemd_home.so
|
||||||
'' + ''
|
'' + ''
|
||||||
password sufficient pam_unix.so nullok sha512
|
password sufficient pam_unix.so nullok yescrypt
|
||||||
'' +
|
'' +
|
||||||
optionalString config.security.pam.enableEcryptfs ''
|
optionalString config.security.pam.enableEcryptfs ''
|
||||||
password optional ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so
|
password optional ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so
|
||||||
@ -793,7 +793,7 @@ let
|
|||||||
};
|
};
|
||||||
}));
|
}));
|
||||||
|
|
||||||
motd = if isNull config.users.motdFile
|
motd = if config.users.motdFile == null
|
||||||
then pkgs.writeText "motd" config.users.motd
|
then pkgs.writeText "motd" config.users.motd
|
||||||
else config.users.motdFile;
|
else config.users.motdFile;
|
||||||
|
|
||||||
@ -1233,7 +1233,7 @@ in
|
|||||||
config = {
|
config = {
|
||||||
assertions = [
|
assertions = [
|
||||||
{
|
{
|
||||||
assertion = isNull config.users.motd || isNull config.users.motdFile;
|
assertion = config.users.motd == null || config.users.motdFile == null;
|
||||||
message = ''
|
message = ''
|
||||||
Only one of users.motd and users.motdFile can be set.
|
Only one of users.motd and users.motdFile can be set.
|
||||||
'';
|
'';
|
||||||
|
@ -303,8 +303,8 @@ in
|
|||||||
then if (backup.paths != null) then concatStringsSep " " backup.paths else ""
|
then if (backup.paths != null) then concatStringsSep " " backup.paths else ""
|
||||||
else "--files-from ${filesFromTmpFile}";
|
else "--files-from ${filesFromTmpFile}";
|
||||||
pruneCmd = optionals (builtins.length backup.pruneOpts > 0) [
|
pruneCmd = optionals (builtins.length backup.pruneOpts > 0) [
|
||||||
(resticCmd + " forget --prune --cache-dir=%C/restic-backups-${name} " + (concatStringsSep " " backup.pruneOpts))
|
(resticCmd + " forget --prune " + (concatStringsSep " " backup.pruneOpts))
|
||||||
(resticCmd + " check --cache-dir=%C/restic-backups-${name} " + (concatStringsSep " " backup.checkOpts))
|
(resticCmd + " check " + (concatStringsSep " " backup.checkOpts))
|
||||||
];
|
];
|
||||||
# Helper functions for rclone remotes
|
# Helper functions for rclone remotes
|
||||||
rcloneRemoteName = builtins.elemAt (splitString ":" backup.repository) 1;
|
rcloneRemoteName = builtins.elemAt (splitString ":" backup.repository) 1;
|
||||||
@ -314,6 +314,7 @@ in
|
|||||||
in
|
in
|
||||||
nameValuePair "restic-backups-${name}" ({
|
nameValuePair "restic-backups-${name}" ({
|
||||||
environment = {
|
environment = {
|
||||||
|
RESTIC_CACHE_DIR = "%C/restic-backups-${name}";
|
||||||
RESTIC_PASSWORD_FILE = backup.passwordFile;
|
RESTIC_PASSWORD_FILE = backup.passwordFile;
|
||||||
RESTIC_REPOSITORY = backup.repository;
|
RESTIC_REPOSITORY = backup.repository;
|
||||||
RESTIC_REPOSITORY_FILE = backup.repositoryFile;
|
RESTIC_REPOSITORY_FILE = backup.repositoryFile;
|
||||||
@ -332,7 +333,7 @@ in
|
|||||||
restartIfChanged = false;
|
restartIfChanged = false;
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Type = "oneshot";
|
Type = "oneshot";
|
||||||
ExecStart = (optionals (backupPaths != "") [ "${resticCmd} backup --cache-dir=%C/restic-backups-${name} ${concatStringsSep " " (backup.extraBackupArgs ++ excludeFlags)} ${backupPaths}" ])
|
ExecStart = (optionals (backupPaths != "") [ "${resticCmd} backup ${concatStringsSep " " (backup.extraBackupArgs ++ excludeFlags)} ${backupPaths}" ])
|
||||||
++ pruneCmd;
|
++ pruneCmd;
|
||||||
User = backup.user;
|
User = backup.user;
|
||||||
RuntimeDirectory = "restic-backups-${name}";
|
RuntimeDirectory = "restic-backups-${name}";
|
||||||
|
@ -5,11 +5,95 @@ let
|
|||||||
cfg = config.services.hadoop;
|
cfg = config.services.hadoop;
|
||||||
hadoopConf = "${import ./conf.nix { inherit cfg pkgs lib; }}/";
|
hadoopConf = "${import ./conf.nix { inherit cfg pkgs lib; }}/";
|
||||||
mkIfNotNull = x: mkIf (x != null) x;
|
mkIfNotNull = x: mkIf (x != null) x;
|
||||||
|
# generic hbase role options
|
||||||
|
hbaseRoleOption = name: extraOpts: {
|
||||||
|
enable = mkEnableOption (mdDoc "HBase ${name}");
|
||||||
|
|
||||||
|
openFirewall = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = mdDoc "Open firewall ports for HBase ${name}.";
|
||||||
|
};
|
||||||
|
|
||||||
|
restartIfChanged = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = mdDoc "Restart ${name} con config change.";
|
||||||
|
};
|
||||||
|
|
||||||
|
extraFlags = mkOption {
|
||||||
|
type = with types; listOf str;
|
||||||
|
default = [];
|
||||||
|
example = literalExpression ''[ "--backup" ]'';
|
||||||
|
description = mdDoc "Extra flags for the ${name} service.";
|
||||||
|
};
|
||||||
|
|
||||||
|
environment = mkOption {
|
||||||
|
type = with types; attrsOf str;
|
||||||
|
default = {};
|
||||||
|
example = literalExpression ''
|
||||||
|
{
|
||||||
|
HBASE_MASTER_OPTS = "-Dcom.sun.management.jmxremote.ssl=true";
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
description = mdDoc "Environment variables passed to ${name}.";
|
||||||
|
};
|
||||||
|
} // extraOpts;
|
||||||
|
# generic hbase role configs
|
||||||
|
hbaseRoleConfig = name: ports: (mkIf cfg.hbase."${name}".enable {
|
||||||
|
services.hadoop.gatewayRole = {
|
||||||
|
enable = true;
|
||||||
|
enableHbaseCli = mkDefault true;
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services."hbase-${toLower name}" = {
|
||||||
|
description = "HBase ${name}";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
path = with cfg; [ hbase.package ] ++ optional
|
||||||
|
(with cfg.hbase.master; enable && initHDFS) package;
|
||||||
|
preStart = mkIf (with cfg.hbase.master; enable && initHDFS)
|
||||||
|
(concatStringsSep "\n" (
|
||||||
|
map (x: "HADOOP_USER_NAME=hdfs hdfs --config /etc/hadoop-conf ${x}")[
|
||||||
|
"dfsadmin -safemode wait"
|
||||||
|
"dfs -mkdir -p ${cfg.hbase.rootdir}"
|
||||||
|
"dfs -chown hbase ${cfg.hbase.rootdir}"
|
||||||
|
]
|
||||||
|
));
|
||||||
|
|
||||||
|
inherit (cfg.hbase."${name}") environment;
|
||||||
|
script = concatStringsSep " " (
|
||||||
|
[
|
||||||
|
"hbase --config /etc/hadoop-conf/"
|
||||||
|
"${toLower name} start"
|
||||||
|
]
|
||||||
|
++ cfg.hbase."${name}".extraFlags
|
||||||
|
++ map (x: "--${toLower x} ${toString cfg.hbase.${name}.${x}}")
|
||||||
|
(filter (x: hasAttr x cfg.hbase.${name}) ["port" "infoPort"])
|
||||||
|
);
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
User = "hbase";
|
||||||
|
SyslogIdentifier = "hbase-${toLower name}";
|
||||||
|
Restart = "always";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.hadoop.hbaseSiteInternal."hbase.rootdir" = cfg.hbase.rootdir;
|
||||||
|
|
||||||
|
networking = {
|
||||||
|
firewall.allowedTCPPorts = mkIf cfg.hbase."${name}".openFirewall ports;
|
||||||
|
hosts = mkIf (with cfg.hbase.regionServer; enable && overrideHosts) {
|
||||||
|
"127.0.0.2" = mkForce [ ];
|
||||||
|
"::1" = mkForce [ ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
});
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.services.hadoop = {
|
options.services.hadoop = {
|
||||||
|
|
||||||
gatewayRole.enableHbaseCli = mkEnableOption (lib.mdDoc "HBase CLI tools");
|
gatewayRole.enableHbaseCli = mkEnableOption (mdDoc "HBase CLI tools");
|
||||||
|
|
||||||
hbaseSiteDefault = mkOption {
|
hbaseSiteDefault = mkOption {
|
||||||
default = {
|
default = {
|
||||||
@ -21,7 +105,7 @@ in
|
|||||||
"hbase.cluster.distributed" = "true";
|
"hbase.cluster.distributed" = "true";
|
||||||
};
|
};
|
||||||
type = types.attrsOf types.anything;
|
type = types.attrsOf types.anything;
|
||||||
description = lib.mdDoc ''
|
description = mdDoc ''
|
||||||
Default options for hbase-site.xml
|
Default options for hbase-site.xml
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
@ -29,8 +113,12 @@ in
|
|||||||
default = {};
|
default = {};
|
||||||
type = with types; attrsOf anything;
|
type = with types; attrsOf anything;
|
||||||
example = literalExpression ''
|
example = literalExpression ''
|
||||||
|
{
|
||||||
|
"hbase.hregion.max.filesize" = 20*1024*1024*1024;
|
||||||
|
"hbase.table.normalization.enabled" = "true";
|
||||||
|
}
|
||||||
'';
|
'';
|
||||||
description = lib.mdDoc ''
|
description = mdDoc ''
|
||||||
Additional options and overrides for hbase-site.xml
|
Additional options and overrides for hbase-site.xml
|
||||||
<https://github.com/apache/hbase/blob/rel/2.4.11/hbase-common/src/main/resources/hbase-default.xml>
|
<https://github.com/apache/hbase/blob/rel/2.4.11/hbase-common/src/main/resources/hbase-default.xml>
|
||||||
'';
|
'';
|
||||||
@ -39,7 +127,7 @@ in
|
|||||||
default = {};
|
default = {};
|
||||||
type = with types; attrsOf anything;
|
type = with types; attrsOf anything;
|
||||||
internal = true;
|
internal = true;
|
||||||
description = lib.mdDoc ''
|
description = mdDoc ''
|
||||||
Internal option to add configs to hbase-site.xml based on module options
|
Internal option to add configs to hbase-site.xml based on module options
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
@ -50,11 +138,11 @@ in
|
|||||||
type = types.package;
|
type = types.package;
|
||||||
default = pkgs.hbase;
|
default = pkgs.hbase;
|
||||||
defaultText = literalExpression "pkgs.hbase";
|
defaultText = literalExpression "pkgs.hbase";
|
||||||
description = lib.mdDoc "HBase package";
|
description = mdDoc "HBase package";
|
||||||
};
|
};
|
||||||
|
|
||||||
rootdir = mkOption {
|
rootdir = mkOption {
|
||||||
description = lib.mdDoc ''
|
description = mdDoc ''
|
||||||
This option will set "hbase.rootdir" in hbase-site.xml and determine
|
This option will set "hbase.rootdir" in hbase-site.xml and determine
|
||||||
the directory shared by region servers and into which HBase persists.
|
the directory shared by region servers and into which HBase persists.
|
||||||
The URL should be 'fully-qualified' to include the filesystem scheme.
|
The URL should be 'fully-qualified' to include the filesystem scheme.
|
||||||
@ -68,7 +156,7 @@ in
|
|||||||
default = "/hbase";
|
default = "/hbase";
|
||||||
};
|
};
|
||||||
zookeeperQuorum = mkOption {
|
zookeeperQuorum = mkOption {
|
||||||
description = lib.mdDoc ''
|
description = mdDoc ''
|
||||||
This option will set "hbase.zookeeper.quorum" in hbase-site.xml.
|
This option will set "hbase.zookeeper.quorum" in hbase-site.xml.
|
||||||
Comma separated list of servers in the ZooKeeper ensemble.
|
Comma separated list of servers in the ZooKeeper ensemble.
|
||||||
'';
|
'';
|
||||||
@ -76,107 +164,36 @@ in
|
|||||||
example = "zk1.internal,zk2.internal,zk3.internal";
|
example = "zk1.internal,zk2.internal,zk3.internal";
|
||||||
default = null;
|
default = null;
|
||||||
};
|
};
|
||||||
master = {
|
} // (let
|
||||||
enable = mkEnableOption (lib.mdDoc "HBase Master");
|
ports = port: infoPort: {
|
||||||
initHDFS = mkEnableOption (lib.mdDoc "initialization of the hbase directory on HDFS");
|
port = mkOption {
|
||||||
|
type = types.int;
|
||||||
openFirewall = mkOption {
|
default = port;
|
||||||
type = types.bool;
|
description = mdDoc "RPC port";
|
||||||
default = false;
|
};
|
||||||
description = lib.mdDoc ''
|
infoPort = mkOption {
|
||||||
Open firewall ports for HBase master.
|
type = types.int;
|
||||||
'';
|
default = infoPort;
|
||||||
|
description = mdDoc "web UI port";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
regionServer = {
|
in mapAttrs hbaseRoleOption {
|
||||||
enable = mkEnableOption (lib.mdDoc "HBase RegionServer");
|
master.initHDFS = mkEnableOption (mdDoc "initialization of the hbase directory on HDFS");
|
||||||
|
regionServer.overrideHosts = mkOption {
|
||||||
overrideHosts = mkOption {
|
type = types.bool;
|
||||||
type = types.bool;
|
default = true;
|
||||||
default = true;
|
description = mdDoc ''
|
||||||
description = lib.mdDoc ''
|
Remove /etc/hosts entries for "127.0.0.2" and "::1" defined in nixos/modules/config/networking.nix
|
||||||
Remove /etc/hosts entries for "127.0.0.2" and "::1" defined in nixos/modules/config/networking.nix
|
Regionservers must be able to resolve their hostnames to their IP addresses, through PTR records
|
||||||
Regionservers must be able to resolve their hostnames to their IP addresses, through PTR records
|
or /etc/hosts entries.
|
||||||
or /etc/hosts entries.
|
'';
|
||||||
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
openFirewall = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
Open firewall ports for HBase master.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
thrift = ports 9090 9095;
|
||||||
|
rest = ports 8080 8085;
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkMerge [
|
config = mkMerge ([
|
||||||
(mkIf cfg.hbase.master.enable {
|
|
||||||
services.hadoop.gatewayRole = {
|
|
||||||
enable = true;
|
|
||||||
enableHbaseCli = mkDefault true;
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services.hbase-master = {
|
|
||||||
description = "HBase master";
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
|
|
||||||
preStart = mkIf cfg.hbase.master.initHDFS ''
|
|
||||||
HADOOP_USER_NAME=hdfs ${cfg.package}/bin/hdfs --config ${hadoopConf} dfsadmin -safemode wait
|
|
||||||
HADOOP_USER_NAME=hdfs ${cfg.package}/bin/hdfs --config ${hadoopConf} dfs -mkdir -p ${cfg.hbase.rootdir}
|
|
||||||
HADOOP_USER_NAME=hdfs ${cfg.package}/bin/hdfs --config ${hadoopConf} dfs -chown hbase ${cfg.hbase.rootdir}
|
|
||||||
'';
|
|
||||||
|
|
||||||
serviceConfig = {
|
|
||||||
User = "hbase";
|
|
||||||
SyslogIdentifier = "hbase-master";
|
|
||||||
ExecStart = "${cfg.hbase.package}/bin/hbase --config ${hadoopConf} " +
|
|
||||||
"master start";
|
|
||||||
Restart = "always";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services.hadoop.hbaseSiteInternal."hbase.rootdir" = cfg.hbase.rootdir;
|
|
||||||
|
|
||||||
networking.firewall.allowedTCPPorts = mkIf cfg.hbase.master.openFirewall [
|
|
||||||
16000 16010
|
|
||||||
];
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
(mkIf cfg.hbase.regionServer.enable {
|
|
||||||
services.hadoop.gatewayRole = {
|
|
||||||
enable = true;
|
|
||||||
enableHbaseCli = mkDefault true;
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services.hbase-regionserver = {
|
|
||||||
description = "HBase RegionServer";
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
serviceConfig = {
|
|
||||||
User = "hbase";
|
|
||||||
SyslogIdentifier = "hbase-regionserver";
|
|
||||||
ExecStart = "${cfg.hbase.package}/bin/hbase --config /etc/hadoop-conf/ " +
|
|
||||||
"regionserver start";
|
|
||||||
Restart = "always";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services.hadoop.hbaseSiteInternal."hbase.rootdir" = cfg.hbase.rootdir;
|
|
||||||
|
|
||||||
networking = {
|
|
||||||
firewall.allowedTCPPorts = mkIf cfg.hbase.regionServer.openFirewall [
|
|
||||||
16020 16030
|
|
||||||
];
|
|
||||||
hosts = mkIf cfg.hbase.regionServer.overrideHosts {
|
|
||||||
"127.0.0.2" = mkForce [ ];
|
|
||||||
"::1" = mkForce [ ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
})
|
|
||||||
|
|
||||||
(mkIf cfg.gatewayRole.enable {
|
(mkIf cfg.gatewayRole.enable {
|
||||||
|
|
||||||
@ -192,5 +209,10 @@ in
|
|||||||
isSystemUser = true;
|
isSystemUser = true;
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
];
|
] ++ (mapAttrsToList hbaseRoleConfig {
|
||||||
|
master = [ 16000 16010 ];
|
||||||
|
regionServer = [ 16020 16030 ];
|
||||||
|
thrift = with cfg.hbase.thrift; [ port infoPort ];
|
||||||
|
rest = with cfg.hbase.rest; [ port infoPort ];
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
with lib;
|
with lib;
|
||||||
|
|
||||||
let
|
let
|
||||||
version = "1.7.1";
|
version = "1.10.1";
|
||||||
cfg = config.services.kubernetes.addons.dns;
|
cfg = config.services.kubernetes.addons.dns;
|
||||||
ports = {
|
ports = {
|
||||||
dns = 10053;
|
dns = 10053;
|
||||||
@ -59,9 +59,9 @@ in {
|
|||||||
type = types.attrs;
|
type = types.attrs;
|
||||||
default = {
|
default = {
|
||||||
imageName = "coredns/coredns";
|
imageName = "coredns/coredns";
|
||||||
imageDigest = "sha256:4a6e0769130686518325b21b0c1d0688b54e7c79244d48e1b15634e98e40c6ef";
|
imageDigest = "sha256:a0ead06651cf580044aeb0a0feba63591858fb2e43ade8c9dea45a6a89ae7e5e";
|
||||||
finalImageTag = version;
|
finalImageTag = version;
|
||||||
sha256 = "02r440xcdsgi137k5lmmvp0z5w5fmk8g9mysq5pnysq1wl8sj6mw";
|
sha256 = "0wg696920smmal7552a2zdhfncndn5kfammfa8bk8l7dz9bhk0y1";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -136,6 +136,11 @@ in {
|
|||||||
resources = [ "nodes" ];
|
resources = [ "nodes" ];
|
||||||
verbs = [ "get" ];
|
verbs = [ "get" ];
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
apiGroups = [ "discovery.k8s.io" ];
|
||||||
|
resources = [ "endpointslices" ];
|
||||||
|
verbs = [ "list" "watch" ];
|
||||||
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -270,7 +270,7 @@ in
|
|||||||
'';
|
'';
|
||||||
})]);
|
})]);
|
||||||
|
|
||||||
environment.etc.${cfg.etcClusterAdminKubeconfig}.source = mkIf (!isNull cfg.etcClusterAdminKubeconfig)
|
environment.etc.${cfg.etcClusterAdminKubeconfig}.source = mkIf (cfg.etcClusterAdminKubeconfig != null)
|
||||||
clusterAdminKubeconfig;
|
clusterAdminKubeconfig;
|
||||||
|
|
||||||
environment.systemPackages = mkIf (top.kubelet.enable || top.proxy.enable) [
|
environment.systemPackages = mkIf (top.kubelet.enable || top.proxy.enable) [
|
||||||
|
@ -0,0 +1,144 @@
|
|||||||
|
{ config
|
||||||
|
, lib
|
||||||
|
, pkgs
|
||||||
|
, ...
|
||||||
|
}:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.woodpecker-agents;
|
||||||
|
|
||||||
|
agentModule = lib.types.submodule {
|
||||||
|
options = {
|
||||||
|
enable = lib.mkEnableOption (lib.mdDoc "this Woodpecker-Agent. Agents execute tasks generated by a Server, every install will need one server and at least one agent");
|
||||||
|
|
||||||
|
package = lib.mkPackageOptionMD pkgs "woodpecker-agent" { };
|
||||||
|
|
||||||
|
environment = lib.mkOption {
|
||||||
|
default = { };
|
||||||
|
type = lib.types.attrsOf lib.types.str;
|
||||||
|
example = lib.literalExpression ''
|
||||||
|
{
|
||||||
|
WOODPECKER_SERVER = "localhost:9000";
|
||||||
|
WOODPECKER_BACKEND = "docker";
|
||||||
|
DOCKER_HOST = "unix:///run/podman/podman.sock";
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
description = lib.mdDoc "woodpecker-agent config envrionment variables, for other options read the [documentation](https://woodpecker-ci.org/docs/administration/agent-config)";
|
||||||
|
};
|
||||||
|
|
||||||
|
extraGroups = lib.mkOption {
|
||||||
|
type = lib.types.listOf lib.types.str;
|
||||||
|
default = [ ];
|
||||||
|
example = [ "podman" ];
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Additional groups for the systemd service.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
environmentFile = lib.mkOption {
|
||||||
|
type = lib.types.listOf lib.types.path;
|
||||||
|
default = [ ];
|
||||||
|
example = [ "/var/secrets/woodpecker-agent.env" ];
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
File to load environment variables
|
||||||
|
from. This is helpful for specifying secrets.
|
||||||
|
Example content of environmentFile:
|
||||||
|
```
|
||||||
|
WOODPECKER_AGENT_SECRET=your-shared-secret-goes-here
|
||||||
|
```
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
mkAgentService = name: agentCfg: {
|
||||||
|
name = "woodpecker-agent-${name}";
|
||||||
|
value = {
|
||||||
|
description = "Woodpecker-Agent Service - ${name}";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
after = [ "network-online.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
|
serviceConfig = {
|
||||||
|
DynamicUser = true;
|
||||||
|
SupplementaryGroups = agentCfg.extraGroups;
|
||||||
|
EnvironmentFile = agentCfg.environmentFile;
|
||||||
|
ExecStart = lib.getExe agentCfg.package;
|
||||||
|
Restart = "on-failure";
|
||||||
|
RestartSec = 15;
|
||||||
|
CapabilityBoundingSet = "";
|
||||||
|
NoNewPrivileges = true;
|
||||||
|
ProtectSystem = "strict";
|
||||||
|
PrivateTmp = true;
|
||||||
|
PrivateDevices = true;
|
||||||
|
PrivateUsers = true;
|
||||||
|
ProtectHostname = true;
|
||||||
|
ProtectClock = true;
|
||||||
|
ProtectKernelTunables = true;
|
||||||
|
ProtectKernelModules = true;
|
||||||
|
ProtectKernelLogs = true;
|
||||||
|
ProtectControlGroups = true;
|
||||||
|
RestrictAddressFamilies = [ "AF_UNIX AF_INET AF_INET6" ];
|
||||||
|
LockPersonality = true;
|
||||||
|
MemoryDenyWriteExecute = true;
|
||||||
|
RestrictRealtime = true;
|
||||||
|
RestrictSUIDSGID = true;
|
||||||
|
PrivateMounts = true;
|
||||||
|
SystemCallArchitectures = "native";
|
||||||
|
SystemCallFilter = "~@clock @privileged @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io @reboot @setuid @swap";
|
||||||
|
BindReadOnlyPaths = [
|
||||||
|
"-/etc/resolv.conf"
|
||||||
|
"-/etc/nsswitch.conf"
|
||||||
|
"-/etc/ssl/certs"
|
||||||
|
"-/etc/static/ssl/certs"
|
||||||
|
"-/etc/hosts"
|
||||||
|
"-/etc/localtime"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
inherit (agentCfg) environment;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
meta.maintainers = with lib.maintainers; [ janik ambroisie ];
|
||||||
|
|
||||||
|
options = {
|
||||||
|
services.woodpecker-agents = {
|
||||||
|
agents = lib.mkOption {
|
||||||
|
default = { };
|
||||||
|
type = lib.types.attrsOf agentModule;
|
||||||
|
example = {
|
||||||
|
docker = {
|
||||||
|
environment = {
|
||||||
|
WOODPECKER_SERVER = "localhost:9000";
|
||||||
|
WOODPECKER_BACKEND = "docker";
|
||||||
|
DOCKER_HOST = "unix:///run/podman/podman.sock";
|
||||||
|
};
|
||||||
|
|
||||||
|
extraGroups = [ "docker" ];
|
||||||
|
|
||||||
|
environmentFile = "/run/secrets/woodpecker/agent-secret.txt";
|
||||||
|
};
|
||||||
|
|
||||||
|
exec = {
|
||||||
|
environment = {
|
||||||
|
WOODPECKER_SERVER = "localhost:9000";
|
||||||
|
WOODPECKER_BACKEND = "exec";
|
||||||
|
};
|
||||||
|
|
||||||
|
environmentFile = "/run/secrets/woodpecker/agent-secret.txt";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
description = lib.mdDoc "woodpecker-agents configurations";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
systemd.services =
|
||||||
|
let
|
||||||
|
mkServices = lib.mapAttrs' mkAgentService;
|
||||||
|
enabledAgents = lib.filterAttrs (_: agent: agent.enable) cfg.agents;
|
||||||
|
in
|
||||||
|
mkServices enabledAgents;
|
||||||
|
};
|
||||||
|
}
|
@ -0,0 +1,98 @@
|
|||||||
|
{ config
|
||||||
|
, lib
|
||||||
|
, pkgs
|
||||||
|
, ...
|
||||||
|
}:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.woodpecker-server;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
meta.maintainers = with lib.maintainers; [ janik ambroisie ];
|
||||||
|
|
||||||
|
|
||||||
|
options = {
|
||||||
|
services.woodpecker-server = {
|
||||||
|
enable = lib.mkEnableOption (lib.mdDoc "the Woodpecker-Server, a CI/CD application for automatic builds, deployments and tests");
|
||||||
|
package = lib.mkPackageOptionMD pkgs "woodpecker-server" { };
|
||||||
|
environment = lib.mkOption {
|
||||||
|
default = { };
|
||||||
|
type = lib.types.attrsOf lib.types.str;
|
||||||
|
example = lib.literalExpression
|
||||||
|
''
|
||||||
|
{
|
||||||
|
WOODPECKER_HOST = "https://woodpecker.example.com";
|
||||||
|
WOODPECKER_OPEN = "true";
|
||||||
|
WOODPECKER_GITEA = "true";
|
||||||
|
WOODPECKER_GITEA_CLIENT = "ffffffff-ffff-ffff-ffff-ffffffffffff";
|
||||||
|
WOODPECKER_GITEA_URL = "https://git.example.com";
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
description = lib.mdDoc "woodpecker-server config envrionment variables, for other options read the [documentation](https://woodpecker-ci.org/docs/administration/server-config)";
|
||||||
|
};
|
||||||
|
environmentFile = lib.mkOption {
|
||||||
|
type = lib.types.nullOr lib.types.path;
|
||||||
|
default = null;
|
||||||
|
example = "/root/woodpecker-server.env";
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
File to load environment variables
|
||||||
|
from. This is helpful for specifying secrets.
|
||||||
|
Example content of environmentFile:
|
||||||
|
```
|
||||||
|
WOODPECKER_AGENT_SECRET=your-shared-secret-goes-here
|
||||||
|
WOODPECKER_GITEA_SECRET=gto_**************************************
|
||||||
|
```
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
systemd.services = {
|
||||||
|
woodpecker-server = {
|
||||||
|
description = "Woodpecker-Server Service";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
after = [ "network-online.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
|
serviceConfig = {
|
||||||
|
DynamicUser = true;
|
||||||
|
WorkingDirectory = "%S/woodpecker-server";
|
||||||
|
StateDirectory = "woodpecker-server";
|
||||||
|
StateDirectoryMode = "0700";
|
||||||
|
UMask = "0007";
|
||||||
|
ConfigurationDirectory = "woodpecker-server";
|
||||||
|
EnvironmentFile = lib.optional (cfg.environmentFile != null) cfg.environmentFile;
|
||||||
|
ExecStart = "${cfg.package}/bin/woodpecker-server";
|
||||||
|
Restart = "on-failure";
|
||||||
|
RestartSec = 15;
|
||||||
|
CapabilityBoundingSet = "";
|
||||||
|
# Security
|
||||||
|
NoNewPrivileges = true;
|
||||||
|
# Sandboxing
|
||||||
|
ProtectSystem = "strict";
|
||||||
|
ProtectHome = true;
|
||||||
|
PrivateTmp = true;
|
||||||
|
PrivateDevices = true;
|
||||||
|
PrivateUsers = true;
|
||||||
|
ProtectHostname = true;
|
||||||
|
ProtectClock = true;
|
||||||
|
ProtectKernelTunables = true;
|
||||||
|
ProtectKernelModules = true;
|
||||||
|
ProtectKernelLogs = true;
|
||||||
|
ProtectControlGroups = true;
|
||||||
|
RestrictAddressFamilies = [ "AF_UNIX AF_INET AF_INET6" ];
|
||||||
|
LockPersonality = true;
|
||||||
|
MemoryDenyWriteExecute = true;
|
||||||
|
RestrictRealtime = true;
|
||||||
|
RestrictSUIDSGID = true;
|
||||||
|
PrivateMounts = true;
|
||||||
|
# System Call Filtering
|
||||||
|
SystemCallArchitectures = "native";
|
||||||
|
SystemCallFilter = "~@clock @privileged @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io @reboot @setuid @swap";
|
||||||
|
};
|
||||||
|
inherit (cfg) environment;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -12,7 +12,7 @@ let
|
|||||||
''
|
''
|
||||||
mkdir -p $out/bin
|
mkdir -p $out/bin
|
||||||
makeWrapper ${cfg.package}/bin/dgraph $out/bin/dgraph \
|
makeWrapper ${cfg.package}/bin/dgraph $out/bin/dgraph \
|
||||||
--set PATH '${lib.makeBinPath [ pkgs.nodejs ]}:$PATH' \
|
--prefix PATH : "${lib.makeBinPath [ pkgs.nodejs ]}" \
|
||||||
'';
|
'';
|
||||||
securityOptions = {
|
securityOptions = {
|
||||||
NoNewPrivileges = true;
|
NoNewPrivileges = true;
|
||||||
|
@ -1,54 +0,0 @@
|
|||||||
{
|
|
||||||
"context.properties": {
|
|
||||||
"log.level": 0
|
|
||||||
},
|
|
||||||
"context.spa-libs": {
|
|
||||||
"audio.convert.*": "audioconvert/libspa-audioconvert",
|
|
||||||
"support.*": "support/libspa-support"
|
|
||||||
},
|
|
||||||
"context.modules": [
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-rt",
|
|
||||||
"args": {},
|
|
||||||
"flags": [
|
|
||||||
"ifexists",
|
|
||||||
"nofail"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-protocol-native"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-client-node"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-client-device"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-adapter"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-metadata"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-session-manager"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"filter.properties": {},
|
|
||||||
"stream.properties": {},
|
|
||||||
"alsa.properties": {},
|
|
||||||
"alsa.rules": [
|
|
||||||
{
|
|
||||||
"matches": [
|
|
||||||
{
|
|
||||||
"application.process.binary": "resolve"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"actions": {
|
|
||||||
"update-props": {
|
|
||||||
"alsa.buffer-bytes": 131072
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
{
|
|
||||||
"context.properties": {
|
|
||||||
"log.level": 0
|
|
||||||
},
|
|
||||||
"context.spa-libs": {
|
|
||||||
"audio.convert.*": "audioconvert/libspa-audioconvert",
|
|
||||||
"support.*": "support/libspa-support"
|
|
||||||
},
|
|
||||||
"context.modules": [
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-protocol-native"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-client-node"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-client-device"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-adapter"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-metadata"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-session-manager"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"filter.properties": {},
|
|
||||||
"stream.properties": {}
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
{
|
|
||||||
"context.properties": {
|
|
||||||
"log.level": 0
|
|
||||||
},
|
|
||||||
"context.spa-libs": {
|
|
||||||
"audio.convert.*": "audioconvert/libspa-audioconvert",
|
|
||||||
"support.*": "support/libspa-support"
|
|
||||||
},
|
|
||||||
"context.modules": [
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-rt",
|
|
||||||
"args": {},
|
|
||||||
"flags": [
|
|
||||||
"ifexists",
|
|
||||||
"nofail"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-protocol-native"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-client-node"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-adapter"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,75 +0,0 @@
|
|||||||
{
|
|
||||||
"context.properties": {
|
|
||||||
"log.level": 0
|
|
||||||
},
|
|
||||||
"context.spa-libs": {
|
|
||||||
"support.*": "support/libspa-support"
|
|
||||||
},
|
|
||||||
"context.modules": [
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-rt",
|
|
||||||
"args": {},
|
|
||||||
"flags": [
|
|
||||||
"ifexists",
|
|
||||||
"nofail"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-protocol-native"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-client-node"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-metadata"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"jack.properties": {},
|
|
||||||
"jack.rules": [
|
|
||||||
{
|
|
||||||
"matches": [
|
|
||||||
{}
|
|
||||||
],
|
|
||||||
"actions": {
|
|
||||||
"update-props": {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"matches": [
|
|
||||||
{
|
|
||||||
"application.process.binary": "jack_bufsize"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"actions": {
|
|
||||||
"update-props": {
|
|
||||||
"jack.global-buffer-size": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"matches": [
|
|
||||||
{
|
|
||||||
"application.process.binary": "qsynth"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"actions": {
|
|
||||||
"update-props": {
|
|
||||||
"node.pause-on-idle": false,
|
|
||||||
"node.passive": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"matches": [
|
|
||||||
{
|
|
||||||
"client.name": "Mixxx"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"actions": {
|
|
||||||
"update-props": {
|
|
||||||
"jack.merge-monitor": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,120 +0,0 @@
|
|||||||
{
|
|
||||||
"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,
|
|
||||||
"control": 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,
|
|
||||||
"control": false,
|
|
||||||
"position": "unknown"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"context.exec": []
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
{
|
|
||||||
"context.properties": {},
|
|
||||||
"context.modules": [
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-rt",
|
|
||||||
"args": {
|
|
||||||
"nice.level": -11
|
|
||||||
},
|
|
||||||
"flags": [
|
|
||||||
"ifexists",
|
|
||||||
"nofail"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-protocol-native"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-client-node"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-adapter"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-rtp-source",
|
|
||||||
"args": {
|
|
||||||
"sap.ip": "239.255.255.255",
|
|
||||||
"sap.port": 9875,
|
|
||||||
"sess.latency.msec": 10,
|
|
||||||
"local.ifname": "eth0",
|
|
||||||
"stream.props": {
|
|
||||||
"media.class": "Audio/Source",
|
|
||||||
"node.virtual": false,
|
|
||||||
"device.api": "aes67"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
{
|
|
||||||
"context.properties": {},
|
|
||||||
"context.spa-libs": {
|
|
||||||
"audio.convert.*": "audioconvert/libspa-audioconvert",
|
|
||||||
"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-client-node"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-adapter"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-avb",
|
|
||||||
"args": {}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"context.exec": [],
|
|
||||||
"stream.properties": {},
|
|
||||||
"avb.properties": {
|
|
||||||
"ifname": "enp3s0",
|
|
||||||
"vm.overrides": {}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,106 +0,0 @@
|
|||||||
{
|
|
||||||
"context.properties": {},
|
|
||||||
"context.spa-libs": {
|
|
||||||
"audio.convert.*": "audioconvert/libspa-audioconvert",
|
|
||||||
"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-client-node"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-adapter"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-metadata"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-protocol-pulse",
|
|
||||||
"args": {}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"context.exec": [],
|
|
||||||
"pulse.cmd": [
|
|
||||||
{
|
|
||||||
"cmd": "load-module",
|
|
||||||
"args": "module-always-sink",
|
|
||||||
"flags": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"stream.properties": {},
|
|
||||||
"pulse.properties": {
|
|
||||||
"server.address": [
|
|
||||||
"unix:native"
|
|
||||||
],
|
|
||||||
"vm.overrides": {
|
|
||||||
"pulse.min.quantum": "1024/48000"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pulse.rules": [
|
|
||||||
{
|
|
||||||
"matches": [
|
|
||||||
{}
|
|
||||||
],
|
|
||||||
"actions": {
|
|
||||||
"update-props": {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"matches": [
|
|
||||||
{
|
|
||||||
"application.process.binary": "teams"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"application.process.binary": "teams-insiders"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"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": "512/48000",
|
|
||||||
"pulse.min.quantum": "512/48000",
|
|
||||||
"pulse.idle.timeout": 5
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,110 +0,0 @@
|
|||||||
{
|
|
||||||
"context.properties": {
|
|
||||||
"link.max-buffers": 16,
|
|
||||||
"core.daemon": true,
|
|
||||||
"core.name": "pipewire-0",
|
|
||||||
"vm.overrides": {
|
|
||||||
"default.clock.min-quantum": 1024
|
|
||||||
},
|
|
||||||
"module.x11.bell": true
|
|
||||||
},
|
|
||||||
"context.spa-libs": {
|
|
||||||
"audio.convert.*": "audioconvert/libspa-audioconvert",
|
|
||||||
"avb.*": "avb/libspa-avb",
|
|
||||||
"api.alsa.*": "alsa/libspa-alsa",
|
|
||||||
"api.v4l2.*": "v4l2/libspa-v4l2",
|
|
||||||
"api.libcamera.*": "libcamera/libspa-libcamera",
|
|
||||||
"api.bluez5.*": "bluez5/libspa-bluez5",
|
|
||||||
"api.vulkan.*": "vulkan/libspa-vulkan",
|
|
||||||
"api.jack.*": "jack/libspa-jack",
|
|
||||||
"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-device-factory"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-spa-node-factory"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-client-node"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-client-device"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-portal",
|
|
||||||
"flags": [
|
|
||||||
"ifexists",
|
|
||||||
"nofail"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-access",
|
|
||||||
"args": {}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-adapter"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-link-factory"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-session-manager"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-x11-bell",
|
|
||||||
"args": {},
|
|
||||||
"flags": [
|
|
||||||
"ifexists",
|
|
||||||
"nofail"
|
|
||||||
],
|
|
||||||
"condition": [
|
|
||||||
{
|
|
||||||
"module.x11.bell": true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"context.objects": [
|
|
||||||
{
|
|
||||||
"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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"context.exec": []
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
{
|
|
||||||
"properties": {},
|
|
||||||
"rules": [
|
|
||||||
{
|
|
||||||
"matches": [
|
|
||||||
{
|
|
||||||
"device.name": "~alsa_card.*"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"actions": {
|
|
||||||
"update-props": {
|
|
||||||
"api.alsa.use-acp": true,
|
|
||||||
"api.acp.auto-profile": false,
|
|
||||||
"api.acp.auto-port": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"matches": [
|
|
||||||
{
|
|
||||||
"node.name": "~alsa_input.*"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"node.name": "~alsa_output.*"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"actions": {
|
|
||||||
"update-props": {
|
|
||||||
"node.pause-on-idle": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,36 +0,0 @@
|
|||||||
{
|
|
||||||
"properties": {},
|
|
||||||
"rules": [
|
|
||||||
{
|
|
||||||
"matches": [
|
|
||||||
{
|
|
||||||
"device.name": "~bluez_card.*"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"actions": {
|
|
||||||
"update-props": {
|
|
||||||
"bluez5.auto-connect": [
|
|
||||||
"hfp_hf",
|
|
||||||
"hsp_hs",
|
|
||||||
"a2dp_sink"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"matches": [
|
|
||||||
{
|
|
||||||
"node.name": "~bluez_input.*"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"node.name": "~bluez_output.*"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"actions": {
|
|
||||||
"update-props": {
|
|
||||||
"node.pause-on-idle": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,68 +0,0 @@
|
|||||||
{
|
|
||||||
"context.properties": {},
|
|
||||||
"context.spa-libs": {
|
|
||||||
"api.bluez5.*": "bluez5/libspa-bluez5",
|
|
||||||
"api.alsa.*": "alsa/libspa-alsa",
|
|
||||||
"api.v4l2.*": "v4l2/libspa-v4l2",
|
|
||||||
"api.libcamera.*": "libcamera/libspa-libcamera"
|
|
||||||
},
|
|
||||||
"context.modules": [
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-rtkit",
|
|
||||||
"args": {},
|
|
||||||
"flags": [
|
|
||||||
"ifexists",
|
|
||||||
"nofail"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-protocol-native"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-client-node"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-client-device"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-adapter"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-metadata"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "libpipewire-module-session-manager"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"session.modules": {
|
|
||||||
"default": [
|
|
||||||
"flatpak",
|
|
||||||
"portal",
|
|
||||||
"v4l2",
|
|
||||||
"suspend-node",
|
|
||||||
"policy-node"
|
|
||||||
],
|
|
||||||
"with-audio": [
|
|
||||||
"metadata",
|
|
||||||
"default-nodes",
|
|
||||||
"default-profile",
|
|
||||||
"default-routes",
|
|
||||||
"alsa-seq",
|
|
||||||
"alsa-monitor"
|
|
||||||
],
|
|
||||||
"with-alsa": [
|
|
||||||
"with-audio"
|
|
||||||
],
|
|
||||||
"with-jack": [
|
|
||||||
"with-audio"
|
|
||||||
],
|
|
||||||
"with-pulseaudio": [
|
|
||||||
"with-audio",
|
|
||||||
"bluez5",
|
|
||||||
"bluez5-autoswitch",
|
|
||||||
"logind",
|
|
||||||
"restore-stream",
|
|
||||||
"streams-follow-default"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
{
|
|
||||||
"properties": {},
|
|
||||||
"rules": [
|
|
||||||
{
|
|
||||||
"matches": [
|
|
||||||
{
|
|
||||||
"device.name": "~v4l2_device.*"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"actions": {
|
|
||||||
"update-props": {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"matches": [
|
|
||||||
{
|
|
||||||
"node.name": "~v4l2_input.*"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"node.name": "~v4l2_output.*"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"actions": {
|
|
||||||
"update-props": {
|
|
||||||
"node.pause-on-idle": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,141 +0,0 @@
|
|||||||
# pipewire example session manager.
|
|
||||||
{ config, lib, pkgs, ... }:
|
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
let
|
|
||||||
json = pkgs.formats.json {};
|
|
||||||
cfg = config.services.pipewire.media-session;
|
|
||||||
enable32BitAlsaPlugins = cfg.alsa.support32Bit
|
|
||||||
&& pkgs.stdenv.isx86_64
|
|
||||||
&& pkgs.pkgsi686Linux.pipewire != null;
|
|
||||||
|
|
||||||
# Use upstream config files passed through spa-json-dump as the base
|
|
||||||
# Patched here as necessary for them to work with this module
|
|
||||||
defaults = {
|
|
||||||
alsa-monitor = lib.importJSON ./media-session/alsa-monitor.conf.json;
|
|
||||||
bluez-monitor = lib.importJSON ./media-session/bluez-monitor.conf.json;
|
|
||||||
media-session = lib.importJSON ./media-session/media-session.conf.json;
|
|
||||||
v4l2-monitor = lib.importJSON ./media-session/v4l2-monitor.conf.json;
|
|
||||||
};
|
|
||||||
|
|
||||||
configs = {
|
|
||||||
alsa-monitor = recursiveUpdate defaults.alsa-monitor cfg.config.alsa-monitor;
|
|
||||||
bluez-monitor = recursiveUpdate defaults.bluez-monitor cfg.config.bluez-monitor;
|
|
||||||
media-session = recursiveUpdate defaults.media-session cfg.config.media-session;
|
|
||||||
v4l2-monitor = recursiveUpdate defaults.v4l2-monitor cfg.config.v4l2-monitor;
|
|
||||||
};
|
|
||||||
in {
|
|
||||||
|
|
||||||
meta = {
|
|
||||||
maintainers = teams.freedesktop.members;
|
|
||||||
# uses attributes of the linked package
|
|
||||||
buildDocsInSandbox = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
###### interface
|
|
||||||
options = {
|
|
||||||
services.pipewire.media-session = {
|
|
||||||
enable = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = lib.mdDoc "Whether to enable the deprecated example Pipewire session manager";
|
|
||||||
};
|
|
||||||
|
|
||||||
package = mkOption {
|
|
||||||
type = types.package;
|
|
||||||
default = pkgs.pipewire-media-session;
|
|
||||||
defaultText = literalExpression "pkgs.pipewire-media-session";
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
The pipewire-media-session derivation to use.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
config = {
|
|
||||||
media-session = mkOption {
|
|
||||||
type = json.type;
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
Configuration for the media session core. For details see
|
|
||||||
https://gitlab.freedesktop.org/pipewire/media-session/-/blob/${cfg.package.version}/src/daemon/media-session.d/media-session.conf
|
|
||||||
'';
|
|
||||||
default = defaults.media-session;
|
|
||||||
};
|
|
||||||
|
|
||||||
alsa-monitor = mkOption {
|
|
||||||
type = json.type;
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
Configuration for the alsa monitor. For details see
|
|
||||||
https://gitlab.freedesktop.org/pipewire/media-session/-/blob/${cfg.package.version}/src/daemon/media-session.d/alsa-monitor.conf
|
|
||||||
'';
|
|
||||||
default = defaults.alsa-monitor;
|
|
||||||
};
|
|
||||||
|
|
||||||
bluez-monitor = mkOption {
|
|
||||||
type = json.type;
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
Configuration for the bluez5 monitor. For details see
|
|
||||||
https://gitlab.freedesktop.org/pipewire/media-session/-/blob/${cfg.package.version}/src/daemon/media-session.d/bluez-monitor.conf
|
|
||||||
'';
|
|
||||||
default = defaults.bluez-monitor;
|
|
||||||
};
|
|
||||||
|
|
||||||
v4l2-monitor = mkOption {
|
|
||||||
type = json.type;
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
Configuration for the V4L2 monitor. For details see
|
|
||||||
https://gitlab.freedesktop.org/pipewire/media-session/-/blob/${cfg.package.version}/src/daemon/media-session.d/v4l2-monitor.conf
|
|
||||||
'';
|
|
||||||
default = defaults.v4l2-monitor;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
###### implementation
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
environment.systemPackages = [ cfg.package ];
|
|
||||||
systemd.packages = [ cfg.package ];
|
|
||||||
|
|
||||||
# Enable either system or user units.
|
|
||||||
systemd.services.pipewire-media-session.enable = config.services.pipewire.systemWide;
|
|
||||||
systemd.user.services.pipewire-media-session.enable = !config.services.pipewire.systemWide;
|
|
||||||
|
|
||||||
systemd.services.pipewire-media-session.wantedBy = [ "pipewire.service" ];
|
|
||||||
systemd.user.services.pipewire-media-session.wantedBy = [ "pipewire.service" ];
|
|
||||||
|
|
||||||
environment.etc."pipewire/media-session.d/media-session.conf" = {
|
|
||||||
source = json.generate "media-session.conf" configs.media-session;
|
|
||||||
};
|
|
||||||
environment.etc."pipewire/media-session.d/v4l2-monitor.conf" = {
|
|
||||||
source = json.generate "v4l2-monitor.conf" configs.v4l2-monitor;
|
|
||||||
};
|
|
||||||
|
|
||||||
environment.etc."pipewire/media-session.d/with-audio" =
|
|
||||||
mkIf config.services.pipewire.audio.enable {
|
|
||||||
text = "";
|
|
||||||
};
|
|
||||||
|
|
||||||
environment.etc."pipewire/media-session.d/with-alsa" =
|
|
||||||
mkIf config.services.pipewire.alsa.enable {
|
|
||||||
text = "";
|
|
||||||
};
|
|
||||||
environment.etc."pipewire/media-session.d/alsa-monitor.conf" =
|
|
||||||
mkIf config.services.pipewire.alsa.enable {
|
|
||||||
source = json.generate "alsa-monitor.conf" configs.alsa-monitor;
|
|
||||||
};
|
|
||||||
|
|
||||||
environment.etc."pipewire/media-session.d/with-pulseaudio" =
|
|
||||||
mkIf config.services.pipewire.pulse.enable {
|
|
||||||
text = "";
|
|
||||||
};
|
|
||||||
environment.etc."pipewire/media-session.d/bluez-monitor.conf" =
|
|
||||||
mkIf config.services.pipewire.pulse.enable {
|
|
||||||
source = json.generate "bluez-monitor.conf" configs.bluez-monitor;
|
|
||||||
};
|
|
||||||
|
|
||||||
environment.etc."pipewire/media-session.d/with-jack" =
|
|
||||||
mkIf config.services.pipewire.jack.enable {
|
|
||||||
text = "";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
@ -4,7 +4,6 @@
|
|||||||
with lib;
|
with lib;
|
||||||
|
|
||||||
let
|
let
|
||||||
json = pkgs.formats.json {};
|
|
||||||
cfg = config.services.pipewire;
|
cfg = config.services.pipewire;
|
||||||
enable32BitAlsaPlugins = cfg.alsa.support32Bit
|
enable32BitAlsaPlugins = cfg.alsa.support32Bit
|
||||||
&& pkgs.stdenv.isx86_64
|
&& pkgs.stdenv.isx86_64
|
||||||
@ -18,34 +17,8 @@ let
|
|||||||
mkdir -p "$out/lib"
|
mkdir -p "$out/lib"
|
||||||
ln -s "${cfg.package.jack}/lib" "$out/lib/pipewire"
|
ln -s "${cfg.package.jack}/lib" "$out/lib/pipewire"
|
||||||
'';
|
'';
|
||||||
|
|
||||||
# Use upstream config files passed through spa-json-dump as the base
|
|
||||||
# Patched here as necessary for them to work with this module
|
|
||||||
defaults = {
|
|
||||||
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 (if useSessionManager then defaults.pipewire else defaults.minimal) cfg.config.pipewire;
|
|
||||||
pipewire-pulse = recursiveUpdate defaults.pipewire-pulse cfg.config.pipewire-pulse;
|
|
||||||
};
|
|
||||||
in {
|
in {
|
||||||
|
meta.maintainers = teams.freedesktop.members ++ [ lib.maintainers.k900 ];
|
||||||
meta = {
|
|
||||||
maintainers = teams.freedesktop.members ++ [ lib.maintainers.k900 ];
|
|
||||||
# uses attributes of the linked package
|
|
||||||
buildDocsInSandbox = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
###### interface
|
###### interface
|
||||||
options = {
|
options = {
|
||||||
@ -69,53 +42,6 @@ in {
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
config = {
|
|
||||||
client = mkOption {
|
|
||||||
type = json.type;
|
|
||||||
default = {};
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
Configuration for pipewire clients. For details see
|
|
||||||
https://gitlab.freedesktop.org/pipewire/pipewire/-/blob/${cfg.package.version}/src/daemon/client.conf.in
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
client-rt = mkOption {
|
|
||||||
type = json.type;
|
|
||||||
default = {};
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
Configuration for realtime pipewire clients. For details see
|
|
||||||
https://gitlab.freedesktop.org/pipewire/pipewire/-/blob/${cfg.package.version}/src/daemon/client-rt.conf.in
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
jack = mkOption {
|
|
||||||
type = json.type;
|
|
||||||
default = {};
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
Configuration for the pipewire daemon's jack module. For details see
|
|
||||||
https://gitlab.freedesktop.org/pipewire/pipewire/-/blob/${cfg.package.version}/src/daemon/jack.conf.in
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
pipewire = mkOption {
|
|
||||||
type = json.type;
|
|
||||||
default = {};
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
Configuration for the pipewire daemon. For details see
|
|
||||||
https://gitlab.freedesktop.org/pipewire/pipewire/-/blob/${cfg.package.version}/src/daemon/pipewire.conf.in
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
pipewire-pulse = mkOption {
|
|
||||||
type = json.type;
|
|
||||||
default = {};
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
Configuration for the pipewire-pulse daemon. For details see
|
|
||||||
https://gitlab.freedesktop.org/pipewire/pipewire/-/blob/${cfg.package.version}/src/daemon/pipewire-pulse.conf.in
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
audio = {
|
audio = {
|
||||||
enable = lib.mkOption {
|
enable = lib.mkOption {
|
||||||
type = lib.types.bool;
|
type = lib.types.bool;
|
||||||
@ -153,10 +79,20 @@ in {
|
|||||||
https://github.com/PipeWire/pipewire/blob/master/NEWS
|
https://github.com/PipeWire/pipewire/blob/master/NEWS
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
imports = [
|
||||||
|
(lib.mkRemovedOptionModule ["services" "pipewire" "config"] ''
|
||||||
|
Overriding default Pipewire configuration through NixOS options never worked correctly and is no longer supported.
|
||||||
|
Please create drop-in files in /etc/pipewire/pipewire.conf.d/ to make the desired setting changes instead.
|
||||||
|
'')
|
||||||
|
|
||||||
|
(lib.mkRemovedOptionModule ["services" "pipewire" "media-session"] ''
|
||||||
|
pipewire-media-session is no longer supported upstream and has been removed.
|
||||||
|
Please switch to `services.pipewire.wireplumber` instead.
|
||||||
|
'')
|
||||||
|
];
|
||||||
|
|
||||||
###### implementation
|
###### implementation
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
@ -222,22 +158,6 @@ in {
|
|||||||
source = "${cfg.package}/share/alsa/alsa.conf.d/99-pipewire-default.conf";
|
source = "${cfg.package}/share/alsa/alsa.conf.d/99-pipewire-default.conf";
|
||||||
};
|
};
|
||||||
|
|
||||||
environment.etc."pipewire/client.conf" = {
|
|
||||||
source = json.generate "client.conf" configs.client;
|
|
||||||
};
|
|
||||||
environment.etc."pipewire/client-rt.conf" = {
|
|
||||||
source = json.generate "client-rt.conf" configs.client-rt;
|
|
||||||
};
|
|
||||||
environment.etc."pipewire/jack.conf" = {
|
|
||||||
source = json.generate "jack.conf" configs.jack;
|
|
||||||
};
|
|
||||||
environment.etc."pipewire/pipewire.conf" = {
|
|
||||||
source = json.generate "pipewire.conf" configs.pipewire;
|
|
||||||
};
|
|
||||||
environment.etc."pipewire/pipewire-pulse.conf" = mkIf cfg.pulse.enable {
|
|
||||||
source = json.generate "pipewire-pulse.conf" configs.pipewire-pulse;
|
|
||||||
};
|
|
||||||
|
|
||||||
environment.sessionVariables.LD_LIBRARY_PATH =
|
environment.sessionVariables.LD_LIBRARY_PATH =
|
||||||
lib.mkIf cfg.jack.enable [ "${cfg.package.jack}/lib" ];
|
lib.mkIf cfg.jack.enable [ "${cfg.package.jack}/lib" ];
|
||||||
|
|
||||||
@ -256,12 +176,5 @@ in {
|
|||||||
};
|
};
|
||||||
groups.pipewire.gid = config.ids.gids.pipewire;
|
groups.pipewire.gid = config.ids.gids.pipewire;
|
||||||
};
|
};
|
||||||
|
|
||||||
# https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/464#note_723554
|
|
||||||
systemd.services.pipewire.environment."PIPEWIRE_LINK_PASSIVE" = "1";
|
|
||||||
systemd.user.services.pipewire.environment."PIPEWIRE_LINK_PASSIVE" = "1";
|
|
||||||
|
|
||||||
# pipewire-pulse default config expects pactl to be in PATH
|
|
||||||
systemd.user.services.pipewire-pulse.path = lib.mkIf cfg.pulse.enable [ pkgs.pulseaudio ];
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -28,10 +28,6 @@ in
|
|||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
assertions = [
|
assertions = [
|
||||||
{
|
|
||||||
assertion = !config.services.pipewire.media-session.enable;
|
|
||||||
message = "WirePlumber and pipewire-media-session can't be enabled at the same time.";
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
assertion = !config.hardware.bluetooth.hsphfpd.enable;
|
assertion = !config.hardware.bluetooth.hsphfpd.enable;
|
||||||
message = "Using Wireplumber conflicts with hsphfpd, as it provides the same functionality. `hardware.bluetooth.hsphfpd.enable` needs be set to false";
|
message = "Using Wireplumber conflicts with hsphfpd, as it provides the same functionality. `hardware.bluetooth.hsphfpd.enable` needs be set to false";
|
||||||
|
@ -86,6 +86,7 @@ let
|
|||||||
mkService = name: keyboard: nameValuePair (mkName name) {
|
mkService = name: keyboard: nameValuePair (mkName name) {
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
|
Type = "notify";
|
||||||
ExecStart = ''
|
ExecStart = ''
|
||||||
${getExe cfg.package} \
|
${getExe cfg.package} \
|
||||||
--cfg ${mkConfig name keyboard} \
|
--cfg ${mkConfig name keyboard} \
|
||||||
@ -123,8 +124,7 @@ let
|
|||||||
ProtectKernelModules = true;
|
ProtectKernelModules = true;
|
||||||
ProtectKernelTunables = true;
|
ProtectKernelTunables = true;
|
||||||
ProtectProc = "invisible";
|
ProtectProc = "invisible";
|
||||||
RestrictAddressFamilies =
|
RestrictAddressFamilies = [ "AF_UNIX" ] ++ optional (keyboard.port != null) "AF_INET";
|
||||||
if (keyboard.port == null) then "none" else [ "AF_INET" ];
|
|
||||||
RestrictNamespaces = true;
|
RestrictNamespaces = true;
|
||||||
RestrictRealtime = true;
|
RestrictRealtime = true;
|
||||||
SystemCallArchitectures = [ "native" ];
|
SystemCallArchitectures = [ "native" ];
|
||||||
|
112
nixos/modules/services/hardware/keyd.nix
Normal file
112
nixos/modules/services/hardware/keyd.nix
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.services.keyd;
|
||||||
|
settingsFormat = pkgs.formats.ini { };
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
services.keyd = {
|
||||||
|
enable = mkEnableOption (lib.mdDoc "keyd, a key remapping daemon");
|
||||||
|
|
||||||
|
ids = mkOption {
|
||||||
|
type = types.listOf types.string;
|
||||||
|
default = [ "*" ];
|
||||||
|
example = [ "*" "-0123:0456" ];
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Device identifiers, as shown by {manpage}`keyd(1)`.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
settings = mkOption {
|
||||||
|
type = settingsFormat.type;
|
||||||
|
default = { };
|
||||||
|
example = {
|
||||||
|
main = {
|
||||||
|
capslock = "overload(control, esc)";
|
||||||
|
rightalt = "layer(rightalt)";
|
||||||
|
};
|
||||||
|
|
||||||
|
rightalt = {
|
||||||
|
j = "down";
|
||||||
|
k = "up";
|
||||||
|
h = "left";
|
||||||
|
l = "right";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Configuration, except `ids` section, that is written to {file}`/etc/keyd/default.conf`.
|
||||||
|
See <https://github.com/rvaiya/keyd> how to configure.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
environment.etc."keyd/default.conf".source = pkgs.runCommand "default.conf"
|
||||||
|
{
|
||||||
|
ids = ''
|
||||||
|
[ids]
|
||||||
|
${concatStringsSep "\n" cfg.ids}
|
||||||
|
'';
|
||||||
|
passAsFile = [ "ids" ];
|
||||||
|
} ''
|
||||||
|
cat $idsPath <(echo) ${settingsFormat.generate "keyd-main.conf" cfg.settings} >$out
|
||||||
|
'';
|
||||||
|
|
||||||
|
hardware.uinput.enable = lib.mkDefault true;
|
||||||
|
|
||||||
|
systemd.services.keyd = {
|
||||||
|
description = "Keyd remapping daemon";
|
||||||
|
documentation = [ "man:keyd(1)" ];
|
||||||
|
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
|
||||||
|
restartTriggers = [
|
||||||
|
config.environment.etc."keyd/default.conf".source
|
||||||
|
];
|
||||||
|
|
||||||
|
# this is configurable in 2.4.2, later versions seem to remove this option.
|
||||||
|
# post-2.4.2 may need to set makeFlags in the derivation:
|
||||||
|
#
|
||||||
|
# makeFlags = [ "SOCKET_PATH/run/keyd/keyd.socket" ];
|
||||||
|
environment.KEYD_SOCKET = "/run/keyd/keyd.sock";
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart = "${pkgs.keyd}/bin/keyd";
|
||||||
|
Restart = "always";
|
||||||
|
|
||||||
|
DynamicUser = true;
|
||||||
|
SupplementaryGroups = [
|
||||||
|
config.users.groups.input.name
|
||||||
|
config.users.groups.uinput.name
|
||||||
|
];
|
||||||
|
|
||||||
|
RuntimeDirectory = "keyd";
|
||||||
|
|
||||||
|
# Hardening
|
||||||
|
CapabilityBoundingSet = "";
|
||||||
|
DeviceAllow = [
|
||||||
|
"char-input rw"
|
||||||
|
"/dev/uinput rw"
|
||||||
|
];
|
||||||
|
ProtectClock = true;
|
||||||
|
PrivateNetwork = true;
|
||||||
|
ProtectHome = true;
|
||||||
|
ProtectHostname = true;
|
||||||
|
PrivateUsers = true;
|
||||||
|
PrivateMounts = true;
|
||||||
|
RestrictNamespaces = true;
|
||||||
|
ProtectKernelLogs = true;
|
||||||
|
ProtectKernelModules = true;
|
||||||
|
ProtectKernelTunables = true;
|
||||||
|
ProtectControlGroups = true;
|
||||||
|
MemoryDenyWriteExecute = true;
|
||||||
|
RestrictRealtime = true;
|
||||||
|
LockPersonality = true;
|
||||||
|
ProtectProc = "noaccess";
|
||||||
|
UMask = "0077";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
@ -32,6 +32,7 @@ in
|
|||||||
|
|
||||||
systemd.packages = [ pkgs.supergfxctl ];
|
systemd.packages = [ pkgs.supergfxctl ];
|
||||||
systemd.services.supergfxd.wantedBy = [ "multi-user.target" ];
|
systemd.services.supergfxd.wantedBy = [ "multi-user.target" ];
|
||||||
|
systemd.services.supergfxd.path = [ pkgs.kmod ];
|
||||||
|
|
||||||
services.dbus.packages = [ pkgs.supergfxctl ];
|
services.dbus.packages = [ pkgs.supergfxctl ];
|
||||||
services.udev.packages = [ pkgs.supergfxctl ];
|
services.udev.packages = [ pkgs.supergfxctl ];
|
||||||
|
@ -5,8 +5,8 @@ let
|
|||||||
cfg = config.services.undervolt;
|
cfg = config.services.undervolt;
|
||||||
|
|
||||||
mkPLimit = limit: window:
|
mkPLimit = limit: window:
|
||||||
if (isNull limit && isNull window) then null
|
if (limit == null && window == null) then null
|
||||||
else assert asserts.assertMsg (!isNull limit && !isNull window) "Both power limit and window must be set";
|
else assert asserts.assertMsg (limit != null && window != null) "Both power limit and window must be set";
|
||||||
"${toString limit} ${toString window}";
|
"${toString limit} ${toString window}";
|
||||||
cliArgs = lib.cli.toGNUCommandLine {} {
|
cliArgs = lib.cli.toGNUCommandLine {} {
|
||||||
inherit (cfg)
|
inherit (cfg)
|
||||||
|
@ -362,7 +362,7 @@ in {
|
|||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
assertions = [
|
assertions = [
|
||||||
{
|
{
|
||||||
assertion = cfg.openFirewall -> !isNull cfg.config;
|
assertion = cfg.openFirewall -> cfg.config != null;
|
||||||
message = "openFirewall can only be used with a declarative config";
|
message = "openFirewall can only be used with a declarative config";
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
@ -187,7 +187,7 @@ in
|
|||||||
A configuration file automatically generated by NixOS.
|
A configuration file automatically generated by NixOS.
|
||||||
'';
|
'';
|
||||||
description = lib.mdDoc ''
|
description = lib.mdDoc ''
|
||||||
Override the configuration file used by MySQL. By default,
|
Override the configuration file used by logrotate. By default,
|
||||||
NixOS generates one automatically from [](#opt-services.logrotate.settings).
|
NixOS generates one automatically from [](#opt-services.logrotate.settings).
|
||||||
'';
|
'';
|
||||||
example = literalExpression ''
|
example = literalExpression ''
|
||||||
|
@ -132,6 +132,8 @@ in
|
|||||||
$config['plugins'] = [${concatMapStringsSep "," (p: "'${p}'") cfg.plugins}];
|
$config['plugins'] = [${concatMapStringsSep "," (p: "'${p}'") cfg.plugins}];
|
||||||
$config['des_key'] = file_get_contents('/var/lib/roundcube/des_key');
|
$config['des_key'] = file_get_contents('/var/lib/roundcube/des_key');
|
||||||
$config['mime_types'] = '${pkgs.nginx}/conf/mime.types';
|
$config['mime_types'] = '${pkgs.nginx}/conf/mime.types';
|
||||||
|
# Roundcube uses PHP-FPM which has `PrivateTmp = true;`
|
||||||
|
$config['temp_dir'] = '/tmp';
|
||||||
$config['enable_spellcheck'] = ${if cfg.dicts == [] then "false" else "true"};
|
$config['enable_spellcheck'] = ${if cfg.dicts == [] then "false" else "true"};
|
||||||
# by default, spellchecking uses a third-party cloud services
|
# by default, spellchecking uses a third-party cloud services
|
||||||
$config['spellcheck_engine'] = 'pspell';
|
$config['spellcheck_engine'] = 'pspell';
|
||||||
|
@ -27,10 +27,7 @@ please refer to the
|
|||||||
{ pkgs, lib, config, ... }:
|
{ pkgs, lib, config, ... }:
|
||||||
let
|
let
|
||||||
fqdn = "${config.networking.hostName}.${config.networking.domain}";
|
fqdn = "${config.networking.hostName}.${config.networking.domain}";
|
||||||
clientConfig = {
|
clientConfig."m.homeserver".base_url = "https://${fqdn}";
|
||||||
"m.homeserver".base_url = "https://${fqdn}";
|
|
||||||
"m.identity_server" = {};
|
|
||||||
};
|
|
||||||
serverConfig."m.server" = "${fqdn}:443";
|
serverConfig."m.server" = "${fqdn}:443";
|
||||||
mkWellKnown = data: ''
|
mkWellKnown = data: ''
|
||||||
add_header Content-Type application/json;
|
add_header Content-Type application/json;
|
||||||
|
@ -60,7 +60,7 @@ in {
|
|||||||
'')
|
'')
|
||||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "create_local_database" ] ''
|
(mkRemovedOptionModule [ "services" "matrix-synapse" "create_local_database" ] ''
|
||||||
Database configuration must be done manually. An exemplary setup is demonstrated in
|
Database configuration must be done manually. An exemplary setup is demonstrated in
|
||||||
<nixpkgs/nixos/tests/matrix-synapse.nix>
|
<nixpkgs/nixos/tests/matrix/synapse.nix>
|
||||||
'')
|
'')
|
||||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "web_client" ] "")
|
(mkRemovedOptionModule [ "services" "matrix-synapse" "web_client" ] "")
|
||||||
(mkRemovedOptionModule [ "services" "matrix-synapse" "room_invite_state_types" ] ''
|
(mkRemovedOptionModule [ "services" "matrix-synapse" "room_invite_state_types" ] ''
|
||||||
@ -711,7 +711,7 @@ in {
|
|||||||
|
|
||||||
If you
|
If you
|
||||||
- try to deploy a fresh synapse, you need to configure the database yourself. An example
|
- 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>
|
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`
|
- update your existing matrix-synapse instance, you simply need to add `services.postgresql.enable = true`
|
||||||
to your configuration.
|
to your configuration.
|
||||||
|
|
||||||
|
@ -365,6 +365,8 @@ in
|
|||||||
];
|
];
|
||||||
|
|
||||||
services.gitea.settings = {
|
services.gitea.settings = {
|
||||||
|
"cron.update_checker".ENABLED = lib.mkDefault false;
|
||||||
|
|
||||||
database = mkMerge [
|
database = mkMerge [
|
||||||
{
|
{
|
||||||
DB_TYPE = cfg.database.type;
|
DB_TYPE = cfg.database.type;
|
||||||
|
@ -156,7 +156,7 @@ let
|
|||||||
};
|
};
|
||||||
extra = {};
|
extra = {};
|
||||||
uploads.storage_path = cfg.statePath;
|
uploads.storage_path = cfg.statePath;
|
||||||
pages = {
|
pages = optionalAttrs cfg.pages.enable {
|
||||||
enabled = cfg.pages.enable;
|
enabled = cfg.pages.enable;
|
||||||
port = 8090;
|
port = 8090;
|
||||||
host = cfg.pages.settings.pages-domain;
|
host = cfg.pages.settings.pages-domain;
|
||||||
|
@ -238,7 +238,7 @@ in
|
|||||||
PORTUNUS_SERVER_BINARY = "${cfg.package}/bin/portunus-server";
|
PORTUNUS_SERVER_BINARY = "${cfg.package}/bin/portunus-server";
|
||||||
PORTUNUS_SERVER_GROUP = cfg.group;
|
PORTUNUS_SERVER_GROUP = cfg.group;
|
||||||
PORTUNUS_SERVER_USER = cfg.user;
|
PORTUNUS_SERVER_USER = cfg.user;
|
||||||
PORTUNUS_SERVER_HTTP_LISTEN = "[::]:${toString cfg.port}";
|
PORTUNUS_SERVER_HTTP_LISTEN = "127.0.0.1:${toString cfg.port}";
|
||||||
PORTUNUS_SERVER_STATE_DIR = cfg.stateDir;
|
PORTUNUS_SERVER_STATE_DIR = cfg.stateDir;
|
||||||
PORTUNUS_SLAPD_BINARY = "${cfg.ldap.package}/libexec/slapd";
|
PORTUNUS_SLAPD_BINARY = "${cfg.ldap.package}/libexec/slapd";
|
||||||
PORTUNUS_SLAPD_GROUP = cfg.ldap.group;
|
PORTUNUS_SLAPD_GROUP = cfg.ldap.group;
|
||||||
|
@ -77,6 +77,10 @@ in {
|
|||||||
};
|
};
|
||||||
config = mkMerge [
|
config = mkMerge [
|
||||||
(mkIf cfg.enable {
|
(mkIf cfg.enable {
|
||||||
|
# For `sssctl` to work.
|
||||||
|
environment.etc."sssd/sssd.conf".source = settingsFile;
|
||||||
|
environment.etc."sssd/conf.d".source = "${dataDir}/conf.d";
|
||||||
|
|
||||||
systemd.services.sssd = {
|
systemd.services.sssd = {
|
||||||
description = "System Security Services Daemon";
|
description = "System Security Services Daemon";
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
@ -101,6 +105,7 @@ in {
|
|||||||
EnvironmentFile = lib.mkIf (cfg.environmentFile != null) cfg.environmentFile;
|
EnvironmentFile = lib.mkIf (cfg.environmentFile != null) cfg.environmentFile;
|
||||||
};
|
};
|
||||||
preStart = ''
|
preStart = ''
|
||||||
|
mkdir -p "${dataDir}/conf.d"
|
||||||
[ -f ${settingsFile} ] && rm -f ${settingsFile}
|
[ -f ${settingsFile} ] && rm -f ${settingsFile}
|
||||||
old_umask=$(umask)
|
old_umask=$(umask)
|
||||||
umask 0177
|
umask 0177
|
||||||
|
@ -283,7 +283,8 @@ in {
|
|||||||
phpfpm = lib.mkIf useNginx {
|
phpfpm = lib.mkIf useNginx {
|
||||||
pools.zoneminder = {
|
pools.zoneminder = {
|
||||||
inherit user group;
|
inherit user group;
|
||||||
phpPackage = pkgs.php.withExtensions ({ enabled, all }: enabled ++ [ all.apcu ]);
|
phpPackage = pkgs.php.withExtensions (
|
||||||
|
{ enabled, all }: enabled ++ [ all.apcu all.sysvsem ]);
|
||||||
phpOptions = ''
|
phpOptions = ''
|
||||||
date.timezone = "${config.time.timeZone}"
|
date.timezone = "${config.time.timeZone}"
|
||||||
'';
|
'';
|
||||||
@ -326,6 +327,15 @@ in {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
${zoneminder}/bin/zmupdate.pl -nointeractive
|
${zoneminder}/bin/zmupdate.pl -nointeractive
|
||||||
|
${zoneminder}/bin/zmupdate.pl --nointeractive -f
|
||||||
|
|
||||||
|
# Update ZM's Nix store path in the configuration table. Do nothing if the config doesn't
|
||||||
|
# contain ZM's Nix store path.
|
||||||
|
${config.services.mysql.package}/bin/mysql -u zoneminder zm << EOF
|
||||||
|
UPDATE Config
|
||||||
|
SET Value = REGEXP_REPLACE(Value, "^/nix/store/[^-/]+-zoneminder-[^/]+", "${pkgs.zoneminder}")
|
||||||
|
WHERE Name = "ZM_FONT_FILE_LOCATION";
|
||||||
|
EOF
|
||||||
'';
|
'';
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
User = user;
|
User = user;
|
||||||
|
@ -1300,7 +1300,7 @@ in {
|
|||||||
SystemCallFilter = [
|
SystemCallFilter = [
|
||||||
"@system-service"
|
"@system-service"
|
||||||
"~@privileged"
|
"~@privileged"
|
||||||
] ++ lib.optional (cfg.settings.server.protocol == "socket") [ "@chown" ];
|
] ++ lib.optionals (cfg.settings.server.protocol == "socket") [ "@chown" ];
|
||||||
UMask = "0027";
|
UMask = "0027";
|
||||||
};
|
};
|
||||||
preStart = ''
|
preStart = ''
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user