Merge branch 'NixOS:master' into swww
This commit is contained in:
@@ -34,6 +34,10 @@ jobs:
|
||||
pairs:
|
||||
- from: master
|
||||
into: haskell-updates
|
||||
- from: release-22.11
|
||||
into: staging-next-22.11
|
||||
- from: staging-next-22.11
|
||||
into: staging-22.11
|
||||
- from: release-22.05
|
||||
into: staging-next-22.05
|
||||
- from: staging-next-22.05
|
||||
|
||||
@@ -100,10 +100,10 @@ stdenv.mkDerivation {
|
||||
name = "hello";
|
||||
src = fetchgit {
|
||||
url = "https://...";
|
||||
sparseCheckout = ''
|
||||
directory/to/be/included
|
||||
another/directory
|
||||
'';
|
||||
sparseCheckout = [
|
||||
"directory/to/be/included"
|
||||
"another/directory"
|
||||
];
|
||||
sha256 = "0000000000000000000000000000000000000000000000000000";
|
||||
};
|
||||
}
|
||||
|
||||
@@ -35,6 +35,70 @@ passthru.tests.version = testers.testVersion {
|
||||
};
|
||||
```
|
||||
|
||||
## `testBuildFailure` {#tester-testBuildFailure}
|
||||
|
||||
Make sure that a build does not succeed. This is useful for testing testers.
|
||||
|
||||
This returns a derivation with an override on the builder, with the following effects:
|
||||
|
||||
- Fail the build when the original builder succeeds
|
||||
- Move `$out` to `$out/result`, if it exists (assuming `out` is the default output)
|
||||
- Save the build log to `$out/testBuildFailure.log` (same)
|
||||
|
||||
Example:
|
||||
|
||||
```nix
|
||||
runCommand "example" {
|
||||
failed = testers.testBuildFailure (runCommand "fail" {} ''
|
||||
echo ok-ish >$out
|
||||
echo failing though
|
||||
exit 3
|
||||
'');
|
||||
} ''
|
||||
grep -F 'ok-ish' $failed/result
|
||||
grep -F 'failing though' $failed/testBuildFailure.log
|
||||
[[ 3 = $(cat $failed/testBuildFailure.exit) ]]
|
||||
touch $out
|
||||
'';
|
||||
```
|
||||
|
||||
While `testBuildFailure` is designed to keep changes to the original builder's
|
||||
environment to a minimum, some small changes are inevitable.
|
||||
|
||||
- The file `$TMPDIR/testBuildFailure.log` is present. It should not be deleted.
|
||||
- `stdout` and `stderr` are a pipe instead of a tty. This could be improved.
|
||||
- One or two extra processes are present in the sandbox during the original
|
||||
builder's execution.
|
||||
- The derivation and output hashes are different, but not unusual.
|
||||
- The derivation includes a dependency on `buildPackages.bash` and
|
||||
`expect-failure.sh`, which is built to include a transitive dependency on
|
||||
`buildPackages.coreutils` and possibly more. These are not added to `PATH`
|
||||
or any other environment variable, so they should be hard to observe.
|
||||
|
||||
## `testEqualContents` {#tester-equalContents}
|
||||
|
||||
Check that two paths have the same contents.
|
||||
|
||||
Example:
|
||||
|
||||
```nix
|
||||
testers.testEqualContents {
|
||||
assertion = "sed -e performs replacement";
|
||||
expected = writeText "expected" ''
|
||||
foo baz baz
|
||||
'';
|
||||
actual = runCommand "actual" {
|
||||
# not really necessary for a package that's in stdenv
|
||||
nativeBuildInputs = [ gnused ];
|
||||
base = writeText "base" ''
|
||||
foo bar baz
|
||||
'';
|
||||
} ''
|
||||
sed -e 's/bar/baz/g' $base >$out
|
||||
'';
|
||||
}
|
||||
```
|
||||
|
||||
## `testEqualDerivation` {#tester-testEqualDerivation}
|
||||
|
||||
Checks that two packages produce the exact same build instructions.
|
||||
|
||||
@@ -196,7 +196,7 @@ buildNpmPackage rec {
|
||||
* `makeCacheWritable`: Whether to make the cache writable prior to installing dependencies. Don't set this unless npm tries to write to the cache directory, as it can slow down the build.
|
||||
* `npmBuildScript`: The script to run to build the project. Defaults to `"build"`.
|
||||
* `npmFlags`: Flags to pass to all npm commands.
|
||||
* `npmInstallFlags`: Flags to pass to `npm ci`.
|
||||
* `npmInstallFlags`: Flags to pass to `npm ci` and `npm prune`.
|
||||
* `npmBuildFlags`: Flags to pass to `npm run ${npmBuildScript}`.
|
||||
* `npmPackFlags`: Flags to pass to `npm pack`.
|
||||
|
||||
|
||||
@@ -789,7 +789,7 @@ documentation source root.
|
||||
```
|
||||
|
||||
The hook is also available to packages outside the python ecosystem by
|
||||
referencing it using `python3.pkgs.sphinxHook`.
|
||||
referencing it using `sphinxHook` from top-level.
|
||||
|
||||
### Develop local package {#develop-local-package}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ For other versions such as daily builds (beta and nightly),
|
||||
use either `rustup` from nixpkgs (which will manage the rust installation in your home directory),
|
||||
or use a community maintained [Rust overlay](#using-community-rust-overlays).
|
||||
|
||||
## Compiling Rust applications with Cargo {#compiling-rust-applications-with-cargo}
|
||||
## `buildRustPackage`: Compiling Rust applications with Cargo {#compiling-rust-applications-with-cargo}
|
||||
|
||||
Rust applications are packaged by using the `buildRustPackage` helper from `rustPlatform`:
|
||||
|
||||
@@ -608,7 +608,7 @@ buildPythonPackage rec {
|
||||
}
|
||||
```
|
||||
|
||||
## Compiling Rust crates using Nix instead of Cargo {#compiling-rust-crates-using-nix-instead-of-cargo}
|
||||
## `buildRustCrate`: Compiling Rust crates using Nix instead of Cargo {#compiling-rust-crates-using-nix-instead-of-cargo}
|
||||
|
||||
### Simple operation {#simple-operation}
|
||||
|
||||
|
||||
@@ -250,5 +250,5 @@ Thirdly, it is because everything target-mentioning only exists to accommodate c
|
||||
:::
|
||||
|
||||
::: {.note}
|
||||
If one explores Nixpkgs, they will see derivations with names like `gccCross`. Such `*Cross` derivations is a holdover from before we properly distinguished between the host and target platforms—the derivation with “Cross” in the name covered the `build = host != target` case, while the other covered the `host = target`, with build platform the same or not based on whether one was using its `.nativeDrv` or `.crossDrv`. This ugliness will disappear soon.
|
||||
If one explores Nixpkgs, they will see derivations with names like `gccCross`. Such `*Cross` derivations is a holdover from before we properly distinguished between the host and target platforms—the derivation with “Cross” in the name covered the `build = host != target` case, while the other covered the `host = target`, with build platform the same or not based on whether one was using its `.__spliced.buildHost` or `.__spliced.hostTarget`.
|
||||
:::
|
||||
|
||||
+21
-2
@@ -3,7 +3,7 @@
|
||||
|
||||
let
|
||||
inherit (builtins) head tail length;
|
||||
inherit (lib.trivial) id;
|
||||
inherit (lib.trivial) flip id mergeAttrs pipe;
|
||||
inherit (lib.strings) concatStringsSep concatMapStringsSep escapeNixIdentifier sanitizeDerivationName;
|
||||
inherit (lib.lists) foldr foldl' concatMap concatLists elemAt all partition groupBy take foldl;
|
||||
in
|
||||
@@ -77,6 +77,25 @@ rec {
|
||||
let errorMsg = "cannot find attribute `" + concatStringsSep "." attrPath + "'";
|
||||
in attrByPath attrPath (abort errorMsg);
|
||||
|
||||
/* Map each attribute in the given set and merge them into a new attribute set.
|
||||
|
||||
Type:
|
||||
concatMapAttrs ::
|
||||
(String -> a -> AttrSet)
|
||||
-> AttrSet
|
||||
-> AttrSet
|
||||
|
||||
Example:
|
||||
concatMapAttrs
|
||||
(name: value: {
|
||||
${name} = value;
|
||||
${name + value} = value;
|
||||
})
|
||||
{ x = "a"; y = "b"; }
|
||||
=> { x = "a"; xa = "a"; y = "b"; yb = "b"; }
|
||||
*/
|
||||
concatMapAttrs = f: flip pipe [ (mapAttrs f) attrValues (foldl' mergeAttrs { }) ];
|
||||
|
||||
|
||||
/* Update or set specific paths of an attribute set.
|
||||
|
||||
@@ -606,7 +625,7 @@ rec {
|
||||
getMan = getOutput "man";
|
||||
|
||||
/* Pick the outputs of packages to place in buildInputs */
|
||||
chooseDevOutputs = drvs: builtins.map getDev drvs;
|
||||
chooseDevOutputs = builtins.map getDev;
|
||||
|
||||
/* Make various Nix tools consider the contents of the resulting
|
||||
attribute set when looking for what to build, find, etc.
|
||||
|
||||
@@ -38,12 +38,15 @@ rec {
|
||||
//
|
||||
(drv.passthru or {})
|
||||
//
|
||||
(if (drv ? crossDrv && drv ? nativeDrv)
|
||||
then {
|
||||
crossDrv = overrideDerivation drv.crossDrv f;
|
||||
nativeDrv = overrideDerivation drv.nativeDrv f;
|
||||
}
|
||||
else { }));
|
||||
# TODO(@Artturin): remove before release 23.05 and only have __spliced.
|
||||
(lib.optionalAttrs (drv ? crossDrv && drv ? nativeDrv) {
|
||||
crossDrv = overrideDerivation drv.crossDrv f;
|
||||
nativeDrv = overrideDerivation drv.nativeDrv f;
|
||||
})
|
||||
//
|
||||
lib.optionalAttrs (drv ? __spliced) {
|
||||
__spliced = {} // (lib.mapAttrs (_: sDrv: overrideDerivation sDrv f) drv.__spliced);
|
||||
});
|
||||
|
||||
|
||||
/* `makeOverridable` takes a function from attribute set to attribute set and
|
||||
|
||||
+1
-1
@@ -78,7 +78,7 @@ let
|
||||
inherit (self.attrsets) attrByPath hasAttrByPath setAttrByPath
|
||||
getAttrFromPath attrVals attrValues getAttrs catAttrs filterAttrs
|
||||
filterAttrsRecursive foldAttrs collect nameValuePair mapAttrs
|
||||
mapAttrs' mapAttrsToList mapAttrsRecursive mapAttrsRecursiveCond
|
||||
mapAttrs' mapAttrsToList concatMapAttrs mapAttrsRecursive mapAttrsRecursiveCond
|
||||
genAttrs isDerivation toDerivation optionalAttrs
|
||||
zipAttrsWithNames zipAttrsWith zipAttrs recursiveUpdateUntil
|
||||
recursiveUpdate matchAttrs overrideExisting showAttrPath getOutput getBin
|
||||
|
||||
+7
-8
@@ -166,7 +166,7 @@ let
|
||||
in type == "directory" || lib.any (ext: lib.hasSuffix ext base) exts;
|
||||
in cleanSourceWith { inherit filter src; };
|
||||
|
||||
pathIsGitRepo = path: (commitIdFromGitRepoOrError path)?value;
|
||||
pathIsGitRepo = path: (_commitIdFromGitRepoOrError path)?value;
|
||||
|
||||
/*
|
||||
Get the commit id of a git repo.
|
||||
@@ -174,17 +174,16 @@ let
|
||||
Example: commitIdFromGitRepo <nixpkgs/.git>
|
||||
*/
|
||||
commitIdFromGitRepo = path:
|
||||
let commitIdOrError = commitIdFromGitRepoOrError path;
|
||||
let commitIdOrError = _commitIdFromGitRepoOrError path;
|
||||
in commitIdOrError.value or (throw commitIdOrError.error);
|
||||
|
||||
/*
|
||||
Get the commit id of a git repo.
|
||||
# Get the commit id of a git repo.
|
||||
|
||||
Returns `{ value = commitHash }` or `{ error = "... message ..." }`.
|
||||
# Returns `{ value = commitHash }` or `{ error = "... message ..." }`.
|
||||
|
||||
Example: commitIdFromGitRepo <nixpkgs/.git>
|
||||
*/
|
||||
commitIdFromGitRepoOrError =
|
||||
# Example: commitIdFromGitRepo <nixpkgs/.git>
|
||||
# not exported, used for commitIdFromGitRepo
|
||||
_commitIdFromGitRepoOrError =
|
||||
let readCommitFromFile = file: path:
|
||||
let fileName = path + "/${file}";
|
||||
packedRefsName = path + "/packed-refs";
|
||||
|
||||
@@ -557,7 +557,7 @@ rec {
|
||||
|
||||
else if platform.isRiscV then riscv-multiplatform
|
||||
|
||||
else if platform.parsed.cpu == lib.systems.parse.cpuTypes.mipsel then fuloong2f_n32
|
||||
else if platform.parsed.cpu == lib.systems.parse.cpuTypes.mipsel then (import ./examples.nix { inherit lib; }).mipsel-linux-gnu
|
||||
|
||||
else if platform.parsed.cpu == lib.systems.parse.cpuTypes.powerpc64le then powernv
|
||||
|
||||
|
||||
@@ -478,6 +478,23 @@ runTests {
|
||||
|
||||
# ATTRSETS
|
||||
|
||||
testConcatMapAttrs = {
|
||||
expr = concatMapAttrs
|
||||
(name: value: {
|
||||
${name} = value;
|
||||
${name + value} = value;
|
||||
})
|
||||
{
|
||||
foo = "bar";
|
||||
foobar = "baz";
|
||||
};
|
||||
expected = {
|
||||
foo = "bar";
|
||||
foobar = "baz";
|
||||
foobarbaz = "baz";
|
||||
};
|
||||
};
|
||||
|
||||
# code from the example
|
||||
testRecursiveUpdateUntil = {
|
||||
expr = recursiveUpdateUntil (path: l: r: path == ["foo"]) {
|
||||
|
||||
+1
-1
@@ -195,7 +195,7 @@ rec {
|
||||
On each release the first letter is bumped and a new animal is chosen
|
||||
starting with that new letter.
|
||||
*/
|
||||
codeName = "Raccoon";
|
||||
codeName = "Stoat";
|
||||
|
||||
/* Returns the current nixpkgs version suffix as string. */
|
||||
versionSuffix =
|
||||
|
||||
@@ -1285,6 +1285,15 @@
|
||||
fingerprint = "DD52 6BC7 767D BA28 16C0 95E5 6840 89CE 67EB B691";
|
||||
}];
|
||||
};
|
||||
ataraxiasjel = {
|
||||
email = "nix@ataraxiadev.com";
|
||||
github = "AtaraxiaSjel";
|
||||
githubId = 5314145;
|
||||
name = "Dmitriy";
|
||||
keys = [{
|
||||
fingerprint = "922D A6E7 58A0 FE4C FAB4 E4B2 FD26 6B81 0DF4 8DF2";
|
||||
}];
|
||||
};
|
||||
atemu = {
|
||||
name = "Atemu";
|
||||
email = "atemu.main+nixpkgs@gmail.com";
|
||||
@@ -4820,6 +4829,12 @@
|
||||
githubId = 868283;
|
||||
name = "Fatih Altinok";
|
||||
};
|
||||
fstamour = {
|
||||
email = "fr.st-amour@gmail.com";
|
||||
github = "fstamour";
|
||||
githubId = 2881922;
|
||||
name = "Francis St-Amour";
|
||||
};
|
||||
ftrvxmtrx = {
|
||||
email = "ftrvxmtrx@gmail.com";
|
||||
github = "ftrvxmtrx";
|
||||
@@ -4949,6 +4964,13 @@
|
||||
githubId = 37017396;
|
||||
name = "gbtb";
|
||||
};
|
||||
gdamjan = {
|
||||
email = "gdamjan@gmail.com";
|
||||
matrix = "@gdamjan:spodeli.org";
|
||||
github = "gdamjan";
|
||||
githubId = 81654;
|
||||
name = "Damjan Georgievski";
|
||||
};
|
||||
gdinh = {
|
||||
email = "nix@contact.dinh.ai";
|
||||
github = "gdinh";
|
||||
@@ -9425,12 +9447,6 @@
|
||||
githubId = 2072185;
|
||||
name = "Marc Scholten";
|
||||
};
|
||||
mpsyco = {
|
||||
email = "fr.st-amour@gmail.com";
|
||||
github = "fstamour";
|
||||
githubId = 2881922;
|
||||
name = "Francis St-Amour";
|
||||
};
|
||||
mtrsk = {
|
||||
email = "marcos.schonfinkel@protonmail.com";
|
||||
github = "mtrsk";
|
||||
@@ -11336,6 +11352,13 @@
|
||||
githubId = 35086;
|
||||
name = "Jonathan Wright";
|
||||
};
|
||||
quantenzitrone = {
|
||||
email = "quantenzitrone@protonmail.com";
|
||||
github = "Quantenzitrone";
|
||||
githubId = 74491719;
|
||||
matrix = "@quantenzitrone:matrix.org";
|
||||
name = "quantenzitrone";
|
||||
};
|
||||
queezle = {
|
||||
email = "git@queezle.net";
|
||||
github = "queezle42";
|
||||
@@ -13686,6 +13709,12 @@
|
||||
githubId = 3105057;
|
||||
name = "Jan Beinke";
|
||||
};
|
||||
thenonameguy = {
|
||||
email = "thenonameguy24@gmail.com";
|
||||
name = "Krisztian Szabo";
|
||||
github = "thenonameguy";
|
||||
githubId = 2217181;
|
||||
};
|
||||
therealansh = {
|
||||
email = "tyagiansh23@gmail.com";
|
||||
github = "therealansh";
|
||||
@@ -14264,6 +14293,12 @@
|
||||
githubId = 32751441;
|
||||
name = "urlordjames";
|
||||
};
|
||||
ursi = {
|
||||
email = "masondeanm@aol.com";
|
||||
github = "ursi";
|
||||
githubId = 17836748;
|
||||
name = "Mason Mackaman";
|
||||
};
|
||||
uskudnik = {
|
||||
email = "urban.skudnik@gmail.com";
|
||||
github = "uskudnik";
|
||||
@@ -15886,4 +15921,10 @@
|
||||
github = "wuyoli";
|
||||
githubId = 104238274;
|
||||
};
|
||||
jordanisaacs = {
|
||||
name = "Jordan Isaacs";
|
||||
email = "nix@jdisaacs.com";
|
||||
github = "jordanisaacs";
|
||||
githubId = 19742638;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -142,10 +142,10 @@ class Repo:
|
||||
|
||||
def as_nix(self, plugin: "Plugin") -> str:
|
||||
return f'''fetchgit {{
|
||||
url = "{self.uri}";
|
||||
rev = "{plugin.commit}";
|
||||
sha256 = "{plugin.sha256}";
|
||||
}}'''
|
||||
url = "{self.uri}";
|
||||
rev = "{plugin.commit}";
|
||||
sha256 = "{plugin.sha256}";
|
||||
}}'''
|
||||
|
||||
|
||||
class RepoGitHub(Repo):
|
||||
|
||||
@@ -15,5 +15,4 @@ NixOS configuration files.
|
||||
<xi:include href="config-file.section.xml" />
|
||||
<xi:include href="abstractions.section.xml" />
|
||||
<xi:include href="modularity.section.xml" />
|
||||
<xi:include href="summary.section.xml" />
|
||||
```
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
# Syntax Summary {#sec-nix-syntax-summary}
|
||||
|
||||
Below is a summary of the most important syntactic constructs in the Nix
|
||||
expression language. It's not complete. In particular, there are many
|
||||
other built-in functions. See the [Nix
|
||||
manual](https://nixos.org/nix/manual/#chap-writing-nix-expressions) for
|
||||
the rest.
|
||||
|
||||
| Example | Description |
|
||||
|-----------------------------------------------|--------------------------------------------------------------------------------------------------------------------|
|
||||
| *Basic values* | |
|
||||
| `"Hello world"` | A string |
|
||||
| `"${pkgs.bash}/bin/sh"` | A string containing an expression (expands to `"/nix/store/hash-bash-version/bin/sh"`) |
|
||||
| `true`, `false` | Booleans |
|
||||
| `123` | An integer |
|
||||
| `./foo.png` | A path (relative to the containing Nix expression) |
|
||||
| *Compound values* | |
|
||||
| `{ x = 1; y = 2; }` | A set with attributes named `x` and `y` |
|
||||
| `{ foo.bar = 1; }` | A nested set, equivalent to `{ foo = { bar = 1; }; }` |
|
||||
| `rec { x = "foo"; y = x + "bar"; }` | A recursive set, equivalent to `{ x = "foo"; y = "foobar"; }` |
|
||||
| `[ "foo" "bar" ]` | A list with two elements |
|
||||
| *Operators* | |
|
||||
| `"foo" + "bar"` | String concatenation |
|
||||
| `1 + 2` | Integer addition |
|
||||
| `"foo" == "f" + "oo"` | Equality test (evaluates to `true`) |
|
||||
| `"foo" != "bar"` | Inequality test (evaluates to `true`) |
|
||||
| `!true` | Boolean negation |
|
||||
| `{ x = 1; y = 2; }.x` | Attribute selection (evaluates to `1`) |
|
||||
| `{ x = 1; y = 2; }.z or 3` | Attribute selection with default (evaluates to `3`) |
|
||||
| `{ x = 1; y = 2; } // { z = 3; }` | Merge two sets (attributes in the right-hand set taking precedence) |
|
||||
| *Control structures* | |
|
||||
| `if 1 + 1 == 2 then "yes!" else "no!"` | Conditional expression |
|
||||
| `assert 1 + 1 == 2; "yes!"` | Assertion check (evaluates to `"yes!"`). See [](#sec-assertions) for using assertions in modules |
|
||||
| `let x = "foo"; y = "bar"; in x + y` | Variable definition |
|
||||
| `with pkgs.lib; head [ 1 2 3 ]` | Add all attributes from the given set to the scope (evaluates to `1`) |
|
||||
| *Functions (lambdas)* | |
|
||||
| `x: x + 1` | A function that expects an integer and returns it increased by 1 |
|
||||
| `(x: x + 1) 100` | A function call (evaluates to 101) |
|
||||
| `let inc = x: x + 1; in inc (inc (inc 100))` | A function bound to a variable and subsequently called by name (evaluates to 103) |
|
||||
| `{ x, y }: x + y` | A function that expects a set with required attributes `x` and `y` and concatenates them |
|
||||
| `{ x, y ? "bar" }: x + y` | A function that expects a set with required attribute `x` and optional `y`, using `"bar"` as default value for `y` |
|
||||
| `{ x, y, ... }: x + y` | A function that expects a set with required attributes `x` and `y` and ignores any other attributes |
|
||||
| `{ x, y } @ args: x + y` | A function that expects a set with required attributes `x` and `y`, and binds the whole set to `args` |
|
||||
| *Built-in functions* | |
|
||||
| `import ./foo.nix` | Load and return Nix expression in given file |
|
||||
| `map (x: x + x) [ 1 2 3 ]` | Apply a function to every element of a list (evaluates to `[ 2 4 6 ]`) |
|
||||
@@ -32,8 +32,7 @@ account will cease to exist. Also, imperative commands for managing users and
|
||||
groups, such as useradd, are no longer available. Passwords may still be
|
||||
assigned by setting the user\'s
|
||||
[hashedPassword](#opt-users.users._name_.hashedPassword) option. A
|
||||
hashed password can be generated using `mkpasswd -m
|
||||
sha-512`.
|
||||
hashed password can be generated using `mkpasswd`.
|
||||
|
||||
A user ID (uid) is assigned automatically. You can also specify a uid
|
||||
manually by adding
|
||||
|
||||
@@ -17,5 +17,4 @@
|
||||
<xi:include href="config-file.section.xml" />
|
||||
<xi:include href="abstractions.section.xml" />
|
||||
<xi:include href="modularity.section.xml" />
|
||||
<xi:include href="summary.section.xml" />
|
||||
</chapter>
|
||||
|
||||
@@ -1,332 +0,0 @@
|
||||
<section xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="sec-nix-syntax-summary">
|
||||
<title>Syntax Summary</title>
|
||||
<para>
|
||||
Below is a summary of the most important syntactic constructs in the
|
||||
Nix expression language. It’s not complete. In particular, there are
|
||||
many other built-in functions. See the
|
||||
<link xlink:href="https://nixos.org/nix/manual/#chap-writing-nix-expressions">Nix
|
||||
manual</link> for the rest.
|
||||
</para>
|
||||
<informaltable>
|
||||
<tgroup cols="2">
|
||||
<colspec align="left" />
|
||||
<colspec align="left" />
|
||||
<thead>
|
||||
<row>
|
||||
<entry>
|
||||
Example
|
||||
</entry>
|
||||
<entry>
|
||||
Description
|
||||
</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>
|
||||
<emphasis>Basic values</emphasis>
|
||||
</entry>
|
||||
<entry>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<literal>"Hello world"</literal>
|
||||
</entry>
|
||||
<entry>
|
||||
A string
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<literal>"${pkgs.bash}/bin/sh"</literal>
|
||||
</entry>
|
||||
<entry>
|
||||
A string containing an expression (expands to
|
||||
<literal>"/nix/store/hash-bash-version/bin/sh"</literal>)
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<literal>true</literal>, <literal>false</literal>
|
||||
</entry>
|
||||
<entry>
|
||||
Booleans
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<literal>123</literal>
|
||||
</entry>
|
||||
<entry>
|
||||
An integer
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<literal>./foo.png</literal>
|
||||
</entry>
|
||||
<entry>
|
||||
A path (relative to the containing Nix expression)
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<emphasis>Compound values</emphasis>
|
||||
</entry>
|
||||
<entry>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<literal>{ x = 1; y = 2; }</literal>
|
||||
</entry>
|
||||
<entry>
|
||||
A set with attributes named <literal>x</literal> and
|
||||
<literal>y</literal>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<literal>{ foo.bar = 1; }</literal>
|
||||
</entry>
|
||||
<entry>
|
||||
A nested set, equivalent to
|
||||
<literal>{ foo = { bar = 1; }; }</literal>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<literal>rec { x = "foo"; y = x + "bar"; }</literal>
|
||||
</entry>
|
||||
<entry>
|
||||
A recursive set, equivalent to
|
||||
<literal>{ x = "foo"; y = "foobar"; }</literal>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<literal>[ "foo" "bar" ]</literal>
|
||||
</entry>
|
||||
<entry>
|
||||
A list with two elements
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<emphasis>Operators</emphasis>
|
||||
</entry>
|
||||
<entry>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<literal>"foo" + "bar"</literal>
|
||||
</entry>
|
||||
<entry>
|
||||
String concatenation
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<literal>1 + 2</literal>
|
||||
</entry>
|
||||
<entry>
|
||||
Integer addition
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<literal>"foo" == "f" + "oo"</literal>
|
||||
</entry>
|
||||
<entry>
|
||||
Equality test (evaluates to <literal>true</literal>)
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<literal>"foo" != "bar"</literal>
|
||||
</entry>
|
||||
<entry>
|
||||
Inequality test (evaluates to <literal>true</literal>)
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<literal>!true</literal>
|
||||
</entry>
|
||||
<entry>
|
||||
Boolean negation
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<literal>{ x = 1; y = 2; }.x</literal>
|
||||
</entry>
|
||||
<entry>
|
||||
Attribute selection (evaluates to <literal>1</literal>)
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<literal>{ x = 1; y = 2; }.z or 3</literal>
|
||||
</entry>
|
||||
<entry>
|
||||
Attribute selection with default (evaluates to
|
||||
<literal>3</literal>)
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<literal>{ x = 1; y = 2; } // { z = 3; }</literal>
|
||||
</entry>
|
||||
<entry>
|
||||
Merge two sets (attributes in the right-hand set taking
|
||||
precedence)
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<emphasis>Control structures</emphasis>
|
||||
</entry>
|
||||
<entry>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<literal>if 1 + 1 == 2 then "yes!" else "no!"</literal>
|
||||
</entry>
|
||||
<entry>
|
||||
Conditional expression
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<literal>assert 1 + 1 == 2; "yes!"</literal>
|
||||
</entry>
|
||||
<entry>
|
||||
Assertion check (evaluates to
|
||||
<literal>"yes!"</literal>). See
|
||||
<xref linkend="sec-assertions" /> for using assertions in
|
||||
modules
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<literal>let x = "foo"; y = "bar"; in x + y</literal>
|
||||
</entry>
|
||||
<entry>
|
||||
Variable definition
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<literal>with pkgs.lib; head [ 1 2 3 ]</literal>
|
||||
</entry>
|
||||
<entry>
|
||||
Add all attributes from the given set to the scope
|
||||
(evaluates to <literal>1</literal>)
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<emphasis>Functions (lambdas)</emphasis>
|
||||
</entry>
|
||||
<entry>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<literal>x: x + 1</literal>
|
||||
</entry>
|
||||
<entry>
|
||||
A function that expects an integer and returns it increased
|
||||
by 1
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<literal>(x: x + 1) 100</literal>
|
||||
</entry>
|
||||
<entry>
|
||||
A function call (evaluates to 101)
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<literal>let inc = x: x + 1; in inc (inc (inc 100))</literal>
|
||||
</entry>
|
||||
<entry>
|
||||
A function bound to a variable and subsequently called by
|
||||
name (evaluates to 103)
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<literal>{ x, y }: x + y</literal>
|
||||
</entry>
|
||||
<entry>
|
||||
A function that expects a set with required attributes
|
||||
<literal>x</literal> and <literal>y</literal> and
|
||||
concatenates them
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<literal>{ x, y ? "bar" }: x + y</literal>
|
||||
</entry>
|
||||
<entry>
|
||||
A function that expects a set with required attribute
|
||||
<literal>x</literal> and optional <literal>y</literal>,
|
||||
using <literal>"bar"</literal> as default value
|
||||
for <literal>y</literal>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<literal>{ x, y, ... }: x + y</literal>
|
||||
</entry>
|
||||
<entry>
|
||||
A function that expects a set with required attributes
|
||||
<literal>x</literal> and <literal>y</literal> and ignores
|
||||
any other attributes
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<literal>{ x, y } @ args: x + y</literal>
|
||||
</entry>
|
||||
<entry>
|
||||
A function that expects a set with required attributes
|
||||
<literal>x</literal> and <literal>y</literal>, and binds the
|
||||
whole set to <literal>args</literal>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<emphasis>Built-in functions</emphasis>
|
||||
</entry>
|
||||
<entry>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<literal>import ./foo.nix</literal>
|
||||
</entry>
|
||||
<entry>
|
||||
Load and return Nix expression in given file
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<literal>map (x: x + x) [ 1 2 3 ]</literal>
|
||||
</entry>
|
||||
<entry>
|
||||
Apply a function to every element of a list (evaluates to
|
||||
<literal>[ 2 4 6 ]</literal>)
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</informaltable>
|
||||
</section>
|
||||
@@ -39,7 +39,7 @@ users.users.alice = {
|
||||
Passwords may still be assigned by setting the user's
|
||||
<link linkend="opt-users.users._name_.hashedPassword">hashedPassword</link>
|
||||
option. A hashed password can be generated using
|
||||
<literal>mkpasswd -m sha-512</literal>.
|
||||
<literal>mkpasswd</literal>.
|
||||
</para>
|
||||
<para>
|
||||
A user ID (uid) is assigned automatically. You can also specify a
|
||||
|
||||
@@ -139,6 +139,11 @@
|
||||
other distributions.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
PHP 8.2.0 RC 6 is available.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>protonup</literal> has been aliased to and replaced
|
||||
@@ -273,6 +278,16 @@
|
||||
<link linkend="opt-services.prometheus.sachet.enable">services.prometheus.sachet</link>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<link xlink:href="https://evcc.io">EVCC</link> is an EV charge
|
||||
controller with PV integration. It supports a multitude of
|
||||
chargers, meters, vehicle APIs and more and ties that together
|
||||
with a well-tested backend and a lightweight web frontend.
|
||||
Available as
|
||||
<link linkend="opt-services.evcc.enable">services.evcc</link>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<link xlink:href="https://github.com/leetronics/infnoise">infnoise</link>,
|
||||
@@ -575,6 +590,15 @@
|
||||
future Git update without notice.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The <literal>fetchgit</literal> fetcher supports sparse
|
||||
checkouts via the <literal>sparseCheckout</literal> option.
|
||||
This used to accept a multi-line string with
|
||||
directories/patterns to check out, but now requires a list of
|
||||
strings.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>openssh</literal> was updated to version 9.1,
|
||||
@@ -624,6 +648,23 @@
|
||||
binaries, use the <literal>p4d</literal> package instead.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The <literal>openssl</literal>-extension for the PHP
|
||||
interpreter used by Nextcloud is built against OpenSSL 1.1 if
|
||||
<xref linkend="opt-system.stateVersion" /> is below
|
||||
<literal>22.11</literal>. This is to make sure that people
|
||||
using
|
||||
<link xlink:href="https://docs.nextcloud.com/server/latest/admin_manual/configuration_files/encryption_configuration.html">server-side
|
||||
encryption</link> don’t loose access to their files.
|
||||
</para>
|
||||
<para>
|
||||
In any other case it’s safe to use OpenSSL 3 for PHP’s openssl
|
||||
extension. This can be done by setting
|
||||
<xref linkend="opt-services.nextcloud.enableBrokenCiphersForSSE" />
|
||||
to <literal>false</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The <literal>coq</literal> package and versioned variants
|
||||
@@ -1049,6 +1090,17 @@ services.github-runner.serviceOverrides.SupplementaryGroups = [
|
||||
<section xml:id="sec-release-22.11-notable-changes">
|
||||
<title>Other Notable Changes</title>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>firefox</literal>, <literal>thunderbird</literal> and
|
||||
<literal>librewolf</literal> come with enabled Wayland support
|
||||
by default. The <literal>firefox-wayland</literal>,
|
||||
<literal>firefox-esr-wayland</literal>,
|
||||
<literal>thunderbird-wayland</literal> and
|
||||
<literal>librewolf-wayland</literal> attributes are obsolete
|
||||
and have been aliased to their generic attribute.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The <literal>xplr</literal> package has been updated from
|
||||
@@ -1173,22 +1225,146 @@ services.github-runner.serviceOverrides.SupplementaryGroups = [
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The <literal>services.grafana</literal> options were converted
|
||||
to a
|
||||
The module <literal>services.grafana</literal> was refactored
|
||||
to be compliant with
|
||||
<link xlink:href="https://github.com/NixOS/rfcs/blob/master/rfcs/0042-config-option.md">RFC
|
||||
0042</link> configuration.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The <literal>services.grafana.provision.datasources</literal>
|
||||
and <literal>services.grafana.provision.dashboards</literal>
|
||||
options were converted to a
|
||||
<link xlink:href="https://github.com/NixOS/rfcs/blob/master/rfcs/0042-config-option.md">RFC
|
||||
0042</link> configuration. They also now support specifying
|
||||
the provisioning YAML file with <literal>path</literal>
|
||||
option.
|
||||
0042</link>. To be precise, this means that the following
|
||||
things have changed:
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
The newly introduced option
|
||||
<xref linkend="opt-services.grafana.settings" /> is an
|
||||
attribute-set that will be converted into Grafana’s INI
|
||||
format. This means that the configuration from
|
||||
<link xlink:href="https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/">Grafana’s
|
||||
configuration reference</link> can be directly written as
|
||||
attribute-set in Nix within this option.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The option
|
||||
<literal>services.grafana.extraOptions</literal> has been
|
||||
removed. This option was an association of environment
|
||||
variables for Grafana. If you had an expression like
|
||||
</para>
|
||||
<programlisting language="bash">
|
||||
{
|
||||
services.grafana.extraOptions.SECURITY_ADMIN_USER = "foobar";
|
||||
}
|
||||
</programlisting>
|
||||
<para>
|
||||
your Grafana instance was running with
|
||||
<literal>GF_SECURITY_ADMIN_USER=foobar</literal> in its
|
||||
environment.
|
||||
</para>
|
||||
<para>
|
||||
For the migration, it is recommended to turn it into the
|
||||
INI format, i.e. to declare
|
||||
</para>
|
||||
<programlisting language="bash">
|
||||
{
|
||||
services.grafana.settings.security.admin_user = "foobar";
|
||||
}
|
||||
</programlisting>
|
||||
<para>
|
||||
instead.
|
||||
</para>
|
||||
<para>
|
||||
The keys in
|
||||
<literal>services.grafana.extraOptions</literal> have the
|
||||
format
|
||||
<literal><INI section name>_<Key Name></literal>.
|
||||
Further details are outlined in the
|
||||
<link xlink:href="https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/#override-configuration-with-environment-variables">configuration
|
||||
reference</link>.
|
||||
</para>
|
||||
<para>
|
||||
Alternatively you can also set all your values from
|
||||
<literal>extraOptions</literal> to
|
||||
<literal>systemd.services.grafana.environment</literal>,
|
||||
make sure you don’t forget to add the
|
||||
<literal>GF_</literal> prefix though!
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Previously, the options
|
||||
<xref linkend="opt-services.grafana.provision.datasources" />
|
||||
and
|
||||
<xref linkend="opt-services.grafana.provision.dashboards" />
|
||||
expected lists of datasources or dashboards for the
|
||||
<link xlink:href="https://grafana.com/docs/grafana/latest/administration/provisioning/">declarative
|
||||
provisioning</link>.
|
||||
</para>
|
||||
<para>
|
||||
To declare lists of
|
||||
</para>
|
||||
<itemizedlist spacing="compact">
|
||||
<listitem>
|
||||
<para>
|
||||
<emphasis role="strong">datasources</emphasis>, please
|
||||
rename your declarations to
|
||||
<xref linkend="opt-services.grafana.provision.datasources.settings.datasources" />.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<emphasis role="strong">dashboards</emphasis>, please
|
||||
rename your declarations to
|
||||
<xref linkend="opt-services.grafana.provision.dashboards.settings.providers" />.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<para>
|
||||
This change was made to support more features for that:
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
It’s possible to declare the
|
||||
<literal>apiVersion</literal> of your dashboards and
|
||||
datasources by
|
||||
<xref linkend="opt-services.grafana.provision.datasources.settings.apiVersion" />
|
||||
(or
|
||||
<xref linkend="opt-services.grafana.provision.dashboards.settings.apiVersion" />).
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Instead of declaring datasources and dashboards in
|
||||
pure Nix, it’s also possible to specify configuration
|
||||
files (or directories) with YAML instead using
|
||||
<xref linkend="opt-services.grafana.provision.datasources.path" />
|
||||
(or
|
||||
<xref linkend="opt-services.grafana.provision.dashboards.path" />.
|
||||
This is useful when having provisioning files from
|
||||
non-NixOS Grafana instances that you also want to
|
||||
deploy to NixOS.
|
||||
</para>
|
||||
<para>
|
||||
<emphasis role="strong">Note:</emphasis> secrets from
|
||||
these files will be leaked into the store unless you
|
||||
use a
|
||||
<link xlink:href="https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/#file-provider"><emphasis role="strong">file</emphasis>-provider
|
||||
or env-var</link> for secrets!
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<xref linkend="opt-services.grafana.provision.notifiers" />
|
||||
is not affected by this change because this feature is
|
||||
deprecated by Grafana and will probably removed in
|
||||
Grafana 10. It’s recommended to use
|
||||
<literal>services.grafana.provision.alerting.contactPoints</literal>
|
||||
instead.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
@@ -1235,6 +1411,26 @@ services.github-runner.serviceOverrides.SupplementaryGroups = [
|
||||
if you intend to add packages to <literal>/bin</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The <literal>proxmox.qemuConf.bios</literal> option was added,
|
||||
it corresponds to <literal>Hardware->BIOS</literal> field
|
||||
in Proxmox web interface. Use
|
||||
<literal>"ovmf"</literal> value to build UEFI image,
|
||||
default value remains <literal>"bios"</literal>. New
|
||||
option <literal>proxmox.partitionTableType</literal> defaults
|
||||
to either <literal>"legacy"</literal> or
|
||||
<literal>"efi"</literal>, depending on the
|
||||
<literal>bios</literal> value. Setting
|
||||
<literal>partitionTableType</literal> to
|
||||
<literal>"hybrid"</literal> results in an image,
|
||||
which supports both methods
|
||||
(<literal>"bios"</literal> and
|
||||
<literal>"ovmf"</literal>), thereby remaining
|
||||
bootable after change to Proxmox
|
||||
<literal>Hardware->BIOS</literal> field.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
memtest86+ was updated from 5.00-coreboot-002 to 6.00-beta2.
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
<section xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="sec-release-23.05">
|
||||
<title>Release 23.05 (“Stoat”, 2023.05/??)</title>
|
||||
<para>
|
||||
Support is planned until the end of December 2023, handing over to
|
||||
23.11.
|
||||
</para>
|
||||
<section xml:id="sec-release-23.05-highlights">
|
||||
<title>Highlights</title>
|
||||
<para>
|
||||
In addition to numerous new and upgraded packages, this release
|
||||
has the following highlights:
|
||||
</para>
|
||||
<itemizedlist spacing="compact">
|
||||
<listitem>
|
||||
<para>
|
||||
Create the first release note entry in this section!
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
<section xml:id="sec-release-23.05-new-services">
|
||||
<title>New Services</title>
|
||||
<itemizedlist spacing="compact">
|
||||
<listitem>
|
||||
<para>
|
||||
Create the first release note entry in this section!
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
<section xml:id="sec-release-23.05-incompatibilities">
|
||||
<title>Backward Incompatibilities</title>
|
||||
<itemizedlist spacing="compact">
|
||||
<listitem>
|
||||
<para>
|
||||
Create the first release note entry in this section!
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
<section xml:id="sec-release-23.05-notable-changes">
|
||||
<title>Other Notable Changes</title>
|
||||
<itemizedlist spacing="compact">
|
||||
<listitem>
|
||||
<para>
|
||||
Create the first release note entry in this section!
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
</section>
|
||||
@@ -8,6 +8,7 @@
|
||||
This section lists the release notes for each stable version of NixOS and
|
||||
current unstable revision.
|
||||
</para>
|
||||
<xi:include href="../from_md/release-notes/rl-2305.section.xml" />
|
||||
<xi:include href="../from_md/release-notes/rl-2211.section.xml" />
|
||||
<xi:include href="../from_md/release-notes/rl-2205.section.xml" />
|
||||
<xi:include href="../from_md/release-notes/rl-2111.section.xml" />
|
||||
|
||||
@@ -57,6 +57,8 @@ In addition to numerous new and upgraded packages, this release has the followin
|
||||
`mod_php` usage we still enable `ZTS` (Zend Thread Safe). This has been a
|
||||
common practice for a long time in other distributions.
|
||||
|
||||
- PHP 8.2.0 RC 6 is available.
|
||||
|
||||
- `protonup` has been aliased to and replaced by `protonup-ng` due to upstream not maintaining it.
|
||||
|
||||
- Perl has been updated to 5.36, and its core module `HTTP::Tiny` was patched to verify SSL/TLS certificates by default.
|
||||
@@ -96,6 +98,8 @@ In addition to numerous new and upgraded packages, this release has the followin
|
||||
|
||||
- [Sachet](https://github.com/messagebird/sachet/), an SMS alerting tool for the Prometheus Alertmanager. Available as [services.prometheus.sachet](#opt-services.prometheus.sachet.enable).
|
||||
|
||||
- [EVCC](https://evcc.io) is an EV charge controller with PV integration. It supports a multitude of chargers, meters, vehicle APIs and more and ties that together with a well-tested backend and a lightweight web frontend. Available as [services.evcc](#opt-services.evcc.enable).
|
||||
|
||||
- [infnoise](https://github.com/leetronics/infnoise), a hardware True Random Number Generator dongle.
|
||||
Available as [services.infnoise](options.html#opt-services.infnoise.enable).
|
||||
|
||||
@@ -189,6 +193,8 @@ Available as [services.patroni](options.html#opt-services.patroni.enable).
|
||||
|
||||
- The `fetchgit` fetcher now uses [cone mode](https://www.git-scm.com/docs/git-sparse-checkout/2.37.0#_internalscone_mode_handling) by default for sparse checkouts. [Non-cone mode](https://www.git-scm.com/docs/git-sparse-checkout/2.37.0#_internalsnon_cone_problems) can be enabled by passing `nonConeMode = true`, but note that non-cone mode is deprecated and this option may be removed alongside a future Git update without notice.
|
||||
|
||||
- The `fetchgit` fetcher supports sparse checkouts via the `sparseCheckout` option. This used to accept a multi-line string with directories/patterns to check out, but now requires a list of strings.
|
||||
|
||||
- `openssh` was updated to version 9.1, disabling the generation of DSA keys when using `ssh-keygen -A` as they are insecure. Also, `SetEnv` directives in `ssh_config` and `sshd_config` are now first-match-wins
|
||||
|
||||
- `bsp-layout` no longer uses the command `cycle` to switch to other window layouts, as it got replaced by the commands `previous` and `next`.
|
||||
@@ -202,6 +208,13 @@ Available as [services.patroni](options.html#opt-services.patroni.enable).
|
||||
|
||||
- The `p4` package now only includes the open-source Perforce Helix Core command-line client and APIs. It no longer installs the unfree Helix Core Server binaries `p4d`, `p4broker`, and `p4p`. To install the Helix Core Server binaries, use the `p4d` package instead.
|
||||
|
||||
- The `openssl`-extension for the PHP interpreter used by Nextcloud is built against OpenSSL 1.1 if
|
||||
[](#opt-system.stateVersion) is below `22.11`. This is to make sure that people using [server-side encryption](https://docs.nextcloud.com/server/latest/admin_manual/configuration_files/encryption_configuration.html)
|
||||
don't loose access to their files.
|
||||
|
||||
In any other case it's safe to use OpenSSL 3 for PHP's openssl extension. This can be done by setting
|
||||
[](#opt-services.nextcloud.enableBrokenCiphersForSSE) to `false`.
|
||||
|
||||
- The `coq` package and versioned variants starting at `coq_8_14` no
|
||||
longer include CoqIDE, which is now available through
|
||||
`coqPackages.coqide`. It is still possible to get CoqIDE as part of
|
||||
@@ -332,6 +345,8 @@ Available as [services.patroni](options.html#opt-services.patroni.enable).
|
||||
|
||||
## Other Notable Changes {#sec-release-22.11-notable-changes}
|
||||
|
||||
- `firefox`, `thunderbird` and `librewolf` come with enabled Wayland support by default. The `firefox-wayland`, `firefox-esr-wayland`, `thunderbird-wayland` and `librewolf-wayland` attributes are obsolete and have been aliased to their generic attribute.
|
||||
|
||||
- The `xplr` package has been updated from 0.18.0 to 0.19.0, which brings some breaking changes. See the [upstream release notes](https://github.com/sayanarijit/xplr/releases/tag/v0.19.0) for more details.
|
||||
|
||||
- Configuring multiple GitHub runners is now possible through `services.github-runners.<name>`. The option `services.github-runner` remains.
|
||||
@@ -368,9 +383,66 @@ Available as [services.patroni](options.html#opt-services.patroni.enable).
|
||||
|
||||
- The `services.matrix-synapse` systemd unit has been hardened.
|
||||
|
||||
- The `services.grafana` options were converted to a [RFC 0042](https://github.com/NixOS/rfcs/blob/master/rfcs/0042-config-option.md) configuration.
|
||||
- The module `services.grafana` was refactored to be compliant with [RFC 0042](https://github.com/NixOS/rfcs/blob/master/rfcs/0042-config-option.md). To be precise, this means that the following things have changed:
|
||||
- The newly introduced option [](#opt-services.grafana.settings) is an attribute-set that
|
||||
will be converted into Grafana's INI format. This means that the configuration from
|
||||
[Grafana's configuration reference](https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/)
|
||||
can be directly written as attribute-set in Nix within this option.
|
||||
- The option `services.grafana.extraOptions` has been removed. This option was an association
|
||||
of environment variables for Grafana. If you had an expression like
|
||||
|
||||
- The `services.grafana.provision.datasources` and `services.grafana.provision.dashboards` options were converted to a [RFC 0042](https://github.com/NixOS/rfcs/blob/master/rfcs/0042-config-option.md) configuration. They also now support specifying the provisioning YAML file with `path` option.
|
||||
```nix
|
||||
{
|
||||
services.grafana.extraOptions.SECURITY_ADMIN_USER = "foobar";
|
||||
}
|
||||
```
|
||||
|
||||
your Grafana instance was running with `GF_SECURITY_ADMIN_USER=foobar` in its environment.
|
||||
|
||||
For the migration, it is recommended to turn it into the INI format, i.e.
|
||||
to declare
|
||||
|
||||
```nix
|
||||
{
|
||||
services.grafana.settings.security.admin_user = "foobar";
|
||||
}
|
||||
```
|
||||
|
||||
instead.
|
||||
|
||||
The keys in `services.grafana.extraOptions` have the format `<INI section name>_<Key Name>`.
|
||||
Further details are outlined in the [configuration reference](https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/#override-configuration-with-environment-variables).
|
||||
|
||||
Alternatively you can also set all your values from `extraOptions` to
|
||||
`systemd.services.grafana.environment`, make sure you don't forget to add
|
||||
the `GF_` prefix though!
|
||||
- Previously, the options [](#opt-services.grafana.provision.datasources) and
|
||||
[](#opt-services.grafana.provision.dashboards) expected lists of datasources
|
||||
or dashboards for the [declarative provisioning](https://grafana.com/docs/grafana/latest/administration/provisioning/).
|
||||
|
||||
To declare lists of
|
||||
- **datasources**, please rename your declarations to [](#opt-services.grafana.provision.datasources.settings.datasources).
|
||||
- **dashboards**, please rename your declarations to [](#opt-services.grafana.provision.dashboards.settings.providers).
|
||||
|
||||
This change was made to support more features for that:
|
||||
|
||||
- It's possible to declare the `apiVersion` of your dashboards and datasources
|
||||
by [](#opt-services.grafana.provision.datasources.settings.apiVersion) (or
|
||||
[](#opt-services.grafana.provision.dashboards.settings.apiVersion)).
|
||||
|
||||
- Instead of declaring datasources and dashboards in pure Nix, it's also possible
|
||||
to specify configuration files (or directories) with YAML instead using
|
||||
[](#opt-services.grafana.provision.datasources.path) (or
|
||||
[](#opt-services.grafana.provision.dashboards.path). This is useful when having
|
||||
provisioning files from non-NixOS Grafana instances that you also want to
|
||||
deploy to NixOS.
|
||||
|
||||
__Note:__ secrets from these files will be leaked into the store unless you use a
|
||||
[**file**-provider or env-var](https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/#file-provider) for secrets!
|
||||
|
||||
- [](#opt-services.grafana.provision.notifiers) is not affected by this change because
|
||||
this feature is deprecated by Grafana and will probably removed in Grafana 10.
|
||||
It's recommended to use `services.grafana.provision.alerting.contactPoints` instead.
|
||||
|
||||
- The `services.grafana.provision.alerting` option was added. It includes suboptions for every alerting-related objects (with the exception of `notifiers`), which means it's now possible to configure modern Grafana alerting declaratively.
|
||||
|
||||
@@ -383,6 +455,8 @@ Available as [services.patroni](options.html#opt-services.patroni.enable).
|
||||
- `dockerTools.buildImage` deprecates the misunderstood `contents` parameter, in favor of `copyToRoot`.
|
||||
Use `copyToRoot = buildEnv { ... };` or similar if you intend to add packages to `/bin`.
|
||||
|
||||
- The `proxmox.qemuConf.bios` option was added, it corresponds to `Hardware->BIOS` field in Proxmox web interface. Use `"ovmf"` value to build UEFI image, default value remains `"bios"`. New option `proxmox.partitionTableType` defaults to either `"legacy"` or `"efi"`, depending on the `bios` value. Setting `partitionTableType` to `"hybrid"` results in an image, which supports both methods (`"bios"` and `"ovmf"`), thereby remaining bootable after change to Proxmox `Hardware->BIOS` field.
|
||||
|
||||
- memtest86+ was updated from 5.00-coreboot-002 to 6.00-beta2. It is now the upstream version from https://www.memtest.org/, as coreboot's fork is no longer available.
|
||||
|
||||
- Option descriptions, examples, and defaults writting in DocBook are now deprecated. Using CommonMark is preferred and will become the default in a future release.
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
# Release 23.05 (“Stoat”, 2023.05/??) {#sec-release-23.05}
|
||||
|
||||
Support is planned until the end of December 2023, handing over to 23.11.
|
||||
|
||||
## Highlights {#sec-release-23.05-highlights}
|
||||
|
||||
In addition to numerous new and upgraded packages, this release has the following highlights:
|
||||
|
||||
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
|
||||
|
||||
- Create the first release note entry in this section!
|
||||
|
||||
## New Services {#sec-release-23.05-new-services}
|
||||
|
||||
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
|
||||
|
||||
- Create the first release note entry in this section!
|
||||
|
||||
## Backward Incompatibilities {#sec-release-23.05-incompatibilities}
|
||||
|
||||
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
|
||||
|
||||
- Create the first release note entry in this section!
|
||||
|
||||
## 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. -->
|
||||
|
||||
- Create the first release note entry in this section!
|
||||
@@ -684,10 +684,10 @@ class Machine:
|
||||
with self.nested("waiting for {} to appear on tty {}".format(regexp, tty)):
|
||||
retry(tty_matches)
|
||||
|
||||
def send_chars(self, chars: str) -> None:
|
||||
def send_chars(self, chars: str, delay: Optional[float] = 0.01) -> None:
|
||||
with self.nested("sending keys ‘{}‘".format(chars)):
|
||||
for char in chars:
|
||||
self.send_key(char)
|
||||
self.send_key(char, delay)
|
||||
|
||||
def wait_for_file(self, filename: str) -> None:
|
||||
"""Waits until the file exists in machine's file system."""
|
||||
@@ -860,10 +860,11 @@ class Machine:
|
||||
if matches is not None:
|
||||
return
|
||||
|
||||
def send_key(self, key: str) -> None:
|
||||
def send_key(self, key: str, delay: Optional[float] = 0.01) -> None:
|
||||
key = CHAR_TO_KEY.get(key, key)
|
||||
self.send_monitor_command("sendkey {}".format(key))
|
||||
time.sleep(0.01)
|
||||
if delay is not None:
|
||||
time.sleep(delay)
|
||||
|
||||
def send_console(self, chars: str) -> None:
|
||||
assert self.process
|
||||
|
||||
@@ -35,7 +35,7 @@ let
|
||||
'';
|
||||
|
||||
hashedPasswordDescription = ''
|
||||
To generate a hashed password run `mkpasswd -m sha-512`.
|
||||
To generate a hashed password run `mkpasswd`.
|
||||
|
||||
If set to an empty string (`""`), this user will
|
||||
be able to log in without being asked for a password (but not via remote
|
||||
@@ -592,6 +592,26 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
# Warn about user accounts with deprecated password hashing schemes
|
||||
system.activationScripts.hashes = {
|
||||
deps = [ "users" ];
|
||||
text = ''
|
||||
users=()
|
||||
while IFS=: read -r user hash tail; do
|
||||
if [[ "$hash" = "$"* && ! "$hash" =~ ^\$(y|gy|7|2b|2y|2a|6)\$ ]]; then
|
||||
users+=("$user")
|
||||
fi
|
||||
done </etc/shadow
|
||||
|
||||
if (( "''${#users[@]}" )); then
|
||||
echo "
|
||||
WARNING: The following user accounts rely on password hashes that will
|
||||
be removed in NixOS 23.05. They should be renewed as soon as possible."
|
||||
printf ' - %s\n' "''${users[@]}"
|
||||
fi
|
||||
'';
|
||||
};
|
||||
|
||||
# for backwards compatibility
|
||||
system.activationScripts.groups = stringAfter [ "users" ] "";
|
||||
|
||||
|
||||
@@ -14,8 +14,6 @@ in
|
||||
calamares-nixos
|
||||
calamares-nixos-autostart
|
||||
calamares-nixos-extensions
|
||||
# Needed for calamares QML module packagechooserq
|
||||
libsForQt5.full
|
||||
# Get list of locales
|
||||
glibcLocales
|
||||
];
|
||||
|
||||
@@ -382,6 +382,7 @@
|
||||
./services/databases/pgmanage.nix
|
||||
./services/databases/postgresql.nix
|
||||
./services/databases/redis.nix
|
||||
./services/databases/surrealdb.nix
|
||||
./services/databases/victoriametrics.nix
|
||||
./services/desktops/accountsservice.nix
|
||||
./services/desktops/bamf.nix
|
||||
@@ -490,6 +491,7 @@
|
||||
./services/hardware/vdr.nix
|
||||
./services/home-automation/home-assistant.nix
|
||||
./services/home-automation/zigbee2mqtt.nix
|
||||
./services/home-automation/evcc.nix
|
||||
./services/logging/SystemdJournal2Gelf.nix
|
||||
./services/logging/awstats.nix
|
||||
./services/logging/filebeat.nix
|
||||
@@ -718,6 +720,7 @@
|
||||
./services/monitoring/teamviewer.nix
|
||||
./services/monitoring/telegraf.nix
|
||||
./services/monitoring/thanos.nix
|
||||
./services/monitoring/tremor-rs.nix
|
||||
./services/monitoring/tuptime.nix
|
||||
./services/monitoring/unifi-poller.nix
|
||||
./services/monitoring/ups.nix
|
||||
|
||||
@@ -4,17 +4,31 @@ with lib;
|
||||
|
||||
let
|
||||
cfg = config.programs.steam;
|
||||
|
||||
steam = pkgs.steam.override {
|
||||
extraLibraries = pkgs: with config.hardware.opengl;
|
||||
if pkgs.hostPlatform.is64bit
|
||||
then [ package ] ++ extraPackages
|
||||
else [ package32 ] ++ extraPackages32;
|
||||
};
|
||||
in {
|
||||
options.programs.steam = {
|
||||
enable = mkEnableOption (lib.mdDoc "steam");
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.steam.override {
|
||||
extraLibraries = pkgs: with config.hardware.opengl;
|
||||
if pkgs.hostPlatform.is64bit
|
||||
then [ package ] ++ extraPackages
|
||||
else [ package32 ] ++ extraPackages32;
|
||||
};
|
||||
defaultText = literalExpression ''
|
||||
pkgs.steam.override {
|
||||
extraLibraries = pkgs: with config.hardware.opengl;
|
||||
if pkgs.hostPlatform.is64bit
|
||||
then [ package ] ++ extraPackages
|
||||
else [ package32 ] ++ extraPackages32;
|
||||
}
|
||||
'';
|
||||
description = lib.mdDoc ''
|
||||
steam package to use.
|
||||
'';
|
||||
};
|
||||
|
||||
remotePlay.openFirewall = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
@@ -44,7 +58,10 @@ in {
|
||||
|
||||
hardware.steam-hardware.enable = true;
|
||||
|
||||
environment.systemPackages = [ steam steam.run ];
|
||||
environment.systemPackages = [
|
||||
cfg.package
|
||||
cfg.package.run
|
||||
];
|
||||
|
||||
networking.firewall = lib.mkMerge [
|
||||
(mkIf cfg.remotePlay.openFirewall {
|
||||
|
||||
@@ -361,8 +361,10 @@ in {
|
||||
fi
|
||||
echo 'include "${redisConfStore}"' > "${redisConfRun}"
|
||||
${optionalString (conf.requirePassFile != null) ''
|
||||
{echo -n "requirepass "
|
||||
cat ${escapeShellArg conf.requirePassFile}} >> "${redisConfRun}"
|
||||
{
|
||||
echo -n "requirepass "
|
||||
cat ${escapeShellArg conf.requirePassFile}
|
||||
} >> "${redisConfRun}"
|
||||
''}
|
||||
'');
|
||||
Type = "notify";
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
|
||||
cfg = config.services.surrealdb;
|
||||
in {
|
||||
|
||||
options = {
|
||||
services.surrealdb = {
|
||||
enable = mkEnableOption (lib.mdDoc "A scalable, distributed, collaborative, document-graph database, for the realtime web ");
|
||||
|
||||
dbPath = mkOption {
|
||||
type = types.str;
|
||||
description = lib.mdDoc ''
|
||||
The path that surrealdb will write data to. Use null for in-memory.
|
||||
Can be one of "memory", "file://:path", "tikv://:addr".
|
||||
'';
|
||||
default = "file:///var/lib/surrealdb/";
|
||||
example = "memory";
|
||||
};
|
||||
|
||||
host = mkOption {
|
||||
type = types.str;
|
||||
description = lib.mdDoc ''
|
||||
The host that surrealdb will connect to.
|
||||
'';
|
||||
default = "127.0.0.1";
|
||||
example = "127.0.0.1";
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
description = lib.mdDoc ''
|
||||
The port that surrealdb will connect to.
|
||||
'';
|
||||
default = 8000;
|
||||
example = 8000;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
# Used to connect to the running service
|
||||
environment.systemPackages = [ pkgs.surrealdb ] ;
|
||||
|
||||
systemd.services.surrealdb = {
|
||||
description = "A scalable, distributed, collaborative, document-graph database, for the realtime web ";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = "${pkgs.surrealdb}/bin/surreal start --bind ${cfg.host}:${toString cfg.port} ${optionalString (cfg.dbPath != null) "-- ${cfg.dbPath}"}";
|
||||
DynamicUser = true;
|
||||
Restart = "on-failure";
|
||||
StateDirectory = "surrealdb";
|
||||
CapabilityBoundingSet = "";
|
||||
NoNewPrivileges = true;
|
||||
PrivateTmp = true;
|
||||
ProtectHome = true;
|
||||
ProtectClock = true;
|
||||
ProtectProc = "noaccess";
|
||||
ProcSubset = "pid";
|
||||
ProtectKernelLogs = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectControlGroups = true;
|
||||
ProtectHostname = true;
|
||||
RestrictSUIDSGID = true;
|
||||
RestrictRealtime = true;
|
||||
RestrictNamespaces = true;
|
||||
LockPersonality = true;
|
||||
RemoveIPC = true;
|
||||
SystemCallFilter = [ "@system-service" "~@privileged" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -51,7 +51,10 @@ with lib;
|
||||
})
|
||||
|
||||
(mkIf (!config.services.gnome.at-spi2-core.enable) {
|
||||
environment.variables.NO_AT_BRIDGE = "1";
|
||||
environment.variables = {
|
||||
NO_AT_BRIDGE = "1";
|
||||
GTK_A11Y = "none";
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
||||
|
||||
@@ -46,6 +46,11 @@ let
|
||||
SUBSYSTEM=="input", KERNEL=="mice", TAG+="systemd"
|
||||
'';
|
||||
|
||||
nixosInitrdRules = ''
|
||||
# Mark dm devices as db_persist so that they are kept active after switching root
|
||||
SUBSYSTEM=="block", KERNEL=="dm-[0-9]*", ACTION=="add|change", OPTIONS+="db_persist"
|
||||
'';
|
||||
|
||||
# Perform substitutions in all udev rules files.
|
||||
udevRulesFor = { name, udevPackages, udevPath, udev, systemd, binPackages, initrdBin ? null }: pkgs.runCommand name
|
||||
{ preferLocalBuild = true;
|
||||
@@ -364,8 +369,10 @@ in
|
||||
EOF
|
||||
'';
|
||||
|
||||
boot.initrd.services.udev.rules = nixosInitrdRules;
|
||||
|
||||
boot.initrd.systemd.additionalUpstreamUnits = [
|
||||
# TODO: "initrd-udevadm-cleanup-db.service" is commented out because of https://github.com/systemd/systemd/issues/12953
|
||||
"initrd-udevadm-cleanup-db.service"
|
||||
"systemd-udevd-control.socket"
|
||||
"systemd-udevd-kernel.socket"
|
||||
"systemd-udevd.service"
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
{ lib
|
||||
, pkgs
|
||||
, config
|
||||
, ...
|
||||
}:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.evcc;
|
||||
|
||||
format = pkgs.formats.yaml {};
|
||||
configFile = format.generate "evcc.yml" cfg.settings;
|
||||
|
||||
package = pkgs.evcc;
|
||||
in
|
||||
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [ hexa ];
|
||||
|
||||
options.services.evcc = with types; {
|
||||
enable = mkEnableOption (lib.mdDoc "EVCC, the extensible EV Charge Controller with PV integration");
|
||||
|
||||
extraArgs = mkOption {
|
||||
type = listOf str;
|
||||
default = [];
|
||||
description = lib.mdDoc ''
|
||||
Extra arguments to pass to the evcc executable.
|
||||
'';
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
type = format.type;
|
||||
description = lib.mdDoc ''
|
||||
evcc configuration as a Nix attribute set.
|
||||
|
||||
Check for possible options in the sample [evcc.dist.yaml](https://github.com/andig/evcc/blob/${package.version}/evcc.dist.yaml].
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
systemd.services.evcc = {
|
||||
after = [
|
||||
"network-online.target"
|
||||
"mosquitto.target"
|
||||
];
|
||||
wantedBy = [
|
||||
"multi-user.target"
|
||||
];
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = "${package}/bin/evcc --config ${configFile} ${escapeShellArgs cfg.extraArgs}";
|
||||
CapabilityBoundingSet = [ "" ];
|
||||
DeviceAllow = [
|
||||
"char-ttyUSB"
|
||||
];
|
||||
DevicePolicy = "closed";
|
||||
DynamicUser = true;
|
||||
LockPersonality = true;
|
||||
MemoryDenyWriteExecute = true;
|
||||
RestrictAddressFamilies = [
|
||||
"AF_INET"
|
||||
"AF_INET6"
|
||||
"AF_UNIX"
|
||||
];
|
||||
RestrictNamespaces = true;
|
||||
RestrictRealtime = true;
|
||||
PrivateTmp = true;
|
||||
PrivateUsers = true;
|
||||
ProcSubset = "pid";
|
||||
ProtectClock = true;
|
||||
ProtectControlGroups= true;
|
||||
ProtectHome = true;
|
||||
ProtectHostname = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectProc = "invisible";
|
||||
SystemCallArchitectures = "native";
|
||||
SystemCallFilter = [
|
||||
"@system-service"
|
||||
"~@privileged"
|
||||
];
|
||||
UMask = "0077";
|
||||
User = "evcc";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
meta.buildDocsInSandbox = false;
|
||||
}
|
||||
@@ -7,8 +7,8 @@ let
|
||||
registrationFile = "${dataDir}/telegram-registration.yaml";
|
||||
cfg = config.services.mautrix-telegram;
|
||||
settingsFormat = pkgs.formats.json {};
|
||||
settingsFileUnsubstituted = settingsFormat.generate "mautrix-telegram-config-unsubstituted.json" cfg.settings;
|
||||
settingsFile = "${dataDir}/config.json";
|
||||
settingsFile =
|
||||
settingsFormat.generate "mautrix-telegram-config.json" cfg.settings;
|
||||
|
||||
in {
|
||||
options = {
|
||||
@@ -97,12 +97,23 @@ in {
|
||||
default = null;
|
||||
description = lib.mdDoc ''
|
||||
File containing environment variables to be passed to the mautrix-telegram service,
|
||||
in which secret tokens can be specified securely by defining values for
|
||||
in which secret tokens can be specified securely by defining values for e.g.
|
||||
`MAUTRIX_TELEGRAM_APPSERVICE_AS_TOKEN`,
|
||||
`MAUTRIX_TELEGRAM_APPSERVICE_HS_TOKEN`,
|
||||
`MAUTRIX_TELEGRAM_TELEGRAM_API_ID`,
|
||||
`MAUTRIX_TELEGRAM_TELEGRAM_API_HASH` and optionally
|
||||
`MAUTRIX_TELEGRAM_TELEGRAM_BOT_TOKEN`.
|
||||
|
||||
These environment variables can also be used to set other options by
|
||||
replacing hierachy levels by `.`, converting the name to uppercase
|
||||
and prepending `MAUTRIX_TELEGRAM_`.
|
||||
For example, the first value above maps to
|
||||
{option}`settings.appservice.as_token`.
|
||||
|
||||
The environment variable values can be prefixed with `json::` to have
|
||||
them be parsed as JSON. For example, `login_shared_secret_map` can be
|
||||
set as follows:
|
||||
`MAUTRIX_TELEGRAM_BRIDGE_LOGIN_SHARED_SECRET_MAP=json::{"example.com":"secret"}`.
|
||||
'';
|
||||
};
|
||||
|
||||
@@ -141,16 +152,6 @@ in {
|
||||
environment.HOME = dataDir;
|
||||
|
||||
preStart = ''
|
||||
# Not all secrets can be passed as environment variable (yet)
|
||||
# https://github.com/tulir/mautrix-telegram/issues/584
|
||||
[ -f ${settingsFile} ] && rm -f ${settingsFile}
|
||||
old_umask=$(umask)
|
||||
umask 0177
|
||||
${pkgs.envsubst}/bin/envsubst \
|
||||
-o ${settingsFile} \
|
||||
-i ${settingsFileUnsubstituted}
|
||||
umask $old_umask
|
||||
|
||||
# generate the appservice's registration file if absent
|
||||
if [ ! -f '${registrationFile}' ]; then
|
||||
${pkgs.mautrix-telegram}/bin/mautrix-telegram \
|
||||
@@ -186,8 +187,6 @@ in {
|
||||
--config='${settingsFile}'
|
||||
'';
|
||||
};
|
||||
|
||||
restartTriggers = [ settingsFileUnsubstituted ];
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -13,57 +13,96 @@ let
|
||||
settingsFormatIni = pkgs.formats.ini {};
|
||||
configFile = settingsFormatIni.generate "config.ini" cfg.settings;
|
||||
|
||||
datasourceConfiguration = {
|
||||
apiVersion = 1;
|
||||
datasources = cfg.provision.datasources;
|
||||
};
|
||||
mkProvisionCfg = name: attr: provisionCfg:
|
||||
if provisionCfg.path != null
|
||||
then provisionCfg.path
|
||||
else
|
||||
provisioningSettingsFormat.generate "${name}.yaml"
|
||||
(if provisionCfg.settings != null
|
||||
then provisionCfg.settings
|
||||
else {
|
||||
apiVersion = 1;
|
||||
${attr} = [];
|
||||
});
|
||||
|
||||
datasourceFileNew = if (cfg.provision.datasources.path == null) then provisioningSettingsFormat.generate "datasource.yaml" cfg.provision.datasources.settings else cfg.provision.datasources.path;
|
||||
datasourceFile = if (builtins.isList cfg.provision.datasources) then provisioningSettingsFormat.generate "datasource.yaml" datasourceConfiguration else datasourceFileNew;
|
||||
|
||||
dashboardConfiguration = {
|
||||
apiVersion = 1;
|
||||
providers = cfg.provision.dashboards;
|
||||
};
|
||||
|
||||
dashboardFileNew = if (cfg.provision.dashboards.path == null) then provisioningSettingsFormat.generate "dashboard.yaml" cfg.provision.dashboards.settings else cfg.provision.dashboards.path;
|
||||
dashboardFile = if (builtins.isList cfg.provision.dashboards) then provisioningSettingsFormat.generate "dashboard.yaml" dashboardConfiguration else dashboardFileNew;
|
||||
datasourceFileOrDir = mkProvisionCfg "datasource" "datasources" cfg.provision.datasources;
|
||||
dashboardFileOrDir = mkProvisionCfg "dashboard" "providers" cfg.provision.dashboards;
|
||||
|
||||
notifierConfiguration = {
|
||||
apiVersion = 1;
|
||||
notifiers = cfg.provision.notifiers;
|
||||
};
|
||||
|
||||
notifierFile = pkgs.writeText "notifier.yaml" (builtins.toJSON notifierConfiguration);
|
||||
notifierFileOrDir = pkgs.writeText "notifier.yaml" (builtins.toJSON notifierConfiguration);
|
||||
|
||||
generateAlertingProvisioningYaml = x: if (cfg.provision.alerting."${x}".path == null)
|
||||
then provisioningSettingsFormat.generate "${x}.yaml" cfg.provision.alerting."${x}".settings
|
||||
else cfg.provision.alerting."${x}".path;
|
||||
rulesFile = generateAlertingProvisioningYaml "rules";
|
||||
contactPointsFile = generateAlertingProvisioningYaml "contactPoints";
|
||||
policiesFile = generateAlertingProvisioningYaml "policies";
|
||||
templatesFile = generateAlertingProvisioningYaml "templates";
|
||||
muteTimingsFile = generateAlertingProvisioningYaml "muteTimings";
|
||||
rulesFileOrDir = generateAlertingProvisioningYaml "rules";
|
||||
contactPointsFileOrDir = generateAlertingProvisioningYaml "contactPoints";
|
||||
policiesFileOrDir = generateAlertingProvisioningYaml "policies";
|
||||
templatesFileOrDir = generateAlertingProvisioningYaml "templates";
|
||||
muteTimingsFileOrDir = generateAlertingProvisioningYaml "muteTimings";
|
||||
|
||||
provisionConfDir = pkgs.runCommand "grafana-provisioning" { } ''
|
||||
ln = { src, dir, filename }: ''
|
||||
if [[ -d "${src}" ]]; then
|
||||
pushd $out/${dir} &>/dev/null
|
||||
lndir "${src}"
|
||||
popd &>/dev/null
|
||||
else
|
||||
ln -sf ${src} $out/${dir}/${filename}.yaml
|
||||
fi
|
||||
'';
|
||||
provisionConfDir = pkgs.runCommand "grafana-provisioning" { nativeBuildInputs = [ pkgs.xorg.lndir ]; } ''
|
||||
mkdir -p $out/{datasources,dashboards,notifiers,alerting}
|
||||
ln -sf ${datasourceFile} $out/datasources/datasource.yaml
|
||||
ln -sf ${dashboardFile} $out/dashboards/dashboard.yaml
|
||||
ln -sf ${notifierFile} $out/notifiers/notifier.yaml
|
||||
ln -sf ${rulesFile} $out/alerting/rules.yaml
|
||||
ln -sf ${contactPointsFile} $out/alerting/contactPoints.yaml
|
||||
ln -sf ${policiesFile} $out/alerting/policies.yaml
|
||||
ln -sf ${templatesFile} $out/alerting/templates.yaml
|
||||
ln -sf ${muteTimingsFile} $out/alerting/muteTimings.yaml
|
||||
${ln { src = datasourceFileOrDir; dir = "datasources"; filename = "datasource"; }}
|
||||
${ln { src = dashboardFileOrDir; dir = "dashboards"; filename = "dashbaord"; }}
|
||||
${ln { src = notifierFileOrDir; dir = "notifiers"; filename = "notifier"; }}
|
||||
${ln { src = rulesFileOrDir; dir = "alerting"; filename = "rules"; }}
|
||||
${ln { src = contactPointsFileOrDir; dir = "alerting"; filename = "contactPoints"; }}
|
||||
${ln { src = policiesFileOrDir; dir = "alerting"; filename = "policies"; }}
|
||||
${ln { src = templatesFileOrDir; dir = "alerting"; filename = "templates"; }}
|
||||
${ln { src = muteTimingsFileOrDir; dir = "alerting"; filename = "muteTimings"; }}
|
||||
'';
|
||||
|
||||
# Get a submodule without any embedded metadata:
|
||||
_filter = x: filterAttrs (k: v: k != "_module") x;
|
||||
|
||||
# FIXME(@Ma27) remove before 23.05. This is just a helper-type
|
||||
# because `mkRenamedOptionModule` doesn't work if `foo.bar` is renamed
|
||||
# to `foo.bar.baz`.
|
||||
submodule' = module: types.coercedTo
|
||||
(mkOptionType {
|
||||
name = "grafana-provision-submodule";
|
||||
description = "Wrapper-type for backwards compat of Grafana's declarative provisioning";
|
||||
check = x:
|
||||
if builtins.isList x then
|
||||
throw ''
|
||||
Provisioning dashboards and datasources declaratively by
|
||||
setting `dashboards` or `datasources` to a list is not supported
|
||||
anymore. Use `services.grafana.provision.datasources.settings.datasources`
|
||||
(or `services.grafana.provision.dashboards.settings.providers`) instead.
|
||||
''
|
||||
else isAttrs x || isFunction x;
|
||||
})
|
||||
id
|
||||
(types.submodule module);
|
||||
|
||||
# http://docs.grafana.org/administration/provisioning/#datasources
|
||||
grafanaTypes.datasourceConfig = types.submodule {
|
||||
freeformType = provisioningSettingsFormat.type;
|
||||
|
||||
imports = [
|
||||
(mkRemovedOptionModule [ "password" ] ''
|
||||
`services.grafana.provision.datasources.settings.datasources.<name>.password` has been removed
|
||||
in Grafana 9. Use `secureJsonData` instead.
|
||||
'')
|
||||
(mkRemovedOptionModule [ "basicAuthPassword" ] ''
|
||||
`services.grafana.provision.datasources.settings.datasources.<name>.basicAuthPassword` has been removed
|
||||
in Grafana 9. Use `secureJsonData` instead.
|
||||
'')
|
||||
];
|
||||
|
||||
options = {
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
@@ -93,28 +132,6 @@ let
|
||||
default = false;
|
||||
description = lib.mdDoc "Allow users to edit datasources from the UI.";
|
||||
};
|
||||
password = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = lib.mdDoc ''
|
||||
Database password, if used. Please note that the contents of this option
|
||||
will end up in a world-readable Nix store. Use the file provider
|
||||
pointing at a reasonably secured file in the local filesystem
|
||||
to work around that. Look at the documentation for details:
|
||||
<https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/#file-provider>
|
||||
'';
|
||||
};
|
||||
basicAuthPassword = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = lib.mdDoc ''
|
||||
Basic auth password. Please note that the contents of this option
|
||||
will end up in a world-readable Nix store. Use the file provider
|
||||
pointing at a reasonably secured file in the local filesystem
|
||||
to work around that. Look at the documentation for details:
|
||||
<https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/#file-provider>
|
||||
'';
|
||||
};
|
||||
secureJsonData = mkOption {
|
||||
type = types.nullOr types.attrs;
|
||||
default = null;
|
||||
@@ -276,6 +293,10 @@ in {
|
||||
(mkRemovedOptionModule [ "services" "grafana" "auth" "google" "clientSecretFile" ] ''
|
||||
This option has been removed. Use 'services.grafana.settings.google.client_secret' with file provider instead.
|
||||
'')
|
||||
(mkRemovedOptionModule [ "services" "grafana" "extraOptions" ] ''
|
||||
This option has been removed. Use 'services.grafana.settings' instead. For a detailed migration guide, please
|
||||
review the release notes of NixOS 22.11.
|
||||
'')
|
||||
|
||||
(mkRemovedOptionModule [ "services" "grafana" "auth" "azuread" "tenantId" ] "This option has been deprecated upstream.")
|
||||
];
|
||||
@@ -330,19 +351,7 @@ in {
|
||||
Don't change the value of this option if you are planning to use `services.grafana.provision` options.
|
||||
'';
|
||||
default = provisionConfDir;
|
||||
defaultText = literalExpression ''
|
||||
pkgs.runCommand "grafana-provisioning" { } \'\'
|
||||
mkdir -p $out/{datasources,dashboards,notifiers,alerting}
|
||||
ln -sf ''${datasourceFile} $out/datasources/datasource.yaml
|
||||
ln -sf ''${dashboardFile} $out/dashboards/dashboard.yaml
|
||||
ln -sf ''${notifierFile} $out/notifiers/notifier.yaml
|
||||
ln -sf ''${rulesFile} $out/alerting/rules.yaml
|
||||
ln -sf ''${contactPointsFile} $out/alerting/contactPoints.yaml
|
||||
ln -sf ''${policiesFile} $out/alerting/policies.yaml
|
||||
ln -sf ''${templatesFile} $out/alerting/templates.yaml
|
||||
ln -sf ''${muteTimingsFile} $out/alerting/muteTimings.yaml
|
||||
\'\'
|
||||
'';
|
||||
defaultText = "directory with links to files generated from services.grafana.provision";
|
||||
type = types.path;
|
||||
};
|
||||
};
|
||||
@@ -564,17 +573,14 @@ in {
|
||||
|
||||
datasources = mkOption {
|
||||
description = lib.mdDoc ''
|
||||
Deprecated option for Grafana datasource configuration. Use either
|
||||
`services.grafana.provision.datasources.settings` or
|
||||
`services.grafana.provision.datasources.path` instead.
|
||||
Declaratively provision Grafana's datasources.
|
||||
'';
|
||||
default = [];
|
||||
apply = x: if (builtins.isList x) then map _filter x else x;
|
||||
type = with types; either (listOf grafanaTypes.datasourceConfig) (submodule {
|
||||
default = {};
|
||||
type = submodule' {
|
||||
options.settings = mkOption {
|
||||
description = lib.mdDoc ''
|
||||
Grafana datasource configuration in Nix. Can't be used with
|
||||
`services.grafana.provision.datasources.path` simultaneously. See
|
||||
[](#opt-services.grafana.provision.datasources.path) simultaneously. See
|
||||
<https://grafana.com/docs/grafana/latest/administration/provisioning/#data-sources>
|
||||
for supported options.
|
||||
'';
|
||||
@@ -591,6 +597,7 @@ in {
|
||||
description = lib.mdDoc "List of datasources to insert/update.";
|
||||
default = [];
|
||||
type = types.listOf grafanaTypes.datasourceConfig;
|
||||
apply = map (flip builtins.removeAttrs [ "password" "basicAuthPassword" ]);
|
||||
};
|
||||
|
||||
deleteDatasources = mkOption {
|
||||
@@ -630,28 +637,26 @@ in {
|
||||
options.path = mkOption {
|
||||
description = lib.mdDoc ''
|
||||
Path to YAML datasource configuration. Can't be used with
|
||||
`services.grafana.provision.datasources.settings` simultaneously.
|
||||
[](#opt-services.grafana.provision.datasources.settings) simultaneously.
|
||||
Can be either a directory or a single YAML file. Will end up in the store.
|
||||
'';
|
||||
default = null;
|
||||
type = types.nullOr types.path;
|
||||
};
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
dashboards = mkOption {
|
||||
description = lib.mdDoc ''
|
||||
Deprecated option for Grafana dashboard configuration. Use either
|
||||
`services.grafana.provision.dashboards.settings` or
|
||||
`services.grafana.provision.dashboards.path` instead.
|
||||
Declaratively provision Grafana's dashboards.
|
||||
'';
|
||||
default = [];
|
||||
apply = x: if (builtins.isList x) then map _filter x else x;
|
||||
type = with types; either (listOf grafanaTypes.dashboardConfig) (submodule {
|
||||
default = {};
|
||||
type = submodule' {
|
||||
options.settings = mkOption {
|
||||
description = lib.mdDoc ''
|
||||
Grafana dashboard configuration in Nix. Can't be used with
|
||||
`services.grafana.provision.dashboards.path` simultaneously. See
|
||||
[](#opt-services.grafana.provision.dashboards.path) simultaneously. See
|
||||
<https://grafana.com/docs/grafana/latest/administration/provisioning/#dashboards>
|
||||
for supported options.
|
||||
'';
|
||||
@@ -684,12 +689,13 @@ in {
|
||||
options.path = mkOption {
|
||||
description = lib.mdDoc ''
|
||||
Path to YAML dashboard configuration. Can't be used with
|
||||
`services.grafana.provision.dashboards.settings` simultaneously.
|
||||
[](#opt-services.grafana.provision.dashboards.settings) simultaneously.
|
||||
Can be either a directory or a single YAML file. Will end up in the store.
|
||||
'';
|
||||
default = null;
|
||||
type = types.nullOr types.path;
|
||||
};
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -706,7 +712,8 @@ in {
|
||||
path = mkOption {
|
||||
description = lib.mdDoc ''
|
||||
Path to YAML rules configuration. Can't be used with
|
||||
`services.grafana.provision.alerting.rules.settings` simultaneously.
|
||||
[](#opt-services.grafana.provision.alerting.rules.settings) simultaneously.
|
||||
Can be either a directory or a single YAML file. Will end up in the store.
|
||||
'';
|
||||
default = null;
|
||||
type = types.nullOr types.path;
|
||||
@@ -715,7 +722,7 @@ in {
|
||||
settings = mkOption {
|
||||
description = lib.mdDoc ''
|
||||
Grafana rules configuration in Nix. Can't be used with
|
||||
`services.grafana.provision.alerting.rules.path` simultaneously. See
|
||||
[](#opt-services.grafana.provision.alerting.rules.path) simultaneously. See
|
||||
<https://grafana.com/docs/grafana/latest/administration/provisioning/#rules>
|
||||
for supported options.
|
||||
'';
|
||||
@@ -829,7 +836,8 @@ in {
|
||||
path = mkOption {
|
||||
description = lib.mdDoc ''
|
||||
Path to YAML contact points configuration. Can't be used with
|
||||
`services.grafana.provision.alerting.contactPoints.settings` simultaneously.
|
||||
[](#opt-services.grafana.provision.alerting.contactPoints.settings) simultaneously.
|
||||
Can be either a directory or a single YAML file. Will end up in the store.
|
||||
'';
|
||||
default = null;
|
||||
type = types.nullOr types.path;
|
||||
@@ -838,7 +846,7 @@ in {
|
||||
settings = mkOption {
|
||||
description = lib.mdDoc ''
|
||||
Grafana contact points configuration in Nix. Can't be used with
|
||||
`services.grafana.provision.alerting.contactPoints.path` simultaneously. See
|
||||
[](#opt-services.grafana.provision.alerting.contactPoints.path) simultaneously. See
|
||||
<https://grafana.com/docs/grafana/latest/administration/provisioning/#contact-points>
|
||||
for supported options.
|
||||
'';
|
||||
@@ -852,7 +860,7 @@ in {
|
||||
};
|
||||
|
||||
contactPoints = mkOption {
|
||||
description = lib.mdDoc "List of contact points to import or update. Please note that sensitive data will end up in world-readable Nix store.";
|
||||
description = lib.mdDoc "List of contact points to import or update.";
|
||||
default = [];
|
||||
type = types.listOf (types.submodule {
|
||||
freeformType = provisioningSettingsFormat.type;
|
||||
@@ -909,7 +917,8 @@ in {
|
||||
path = mkOption {
|
||||
description = lib.mdDoc ''
|
||||
Path to YAML notification policies configuration. Can't be used with
|
||||
`services.grafana.provision.alerting.policies.settings` simultaneously.
|
||||
[](#opt-services.grafana.provision.alerting.policies.settings) simultaneously.
|
||||
Can be either a directory or a single YAML file. Will end up in the store.
|
||||
'';
|
||||
default = null;
|
||||
type = types.nullOr types.path;
|
||||
@@ -918,7 +927,7 @@ in {
|
||||
settings = mkOption {
|
||||
description = lib.mdDoc ''
|
||||
Grafana notification policies configuration in Nix. Can't be used with
|
||||
`services.grafana.provision.alerting.policies.path` simultaneously. See
|
||||
[](#opt-services.grafana.provision.alerting.policies.path) simultaneously. See
|
||||
<https://grafana.com/docs/grafana/latest/administration/provisioning/#notification-policies>
|
||||
for supported options.
|
||||
'';
|
||||
@@ -978,7 +987,8 @@ in {
|
||||
path = mkOption {
|
||||
description = lib.mdDoc ''
|
||||
Path to YAML templates configuration. Can't be used with
|
||||
`services.grafana.provision.alerting.templates.settings` simultaneously.
|
||||
[](#opt-services.grafana.provision.alerting.templates.settings) simultaneously.
|
||||
Can be either a directory or a single YAML file. Will end up in the store.
|
||||
'';
|
||||
default = null;
|
||||
type = types.nullOr types.path;
|
||||
@@ -987,7 +997,7 @@ in {
|
||||
settings = mkOption {
|
||||
description = lib.mdDoc ''
|
||||
Grafana templates configuration in Nix. Can't be used with
|
||||
`services.grafana.provision.alerting.templates.path` simultaneously. See
|
||||
[](#opt-services.grafana.provision.alerting.templates.path) simultaneously. See
|
||||
<https://grafana.com/docs/grafana/latest/administration/provisioning/#templates>
|
||||
for supported options.
|
||||
'';
|
||||
@@ -1059,7 +1069,8 @@ in {
|
||||
path = mkOption {
|
||||
description = lib.mdDoc ''
|
||||
Path to YAML mute timings configuration. Can't be used with
|
||||
`services.grafana.provision.alerting.muteTimings.settings` simultaneously.
|
||||
[](#opt-services.grafana.provision.alerting.muteTimings.settings) simultaneously.
|
||||
Can be either a directory or a single YAML file. Will end up in the store.
|
||||
'';
|
||||
default = null;
|
||||
type = types.nullOr types.path;
|
||||
@@ -1068,7 +1079,7 @@ in {
|
||||
settings = mkOption {
|
||||
description = lib.mdDoc ''
|
||||
Grafana mute timings configuration in Nix. Can't be used with
|
||||
`services.grafana.provision.alerting.muteTimings.path` simultaneously. See
|
||||
[](#opt-services.grafana.provision.alerting.muteTimings.path) simultaneously. See
|
||||
<https://grafana.com/docs/grafana/latest/administration/provisioning/#mute-timings>
|
||||
for supported options.
|
||||
'';
|
||||
@@ -1159,52 +1170,50 @@ in {
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
warnings = let
|
||||
usesFileProvider = opt: defaultValue: builtins.match "^${defaultValue}$|^\\$__file\\{.*}$" opt != null;
|
||||
in flatten [
|
||||
(optional (
|
||||
! usesFileProvider cfg.settings.database.password "" ||
|
||||
! usesFileProvider cfg.settings.security.admin_password "admin"
|
||||
) "Grafana passwords will be stored as plaintext in the Nix store! Use file provider instead.")
|
||||
(optional (
|
||||
doesntUseFileProvider = opt: defaultValue:
|
||||
let
|
||||
checkOpts = opt: any (x: x.password != null || x.basicAuthPassword != null || x.secureJsonData != null) opt;
|
||||
datasourcesUsed = if (cfg.provision.datasources.settings == null) then [] else cfg.provision.datasources.settings.datasources;
|
||||
in if (builtins.isList cfg.provision.datasources) then checkOpts cfg.provision.datasources else checkOpts datasourcesUsed
|
||||
) ''
|
||||
Datasource passwords will be stored as plaintext in the Nix store!
|
||||
It is not possible to use file provider in provisioning; please provision
|
||||
datasources via `services.grafana.provision.datasources.path` instead.
|
||||
'')
|
||||
regex = "${optionalString (defaultValue != null) "^${defaultValue}$|"}^\\$__(file|env)\\{.*}$|^\\$[^_\\$][^ ]+$";
|
||||
in builtins.match regex opt == null;
|
||||
in
|
||||
# Ensure that no custom credentials are leaked into the Nix store. Unless the default value
|
||||
# is specified, this can be achieved by using the file/env provider:
|
||||
# https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/#variable-expansion
|
||||
(optional (
|
||||
doesntUseFileProvider cfg.settings.database.password "" ||
|
||||
doesntUseFileProvider cfg.settings.security.admin_password "admin"
|
||||
) ''
|
||||
Grafana passwords will be stored as plaintext in the Nix store!
|
||||
Use file provider or an env-var instead.
|
||||
'')
|
||||
# Warn about deprecated notifiers.
|
||||
++ (optional (cfg.provision.notifiers != []) ''
|
||||
Notifiers are deprecated upstream and will be removed in Grafana 10.
|
||||
Use `services.grafana.provision.alerting.contactPoints` instead.
|
||||
'')
|
||||
# Ensure that `secureJsonData` of datasources provisioned via `datasources.settings`
|
||||
# only uses file/env providers.
|
||||
++ (optional (
|
||||
let
|
||||
datasourcesToCheck = optionals
|
||||
(cfg.provision.datasources.settings != null)
|
||||
cfg.provision.datasources.settings.datasources;
|
||||
declarationUnsafe = { secureJsonData, ... }:
|
||||
secureJsonData != null
|
||||
&& any (flip doesntUseFileProvider null) (attrValues secureJsonData);
|
||||
in any declarationUnsafe datasourcesToCheck
|
||||
) ''
|
||||
Declarations in the `secureJsonData`-block of a datasource will be leaked to the
|
||||
Nix store unless a file-provider or an env-var is used!
|
||||
'')
|
||||
++ (optional (
|
||||
any (x: x.secure_settings != null) cfg.provision.notifiers
|
||||
) "Notifier secure settings will be stored as plaintext in the Nix store! Use file provider instead.")
|
||||
(optional (
|
||||
builtins.isList cfg.provision.datasources && cfg.provision.datasources != []
|
||||
) ''
|
||||
Provisioning Grafana datasources with options has been deprecated.
|
||||
Use `services.grafana.provision.datasources.settings` or
|
||||
`services.grafana.provision.datasources.path` instead.
|
||||
'')
|
||||
(optional (
|
||||
builtins.isList cfg.provision.datasources && cfg.provision.dashboards != []
|
||||
) ''
|
||||
Provisioning Grafana dashboards with options has been deprecated.
|
||||
Use `services.grafana.provision.dashboards.settings` or
|
||||
`services.grafana.provision.dashboards.path` instead.
|
||||
'')
|
||||
(optional (
|
||||
cfg.provision.notifiers != []
|
||||
) ''
|
||||
Notifiers are deprecated upstream and will be removed in Grafana 10.
|
||||
Use `services.grafana.provision.alerting.contactPoints` instead.
|
||||
'')
|
||||
];
|
||||
) "Notifier secure settings will be stored as plaintext in the Nix store! Use file provider instead.");
|
||||
|
||||
environment.systemPackages = [ cfg.package ];
|
||||
|
||||
assertions = [
|
||||
{
|
||||
assertion = if (builtins.isList cfg.provision.datasources) then true else cfg.provision.datasources.settings == null || cfg.provision.datasources.path == null;
|
||||
assertion = cfg.provision.datasources.settings == null || cfg.provision.datasources.path == null;
|
||||
message = "Cannot set both datasources settings and datasources path";
|
||||
}
|
||||
{
|
||||
@@ -1213,12 +1222,11 @@ in {
|
||||
({ type, access, ... }: type == "prometheus" -> access != "direct")
|
||||
opt;
|
||||
in
|
||||
if (builtins.isList cfg.provision.datasources) then prometheusIsNotDirect cfg.provision.datasources
|
||||
else cfg.provision.datasources.settings == null || prometheusIsNotDirect cfg.provision.datasources.settings.datasources;
|
||||
cfg.provision.datasources.settings == null || prometheusIsNotDirect cfg.provision.datasources.settings.datasources;
|
||||
message = "For datasources of type `prometheus`, the `direct` access mode is not supported anymore (since Grafana 9.2.0)";
|
||||
}
|
||||
{
|
||||
assertion = if (builtins.isList cfg.provision.dashboards) then true else cfg.provision.dashboards.settings == null || cfg.provision.dashboards.path == null;
|
||||
assertion = cfg.provision.dashboards.settings == null || cfg.provision.dashboards.path == null;
|
||||
message = "Cannot set both dashboards settings and dashboards path";
|
||||
}
|
||||
{
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
|
||||
cfg = config.services.tremor-rs;
|
||||
|
||||
loggerSettingsFormat = pkgs.formats.yaml { };
|
||||
loggerConfigFile = loggerSettingsFormat.generate "logger.yaml" cfg.loggerSettings;
|
||||
in {
|
||||
|
||||
options = {
|
||||
services.tremor-rs = {
|
||||
enable = lib.mkEnableOption (lib.mdDoc "Tremor event- or stream-processing system");
|
||||
|
||||
troyFileList = mkOption {
|
||||
type = types.listOf types.path;
|
||||
default = [];
|
||||
description = lib.mdDoc "List of troy files to load.";
|
||||
};
|
||||
|
||||
tremorLibDir = mkOption {
|
||||
type = types.path;
|
||||
default = "";
|
||||
description = lib.mdDoc "Directory where to find /lib containing tremor script files";
|
||||
};
|
||||
|
||||
host = mkOption {
|
||||
type = types.str;
|
||||
default = "127.0.0.1";
|
||||
description = lib.mdDoc "The host tremor should be listening on";
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
default = 9898;
|
||||
description = lib.mdDoc "the port tremor should be listening on";
|
||||
};
|
||||
|
||||
loggerSettings = mkOption {
|
||||
description = lib.mdDoc "Tremor logger configuration";
|
||||
default = {};
|
||||
type = loggerSettingsFormat.type;
|
||||
|
||||
example = {
|
||||
refresh_rate = "30 seconds";
|
||||
appenders.stdout.kind = "console";
|
||||
root = {
|
||||
level = "warn";
|
||||
appenders = [ "stdout" ];
|
||||
};
|
||||
loggers = {
|
||||
tremor_runtime = {
|
||||
level = "debug";
|
||||
appenders = [ "stdout" ];
|
||||
additive = false;
|
||||
};
|
||||
tremor = {
|
||||
level = "debug";
|
||||
appenders = [ "stdout" ];
|
||||
additive = false;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
defaultText = literalExpression ''
|
||||
{
|
||||
refresh_rate = "30 seconds";
|
||||
appenders.stdout.kind = "console";
|
||||
root = {
|
||||
level = "warn";
|
||||
appenders = [ "stdout" ];
|
||||
};
|
||||
loggers = {
|
||||
tremor_runtime = {
|
||||
level = "debug";
|
||||
appenders = [ "stdout" ];
|
||||
additive = false;
|
||||
};
|
||||
tremor = {
|
||||
level = "debug";
|
||||
appenders = [ "stdout" ];
|
||||
additive = false;
|
||||
};
|
||||
};
|
||||
}
|
||||
'';
|
||||
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf (cfg.enable) {
|
||||
|
||||
environment.systemPackages = [ pkgs.tremor-rs ] ;
|
||||
|
||||
systemd.services.tremor-rs = {
|
||||
description = "Tremor event- or stream-processing system";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
requires = [ "network-online.target" ];
|
||||
after = [ "network-online.target" ];
|
||||
|
||||
environment.TREMOR_PATH = "${pkgs.tremor-rs}/lib:${cfg.tremorLibDir}";
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = "${pkgs.tremor-rs}/bin/tremor --logger-config ${loggerConfigFile} server run ${concatStringsSep " " cfg.troyFileList} --api-host ${cfg.host}:${toString cfg.port}";
|
||||
DynamicUser = true;
|
||||
Restart = "always";
|
||||
NoNewPrivileges = true;
|
||||
PrivateTmp = true;
|
||||
ProtectHome = true;
|
||||
ProtectClock = true;
|
||||
ProtectProc = "noaccess";
|
||||
ProcSubset = "pid";
|
||||
ProtectKernelLogs = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectControlGroups = true;
|
||||
ProtectHostname = true;
|
||||
RestrictSUIDSGID = true;
|
||||
RestrictRealtime = true;
|
||||
RestrictNamespaces = true;
|
||||
LockPersonality = true;
|
||||
RemoveIPC = true;
|
||||
SystemCallFilter = [ "@system-service" "~@privileged" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -325,7 +325,7 @@ in
|
||||
example = literalExpression "pkgs.iptables-legacy";
|
||||
description =
|
||||
lib.mdDoc ''
|
||||
The iptables package to use for running the firewall service."
|
||||
The iptables package to use for running the firewall service.
|
||||
'';
|
||||
};
|
||||
|
||||
|
||||
@@ -41,7 +41,11 @@ in {
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
warnings = optional (firewallOn && rpfIsStrict) "Strict reverse path filtering breaks Tailscale exit node use and some subnet routing setups. Consider setting `networking.firewall.checkReversePath` = 'loose'";
|
||||
warnings = optional (firewallOn && rpfIsStrict) ''
|
||||
Strict reverse path filtering breaks Tailscale exit node use and some subnet routing setups. Consider setting:
|
||||
|
||||
networking.firewall.checkReversePath = "loose";
|
||||
'';
|
||||
environment.systemPackages = [ cfg.package ]; # for the CLI
|
||||
systemd.packages = [ cfg.package ];
|
||||
systemd.services.tailscaled = {
|
||||
|
||||
@@ -22,9 +22,9 @@ let
|
||||
# we can only check for values consistently after converting them to their corresponding environment variable name.
|
||||
configEnv =
|
||||
let
|
||||
configEnv = listToAttrs (concatLists (mapAttrsToList (name: value:
|
||||
if value != null then [ (nameValuePair (nameToEnvVar name) (if isBool value then boolToString value else toString value)) ] else []
|
||||
) cfg.config));
|
||||
configEnv = concatMapAttrs (name: value: optionalAttrs (value != null) {
|
||||
${nameToEnvVar name} = if isBool value then boolToString value else toString value;
|
||||
}) cfg.config;
|
||||
in { DATA_FOLDER = "/var/lib/bitwarden_rs"; } // optionalAttrs (!(configEnv ? WEB_VAULT_ENABLED) || configEnv.WEB_VAULT_ENABLED == "true") {
|
||||
WEB_VAULT_FOLDER = "${cfg.webVaultPackage}/share/vaultwarden/vault";
|
||||
} // configEnv;
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
# D-Bus configuration and system bus daemon.
|
||||
|
||||
{ config, lib, options, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
|
||||
@@ -16,11 +14,11 @@ let
|
||||
serviceDirectories = cfg.packages;
|
||||
};
|
||||
|
||||
inherit (lib) mkOption mkIf mkMerge types;
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
###### interface
|
||||
|
||||
options = {
|
||||
|
||||
services.dbus = {
|
||||
@@ -35,6 +33,18 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
implementation = mkOption {
|
||||
type = types.enum [ "dbus" "broker" ];
|
||||
default = "dbus";
|
||||
description = lib.mdDoc ''
|
||||
The implementation to use for the message bus defined by the D-Bus specification.
|
||||
Can be either the classic dbus daemon or dbus-broker, which aims to provide high
|
||||
performance and reliability, while keeping compatibility to the D-Bus
|
||||
reference implementation.
|
||||
'';
|
||||
|
||||
};
|
||||
|
||||
packages = mkOption {
|
||||
type = types.listOf types.path;
|
||||
default = [ ];
|
||||
@@ -65,75 +75,117 @@ in
|
||||
'';
|
||||
default = "disabled";
|
||||
};
|
||||
|
||||
socketActivated = mkOption {
|
||||
type = types.nullOr types.bool;
|
||||
default = null;
|
||||
visible = false;
|
||||
description = lib.mdDoc ''
|
||||
Removed option, do not use.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
###### implementation
|
||||
config = mkIf cfg.enable (mkMerge [
|
||||
{
|
||||
environment.etc."dbus-1".source = configDir;
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
warnings = optional (cfg.socketActivated != null) (
|
||||
let
|
||||
files = showFiles options.services.dbus.socketActivated.files;
|
||||
in
|
||||
"The option 'services.dbus.socketActivated' in ${files} no longer has"
|
||||
+ " any effect and can be safely removed: the user D-Bus session is"
|
||||
+ " now always socket activated."
|
||||
);
|
||||
environment.pathsToLink = [
|
||||
"/etc/dbus-1"
|
||||
"/share/dbus-1"
|
||||
];
|
||||
|
||||
environment.systemPackages = [ pkgs.dbus.daemon pkgs.dbus ];
|
||||
users.users.messagebus = {
|
||||
uid = config.ids.uids.messagebus;
|
||||
description = "D-Bus system message bus daemon user";
|
||||
home = homeDir;
|
||||
group = "messagebus";
|
||||
};
|
||||
|
||||
environment.etc."dbus-1".source = configDir;
|
||||
users.groups.messagebus.gid = config.ids.gids.messagebus;
|
||||
|
||||
users.users.messagebus = {
|
||||
uid = config.ids.uids.messagebus;
|
||||
description = "D-Bus system message bus daemon user";
|
||||
home = homeDir;
|
||||
group = "messagebus";
|
||||
};
|
||||
# You still need the dbus reference implementation installed to use dbus-broker
|
||||
systemd.packages = [
|
||||
pkgs.dbus
|
||||
];
|
||||
|
||||
users.groups.messagebus.gid = config.ids.gids.messagebus;
|
||||
services.dbus.packages = [
|
||||
pkgs.dbus
|
||||
config.system.path
|
||||
];
|
||||
|
||||
systemd.packages = [ pkgs.dbus.daemon ];
|
||||
systemd.user.sockets.dbus.wantedBy = [
|
||||
"sockets.target"
|
||||
];
|
||||
}
|
||||
|
||||
security.wrappers.dbus-daemon-launch-helper = {
|
||||
source = "${pkgs.dbus.daemon}/libexec/dbus-daemon-launch-helper";
|
||||
owner = "root";
|
||||
group = "messagebus";
|
||||
setuid = true;
|
||||
setgid = false;
|
||||
permissions = "u+rx,g+rx,o-rx";
|
||||
};
|
||||
(mkIf (cfg.implementation == "dbus") {
|
||||
environment.systemPackages = [
|
||||
pkgs.dbus
|
||||
];
|
||||
|
||||
services.dbus.packages = [
|
||||
pkgs.dbus.out
|
||||
config.system.path
|
||||
];
|
||||
security.wrappers.dbus-daemon-launch-helper = {
|
||||
source = "${pkgs.dbus}/libexec/dbus-daemon-launch-helper";
|
||||
owner = "root";
|
||||
group = "messagebus";
|
||||
setuid = true;
|
||||
setgid = false;
|
||||
permissions = "u+rx,g+rx,o-rx";
|
||||
};
|
||||
|
||||
systemd.services.dbus = {
|
||||
# Don't restart dbus-daemon. Bad things tend to happen if we do.
|
||||
reloadIfChanged = true;
|
||||
restartTriggers = [ configDir ];
|
||||
environment = { LD_LIBRARY_PATH = config.system.nssModules.path; };
|
||||
};
|
||||
|
||||
systemd.user = {
|
||||
services.dbus = {
|
||||
systemd.services.dbus = {
|
||||
# Don't restart dbus-daemon. Bad things tend to happen if we do.
|
||||
reloadIfChanged = true;
|
||||
restartTriggers = [ configDir ];
|
||||
restartTriggers = [
|
||||
configDir
|
||||
];
|
||||
environment = {
|
||||
LD_LIBRARY_PATH = config.system.nssModules.path;
|
||||
};
|
||||
};
|
||||
sockets.dbus.wantedBy = [ "sockets.target" ];
|
||||
};
|
||||
|
||||
environment.pathsToLink = [ "/etc/dbus-1" "/share/dbus-1" ];
|
||||
};
|
||||
systemd.user.services.dbus = {
|
||||
# Don't restart dbus-daemon. Bad things tend to happen if we do.
|
||||
reloadIfChanged = true;
|
||||
restartTriggers = [
|
||||
configDir
|
||||
];
|
||||
};
|
||||
|
||||
})
|
||||
|
||||
(mkIf (cfg.implementation == "broker") {
|
||||
environment.systemPackages = [
|
||||
pkgs.dbus-broker
|
||||
];
|
||||
|
||||
systemd.packages = [
|
||||
pkgs.dbus-broker
|
||||
];
|
||||
|
||||
# Just to be sure we don't restart through the unit alias
|
||||
systemd.services.dbus.reloadIfChanged = true;
|
||||
systemd.user.services.dbus.reloadIfChanged = true;
|
||||
|
||||
# NixOS Systemd Module doesn't respect 'Install'
|
||||
# https://github.com/NixOS/nixpkgs/issues/108643
|
||||
systemd.services.dbus-broker = {
|
||||
aliases = [
|
||||
"dbus.service"
|
||||
];
|
||||
# Don't restart dbus. Bad things tend to happen if we do.
|
||||
reloadIfChanged = true;
|
||||
restartTriggers = [
|
||||
configDir
|
||||
];
|
||||
environment = {
|
||||
LD_LIBRARY_PATH = config.system.nssModules.path;
|
||||
};
|
||||
};
|
||||
|
||||
systemd.user.services.dbus-broker = {
|
||||
aliases = [
|
||||
"dbus.service"
|
||||
];
|
||||
# Don't restart dbus. Bad things tend to happen if we do.
|
||||
reloadIfChanged = true;
|
||||
restartTriggers = [
|
||||
configDir
|
||||
];
|
||||
};
|
||||
})
|
||||
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -70,6 +70,23 @@ in {
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
internal = true;
|
||||
type = types.package;
|
||||
default = pkgs.alps;
|
||||
};
|
||||
|
||||
args = mkOption {
|
||||
internal = true;
|
||||
type = types.listOf types.str;
|
||||
default = [
|
||||
"-addr" "${cfg.bindIP}:${toString cfg.port}"
|
||||
"-theme" "${cfg.theme}"
|
||||
"imaps://${cfg.imaps.host}:${toString cfg.imaps.port}"
|
||||
"smpts://${cfg.smtps.host}:${toString cfg.smtps.port}"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
@@ -80,16 +97,33 @@ in {
|
||||
after = [ "network.target" "network-online.target" ];
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = ''
|
||||
${pkgs.alps}/bin/alps \
|
||||
-addr ${cfg.bindIP}:${toString cfg.port} \
|
||||
-theme ${cfg.theme} \
|
||||
imaps://${cfg.imaps.host}:${toString cfg.imaps.port} \
|
||||
smpts://${cfg.smtps.host}:${toString cfg.smtps.port}
|
||||
'';
|
||||
StateDirectory = "alps";
|
||||
WorkingDirectory = "/var/lib/alps";
|
||||
ExecStart = "${cfg.package}/bin/alps ${escapeShellArgs cfg.args}";
|
||||
DynamicUser = true;
|
||||
## This is desirable but would restrict bindIP to 127.0.0.1
|
||||
#IPAddressAllow = "localhost";
|
||||
#IPAddressDeny = "any";
|
||||
LockPersonality = true;
|
||||
NoNewPrivileges = true;
|
||||
PrivateDevices = true;
|
||||
PrivateIPC = true;
|
||||
PrivateTmp = true;
|
||||
PrivateUsers = true;
|
||||
ProtectClock = true;
|
||||
ProtectControlGroups = true;
|
||||
ProtectHome = true;
|
||||
ProtectHostname = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectProc = "invisible";
|
||||
ProtectSystem = "strict";
|
||||
RemoveIPC = true;
|
||||
RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ];
|
||||
RestrictNamespaces = true;
|
||||
RestrictRealtime = true;
|
||||
RestrictSUIDSGID = true;
|
||||
SystemCallArchitectures = "native";
|
||||
SystemCallFilter = [ "@system-service @resources" "~@privileged @obsolete" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -482,6 +482,10 @@ in
|
||||
assertion = (cfg.database.useSSL && cfg.database.type == "postgresql") -> (cfg.database.caCert != null);
|
||||
message = "A CA certificate must be specified (in 'services.keycloak.database.caCert') when PostgreSQL is used with SSL";
|
||||
}
|
||||
{
|
||||
assertion = createLocalPostgreSQL -> config.services.postgresql.settings.standard_conforming_strings or true;
|
||||
message = "Setting up a local PostgreSQL db for Keycloak requires `standard_conforming_strings` turned on to work reliably";
|
||||
}
|
||||
];
|
||||
|
||||
environment.systemPackages = [ keycloakBuild ];
|
||||
@@ -544,7 +548,13 @@ in
|
||||
create_role="$(mktemp)"
|
||||
trap 'rm -f "$create_role"' EXIT
|
||||
|
||||
# Read the password from the credentials directory and
|
||||
# escape any single quotes by adding additional single
|
||||
# quotes after them, following the rules laid out here:
|
||||
# https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-CONSTANTS
|
||||
db_password="$(<"$CREDENTIALS_DIRECTORY/db_password")"
|
||||
db_password="''${db_password//\'/\'\'}"
|
||||
|
||||
echo "CREATE ROLE keycloak WITH LOGIN PASSWORD '$db_password' CREATEDB" > "$create_role"
|
||||
psql -tAc "SELECT 1 FROM pg_roles WHERE rolname='keycloak'" | grep -q 1 || psql -tA --file="$create_role"
|
||||
psql -tAc "SELECT 1 FROM pg_database WHERE datname = 'keycloak'" | grep -q 1 || psql -tAc 'CREATE DATABASE "keycloak" OWNER "keycloak"'
|
||||
@@ -566,8 +576,16 @@ in
|
||||
script = ''
|
||||
set -o errexit -o pipefail -o nounset -o errtrace
|
||||
shopt -s inherit_errexit
|
||||
|
||||
# Read the password from the credentials directory and
|
||||
# escape any single quotes by adding additional single
|
||||
# quotes after them, following the rules laid out here:
|
||||
# https://dev.mysql.com/doc/refman/8.0/en/string-literals.html
|
||||
db_password="$(<"$CREDENTIALS_DIRECTORY/db_password")"
|
||||
( echo "CREATE USER IF NOT EXISTS 'keycloak'@'localhost' IDENTIFIED BY '$db_password';"
|
||||
db_password="''${db_password//\'/\'\'}"
|
||||
|
||||
( echo "SET sql_mode = 'NO_BACKSLASH_ESCAPES';"
|
||||
echo "CREATE USER IF NOT EXISTS 'keycloak'@'localhost' IDENTIFIED BY '$db_password';"
|
||||
echo "CREATE DATABASE IF NOT EXISTS keycloak CHARACTER SET utf8 COLLATE utf8_unicode_ci;"
|
||||
echo "GRANT ALL PRIVILEGES ON keycloak.* TO 'keycloak'@'localhost';"
|
||||
) | mysql -N
|
||||
@@ -632,12 +650,17 @@ in
|
||||
|
||||
${secretReplacements}
|
||||
|
||||
# Escape any backslashes in the db parameters, since
|
||||
# they're otherwise unexpectedly read as escape
|
||||
# sequences.
|
||||
sed -i '/db-/ s|\\|\\\\|g' /run/keycloak/conf/keycloak.conf
|
||||
|
||||
'' + optionalString (cfg.sslCertificate != null && cfg.sslCertificateKey != null) ''
|
||||
mkdir -p /run/keycloak/ssl
|
||||
cp $CREDENTIALS_DIRECTORY/ssl_{cert,key} /run/keycloak/ssl/
|
||||
'' + ''
|
||||
export KEYCLOAK_ADMIN=admin
|
||||
export KEYCLOAK_ADMIN_PASSWORD=${cfg.initialAdminPassword}
|
||||
export KEYCLOAK_ADMIN_PASSWORD=${escapeShellArg cfg.initialAdminPassword}
|
||||
kc.sh start --optimized
|
||||
'';
|
||||
};
|
||||
|
||||
@@ -688,7 +688,7 @@ in {
|
||||
inherit (cfg) group;
|
||||
};
|
||||
})
|
||||
(lib.attrsets.setAttrByPath [ cfg.user "packages" ] [ cfg.package mastodonEnv ])
|
||||
(lib.attrsets.setAttrByPath [ cfg.user "packages" ] [ cfg.package mastodonEnv pkgs.imagemagick ])
|
||||
];
|
||||
|
||||
users.groups.${cfg.group}.members = lib.optional cfg.configureNginx config.services.nginx.user;
|
||||
|
||||
@@ -13,7 +13,12 @@ let
|
||||
phpPackage = cfg.phpPackage.buildEnv {
|
||||
extensions = { enabled, all }:
|
||||
(with all;
|
||||
enabled
|
||||
# disable default openssl extension
|
||||
(lib.filter (e: e.pname != "php-openssl") enabled)
|
||||
# use OpenSSL 1.1 for RC4 Nextcloud encryption if user
|
||||
# has acknowledged the brokeness of the ciphers (RC4).
|
||||
# TODO: remove when https://github.com/nextcloud/server/issues/32003 is fixed.
|
||||
++ (if cfg.enableBrokenCiphersForSSE then [ cfg.phpPackage.extensions.openssl-legacy ] else [ cfg.phpPackage.extensions.openssl ])
|
||||
++ optional cfg.enableImagemagick imagick
|
||||
# Optionally enabled depending on caching settings
|
||||
++ optional cfg.caching.apcu apcu
|
||||
@@ -80,6 +85,40 @@ in {
|
||||
|
||||
options.services.nextcloud = {
|
||||
enable = mkEnableOption (lib.mdDoc "nextcloud");
|
||||
|
||||
enableBrokenCiphersForSSE = mkOption {
|
||||
type = types.bool;
|
||||
default = versionOlder stateVersion "22.11";
|
||||
defaultText = literalExpression "versionOlder system.stateVersion \"22.11\"";
|
||||
description = lib.mdDoc ''
|
||||
This option enables using the OpenSSL PHP extension linked against OpenSSL 1.1
|
||||
rather than latest OpenSSL (≥ 3), this is not recommended unless you need
|
||||
it for server-side encryption (SSE). SSE uses the legacy RC4 cipher which is
|
||||
considered broken for several years now. See also [RFC7465](https://datatracker.ietf.org/doc/html/rfc7465).
|
||||
|
||||
This cipher has been disabled in OpenSSL ≥ 3 and requires
|
||||
a specific legacy profile to re-enable it.
|
||||
|
||||
If you deploy Nextcloud using OpenSSL ≥ 3 for PHP and have
|
||||
server-side encryption configured, you will not be able to access
|
||||
your files anymore. Enabling this option can restore access to your files.
|
||||
Upon testing we didn't encounter any data corruption when turning
|
||||
this on and off again, but this cannot be guaranteed for
|
||||
each Nextcloud installation.
|
||||
|
||||
It is `true` by default for systems with a [](#opt-system.stateVersion) below
|
||||
`22.11` to make sure that existing installations won't break on update. On newer
|
||||
NixOS systems you have to explicitly enable it on your own.
|
||||
|
||||
Please note that this only provides additional value when using
|
||||
external storage such as S3 since it's not an end-to-end encryption.
|
||||
If this is not the case,
|
||||
it is advised to [disable server-side encryption](https://docs.nextcloud.com/server/latest/admin_manual/configuration_files/encryption_configuration.html#disabling-encryption) and set this to `false`.
|
||||
|
||||
In the future, Nextcloud may move to AES-256-GCM, by then,
|
||||
this option will be removed.
|
||||
'';
|
||||
};
|
||||
hostName = mkOption {
|
||||
type = types.str;
|
||||
description = lib.mdDoc "FQDN for the nextcloud instance.";
|
||||
@@ -649,6 +688,23 @@ in {
|
||||
++ (optional (versionOlder cfg.package.version "23") (upgradeWarning 22 "22.05"))
|
||||
++ (optional (versionOlder cfg.package.version "24") (upgradeWarning 23 "22.05"))
|
||||
++ (optional (versionOlder cfg.package.version "25") (upgradeWarning 24 "22.11"))
|
||||
++ (optional cfg.enableBrokenCiphersForSSE ''
|
||||
You're using PHP's openssl extension built against OpenSSL 1.1 for Nextcloud.
|
||||
This is only necessary if you're using Nextcloud's server-side encryption.
|
||||
Please keep in mind that it's using the broken RC4 cipher.
|
||||
|
||||
If you don't use that feature, you can switch to OpenSSL 3 and get
|
||||
rid of this warning by declaring
|
||||
|
||||
services.nextcloud.enableBrokenCiphersForSSE = false;
|
||||
|
||||
If you need to use server-side encryption you can ignore this waring.
|
||||
Otherwise you'd have to disable server-side encryption first in order
|
||||
to be able to safely disable this option and get rid of this warning.
|
||||
See <https://docs.nextcloud.com/server/latest/admin_manual/configuration_files/encryption_configuration.html#disabling-encryption> on how to achieve this.
|
||||
|
||||
For more context, here is the implementing pull request: https://github.com/NixOS/nixpkgs/pull/198470
|
||||
'')
|
||||
++ (optional isUnsupportedMariadb ''
|
||||
You seem to be using MariaDB at an unsupported version (i.e. at least 10.6)!
|
||||
Please note that this isn't supported officially by Nextcloud. You can either
|
||||
|
||||
@@ -170,6 +170,20 @@
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<formalpara>
|
||||
<title>Server-side encryption</title>
|
||||
<para>
|
||||
Nextcloud supports <link xlink:href="https://docs.nextcloud.com/server/latest/admin_manual/configuration_files/encryption_configuration.html">server-side encryption (SSE)</link>.
|
||||
This is not an end-to-end encryption, but can be used to encrypt files that will be persisted
|
||||
to external storage such as S3. Please note that this won't work anymore when using OpenSSL 3
|
||||
for PHP's openssl extension because this is implemented using the legacy cipher RC4.
|
||||
If <xref linkend="opt-system.stateVersion" /> is <emphasis>above</emphasis> <literal>22.05</literal>,
|
||||
this is disabled by default. To turn it on again and for further information please refer to
|
||||
<xref linkend="opt-services.nextcloud.enableBrokenCiphersForSSE" />.
|
||||
</para>
|
||||
</formalpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
|
||||
|
||||
@@ -6,10 +6,10 @@ let
|
||||
in
|
||||
{
|
||||
# See here for a reference of all the options:
|
||||
# https://github.com/outline/outline/blob/v0.65.2/.env.sample
|
||||
# https://github.com/outline/outline/blob/v0.65.2/app.json
|
||||
# https://github.com/outline/outline/blob/v0.65.2/server/env.ts
|
||||
# https://github.com/outline/outline/blob/v0.65.2/shared/types.ts
|
||||
# https://github.com/outline/outline/blob/v0.67.0/.env.sample
|
||||
# https://github.com/outline/outline/blob/v0.67.0/app.json
|
||||
# https://github.com/outline/outline/blob/v0.67.0/server/env.ts
|
||||
# https://github.com/outline/outline/blob/v0.67.0/shared/types.ts
|
||||
# The order is kept the same here to make updating easier.
|
||||
options.services.outline = {
|
||||
enable = lib.mkEnableOption (lib.mdDoc "outline");
|
||||
@@ -123,7 +123,7 @@ in
|
||||
description = lib.mdDoc ''
|
||||
To support uploading of images for avatars and document attachments an
|
||||
s3-compatible storage must be provided. AWS S3 is recommended for
|
||||
redundency however if you want to keep all file storage local an
|
||||
redundancy however if you want to keep all file storage local an
|
||||
alternative such as [minio](https://github.com/minio/minio)
|
||||
can be used.
|
||||
|
||||
@@ -435,6 +435,16 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
sentryTunnel = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = lib.mdDoc ''
|
||||
Optionally add a
|
||||
[Sentry proxy tunnel](https://docs.sentry.io/platforms/javascript/troubleshooting/#using-the-tunnel-option)
|
||||
for bypassing ad blockers in the UI.
|
||||
'';
|
||||
};
|
||||
|
||||
logo = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
@@ -621,6 +631,7 @@ in
|
||||
DEBUG = cfg.debugOutput;
|
||||
GOOGLE_ANALYTICS_ID = lib.optionalString (cfg.googleAnalyticsId != null) cfg.googleAnalyticsId;
|
||||
SENTRY_DSN = lib.optionalString (cfg.sentryDsn != null) cfg.sentryDsn;
|
||||
SENTRY_TUNNEL = lib.optionalString (cfg.sentryTunnel != null) cfg.sentryTunnel;
|
||||
TEAM_LOGO = lib.optionalString (cfg.logo != null) cfg.logo;
|
||||
DEFAULT_LANGUAGE = cfg.defaultLanguage;
|
||||
|
||||
|
||||
@@ -590,9 +590,9 @@ in
|
||||
};
|
||||
};
|
||||
kwinrc = {
|
||||
Windows = {
|
||||
# Forces windows to be maximized
|
||||
Placement = lib.mkDefault "Maximizing";
|
||||
"Wayland" = {
|
||||
"InputMethod[$e]" = "/run/current-system/sw/share/applications/com.github.maliit.keyboard.desktop";
|
||||
"VirtualKeyboardEnabled" = "true";
|
||||
};
|
||||
"org.kde.kdecoration2" = {
|
||||
# No decorations (title bar)
|
||||
|
||||
@@ -342,6 +342,14 @@ checkFS() {
|
||||
return 0
|
||||
}
|
||||
|
||||
escapeFstab() {
|
||||
local original="$1"
|
||||
|
||||
# Replace space
|
||||
local escaped="${original// /\\040}"
|
||||
# Replace tab
|
||||
echo "${escaped//$'\t'/\\011}"
|
||||
}
|
||||
|
||||
# Function for mounting a file system.
|
||||
mountFS() {
|
||||
@@ -569,7 +577,7 @@ while read -u 3 mountPoint; do
|
||||
continue
|
||||
fi
|
||||
|
||||
mountFS "$device" "$mountPoint" "$options" "$fsType"
|
||||
mountFS "$device" "$(escapeFstab "$mountPoint")" "$(escapeFstab "$options")" "$fsType"
|
||||
done
|
||||
|
||||
exec 3>&-
|
||||
|
||||
@@ -167,7 +167,7 @@ let
|
||||
else throw "No device specified for mount point ‘${fs.mountPoint}’.")
|
||||
+ " " + escape (rootPrefix + fs.mountPoint)
|
||||
+ " " + fs.fsType
|
||||
+ " " + builtins.concatStringsSep "," (fs.options ++ (extraOpts fs))
|
||||
+ " " + escape (builtins.concatStringsSep "," (fs.options ++ (extraOpts fs)))
|
||||
+ " " + (optionalString (!excludeChecks)
|
||||
("0 " + (if skipCheck fs then "0" else if fs.mountPoint == "/" then "1" else "2")))
|
||||
+ "\n"
|
||||
|
||||
@@ -3,13 +3,14 @@
|
||||
let
|
||||
|
||||
inInitrd = lib.any (fs: fs == "ext2" || fs == "ext3" || fs == "ext4") config.boot.initrd.supportedFilesystems;
|
||||
inSystem = lib.any (fs: fs == "ext2" || fs == "ext3" || fs == "ext4") config.boot.supportedFilesystems;
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
config = {
|
||||
|
||||
system.fsPackages = lib.mkIf (config.boot.initrd.systemd.enable -> inInitrd) [ pkgs.e2fsprogs ];
|
||||
system.fsPackages = lib.mkIf (config.boot.initrd.systemd.enable -> (inInitrd || inSystem)) [ pkgs.e2fsprogs ];
|
||||
|
||||
# As of kernel 4.3, there is no separate ext3 driver (they're also handled by ext4.ko)
|
||||
boot.initrd.availableKernelModules = lib.mkIf (config.boot.initrd.systemd.enable -> inInitrd) [ "ext2" "ext4" ];
|
||||
|
||||
@@ -53,6 +53,13 @@ with lib;
|
||||
Guest memory in MB
|
||||
'';
|
||||
};
|
||||
bios = mkOption {
|
||||
type = types.enum [ "seabios" "ovmf" ];
|
||||
default = "seabios";
|
||||
description = ''
|
||||
Select BIOS implementation (seabios = Legacy BIOS, ovmf = UEFI).
|
||||
'';
|
||||
};
|
||||
|
||||
# optional configs
|
||||
name = mkOption {
|
||||
@@ -99,6 +106,17 @@ with lib;
|
||||
Additional options appended to qemu-server.conf
|
||||
'';
|
||||
};
|
||||
partitionTableType = mkOption {
|
||||
type = types.enum [ "efi" "hybrid" "legacy" "legacy+gpt" ];
|
||||
description = ''
|
||||
Partition table type to use. See make-disk-image.nix partitionTableType for details.
|
||||
Defaults to 'legacy' for 'proxmox.qemuConf.bios="seabios"' (default), other bios values defaults to 'efi'.
|
||||
Use 'hybrid' to build grub-based hybrid bios+efi images.
|
||||
'';
|
||||
default = if config.proxmox.qemuConf.bios == "seabios" then "legacy" else "efi";
|
||||
defaultText = lib.literalExpression ''if config.proxmox.qemuConf.bios == "seabios" then "legacy" else "efi"'';
|
||||
example = "hybrid";
|
||||
};
|
||||
filenameSuffix = mkOption {
|
||||
type = types.str;
|
||||
default = config.proxmox.qemuConf.name;
|
||||
@@ -122,9 +140,33 @@ with lib;
|
||||
${lib.concatStrings (lib.mapAttrsToList cfgLine properties)}
|
||||
#qmdump#map:virtio0:drive-virtio0:local-lvm:raw:
|
||||
'';
|
||||
inherit (cfg) partitionTableType;
|
||||
supportEfi = partitionTableType == "efi" || partitionTableType == "hybrid";
|
||||
supportBios = partitionTableType == "legacy" || partitionTableType == "hybrid" || partitionTableType == "legacy+gpt";
|
||||
hasBootPartition = partitionTableType == "efi" || partitionTableType == "hybrid";
|
||||
hasNoFsPartition = partitionTableType == "hybrid" || partitionTableType == "legacy+gpt";
|
||||
in {
|
||||
assertions = [
|
||||
{
|
||||
assertion = config.boot.loader.systemd-boot.enable -> config.proxmox.qemuConf.bios == "ovmf";
|
||||
message = "systemd-boot requires 'ovmf' bios";
|
||||
}
|
||||
{
|
||||
assertion = partitionTableType == "efi" -> config.proxmox.qemuConf.bios == "ovmf";
|
||||
message = "'efi' disk partitioning requires 'ovmf' bios";
|
||||
}
|
||||
{
|
||||
assertion = partitionTableType == "legacy" -> config.proxmox.qemuConf.bios == "seabios";
|
||||
message = "'legacy' disk partitioning requires 'seabios' bios";
|
||||
}
|
||||
{
|
||||
assertion = partitionTableType == "legacy+gpt" -> config.proxmox.qemuConf.bios == "seabios";
|
||||
message = "'legacy+gpt' disk partitioning requires 'seabios' bios";
|
||||
}
|
||||
];
|
||||
system.build.VMA = import ../../lib/make-disk-image.nix {
|
||||
name = "proxmox-${cfg.filenameSuffix}";
|
||||
inherit partitionTableType;
|
||||
postVM = let
|
||||
# Build qemu with PVE's patch that adds support for the VMA format
|
||||
vma = (pkgs.qemu_kvm.override {
|
||||
@@ -181,7 +223,18 @@ with lib;
|
||||
boot = {
|
||||
growPartition = true;
|
||||
kernelParams = [ "console=ttyS0" ];
|
||||
loader.grub.device = lib.mkDefault "/dev/vda";
|
||||
loader.grub = {
|
||||
device = lib.mkDefault (if (hasNoFsPartition || supportBios) then
|
||||
# Even if there is a separate no-fs partition ("/dev/disk/by-partlabel/no-fs" i.e. "/dev/vda2"),
|
||||
# which will be used the bootloader, do not set it as loader.grub.device.
|
||||
# GRUB installation fails, unless the whole disk is selected.
|
||||
"/dev/vda"
|
||||
else
|
||||
"nodev");
|
||||
efiSupport = lib.mkDefault supportEfi;
|
||||
efiInstallAsRemovable = lib.mkDefault supportEfi;
|
||||
};
|
||||
|
||||
loader.timeout = 0;
|
||||
initrd.availableKernelModules = [ "uas" "virtio_blk" "virtio_pci" ];
|
||||
};
|
||||
@@ -191,6 +244,10 @@ with lib;
|
||||
autoResize = true;
|
||||
fsType = "ext4";
|
||||
};
|
||||
fileSystems."/boot" = lib.mkIf hasBootPartition {
|
||||
device = "/dev/disk/by-label/ESP";
|
||||
fsType = "vfat";
|
||||
};
|
||||
|
||||
services.qemuGuest.enable = lib.mkDefault true;
|
||||
};
|
||||
|
||||
@@ -77,6 +77,7 @@ in rec {
|
||||
(onFullSupported "nixos.tests.i3wm")
|
||||
(onSystems ["x86_64-linux"] "nixos.tests.installer.btrfsSimple")
|
||||
(onSystems ["x86_64-linux"] "nixos.tests.installer.btrfsSubvolDefault")
|
||||
(onSystems ["x86_64-linux"] "nixos.tests.installer.btrfsSubvolEscape")
|
||||
(onSystems ["x86_64-linux"] "nixos.tests.installer.btrfsSubvols")
|
||||
(onSystems ["x86_64-linux"] "nixos.tests.installer.luksroot")
|
||||
(onSystems ["x86_64-linux"] "nixos.tests.installer.lvm")
|
||||
|
||||
@@ -74,6 +74,7 @@ in {
|
||||
agda = handleTest ./agda.nix {};
|
||||
airsonic = handleTest ./airsonic.nix {};
|
||||
allTerminfo = handleTest ./all-terminfo.nix {};
|
||||
alps = handleTest ./alps.nix {};
|
||||
amazon-init-shell = handleTest ./amazon-init-shell.nix {};
|
||||
apfs = handleTest ./apfs.nix {};
|
||||
apparmor = handleTest ./apparmor.nix {};
|
||||
@@ -197,6 +198,7 @@ in {
|
||||
etebase-server = handleTest ./etebase-server.nix {};
|
||||
etesync-dav = handleTest ./etesync-dav.nix {};
|
||||
extra-python-packages = handleTest ./extra-python-packages.nix {};
|
||||
evcc = handleTest ./evcc.nix {};
|
||||
fancontrol = handleTest ./fancontrol.nix {};
|
||||
fcitx = handleTest ./fcitx {};
|
||||
fenics = handleTest ./fenics.nix {};
|
||||
@@ -251,8 +253,8 @@ in {
|
||||
haproxy = handleTest ./haproxy.nix {};
|
||||
hardened = handleTest ./hardened.nix {};
|
||||
healthchecks = handleTest ./web-apps/healthchecks.nix {};
|
||||
hbase1 = handleTest ./hbase.nix { package=pkgs.hbase1; };
|
||||
hbase2 = handleTest ./hbase.nix { package=pkgs.hbase2; };
|
||||
hbase_2_4 = handleTest ./hbase.nix { package=pkgs.hbase_2_4; };
|
||||
hbase3 = handleTest ./hbase.nix { package=pkgs.hbase3; };
|
||||
hedgedoc = handleTest ./hedgedoc.nix {};
|
||||
herbstluftwm = handleTest ./herbstluftwm.nix {};
|
||||
@@ -490,9 +492,11 @@ in {
|
||||
pgadmin4-standalone = handleTest ./pgadmin4-standalone.nix {};
|
||||
pgjwt = handleTest ./pgjwt.nix {};
|
||||
pgmanage = handleTest ./pgmanage.nix {};
|
||||
phosh = handleTest ./phosh.nix {};
|
||||
php = handleTest ./php {};
|
||||
php80 = handleTest ./php { php = pkgs.php80; };
|
||||
php81 = handleTest ./php { php = pkgs.php81; };
|
||||
php82 = handleTest ./php { php = pkgs.php82; };
|
||||
phylactery = handleTest ./web-apps/phylactery.nix {};
|
||||
pict-rs = handleTest ./pict-rs.nix {};
|
||||
pinnwand = handleTest ./pinnwand.nix {};
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
let
|
||||
certs = import ./common/acme/server/snakeoil-certs.nix;
|
||||
domain = certs.domain;
|
||||
in
|
||||
import ./make-test-python.nix ({ pkgs, ... }: {
|
||||
name = "alps";
|
||||
|
||||
nodes = {
|
||||
server = {
|
||||
imports = [ ./common/user-account.nix ];
|
||||
security.pki.certificateFiles = [
|
||||
certs.ca.cert
|
||||
];
|
||||
networking.extraHosts = ''
|
||||
127.0.0.1 ${domain}
|
||||
'';
|
||||
networking.firewall.allowedTCPPorts = [ 25 465 993 ];
|
||||
services.postfix = {
|
||||
enable = true;
|
||||
enableSubmission = true;
|
||||
enableSubmissions = true;
|
||||
tlsTrustedAuthorities = "${certs.ca.cert}";
|
||||
sslCert = "${certs.${domain}.cert}";
|
||||
sslKey = "${certs.${domain}.key}";
|
||||
};
|
||||
services.dovecot2 = {
|
||||
enable = true;
|
||||
enableImap = true;
|
||||
sslCACert = "${certs.ca.cert}";
|
||||
sslServerCert = "${certs.${domain}.cert}";
|
||||
sslServerKey = "${certs.${domain}.key}";
|
||||
};
|
||||
};
|
||||
|
||||
client = { nodes, config, ... }: {
|
||||
security.pki.certificateFiles = [
|
||||
certs.ca.cert
|
||||
];
|
||||
networking.extraHosts = ''
|
||||
${nodes.server.config.networking.primaryIPAddress} ${domain}
|
||||
'';
|
||||
services.alps = {
|
||||
enable = true;
|
||||
theme = "alps";
|
||||
imaps = {
|
||||
host = domain;
|
||||
port = 993;
|
||||
};
|
||||
smtps = {
|
||||
host = domain;
|
||||
port = 465;
|
||||
};
|
||||
};
|
||||
environment.systemPackages = [
|
||||
(pkgs.writers.writePython3Bin "test-alps-login" { } ''
|
||||
from urllib.request import build_opener, HTTPCookieProcessor, Request
|
||||
from urllib.parse import urlencode, urljoin
|
||||
from http.cookiejar import CookieJar
|
||||
|
||||
baseurl = "http://localhost:${toString config.services.alps.port}"
|
||||
username = "alice"
|
||||
password = "${nodes.server.config.users.users.alice.password}"
|
||||
cookiejar = CookieJar()
|
||||
cookieprocessor = HTTPCookieProcessor(cookiejar)
|
||||
opener = build_opener(cookieprocessor)
|
||||
|
||||
data = urlencode({"username": username, "password": password}).encode()
|
||||
req = Request(urljoin(baseurl, "login"), data=data, method="POST")
|
||||
with opener.open(req) as ret:
|
||||
# Check that the alps_session cookie is set
|
||||
print(cookiejar)
|
||||
assert any(cookie.name == "alps_session" for cookie in cookiejar)
|
||||
|
||||
req = Request(baseurl)
|
||||
with opener.open(req) as ret:
|
||||
# Check that the alps_session cookie is still there...
|
||||
print(cookiejar)
|
||||
assert any(cookie.name == "alps_session" for cookie in cookiejar)
|
||||
# ...and that we have not been redirected back to the login page
|
||||
print(ret.url)
|
||||
assert ret.url == urljoin(baseurl, "mailbox/INBOX")
|
||||
|
||||
req = Request(urljoin(baseurl, "logout"))
|
||||
with opener.open(req) as ret:
|
||||
# Check that the alps_session cookie is now gone
|
||||
print(cookiejar)
|
||||
assert all(cookie.name != "alps_session" for cookie in cookiejar)
|
||||
'')
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
server.start()
|
||||
server.wait_for_unit("postfix.service")
|
||||
server.wait_for_unit("dovecot2.service")
|
||||
server.wait_for_open_port(465)
|
||||
server.wait_for_open_port(993)
|
||||
|
||||
client.start()
|
||||
client.wait_for_unit("alps.service")
|
||||
client.succeed("test-alps-login")
|
||||
'';
|
||||
})
|
||||
@@ -1,19 +1,19 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEAo8XjMVUaljcaqQ5MFhfPuQgSwdyXEUbpSHz+5yPkE0h9Z4Xu
|
||||
5BJF1Oq7h5ggCtadVsIspiY6Jm6aWDOjlh4myzW5UNBNUG3OPEk50vmmHFeHpImH
|
||||
O/d8yb33QoF9VRcTZs4tuJYg7l9bSs4jNG72vYvv2YiGAcmjJcsmAZIfniCNXf/L
|
||||
jIm+Cxykn+Vo3UuzO1w5/iuofdgWO/aZxMezmXUivlL3ih4cNzCJei8WlB/lEnHr
|
||||
kcy3ogRmmynP5zcz7vmGIJX2ji6dhCa4Got5B7eZK76o2QglhQXqPatG0AOYH+Rf
|
||||
QfzKemqPG5om9MgJtwFtTOU1LoaiBw//jXKESQIDAQABAoIBADox/2FwVFo8ioS4
|
||||
R+Ex5OZjMAcjU6sX/516jTmlT05q2+UFerYgqB/YqXqtW/V9/brulN8VhmRRuRbO
|
||||
grq9TBu5o3hMDK0f18EkZB/MBnLbx594H033y6gEkPBZAyhRYtuNOEH3VwxdZhtW
|
||||
1Lu1EoiYSUqLcNMBy6+KWJ8GRaXyacMYBlj2lMHmyzkA/t1+2mwTGC3lT6zN0F5Y
|
||||
E5umXOxsn6Tb6q3KM9O5IvtmMMKpgj4HIHZLZ6j40nNgHwGRaAv4Sha/vx0DeBw3
|
||||
6VlNiTTPdShEkhESlM5/ocqTfI92VHJpM5gkqTYOWBi2aKIPfAopXoqoJdWl4pQ/
|
||||
NCFIu2ECgYEAzntNKIcQtf0ewe0/POo07SIFirvz6jVtYNMTzeQfL6CoEjYArJeu
|
||||
Vzc4wEQfA4ZFVerBb1/O6M449gI3zex1PH4AX0h8q8DSjrppK1Jt2TnpVh97k7Gg
|
||||
Tnat/M/yW3lWYkcMVJJ3AYurXLFTT1dYP0HvBwZN04yInrEcPNXKfmcCgYEAywyJ
|
||||
51d4AE94PrANathKqSI/gk8sP+L1gzylZCcUEAiGk/1r45iYB4HN2gvWbS+CvSdp
|
||||
F7ShlDWrTaNh2Bm1dgTjc4pWb4J+CPy/KN2sgLwIuM4+ZWIZmEDcio6khrM/gNqK
|
||||
aR7xUsvWsqU26O84woY/xR8IHjSNF7cFWE1H2c8CgYEAt6SSi2kVQ8dMg84uYE8t
|
||||
o3qO00U3OycpkOQqyQQLeKC62veMwfRl6swCfX4Y11mkcTXJtPTRYd2Ia8StPUkB
|
||||
PDwUuKoPt/JXUvoYb59wc7M+BIsbrdBdc2u6cw+/zfutCNuH6/AYSBeg4WAVaIuW
|
||||
wSwzG1xP+8cR+5IqOzEqWCECgYATweeVTCyQEyuHJghYMi2poXx+iIesu7/aAkex
|
||||
pB/Oo5W8xrb90XZRnK7UHbzCqRHWqAQQ23Gxgztk9ZXqui2vCzC6qGZauV7cLwPG
|
||||
zTMg36sVmHP314DYEM+k59ZYiQ6P0jQPoIQo407D2VGrfsOOIhQIcUmP7tsfyJ5L
|
||||
hlGMfwKBgGq4VNnnuX8I5kl03NpaKfG+M8jEHmVwtI9RkPTCCX9bMjeG0cDxqPTF
|
||||
TRkf3r8UWQTZ5QfAfAXYAOlZvmGhHjSembRbXMrMdi3rGsYRSrQL6n5NHnORUaMy
|
||||
FCWo4gyAnniry7tx9dVNgmHmbjEHuQnf8AC1r3dibRCjvJWUiQ8H
|
||||
MIIEowIBAAKCAQEAs/Xad8Jn0YMI8nTjbVakGsFplxSKkgWs9Jv8tETC1FBVKNo3
|
||||
yF6IElBhzKw3eF6piZqDwNFXobuMCZ3Ckaj+EOdSA0DhjwUSBmEok/0siIu4WbAS
|
||||
2iKwZGuJlJRYOmfXRPt2nNSPhuNHtZJoTWufN5K1XS+4v1dsVUWdWvkUuaC5/uou
|
||||
jcYd4D6XDhJCubDCE+WSYk0KBLtMQ8irbNu4FGoCn5T7kDq46XwVjulWxc5qdZ/Z
|
||||
/zgKQkoLaHgWKLjvuu7/CZw6RXyBlwVJh36pljixRnpnLfMMykO9Sq7Z3cR2aVcM
|
||||
RjjeH0uScfFHIb3hvqyZLd+NHw3SqE8la/Nq1wIDAQABAoIBAG2s50FXjLgmONyz
|
||||
Giv3wrm/qF94GF+X7+l/64nd4jNM5imonJiT7C/lJ0V6q6/DWWXQcn2f191slJMD
|
||||
v6HQMU8R+2yaLR1hxLN4oSdYA70QEgEvCr5Ap+n7k/SmWAL4aDzVWFuKPBLED178
|
||||
ZG7SqU1QLxIk1F5gpFhvvc/Ev7nE0KAzTJ3jGyWHZjJ1TKAWHx6oeKOw4OejRcGO
|
||||
+rDBfQrV59fiCy8CFraGPDGie5Eb7ioXyt4cf4/odtLol7bSIwH4BLwfvKJbRobi
|
||||
gSjvL5JJLjhjWzeoj+JC4o0sWQegytWpNCHSFETfHQ8rlcagTN8JaTcBg6+wrR2O
|
||||
OPeoFqkCgYEA7o9jSk7i23SiKo3C+T9KFIL2OS7akwUqIQZehZJ6LXljYEDP1lcz
|
||||
wjvWuLGVzlST3fmumHIMZLjjBU1cMYAPZrbUrEeayATD4jBxyiXbHqhB3DQ0W4CX
|
||||
obUhcdsLGsKp0zXls8FeiQs6GOeEwSDU+1nAL9/hLK7w6cJ2zyj8HBUCgYEAwR3H
|
||||
/ltIjD8tXNF05ayOguzrbivx2vaXusskZgn9QqntoGqqsXLOgsqcUH0dtiTyVOn+
|
||||
Nba7w+o5NfaAfE9uR+oeZSo1IJU8oEi/EZqXTcYf5p3oAjXXZ9wXX8kl91EjCzKl
|
||||
0kDpSpsMhUzdB2i5I9Oh1fLaW4iMwyuY1CgnqjsCgYBHIJFmEmcpL3k6XtIHJoub
|
||||
2gA3xHR+6UdKWW/NO4MaE9tBU5GkQpO4EcdPggM8ZZNA17Tq1vZDAa0OY6ZdS+VL
|
||||
pq96Pk8z29fblL4Ym3jdhyU71oTV011iZXL3U2vYKrofsy4tjjX1fldwHXdDbdqS
|
||||
povaulGU1QQXblemJH4mkQKBgC3IUq6Rk4x0OdvkaFM+6nZNlq8Cyg7AIU6OdG2g
|
||||
dqNER+qc/yScdCr7v70xPEb/UVgiNTskvDUBJVkOvH08E4gHD/ep3vh/iOTy+iFB
|
||||
RheRHeT9kJBdlVixC/WQaWjNmoJAGqHS87vVME214Dyubh35QUfIkE3c/IoUnuHF
|
||||
N0obAoGBANJpPBF36H1nb+TcVerOBXI8oqeIyoq7f4W/wbIirnZq/XfBaaOL5R6v
|
||||
6+p4LEcQ1Mf33Yfr5M4aR0q7fgNDg/g4LcMg6fI3+UwPC6lJY+K8zzF4fmGDhheC
|
||||
D+LsZG0Funl9kT0yxPBQhCJmmkJNIHiSNuRLt9Infne2408+YV+T
|
||||
-----END RSA PRIVATE KEY-----
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEAqzU81SwyTirRmBi1PfBBHCyqbLVxwiwuhueCymxHFPNH5/gK
|
||||
1/KrD0h8oXV0JHGI6ulYfxAydU3LckUp7wI8MhuAGtWctUBXPyZ4zI784pgpFHPZ
|
||||
UPsJC8B0jPyhsEdXBo5rUPxDApWUwNDcLpSbFzClc23eWrF26v8iU0OVsNuR7XTY
|
||||
8EUF07we69yCnGPg7BA/QrxbwvaBv2YbWambsskXQpBVK67/FjVA5FkjfpTEesTM
|
||||
fL9OfNyDen9dSIV9G/rLyvfBvNQdnrMAXZM71cr/TLp2QTtCbiRvLHTOdNioVi5s
|
||||
wQtWW74FARfQbpg0aTBR+Awo+/qkNrWlnhsnOwIDAQABAoIBAA3ykVkgd5ysmlSU
|
||||
trcsCnHcJaojgff6l3PACoSpG4VWaGY6a8+54julgRm6MtMBONFCX0ZCsImj484U
|
||||
Wl0xRmwil2YYPuL5MeJgJPktMObY1IfpBCw3tz3w2M3fiuCMf0d2dMGtO1xLiUnH
|
||||
+hgFXTkfamsj6ThkOrbcQBSebeRxbKM5hqyCaQoieV+0IJnyxUVq/apib8N50VsH
|
||||
SHd4oqLUuEZgg6N70+l5DpzedJUb4nrwS/KhUHUBgnoPItYBCiGPmrwLk7fUhPs6
|
||||
kTDqJDtc/xW/JbjmzhWEpVvtumcC/OEKULss7HLdeQqwVBrRQkznb0M9AnSra3d0
|
||||
X11/Y4ECgYEA3FC8SquLPFb2lHK4+YbJ4Ac6QVWeYFEHiZ0Rj+CmONmjcAvOGLPE
|
||||
SblRLm3Nbrkxbm8FF6/AfXa/rviAKEVPs5xqGfSDw/3n1uInPcmShiBCLwM/jHH5
|
||||
NeVG+R5mTg5zyQ/pQMLWRcs+Ail+ZAnZuoGpW3Cdc8OtCUYFQ7XB6nsCgYEAxvBJ
|
||||
zFxcTtsDzWbMWXejugQiUqJcEbKWwEfkRbf3J2rAVO2+EFr7LxdRfN2VwPiTQcWc
|
||||
LnN2QN+ouOjqBMTh3qm5oQY+TLLHy86k9g1k0gXWkMRQgP2ZdfWH1HyrwjLUgLe1
|
||||
VezFN7N1azgy6xFkInAAvuA4loxElZNvkGBgekECgYA/Xw26ILvNIGqO6qzgQXAh
|
||||
+5I7JsiGheg4IjDiBMlrQtbrLMoceuD0H9UFGNplhel9DXwWgxxIOncKejpK2x0A
|
||||
2fX+/0FDh+4+9hA5ipiV8gN3iGSoHkSDxy5yC9d7jlapt+TtFt4Rd1OfxZWwatDw
|
||||
/8jaH3t6yAcmyrhK8KYVrwKBgAE5KwsBqmOlvyE9N5Z5QN189wUREIXfVkP6bTHs
|
||||
jq2EX4hmKdwJ4y+H8i1VY31bSfSGlY5HkXuWpH/2lrHO0CDBZG3UDwADvWzIaYVF
|
||||
0c/kz0v2mRQh+xaZmus4lQnNrDbaalgL666LAPbW0qFVaws3KxoBYPe0BxvwWyhF
|
||||
H3LBAoGBAKRRNsq2pWQ8Gqxc0rVoH0FlexU9U2ci3lsLmgEB0A/o/kQkSyAxaRM+
|
||||
VdKp3sWfO8o8lX5CVQslCNBSjDTNcat3Co4NEBLg6Xv1yKN/WN1GhusnchP9szsP
|
||||
oU47gC89QhUyWSd6vvr2z2NG9C3cACxe4dhDSHQcE4nHSldzCKv2
|
||||
MIIEowIBAAKCAQEAmMTP3n4ku6zTc3bvgCviee/qJkGLKLXlaZsHFOlJfGa+qXLA
|
||||
Ui3rVdjwlhlSin13StRKfiXQaIrhvBGP8H32CcvkqFkUVl/mxiBZcu+Lq19ojh/8
|
||||
ophfFzGh4+As4zA9cDNqxS7MC91StgzPsKwjDtsxNgQIlACfvsLPfQ5e+A0PZRp3
|
||||
vITIxYM2pCDQjXfePP7dvizFcagoEO3yPohwNV+0BdQE+XPOsHfxsS835d+Nw8S0
|
||||
njERWxlFUh+jQQZyEHRQ6tRozRj25/GZQ18OVlnkebn58XEUTaadxpxxt/1TnmxQ
|
||||
K/vuf9M3vkLxelz15PUWVr4YdHQ9eP/FvzzCtQIDAQABAoIBAAMvJv4GNxHKWmXv
|
||||
trI/N+s+uuytNQ9WKz/2QUGIU0XKhnLVt3h/CIazjOA0CupkDxZ6MktK0ns7WdUn
|
||||
sI5cscImg8+We7wJJ7A9gF/K6mhaBr3foM5qyqCbIjqzs3vQx5cNG06c2RfuNwkg
|
||||
XzvZeqmWnAH6N4uOL8Y0HUsH/6a/5rHEBTgUOnOidR8T1vdIN5vnpknef/H575ab
|
||||
jTdDyb15Vns7nC4Q8lortkLsQzOt//LWpVuLZXGDm1Xi47ahNXM8Fo/MFK+xcBDF
|
||||
onMFuclxImN3FqkyMH6PgJS392bZ1LLcmS4bqZ0oIwfUZ/kIEwAI2cTwEYfYmN7C
|
||||
ekgvpsECgYEAxoJUcZW4iWvT8kznWKKT+YJAfTYmgwOxB1Dn3RxFA8cXocQQvwvM
|
||||
mSl1AKOjWHFl/eW9s4zwy/fOnsN1m1tCTuWSNn5sudZSJfbd5CCiYaYTI66McCCm
|
||||
5FGzqLM44Wm5y2qLa7l3in8Tza/645RpLXZyRfMInoW5In0XKbokLbkCgYEAxQM/
|
||||
p63V5KuZYsm9BWNcCvAbS6G9NHjbeRrkAd171SSdibdwLIBeyn7A5JCiVqhZZbsO
|
||||
1q1okO4m4j+JHzntWi63yXwG49sEVNaFbExPE4tfJeHD0Po8MJffoLNVTE+INT0B
|
||||
fl1elhMpE9qpizFIHF7L8KnUf5Igi+yp0d6Amt0CgYACAhmGmKQoR736KosAm4xx
|
||||
rr6mRaD4HFZzI39k/j84fZAgo9IjjKQCPKghXIZvg54rhmJ36YoaFiSx+Ho9Gxw9
|
||||
nhbvlDHXY3KrTacLAsWBxWNWLhLfo4TstGLj5wRBS4eEpkxIx7SM4yI5J3mbScoS
|
||||
mqsnSAEjUWkBD1DnrClniQKBgQCdfC9SNp+Yn6OJWIKE4Bwfkjf/iVbZrxKiCGDj
|
||||
LM1kYFSeVciRijw72n8PNp7ObtyneZQu/4dq8zSZ/vf5wjB9uoKnyUEou1cHCkS1
|
||||
gXpkwTBZ89K4JpAeuAjHSROSYLEc/ZtIDBMkHETl3hFRdx+RriWQR/HZ2FG0CIbn
|
||||
gNmE8QKBgDlFu+TcspI2R9mKbHrbPTXOAlmi2g7RZ3jF1m4S/aZqSL/bqPRBb0OU
|
||||
dY7MX4GHhJYR7RnMMROZQI0H4ZwWSMfokBDa96MDY107atK8TqZmYKaZQsEB8B4r
|
||||
fMmKnQljYj91d/reowLJrQRf5SjBvtDIEIsiC8UgjQImAsZ8huEX
|
||||
-----END RSA PRIVATE KEY-----
|
||||
|
||||
@@ -54,8 +54,10 @@ import ./make-test-python.nix ({ pkgs, ...} : {
|
||||
declarative.wait_for_unit("deluged")
|
||||
declarative.wait_for_unit("delugeweb")
|
||||
declarative.wait_until_succeeds("curl --fail http://declarative:3142")
|
||||
|
||||
# deluge-console always exits with 1. https://dev.deluge-torrent.org/ticket/3291
|
||||
declarative.succeed(
|
||||
"deluge-console 'connect 127.0.0.1:58846 andrew password; help' | grep -q 'rm.*Remove a torrent'"
|
||||
"(deluge-console 'connect 127.0.0.1:58846 andrew password; help' || true) | grep -q 'rm.*Remove a torrent'"
|
||||
)
|
||||
'';
|
||||
})
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
import ./make-test-python.nix ({ pkgs, lib, ...} :
|
||||
|
||||
{
|
||||
name = "evcc";
|
||||
meta.maintainers = with lib.maintainers; [ hexa ];
|
||||
|
||||
nodes = {
|
||||
machine = { config, ... }: {
|
||||
services.evcc = {
|
||||
enable = true;
|
||||
settings = {
|
||||
network = {
|
||||
schema = "http";
|
||||
host = "localhost";
|
||||
port = 7070;
|
||||
};
|
||||
|
||||
log = "info";
|
||||
|
||||
site = {
|
||||
title = "NixOS Test";
|
||||
meters = {
|
||||
grid = "grid";
|
||||
pv = "pv";
|
||||
};
|
||||
};
|
||||
|
||||
meters = [ {
|
||||
type = "custom";
|
||||
name = "grid";
|
||||
power = {
|
||||
source = "script";
|
||||
cmd = "/bin/sh -c 'echo -4500'";
|
||||
};
|
||||
} {
|
||||
type = "custom";
|
||||
name = "pv";
|
||||
power = {
|
||||
source = "script";
|
||||
cmd = "/bin/sh -c 'echo 7500'";
|
||||
};
|
||||
} ];
|
||||
|
||||
chargers = [ {
|
||||
name = "dummy-charger";
|
||||
type = "custom";
|
||||
status = {
|
||||
source = "script";
|
||||
cmd = "/bin/sh -c 'echo charger status F'";
|
||||
};
|
||||
enabled = {
|
||||
source = "script";
|
||||
cmd = "/bin/sh -c 'echo charger enabled state false'";
|
||||
};
|
||||
enable = {
|
||||
source = "script";
|
||||
cmd = "/bin/sh -c 'echo set charger enabled state true'";
|
||||
};
|
||||
maxcurrent = {
|
||||
source = "script";
|
||||
cmd = "/bin/sh -c 'echo set charger max current 7200'";
|
||||
};
|
||||
} ];
|
||||
|
||||
loadpoints = [ {
|
||||
title = "Dummy";
|
||||
charger = "dummy-charger";
|
||||
} ];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
start_all()
|
||||
|
||||
machine.wait_for_unit("evcc.service")
|
||||
machine.wait_for_open_port(7070)
|
||||
|
||||
with subtest("Check package version propagates into frontend"):
|
||||
machine.fail(
|
||||
"curl --fail http://localhost:7070 | grep '0.0.1-alpha'"
|
||||
)
|
||||
machine.succeed(
|
||||
"curl --fail http://localhost:7070 | grep '${pkgs.evcc.version}'"
|
||||
)
|
||||
|
||||
with subtest("Check journal for errors"):
|
||||
_, output = machine.execute("journalctl -o cat -u evcc.service")
|
||||
assert "ERROR" not in output
|
||||
|
||||
with subtest("Check systemd hardening"):
|
||||
_, output = machine.execute("systemd-analyze security evcc.service | grep -v '✓'")
|
||||
machine.log(output)
|
||||
'';
|
||||
})
|
||||
@@ -17,7 +17,7 @@ let
|
||||
|
||||
security = {
|
||||
admin_user = "testadmin";
|
||||
admin_password = "snakeoilpwd";
|
||||
admin_password = "$__file{${pkgs.writeText "pwd" "snakeoilpwd"}}";
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -28,17 +28,24 @@ let
|
||||
};
|
||||
|
||||
extraNodeConfs = {
|
||||
provisionOld = {
|
||||
provisionLegacyNotifiers = {
|
||||
services.grafana.provision = {
|
||||
datasources = [{
|
||||
name = "Test Datasource";
|
||||
type = "testdata";
|
||||
access = "proxy";
|
||||
uid = "test_datasource";
|
||||
}];
|
||||
|
||||
dashboards = [{ options.path = "/var/lib/grafana/dashboards"; }];
|
||||
|
||||
datasources.settings = {
|
||||
apiVersion = 1;
|
||||
datasources = [{
|
||||
name = "Test Datasource";
|
||||
type = "testdata";
|
||||
access = "proxy";
|
||||
uid = "test_datasource";
|
||||
}];
|
||||
};
|
||||
dashboards.settings = {
|
||||
apiVersion = 1;
|
||||
providers = [{
|
||||
name = "default";
|
||||
options.path = "/var/lib/grafana/dashboards";
|
||||
}];
|
||||
};
|
||||
notifiers = [{
|
||||
uid = "test_notifiers";
|
||||
name = "Test Notifiers";
|
||||
@@ -50,7 +57,6 @@ let
|
||||
}];
|
||||
};
|
||||
};
|
||||
|
||||
provisionNix = {
|
||||
services.grafana.provision = {
|
||||
datasources.settings = {
|
||||
@@ -157,6 +163,22 @@ let
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
provisionYamlDirs = let
|
||||
mkdir = p: pkgs.writeTextDir (baseNameOf p) (builtins.readFile p);
|
||||
in {
|
||||
services.grafana.provision = {
|
||||
datasources.path = mkdir ./datasources.yaml;
|
||||
dashboards.path = mkdir ./dashboards.yaml;
|
||||
alerting = {
|
||||
rules.path = mkdir ./rules.yaml;
|
||||
contactPoints.path = mkdir ./contact-points.yaml;
|
||||
policies.path = mkdir ./policies.yaml;
|
||||
templates.path = mkdir ./templates.yaml;
|
||||
muteTimings.path = mkdir ./mute-timings.yaml;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
nodes = builtins.mapAttrs (_: val: mkMerge [ val baseGrafanaConf ]) extraNodeConfs;
|
||||
@@ -172,58 +194,58 @@ in {
|
||||
testScript = ''
|
||||
start_all()
|
||||
|
||||
nodeOld = ("Nix (old format)", provisionOld)
|
||||
nodeNix = ("Nix (new format)", provisionNix)
|
||||
nodeYaml = ("Nix (YAML)", provisionYaml)
|
||||
nodeYamlDir = ("Nix (YAML in dirs)", provisionYamlDirs)
|
||||
|
||||
for nodeInfo in [nodeOld, nodeNix, nodeYaml]:
|
||||
with subtest(f"Should start provision node: {nodeInfo[0]}"):
|
||||
nodeInfo[1].wait_for_unit("grafana.service")
|
||||
nodeInfo[1].wait_for_open_port(3000)
|
||||
for description, machine in [nodeNix, nodeYaml, nodeYamlDir]:
|
||||
with subtest(f"Should start provision node: {description}"):
|
||||
machine.wait_for_unit("grafana.service")
|
||||
machine.wait_for_open_port(3000)
|
||||
|
||||
with subtest(f"Successful datasource provision with {nodeInfo[0]}"):
|
||||
nodeInfo[1].succeed(
|
||||
with subtest(f"Successful datasource provision with {description}"):
|
||||
machine.succeed(
|
||||
"curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/datasources/uid/test_datasource | grep Test\ Datasource"
|
||||
)
|
||||
|
||||
with subtest(f"Successful dashboard provision with {nodeInfo[0]}"):
|
||||
nodeInfo[1].succeed(
|
||||
with subtest(f"Successful dashboard provision with {description}"):
|
||||
machine.succeed(
|
||||
"curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/dashboards/uid/test_dashboard | grep Test\ Dashboard"
|
||||
)
|
||||
|
||||
|
||||
|
||||
with subtest(f"Successful notifiers provision with {nodeOld[0]}"):
|
||||
nodeOld[1].succeed(
|
||||
"curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/alert-notifications/uid/test_notifiers | grep Test\ Notifiers"
|
||||
)
|
||||
|
||||
|
||||
|
||||
for nodeInfo in [nodeNix, nodeYaml]:
|
||||
with subtest(f"Successful rule provision with {nodeInfo[0]}"):
|
||||
nodeInfo[1].succeed(
|
||||
with subtest(f"Successful rule provision with {description}"):
|
||||
machine.succeed(
|
||||
"curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/v1/provisioning/alert-rules/test_rule | grep Test\ Rule"
|
||||
)
|
||||
|
||||
with subtest(f"Successful contact point provision with {nodeInfo[0]}"):
|
||||
nodeInfo[1].succeed(
|
||||
with subtest(f"Successful contact point provision with {description}"):
|
||||
machine.succeed(
|
||||
"curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/v1/provisioning/contact-points | grep Test\ Contact\ Point"
|
||||
)
|
||||
|
||||
with subtest(f"Successful policy provision with {nodeInfo[0]}"):
|
||||
nodeInfo[1].succeed(
|
||||
with subtest(f"Successful policy provision with {description}"):
|
||||
machine.succeed(
|
||||
"curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/v1/provisioning/policies | grep Test\ Contact\ Point"
|
||||
)
|
||||
|
||||
with subtest(f"Successful template provision with {nodeInfo[0]}"):
|
||||
nodeInfo[1].succeed(
|
||||
with subtest(f"Successful template provision with {description}"):
|
||||
machine.succeed(
|
||||
"curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/v1/provisioning/templates | grep Test\ Template"
|
||||
)
|
||||
|
||||
with subtest("Successful mute timings provision with {nodeInfo[0]}"):
|
||||
nodeInfo[1].succeed(
|
||||
with subtest("Successful mute timings provision with {description}"):
|
||||
machine.succeed(
|
||||
"curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/v1/provisioning/mute-timings | grep Test\ Mute\ Timing"
|
||||
)
|
||||
|
||||
with subtest("Successful notifiers provision"):
|
||||
provisionLegacyNotifiers.wait_for_unit("grafana.service")
|
||||
provisionLegacyNotifiers.wait_for_open_port(3000)
|
||||
print(provisionLegacyNotifiers.succeed(
|
||||
"curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/alert-notifications/uid/test_notifiers"
|
||||
))
|
||||
provisionLegacyNotifiers.succeed(
|
||||
"curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/alert-notifications/uid/test_notifiers | grep Test\ Notifiers"
|
||||
)
|
||||
'';
|
||||
})
|
||||
|
||||
@@ -26,8 +26,9 @@ let
|
||||
|
||||
powerManagement.resumeCommands = "systemctl --no-block restart backdoor.service";
|
||||
|
||||
fileSystems = {
|
||||
"/".device = "/dev/vda2";
|
||||
fileSystems."/" = {
|
||||
device = "/dev/vda2";
|
||||
fsType = "ext3";
|
||||
};
|
||||
swapDevices = mkOverride 0 [ { device = "/dev/vda1"; } ];
|
||||
boot.resumeDevice = mkIf systemdStage1 "/dev/vda1";
|
||||
|
||||
@@ -8,9 +8,10 @@
|
||||
# them when fixed.
|
||||
inherit (import ./installer.nix { inherit system config pkgs; systemdStage1 = true; })
|
||||
# bcache
|
||||
# btrfsSimple
|
||||
# btrfsSubvolDefault
|
||||
# btrfsSubvols
|
||||
btrfsSimple
|
||||
btrfsSubvolDefault
|
||||
btrfsSubvolEscape
|
||||
btrfsSubvols
|
||||
# encryptedFSWithKeyfile
|
||||
# grub1
|
||||
# luksroot
|
||||
|
||||
@@ -911,4 +911,25 @@ in {
|
||||
)
|
||||
'';
|
||||
};
|
||||
|
||||
# Test to see if we can deal with subvols that need to be escaped in fstab
|
||||
btrfsSubvolEscape = makeInstallerTest "btrfsSubvolEscape" {
|
||||
createPartitions = ''
|
||||
machine.succeed(
|
||||
"sgdisk -Z /dev/vda",
|
||||
"sgdisk -n 1:0:+1M -n 2:0:+1G -N 3 -t 1:ef02 -t 2:8200 -t 3:8300 -c 3:root /dev/vda",
|
||||
"mkswap /dev/vda2 -L swap",
|
||||
"swapon -L swap",
|
||||
"mkfs.btrfs -L root /dev/vda3",
|
||||
"btrfs device scan",
|
||||
"mount LABEL=root /mnt",
|
||||
"btrfs subvol create '/mnt/nixos in space'",
|
||||
"btrfs subvol create /mnt/boot",
|
||||
"umount /mnt",
|
||||
"mount -o 'defaults,subvol=nixos in space' LABEL=root /mnt",
|
||||
"mkdir /mnt/boot",
|
||||
"mount -o defaults,subvol=boot LABEL=root /mnt/boot",
|
||||
)
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
||||
@@ -5,10 +5,13 @@
|
||||
let
|
||||
certs = import ./common/acme/server/snakeoil-certs.nix;
|
||||
frontendUrl = "https://${certs.domain}";
|
||||
initialAdminPassword = "h4IhoJFnt2iQIR9";
|
||||
|
||||
keycloakTest = import ./make-test-python.nix (
|
||||
{ pkgs, databaseType, ... }:
|
||||
let
|
||||
initialAdminPassword = "h4Iho\"JFn't2>iQIR9";
|
||||
adminPasswordFile = pkgs.writeText "admin-password" "${initialAdminPassword}";
|
||||
in
|
||||
{
|
||||
name = "keycloak";
|
||||
meta = with pkgs.lib.maintainers; {
|
||||
@@ -37,7 +40,7 @@ let
|
||||
type = databaseType;
|
||||
username = "bogus";
|
||||
name = "also bogus";
|
||||
passwordFile = "${pkgs.writeText "dbPassword" "wzf6vOCbPp6cqTH"}";
|
||||
passwordFile = "${pkgs.writeText "dbPassword" ''wzf6\"vO"Cb\nP>p#6;c&o?eu=q'THE'''H''''E''}";
|
||||
};
|
||||
plugins = with config.services.keycloak.package.plugins; [
|
||||
keycloak-discord
|
||||
@@ -111,7 +114,7 @@ let
|
||||
keycloak.succeed("""
|
||||
curl -sSf -d 'client_id=admin-cli' \
|
||||
-d 'username=admin' \
|
||||
-d 'password=${initialAdminPassword}' \
|
||||
-d "password=$(<${adminPasswordFile})" \
|
||||
-d 'grant_type=password' \
|
||||
'${frontendUrl}/realms/master/protocol/openid-connect/token' \
|
||||
| jq -r '"Authorization: bearer " + .access_token' >admin_auth_header
|
||||
@@ -119,10 +122,10 @@ let
|
||||
|
||||
# Register the metrics SPI
|
||||
keycloak.succeed(
|
||||
"${pkgs.jre}/bin/keytool -import -alias snakeoil -file ${certs.ca.cert} -storepass aaaaaa -keystore cacert.jks -noprompt",
|
||||
"KC_OPTS='-Djavax.net.ssl.trustStore=cacert.jks -Djavax.net.ssl.trustStorePassword=aaaaaa' kcadm.sh config credentials --server '${frontendUrl}' --realm master --user admin --password '${initialAdminPassword}'",
|
||||
"KC_OPTS='-Djavax.net.ssl.trustStore=cacert.jks -Djavax.net.ssl.trustStorePassword=aaaaaa' kcadm.sh update events/config -s 'eventsEnabled=true' -s 'adminEventsEnabled=true' -s 'eventsListeners+=metrics-listener'",
|
||||
"curl -sSf '${frontendUrl}/realms/master/metrics' | grep '^keycloak_admin_event_UPDATE'"
|
||||
"""${pkgs.jre}/bin/keytool -import -alias snakeoil -file ${certs.ca.cert} -storepass aaaaaa -keystore cacert.jks -noprompt""",
|
||||
"""KC_OPTS='-Djavax.net.ssl.trustStore=cacert.jks -Djavax.net.ssl.trustStorePassword=aaaaaa' kcadm.sh config credentials --server '${frontendUrl}' --realm master --user admin --password "$(<${adminPasswordFile})" """,
|
||||
"""KC_OPTS='-Djavax.net.ssl.trustStore=cacert.jks -Djavax.net.ssl.trustStorePassword=aaaaaa' kcadm.sh update events/config -s 'eventsEnabled=true' -s 'adminEventsEnabled=true' -s 'eventsListeners+=metrics-listener'""",
|
||||
"""curl -sSf '${frontendUrl}/realms/master/metrics' | grep '^keycloak_admin_event_UPDATE'"""
|
||||
)
|
||||
|
||||
# Publish the realm, including a test OIDC client and user
|
||||
|
||||
@@ -37,6 +37,8 @@ in {
|
||||
"d /var/lib/nextcloud-data 0750 nextcloud nginx - -"
|
||||
];
|
||||
|
||||
system.stateVersion = "22.11"; # stateVersion >=21.11 to make sure that we use OpenSSL3
|
||||
|
||||
services.nextcloud = {
|
||||
enable = true;
|
||||
datadir = "/var/lib/nextcloud-data";
|
||||
@@ -99,6 +101,10 @@ in {
|
||||
# This is just to ensure the nextcloud-occ program is working
|
||||
nextcloud.succeed("nextcloud-occ status")
|
||||
nextcloud.succeed("curl -sSf http://nextcloud/login")
|
||||
# Ensure that no OpenSSL 1.1 is used.
|
||||
nextcloud.succeed(
|
||||
"${nodes.nextcloud.services.phpfpm.pools.nextcloud.phpPackage}/bin/php -i | grep 'OpenSSL Library Version' | awk -F'=>' '{ print $2 }' | awk '{ print $2 }' | grep -v 1.1"
|
||||
)
|
||||
nextcloud.succeed(
|
||||
"${withRcloneEnv} ${copySharedFile}"
|
||||
)
|
||||
@@ -108,5 +114,6 @@ in {
|
||||
"${withRcloneEnv} ${diffSharedFile}"
|
||||
)
|
||||
assert "hi" in client.succeed("cat /mnt/dav/test-shared-file")
|
||||
nextcloud.succeed("grep -vE '^HBEGIN:oc_encryption_module' /var/lib/nextcloud-data/data/root/files/test-shared-file")
|
||||
'';
|
||||
})) args
|
||||
|
||||
@@ -8,6 +8,10 @@ with pkgs.lib;
|
||||
foldl
|
||||
(matrix: ver: matrix // {
|
||||
"basic${toString ver}" = import ./basic.nix { inherit system pkgs; nextcloudVersion = ver; };
|
||||
"openssl-sse${toString ver}" = import ./openssl-sse.nix {
|
||||
inherit system pkgs;
|
||||
nextcloudVersion = ver;
|
||||
};
|
||||
"with-postgresql-and-redis${toString ver}" = import ./with-postgresql-and-redis.nix {
|
||||
inherit system pkgs;
|
||||
nextcloudVersion = ver;
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
args@{ pkgs, nextcloudVersion ? 25, ... }:
|
||||
|
||||
(import ../make-test-python.nix ({ pkgs, ...}: let
|
||||
adminuser = "root";
|
||||
adminpass = "notproduction";
|
||||
nextcloudBase = {
|
||||
networking.firewall.allowedTCPPorts = [ 80 ];
|
||||
system.stateVersion = "22.05"; # stateVersions <22.11 use openssl 1.1 by default
|
||||
services.nextcloud = {
|
||||
enable = true;
|
||||
config.adminpassFile = "${pkgs.writeText "adminpass" adminpass}";
|
||||
package = pkgs.${"nextcloud" + (toString nextcloudVersion)};
|
||||
};
|
||||
};
|
||||
in {
|
||||
name = "nextcloud-openssl";
|
||||
meta = with pkgs.lib.maintainers; {
|
||||
maintainers = [ ma27 ];
|
||||
};
|
||||
nodes.nextcloudwithopenssl1 = {
|
||||
imports = [ nextcloudBase ];
|
||||
services.nextcloud.hostName = "nextcloudwithopenssl1";
|
||||
};
|
||||
nodes.nextcloudwithopenssl3 = {
|
||||
imports = [ nextcloudBase ];
|
||||
services.nextcloud = {
|
||||
hostName = "nextcloudwithopenssl3";
|
||||
enableBrokenCiphersForSSE = false;
|
||||
};
|
||||
};
|
||||
testScript = { nodes, ... }: let
|
||||
withRcloneEnv = host: pkgs.writeScript "with-rclone-env" ''
|
||||
#!${pkgs.runtimeShell}
|
||||
export RCLONE_CONFIG_NEXTCLOUD_TYPE=webdav
|
||||
export RCLONE_CONFIG_NEXTCLOUD_URL="http://${host}/remote.php/webdav/"
|
||||
export RCLONE_CONFIG_NEXTCLOUD_VENDOR="nextcloud"
|
||||
export RCLONE_CONFIG_NEXTCLOUD_USER="${adminuser}"
|
||||
export RCLONE_CONFIG_NEXTCLOUD_PASS="$(${pkgs.rclone}/bin/rclone obscure ${adminpass})"
|
||||
"''${@}"
|
||||
'';
|
||||
withRcloneEnv1 = withRcloneEnv "nextcloudwithopenssl1";
|
||||
withRcloneEnv3 = withRcloneEnv "nextcloudwithopenssl3";
|
||||
copySharedFile1 = pkgs.writeScript "copy-shared-file" ''
|
||||
#!${pkgs.runtimeShell}
|
||||
echo 'hi' | ${withRcloneEnv1} ${pkgs.rclone}/bin/rclone rcat nextcloud:test-shared-file
|
||||
'';
|
||||
copySharedFile3 = pkgs.writeScript "copy-shared-file" ''
|
||||
#!${pkgs.runtimeShell}
|
||||
echo 'bye' | ${withRcloneEnv3} ${pkgs.rclone}/bin/rclone rcat nextcloud:test-shared-file2
|
||||
'';
|
||||
openssl1-node = nodes.nextcloudwithopenssl1.config.system.build.toplevel;
|
||||
openssl3-node = nodes.nextcloudwithopenssl3.config.system.build.toplevel;
|
||||
in ''
|
||||
nextcloudwithopenssl1.start()
|
||||
nextcloudwithopenssl1.wait_for_unit("multi-user.target")
|
||||
nextcloudwithopenssl1.succeed("nextcloud-occ status")
|
||||
nextcloudwithopenssl1.succeed("curl -sSf http://nextcloudwithopenssl1/login")
|
||||
|
||||
with subtest("With OpenSSL 1 SSE can be enabled and used"):
|
||||
nextcloudwithopenssl1.succeed("nextcloud-occ app:enable encryption")
|
||||
nextcloudwithopenssl1.succeed("nextcloud-occ encryption:enable")
|
||||
|
||||
with subtest("Upload file and ensure it's encrypted"):
|
||||
nextcloudwithopenssl1.succeed("${copySharedFile1}")
|
||||
nextcloudwithopenssl1.succeed("grep -E '^HBEGIN:oc_encryption_module' /var/lib/nextcloud/data/root/files/test-shared-file")
|
||||
nextcloudwithopenssl1.succeed("${withRcloneEnv1} ${pkgs.rclone}/bin/rclone cat nextcloud:test-shared-file | grep hi")
|
||||
|
||||
with subtest("Switch to OpenSSL 3"):
|
||||
nextcloudwithopenssl1.succeed("${openssl3-node}/bin/switch-to-configuration test")
|
||||
nextcloudwithopenssl1.wait_for_open_port(80)
|
||||
nextcloudwithopenssl1.succeed("nextcloud-occ status")
|
||||
|
||||
with subtest("Existing encrypted files cannot be read, but new files can be added"):
|
||||
nextcloudwithopenssl1.fail("${withRcloneEnv3} ${pkgs.rclone}/bin/rclone cat nextcloud:test-shared-file >&2")
|
||||
nextcloudwithopenssl1.succeed("nextcloud-occ encryption:disable")
|
||||
nextcloudwithopenssl1.succeed("${copySharedFile3}")
|
||||
nextcloudwithopenssl1.succeed("grep bye /var/lib/nextcloud/data/root/files/test-shared-file2")
|
||||
nextcloudwithopenssl1.succeed("${withRcloneEnv3} ${pkgs.rclone}/bin/rclone cat nextcloud:test-shared-file2 | grep bye")
|
||||
|
||||
with subtest("Switch back to OpenSSL 1.1 and ensure that encrypted files are readable again"):
|
||||
nextcloudwithopenssl1.succeed("${openssl1-node}/bin/switch-to-configuration test")
|
||||
nextcloudwithopenssl1.wait_for_open_port(80)
|
||||
nextcloudwithopenssl1.succeed("nextcloud-occ status")
|
||||
nextcloudwithopenssl1.succeed("nextcloud-occ encryption:enable")
|
||||
nextcloudwithopenssl1.succeed("${withRcloneEnv1} ${pkgs.rclone}/bin/rclone cat nextcloud:test-shared-file2 | grep bye")
|
||||
nextcloudwithopenssl1.succeed("${withRcloneEnv1} ${pkgs.rclone}/bin/rclone cat nextcloud:test-shared-file | grep hi")
|
||||
nextcloudwithopenssl1.succeed("grep -E '^HBEGIN:oc_encryption_module' /var/lib/nextcloud/data/root/files/test-shared-file")
|
||||
nextcloudwithopenssl1.succeed("grep bye /var/lib/nextcloud/data/root/files/test-shared-file2")
|
||||
|
||||
with subtest("Ensure that everything can be decrypted"):
|
||||
nextcloudwithopenssl1.succeed("echo y | nextcloud-occ encryption:decrypt-all >&2")
|
||||
nextcloudwithopenssl1.succeed("${withRcloneEnv1} ${pkgs.rclone}/bin/rclone cat nextcloud:test-shared-file2 | grep bye")
|
||||
nextcloudwithopenssl1.succeed("${withRcloneEnv1} ${pkgs.rclone}/bin/rclone cat nextcloud:test-shared-file | grep hi")
|
||||
nextcloudwithopenssl1.succeed("grep -vE '^HBEGIN:oc_encryption_module' /var/lib/nextcloud/data/root/files/test-shared-file")
|
||||
|
||||
with subtest("Switch to OpenSSL 3 ensure that all files are usable now"):
|
||||
nextcloudwithopenssl1.succeed("${openssl3-node}/bin/switch-to-configuration test")
|
||||
nextcloudwithopenssl1.wait_for_open_port(80)
|
||||
nextcloudwithopenssl1.succeed("nextcloud-occ status")
|
||||
nextcloudwithopenssl1.succeed("${withRcloneEnv3} ${pkgs.rclone}/bin/rclone cat nextcloud:test-shared-file2 | grep bye")
|
||||
nextcloudwithopenssl1.succeed("${withRcloneEnv3} ${pkgs.rclone}/bin/rclone cat nextcloud:test-shared-file | grep hi")
|
||||
|
||||
nextcloudwithopenssl1.shutdown()
|
||||
'';
|
||||
})) args
|
||||
@@ -0,0 +1,65 @@
|
||||
import ./make-test-python.nix ({ pkgs, ...}: let
|
||||
pin = "1234";
|
||||
in {
|
||||
name = "phosh";
|
||||
meta = with pkgs.lib.maintainers; {
|
||||
maintainers = [ zhaofengli ];
|
||||
};
|
||||
|
||||
nodes = {
|
||||
phone = { config, pkgs, ... }: {
|
||||
users.users.nixos = {
|
||||
isNormalUser = true;
|
||||
password = pin;
|
||||
};
|
||||
|
||||
services.xserver.desktopManager.phosh = {
|
||||
enable = true;
|
||||
user = "nixos";
|
||||
group = "users";
|
||||
|
||||
phocConfig = {
|
||||
outputs.Virtual-1 = {
|
||||
scale = 2;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.phosh = {
|
||||
environment = {
|
||||
# Accelerated graphics fail on phoc 0.20 (wlroots 0.15)
|
||||
"WLR_RENDERER" = "pixman";
|
||||
};
|
||||
};
|
||||
|
||||
virtualisation.resolution = { x = 720; y = 1440; };
|
||||
virtualisation.qemu.options = [ "-vga none -device virtio-gpu-pci,xres=720,yres=1440" ];
|
||||
};
|
||||
};
|
||||
|
||||
enableOCR = true;
|
||||
|
||||
testScript = ''
|
||||
import time
|
||||
|
||||
start_all()
|
||||
phone.wait_for_unit("phosh.service")
|
||||
|
||||
with subtest("Check that we can see the lock screen info page"):
|
||||
# Saturday, January 1
|
||||
phone.succeed("timedatectl set-time '2022-01-01 07:00'")
|
||||
|
||||
phone.wait_for_text("Saturday")
|
||||
phone.screenshot("01lockinfo")
|
||||
|
||||
with subtest("Check that we can unlock the screen"):
|
||||
phone.send_chars("${pin}", delay=0.2)
|
||||
time.sleep(1)
|
||||
phone.screenshot("02unlock")
|
||||
|
||||
phone.send_chars("\n")
|
||||
|
||||
phone.wait_for_text("All Apps")
|
||||
phone.screenshot("03launcher")
|
||||
'';
|
||||
})
|
||||
@@ -23,6 +23,8 @@ import ./make-test-python.nix ({ lib, pkgs, ... }: {
|
||||
cryptroot2.device = "/dev/vdd";
|
||||
};
|
||||
virtualisation.bootDevice = "/dev/mapper/cryptroot";
|
||||
# test mounting device unlocked in initrd after switching root
|
||||
virtualisation.fileSystems."/cryptroot2".device = "/dev/mapper/cryptroot2";
|
||||
};
|
||||
};
|
||||
|
||||
@@ -31,6 +33,8 @@ import ./make-test-python.nix ({ lib, pkgs, ... }: {
|
||||
machine.wait_for_unit("multi-user.target")
|
||||
machine.succeed("echo -n supersecret | cryptsetup luksFormat -q --iter-time=1 /dev/vdc -")
|
||||
machine.succeed("echo -n supersecret | cryptsetup luksFormat -q --iter-time=1 /dev/vdd -")
|
||||
machine.succeed("echo -n supersecret | cryptsetup luksOpen -q /dev/vdd cryptroot2")
|
||||
machine.succeed("mkfs.ext4 /dev/mapper/cryptroot2")
|
||||
|
||||
# Boot from the encrypted disk
|
||||
machine.succeed("bootctl set-default nixos-generation-1-specialisation-boot-luks.conf")
|
||||
@@ -44,5 +48,6 @@ import ./make-test-python.nix ({ lib, pkgs, ... }: {
|
||||
machine.wait_for_unit("multi-user.target")
|
||||
|
||||
assert "/dev/mapper/cryptroot on / type ext4" in machine.succeed("mount")
|
||||
assert "/dev/mapper/cryptroot2 on /cryptroot2 type ext4" in machine.succeed("mount")
|
||||
'';
|
||||
})
|
||||
|
||||
@@ -13,13 +13,13 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "wvkbd";
|
||||
version = "0.11";
|
||||
version = "0.12";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "jjsullivan5196";
|
||||
repo = pname;
|
||||
rev = "v${version}";
|
||||
sha256 = "sha256-rMaJzePtT7K0X9o9/yT1hfKIo07W2CLEZKqHwfCLQBE=";
|
||||
sha256 = "sha256-5m4aeuCqSJNgerQKyP9M6Qf7P4ijCtCY4Efew6E09Bc=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ pkg-config ];
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "bitwig-studio";
|
||||
version = "4.4.2";
|
||||
version = "4.4.3";
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://downloads.bitwig.com/stable/${version}/${pname}-${version}.deb";
|
||||
sha256 = "sha256-nLXpf0Xi7yuz/Rm8Sfkr1PGLuazN+Lh6sIqkWFBmP3w=";
|
||||
sha256 = "sha256-NP9cM1xIHblMdUFKIviPKDi6su6Nc3xsX2pnPeP7hdQ=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ dpkg makeWrapper wrapGAppsHook ];
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
python3.pkgs.buildPythonApplication rec {
|
||||
pname = "lollypop";
|
||||
version = "1.4.36";
|
||||
version = "1.4.35";
|
||||
|
||||
format = "other";
|
||||
doCheck = false;
|
||||
@@ -34,7 +34,7 @@ python3.pkgs.buildPythonApplication rec {
|
||||
url = "https://gitlab.gnome.org/World/lollypop";
|
||||
rev = "refs/tags/${version}";
|
||||
fetchSubmodules = true;
|
||||
sha256 = "sha256-Ka/rYgWGuCQTzguJiyQpY5SPC1iB5XOVy/Gezj+DYpk=";
|
||||
sha256 = "sha256-Rdp0gZjdj2tXOWarsTpqgvSZVXAQsCLfk5oUyalE/ZA=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
|
||||
@@ -18,14 +18,14 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "odin2";
|
||||
version = "unstable-2022-02-23";
|
||||
version = "2.3.4";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "baconpaul";
|
||||
owner = "TheWaveWarden";
|
||||
repo = "odin2";
|
||||
rev = "ed02d06cfb5db8a118d291c00bd2e4cd6e262cde";
|
||||
rev = "v${version}";
|
||||
fetchSubmodules = true;
|
||||
sha256 = "sha256-VkZ+mqCmqWQafdN0nQxJdPxbiaZ37/0jOhLvVbnGLvQ=";
|
||||
sha256 = "sha256-N96Nb7G6hqfh8DyMtHbttl/fRZUkS8f2KfPSqeMAhHY=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
@@ -62,10 +62,12 @@ stdenv.mkDerivation rec {
|
||||
];
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out/bin $out/lib/vst3
|
||||
mkdir -p $out/bin $out/lib/vst3 $out/lib/lv2 $out/lib/clap
|
||||
cd Odin2_artefacts/Release
|
||||
cp Standalone/Odin2 $out/bin
|
||||
cp -r VST3/Odin2.vst3 $out/lib/vst3
|
||||
cp -r Standalone/Odin2 $out/bin
|
||||
cp -r LV2/Odin2.lv2 $out/lib/lv2
|
||||
cp -r CLAP/Odin2.clap $out/lib/clap
|
||||
'';
|
||||
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ buildNpmPackage rec {
|
||||
./package-lock.json.patch
|
||||
];
|
||||
|
||||
npmDepsHash = "sha256-UF3pZ+SlrgDLqntciXRNbWfpPMtQw1DXl41x9r37QN4=";
|
||||
npmDepsHash = "sha256-SGLcFjPnmhFoeXtP4gfGr4Qa1dTaXwSnzkweEvYW/1k=";
|
||||
|
||||
nativeBuildInputs = [
|
||||
copyDesktopItems
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
{ stdenv, lib, mkDerivation, fetchFromGitHub, qmake, pkg-config, alsa-lib, libjack2, portaudio, libogg, flac, libvorbis, rtmidi, qtsvg }:
|
||||
{ stdenv, lib, mkDerivation, fetchFromGitHub, qmake, pkg-config, alsa-lib, libjack2, portaudio, libogg, flac, libvorbis, rtmidi, qtsvg, qttools }:
|
||||
|
||||
mkDerivation rec {
|
||||
version = "2.2.0";
|
||||
version = "2.3.0";
|
||||
pname = "polyphone";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "davy7125";
|
||||
repo = "polyphone";
|
||||
rev = version;
|
||||
sha256 = "0w5pidzhpwpggjn5la384fvjzkvprvrnidb06068whci11kgpbp7";
|
||||
sha256 = "09habv51pw71wrb39shqi80i2w39dx5a39klzswsald5j9sia0ir";
|
||||
};
|
||||
|
||||
buildInputs = [
|
||||
@@ -22,7 +22,7 @@ mkDerivation rec {
|
||||
qtsvg
|
||||
];
|
||||
|
||||
nativeBuildInputs = [ qmake pkg-config ];
|
||||
nativeBuildInputs = [ qmake qttools pkg-config ];
|
||||
|
||||
preConfigure = ''
|
||||
cd ./sources/
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "praat";
|
||||
version = "6.2.23";
|
||||
version = "6.3";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "praat";
|
||||
repo = "praat";
|
||||
rev = "v${version}";
|
||||
sha256 = "sha256-gl+kT8wXLCWnNmOBx6Vg+FbmJ8kJ8pJKsahpqcYw9Lk=";
|
||||
sha256 = "sha256-/XSBUM6HkANATl1Y9vs8mQFgBTyVeCv8TxcaIdP/Nm8=";
|
||||
};
|
||||
|
||||
configurePhase = ''
|
||||
|
||||
@@ -13,13 +13,13 @@
|
||||
|
||||
mkDerivation rec {
|
||||
pname = "ptcollab";
|
||||
version = "0.6.4.1";
|
||||
version = "0.6.4.5";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "yuxshao";
|
||||
repo = "ptcollab";
|
||||
rev = "v${version}";
|
||||
sha256 = "sha256-/Z0UDxZtVnGKVmscNCZAvTGMALq/uMd7/h3r/QvUs0M=";
|
||||
sha256 = "sha256-O7CNPMS0eRcqt2xAtyEFyLSV8U2xbxuV1DpBxZAFwQs=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ qmake pkg-config ];
|
||||
|
||||
@@ -59,8 +59,9 @@ python3.pkgs.buildPythonApplication rec {
|
||||
rapidfuzz
|
||||
];
|
||||
|
||||
# the file should be executable but it isn't so our wrapper doesn't run
|
||||
preFixup = ''
|
||||
makeWrapperArgs+=("''${qtWrapperArgs[@]}")
|
||||
chmod 555 $out/bin/puddletag
|
||||
'';
|
||||
|
||||
doCheck = false; # there are no tests
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
{ stdenv
|
||||
, lib
|
||||
, fetchFromSourcehut
|
||||
, fetchFromGitHub
|
||||
, fetchpatch
|
||||
, cmake
|
||||
, wxGTK31
|
||||
, wxGTK32
|
||||
, gtk3
|
||||
, pkg-config
|
||||
, python3
|
||||
@@ -48,15 +49,23 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "tenacity";
|
||||
version = "unstable-2021-10-18";
|
||||
version = "unstable-2022-06-30";
|
||||
|
||||
src = fetchFromSourcehut {
|
||||
owner = "~tenacity";
|
||||
repo = "tenacity";
|
||||
rev = "697c0e764ccb19c1e2f3073ae08ecdac7aa710e4";
|
||||
sha256 = "1fc9xz8lyl8si08wkzncpxq92vizan60c3640qr4kbnxg7vi2iy4";
|
||||
src = fetchFromGitHub {
|
||||
owner = "tenacityteam";
|
||||
repo = pname;
|
||||
rev = "91f8b4340b159af551fff94a284c6b0f704a7932";
|
||||
sha256 = "sha256-4VWckXzqo2xspw9eUloDvjxQYbsHn6ghEDw+hYqJcCE=";
|
||||
};
|
||||
|
||||
patches = [
|
||||
(fetchpatch {
|
||||
url = "https://aur.archlinux.org/cgit/aur.git/plain/wxwidgets-gtk3-3.1.6-plus.patch?h=tenacity-wxgtk3-git&id=c2503538fa7d7001181905988179952d09f69659";
|
||||
postFetch = "echo >> $out";
|
||||
sha256 = "sha256-xRY1tizBJ9CBY6e9oZVz4CWx7DWPGD9A9Ysol4prBww=";
|
||||
})
|
||||
];
|
||||
|
||||
postPatch = ''
|
||||
touch src/RevisionIdent.h
|
||||
|
||||
@@ -124,7 +133,7 @@ stdenv.mkDerivation rec {
|
||||
sratom
|
||||
suil
|
||||
twolame
|
||||
wxGTK31
|
||||
wxGTK32
|
||||
gtk3
|
||||
] ++ lib.optionals stdenv.isLinux [
|
||||
at-spi2-core
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
, python3
|
||||
, fetchFromGitHub
|
||||
, fetchpatch
|
||||
, installShellFiles
|
||||
, libcdio-paranoia
|
||||
, cdrdao
|
||||
, libsndfile
|
||||
@@ -35,6 +36,8 @@ in python3.pkgs.buildPythonApplication rec {
|
||||
];
|
||||
|
||||
nativeBuildInputs = with python3.pkgs; [
|
||||
installShellFiles
|
||||
|
||||
setuptools-scm
|
||||
docutils
|
||||
setuptoolsCheckHook
|
||||
@@ -65,6 +68,11 @@ in python3.pkgs.buildPythonApplication rec {
|
||||
export SETUPTOOLS_SCM_PRETEND_VERSION="${version}"
|
||||
'';
|
||||
|
||||
outputs = [ "out" "man" ];
|
||||
postBuild = ''
|
||||
make -C man
|
||||
'';
|
||||
|
||||
preCheck = ''
|
||||
# disable tests that require internet access
|
||||
# https://github.com/JoeLametta/whipper/issues/291
|
||||
@@ -73,6 +81,10 @@ in python3.pkgs.buildPythonApplication rec {
|
||||
export HOME=$TMPDIR
|
||||
'';
|
||||
|
||||
postInstall = ''
|
||||
installManPage man/*.1
|
||||
'';
|
||||
|
||||
passthru.tests.version = testers.testVersion {
|
||||
package = whipper;
|
||||
command = "HOME=$TMPDIR whipper --version";
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "ergo";
|
||||
version = "4.0.104";
|
||||
version = "5.0.3";
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://github.com/ergoplatform/ergo/releases/download/v${version}/ergo-${version}.jar";
|
||||
sha256 = "sha256-h6OVeDifYIKyIkwbN/pmJWge4/YGL6cnQQ/sI14LsHQ=";
|
||||
sha256 = "sha256-IDAss4qX39qPyOsPpVg5zU6zq/QV/RTnbHTGVl9UmOA=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ makeWrapper ];
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
}:
|
||||
rustPlatform.buildRustPackage rec {
|
||||
pname = "nearcore";
|
||||
version = "1.29.0";
|
||||
version = "1.29.1";
|
||||
|
||||
# https://github.com/near/nearcore/tags
|
||||
src = fetchFromGitHub {
|
||||
@@ -13,10 +13,10 @@ rustPlatform.buildRustPackage rec {
|
||||
# there is also a branch for this version number, so we need to be explicit
|
||||
rev = "refs/tags/${version}";
|
||||
|
||||
sha256 = "sha256-TOZ6j4CaiOXmNn8kgVGP27SjvLDlGvabAA+PAEyFXIk=";
|
||||
sha256 = "sha256-TmmGLrDpNOfadOIwmG7XRgI89XQjaqIavxCEE2plumc=";
|
||||
};
|
||||
|
||||
cargoSha256 = "sha256-LjBgsQynHIfrQP4Z7j1J8+PLqRZWGAOQ5dJaGOqabVk=";
|
||||
cargoSha256 = "sha256-4suoHP6AXhXlt7+sHMX5RW/LGZrbMhNNmzYvFBcnMTs=";
|
||||
cargoPatches = [ ./0001-make-near-test-contracts-optional.patch ];
|
||||
|
||||
postPatch = ''
|
||||
|
||||
@@ -10,13 +10,13 @@
|
||||
}:
|
||||
rustPlatform.buildRustPackage rec {
|
||||
pname = "polkadot";
|
||||
version = "0.9.30";
|
||||
version = "0.9.32";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "paritytech";
|
||||
repo = "polkadot";
|
||||
rev = "v${version}";
|
||||
sha256 = "sha256-lnClnra69vfszPjnrOldSkd3kgC34bgociicC6Kpupw=";
|
||||
sha256 = "sha256-bE7PzvkHKAP/nqNkoBMTGvZZwmf8YY+cGnJ2EM/2xAs=";
|
||||
|
||||
# the build process of polkadot requires a .git folder in order to determine
|
||||
# the git commit hash that is being built and add it to the version string.
|
||||
@@ -32,7 +32,7 @@ rustPlatform.buildRustPackage rec {
|
||||
'';
|
||||
};
|
||||
|
||||
cargoSha256 = "sha256-mnfA0ecfmMMAy1TZeydbep6hCIu9yZQY7/c5hb1OMGc=";
|
||||
cargoSha256 = "sha256-NI50KFXvQgUV+G1l5D2gnAo1EohnCpQWlFCZ0iP2CVQ=";
|
||||
|
||||
buildInputs = lib.optionals stdenv.isDarwin [ Security ];
|
||||
|
||||
|
||||
@@ -249,10 +249,10 @@
|
||||
elpaBuild {
|
||||
pname = "auctex";
|
||||
ename = "auctex";
|
||||
version = "13.1.5";
|
||||
version = "13.1.6";
|
||||
src = fetchurl {
|
||||
url = "https://elpa.gnu.org/packages/auctex-13.1.5.tar";
|
||||
sha256 = "00g6js6089637w8alch4dvk140chjkyirsa8inh9ai6a6kkfvc3p";
|
||||
url = "https://elpa.gnu.org/packages/auctex-13.1.6.tar";
|
||||
sha256 = "0pdinnhkv7vqib01a6vxq1iixs7sw72r0sxzryv78c9hxn2k4552";
|
||||
};
|
||||
packageRequires = [ emacs ];
|
||||
meta = {
|
||||
@@ -414,10 +414,10 @@
|
||||
elpaBuild {
|
||||
pname = "boxy";
|
||||
ename = "boxy";
|
||||
version = "1.1.1";
|
||||
version = "1.1.2";
|
||||
src = fetchurl {
|
||||
url = "https://elpa.gnu.org/packages/boxy-1.1.1.tar";
|
||||
sha256 = "08jb5v93l3y9cx48qhpv20i7kdxvl5dinxj3z0pxkx0ckvml7cvd";
|
||||
url = "https://elpa.gnu.org/packages/boxy-1.1.2.tar";
|
||||
sha256 = "0gqfs8rwqb3clwqgvv9wibl2mfx0njkdcpwl662p4bwnapl4hsi9";
|
||||
};
|
||||
packageRequires = [ emacs ];
|
||||
meta = {
|
||||
@@ -429,10 +429,10 @@
|
||||
elpaBuild {
|
||||
pname = "boxy-headings";
|
||||
ename = "boxy-headings";
|
||||
version = "2.1.3";
|
||||
version = "2.1.4";
|
||||
src = fetchurl {
|
||||
url = "https://elpa.gnu.org/packages/boxy-headings-2.1.3.tar";
|
||||
sha256 = "09k5x123db19v2k49y8acyk5y3r0fxw0xz61qqqidrgrx8fs3mg9";
|
||||
url = "https://elpa.gnu.org/packages/boxy-headings-2.1.4.tar";
|
||||
sha256 = "101kiw10p0sd8j8px16zsw57my7h2f1anhnwj678z22hxhs8vla7";
|
||||
};
|
||||
packageRequires = [ boxy emacs org ];
|
||||
meta = {
|
||||
@@ -891,10 +891,10 @@
|
||||
elpaBuild {
|
||||
pname = "crdt";
|
||||
ename = "crdt";
|
||||
version = "0.3.4";
|
||||
version = "0.3.5";
|
||||
src = fetchurl {
|
||||
url = "https://elpa.gnu.org/packages/crdt-0.3.4.tar";
|
||||
sha256 = "1wha43mrllnpc2i7p91dns8iwaxf60mp20h234c07m9jcjvcxrmc";
|
||||
url = "https://elpa.gnu.org/packages/crdt-0.3.5.tar";
|
||||
sha256 = "0pir9ap8lryrw12slgg4v30bzjphc37r6p0fw36larlh9wp8jj5z";
|
||||
};
|
||||
packageRequires = [];
|
||||
meta = {
|
||||
@@ -2392,6 +2392,21 @@
|
||||
license = lib.licenses.free;
|
||||
};
|
||||
}) {};
|
||||
jarchive = callPackage ({ elpaBuild, emacs, fetchurl, lib }:
|
||||
elpaBuild {
|
||||
pname = "jarchive";
|
||||
ename = "jarchive";
|
||||
version = "0.8.0";
|
||||
src = fetchurl {
|
||||
url = "https://elpa.gnu.org/packages/jarchive-0.8.0.tar";
|
||||
sha256 = "0xfl0gbfqjgbkd28r56j35kc8y6x8nd2zi8xqzxmqvcyv9sd731l";
|
||||
};
|
||||
packageRequires = [ emacs ];
|
||||
meta = {
|
||||
homepage = "https://elpa.gnu.org/packages/jarchive.html";
|
||||
license = lib.licenses.free;
|
||||
};
|
||||
}) {};
|
||||
javaimp = callPackage ({ elpaBuild, fetchurl, lib }:
|
||||
elpaBuild {
|
||||
pname = "javaimp";
|
||||
@@ -3061,10 +3076,10 @@
|
||||
elpaBuild {
|
||||
pname = "nano-theme";
|
||||
ename = "nano-theme";
|
||||
version = "0.3.3";
|
||||
version = "0.3.4";
|
||||
src = fetchurl {
|
||||
url = "https://elpa.gnu.org/packages/nano-theme-0.3.3.tar";
|
||||
sha256 = "0agdvl85ljiawa06x02zj78crq1y1vg0sr7dqxcl36zx8vhzc08v";
|
||||
url = "https://elpa.gnu.org/packages/nano-theme-0.3.4.tar";
|
||||
sha256 = "1hfw6zxnzm4x55iqk1pg6nlp79c86np856bbdac4nv65ff4dkiqq";
|
||||
};
|
||||
packageRequires = [ emacs ];
|
||||
meta = {
|
||||
@@ -3350,10 +3365,10 @@
|
||||
elpaBuild {
|
||||
pname = "org-real";
|
||||
ename = "org-real";
|
||||
version = "1.0.5";
|
||||
version = "1.0.6";
|
||||
src = fetchurl {
|
||||
url = "https://elpa.gnu.org/packages/org-real-1.0.5.tar";
|
||||
sha256 = "0g70bzhr094fah86cyvd9ci8q28qi9c44g33i4lw7clklgdx7mxl";
|
||||
url = "https://elpa.gnu.org/packages/org-real-1.0.6.tar";
|
||||
sha256 = "1qfzmmv3c1yc14v502x0438pxh2bcwli1r3xmcxibhb7h6p9mr3k";
|
||||
};
|
||||
packageRequires = [ boxy emacs org ];
|
||||
meta = {
|
||||
@@ -3650,10 +3665,10 @@
|
||||
elpaBuild {
|
||||
pname = "posframe";
|
||||
ename = "posframe";
|
||||
version = "1.1.8";
|
||||
version = "1.2.0";
|
||||
src = fetchurl {
|
||||
url = "https://elpa.gnu.org/packages/posframe-1.1.8.tar";
|
||||
sha256 = "0560f05c2rh6jkdba4yq9qbazfz6qbdrymqm5zcihvz7cy019dzm";
|
||||
url = "https://elpa.gnu.org/packages/posframe-1.2.0.tar";
|
||||
sha256 = "06xk6z3b5mqgcskjiwkl9viccvzriflr8y51aclyfdamh5qb6kqb";
|
||||
};
|
||||
packageRequires = [ emacs ];
|
||||
meta = {
|
||||
@@ -3665,10 +3680,10 @@
|
||||
elpaBuild {
|
||||
pname = "project";
|
||||
ename = "project";
|
||||
version = "0.8.2";
|
||||
version = "0.8.3";
|
||||
src = fetchurl {
|
||||
url = "https://elpa.gnu.org/packages/project-0.8.2.tar";
|
||||
sha256 = "1l5yxw6xqml176vskd5fz2y2dbjh8925g3kyimda4gdprz4y7aci";
|
||||
url = "https://elpa.gnu.org/packages/project-0.8.3.tar";
|
||||
sha256 = "15x6nbvyy592fwn36syxi9719sknvrm4bwnpyc16z9jn2xm62q3p";
|
||||
};
|
||||
packageRequires = [ emacs xref ];
|
||||
meta = {
|
||||
@@ -4495,10 +4510,10 @@
|
||||
elpaBuild {
|
||||
pname = "srht";
|
||||
ename = "srht";
|
||||
version = "0.1";
|
||||
version = "0.2";
|
||||
src = fetchurl {
|
||||
url = "https://elpa.gnu.org/packages/srht-0.1.tar";
|
||||
sha256 = "1cdylp2hma83iv062nf7qyz21a3r8562gwx2lk6cf45k2kh3hbv8";
|
||||
url = "https://elpa.gnu.org/packages/srht-0.2.tar";
|
||||
sha256 = "1qps9vdsiy5zkz88kh9kl1hnn1wlfz6n5brzcxi28fwx0hb3ksz2";
|
||||
};
|
||||
packageRequires = [ emacs plz ];
|
||||
meta = {
|
||||
@@ -4999,6 +5014,21 @@
|
||||
license = lib.licenses.free;
|
||||
};
|
||||
}) {};
|
||||
use-package = callPackage ({ bind-key, elpaBuild, emacs, fetchurl, lib }:
|
||||
elpaBuild {
|
||||
pname = "use-package";
|
||||
ename = "use-package";
|
||||
version = "2.4.4";
|
||||
src = fetchurl {
|
||||
url = "https://elpa.gnu.org/packages/use-package-2.4.4.tar";
|
||||
sha256 = "1hw73006l1xh0padqxyr0l3sjnr3fxyz619csz8ds6am86fdxvfp";
|
||||
};
|
||||
packageRequires = [ bind-key emacs ];
|
||||
meta = {
|
||||
homepage = "https://elpa.gnu.org/packages/use-package.html";
|
||||
license = lib.licenses.free;
|
||||
};
|
||||
}) {};
|
||||
validate = callPackage ({ cl-lib ? null
|
||||
, elpaBuild
|
||||
, emacs
|
||||
|
||||
@@ -50,8 +50,6 @@ self: with self; {
|
||||
_map = self.map;
|
||||
};
|
||||
|
||||
nano-theme = callPackage ./manual-packages/nano-theme { };
|
||||
|
||||
ott-mode = callPackage ./manual-packages/ott-mode { };
|
||||
|
||||
perl-completion = callPackage ./manual-packages/perl-completion { };
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
{ trivialBuild
|
||||
, fetchFromGitHub
|
||||
, emacs
|
||||
}:
|
||||
|
||||
trivialBuild rec {
|
||||
pname = "nano-theme";
|
||||
version = "0.pre+unstable=2021-06-29";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "rougier";
|
||||
repo = pname;
|
||||
rev = "4a231787a32b3019f9f0abb3511a112fd54bf685";
|
||||
hash = "sha256-eco9BMKLhPuwFJb5QesbM6g3cZv3FdVvQ9fXq6D3Ifc=";
|
||||
};
|
||||
|
||||
meta = {
|
||||
homepage = "https://github.com/rougier/nano-theme";
|
||||
description = "GNU Emacs / N Λ N O Theme";
|
||||
inherit (emacs.meta) platforms;
|
||||
};
|
||||
}
|
||||
+5
-8
@@ -1,6 +1,9 @@
|
||||
{ lib, stdenv, fetchurl }:
|
||||
{ lib
|
||||
, trivial-build
|
||||
, fetchurl
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation {
|
||||
trivial-build {
|
||||
name = "perl-completion";
|
||||
|
||||
src = fetchurl {
|
||||
@@ -10,14 +13,8 @@ stdenv.mkDerivation {
|
||||
|
||||
dontUnpack = true;
|
||||
|
||||
installPhase = ''
|
||||
install -d $out/share/emacs/site-lisp
|
||||
install $src $out/share/emacs/site-lisp/perl-completion.el
|
||||
'';
|
||||
|
||||
meta = {
|
||||
description = "Minor mode provides useful features for editing perl codes";
|
||||
homepage = "http://emacswiki.org/emacs/PerlCompletion";
|
||||
platforms = lib.platforms.all;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -80,7 +80,8 @@ def get_cargo_sha256(drv_path: str):
|
||||
if __name__ == "__main__":
|
||||
cwd = sys.argv[1]
|
||||
|
||||
nixpkgs = abspath(join(cwd, "../../../../../.."))
|
||||
# This should point to the root default.nix of Nixpkgs tree
|
||||
nixpkgs = abspath(join(cwd, "../../../../../../.."))
|
||||
|
||||
tag_name = requests.get(
|
||||
"https://api.github.com/repos/emacs-tree-sitter/elisp-tree-sitter/releases/latest"
|
||||
|
||||
@@ -1208,10 +1208,10 @@
|
||||
elpaBuild {
|
||||
pname = "helm";
|
||||
ename = "helm";
|
||||
version = "3.8.9";
|
||||
version = "3.9.0";
|
||||
src = fetchurl {
|
||||
url = "https://elpa.nongnu.org/nongnu/helm-3.8.9.tar";
|
||||
sha256 = "0hikp6g5g7cy290qxd768vxy91gxj92cwrrzp8kicxy3qck1q39v";
|
||||
url = "https://elpa.nongnu.org/nongnu/helm-3.9.0.tar";
|
||||
sha256 = "00lln7g27iipa9lhd9hw3gl6s92d2di4nlfyjz0hgg32v39fnvjd";
|
||||
};
|
||||
packageRequires = [ helm-core popup ];
|
||||
meta = {
|
||||
@@ -1223,10 +1223,10 @@
|
||||
elpaBuild {
|
||||
pname = "helm-core";
|
||||
ename = "helm-core";
|
||||
version = "3.8.9";
|
||||
version = "3.9.0";
|
||||
src = fetchurl {
|
||||
url = "https://elpa.nongnu.org/nongnu/helm-core-3.8.9.tar";
|
||||
sha256 = "03fzcc84gjslgsssbpjhdgnj7dn0pdfb5b2x79ss9vfvxamf2k94";
|
||||
url = "https://elpa.nongnu.org/nongnu/helm-core-3.9.0.tar";
|
||||
sha256 = "1fvrxj64qc4976s6af2zc428dnx2p0skxdnkjikz8rpw8kmffcb9";
|
||||
};
|
||||
packageRequires = [ async emacs ];
|
||||
meta = {
|
||||
@@ -1969,10 +1969,10 @@
|
||||
elpaBuild {
|
||||
pname = "php-mode";
|
||||
ename = "php-mode";
|
||||
version = "1.24.1";
|
||||
version = "1.24.2";
|
||||
src = fetchurl {
|
||||
url = "https://elpa.nongnu.org/nongnu/php-mode-1.24.1.tar";
|
||||
sha256 = "0ixm7z2bq4aacbwyzx53alfnqwbdn36i5ixdi3qjhr8rh5k48vg1";
|
||||
url = "https://elpa.nongnu.org/nongnu/php-mode-1.24.2.tar";
|
||||
sha256 = "1v84b7mjilr6z1zmjfvwp4mwc68mb298fcn03xcaivnd91gvmvs2";
|
||||
};
|
||||
packageRequires = [ emacs ];
|
||||
meta = {
|
||||
@@ -1984,10 +1984,10 @@
|
||||
elpaBuild {
|
||||
pname = "popon";
|
||||
ename = "popon";
|
||||
version = "0.11";
|
||||
version = "0.12";
|
||||
src = fetchurl {
|
||||
url = "https://elpa.nongnu.org/nongnu/popon-0.11.tar";
|
||||
sha256 = "03xxh9w215kmlw6vr3cjs9afkj6vrcip7k954sssx77bs1bpnqhz";
|
||||
url = "https://elpa.nongnu.org/nongnu/popon-0.12.tar";
|
||||
sha256 = "06vsri7dka3qbiwfkl4ml8b99alah24zq8y4n1szh587xy3c7dj0";
|
||||
};
|
||||
packageRequires = [ emacs ];
|
||||
meta = {
|
||||
@@ -2055,6 +2055,24 @@
|
||||
license = lib.licenses.free;
|
||||
};
|
||||
}) {};
|
||||
racket-mode = callPackage ({ elpaBuild
|
||||
, emacs
|
||||
, fetchurl
|
||||
, lib }:
|
||||
elpaBuild {
|
||||
pname = "racket-mode";
|
||||
ename = "racket-mode";
|
||||
version = "1.0.20221118.122133";
|
||||
src = fetchurl {
|
||||
url = "https://elpa.nongnu.org/nongnu/racket-mode-1.0.20221118.122133.tar";
|
||||
sha256 = "0a2lpvkarcw5rlydm3va7ajjsyhfbj023h93n6n94pjvllhn2rp2";
|
||||
};
|
||||
packageRequires = [ emacs ];
|
||||
meta = {
|
||||
homepage = "https://elpa.gnu.org/packages/racket-mode.html";
|
||||
license = lib.licenses.free;
|
||||
};
|
||||
}) {};
|
||||
rainbow-delimiters = callPackage ({ elpaBuild, fetchurl, lib }:
|
||||
elpaBuild {
|
||||
pname = "rainbow-delimiters";
|
||||
@@ -2179,6 +2197,21 @@
|
||||
license = lib.licenses.free;
|
||||
};
|
||||
}) {};
|
||||
scad-mode = callPackage ({ elpaBuild, emacs, fetchurl, lib }:
|
||||
elpaBuild {
|
||||
pname = "scad-mode";
|
||||
ename = "scad-mode";
|
||||
version = "93.1";
|
||||
src = fetchurl {
|
||||
url = "https://elpa.nongnu.org/nongnu/scad-mode-93.1.tar";
|
||||
sha256 = "0k9wqz2nd4j0wz2y300nn6rs8a9vpshnaa2hx6f8649k4y87bblp";
|
||||
};
|
||||
packageRequires = [ emacs ];
|
||||
meta = {
|
||||
homepage = "https://elpa.gnu.org/packages/scad-mode.html";
|
||||
license = lib.licenses.free;
|
||||
};
|
||||
}) {};
|
||||
scala-mode = callPackage ({ elpaBuild, fetchurl, lib }:
|
||||
elpaBuild {
|
||||
pname = "scala-mode";
|
||||
@@ -2378,10 +2411,10 @@
|
||||
elpaBuild {
|
||||
pname = "subed";
|
||||
ename = "subed";
|
||||
version = "1.0.19";
|
||||
version = "1.0.24";
|
||||
src = fetchurl {
|
||||
url = "https://elpa.nongnu.org/nongnu/subed-1.0.19.tar";
|
||||
sha256 = "1wgicb0lvnghhr3a1xndkaxhs1c9gc1ac5xwvxcsc9zpgzrlmcda";
|
||||
url = "https://elpa.nongnu.org/nongnu/subed-1.0.24.tar";
|
||||
sha256 = "1x9w858pgyhd7hlvn85h379f8sfvf8ly3a9596q4jkqbcp9riymq";
|
||||
};
|
||||
packageRequires = [ emacs ];
|
||||
meta = {
|
||||
@@ -2393,10 +2426,10 @@
|
||||
elpaBuild {
|
||||
pname = "sweeprolog";
|
||||
ename = "sweeprolog";
|
||||
version = "0.8.6";
|
||||
version = "0.8.8";
|
||||
src = fetchurl {
|
||||
url = "https://elpa.nongnu.org/nongnu/sweeprolog-0.8.6.tar";
|
||||
sha256 = "108hjh276xgl0xhn2f7h43725xi49zh6j2xrcc17xw2i0phhhswf";
|
||||
url = "https://elpa.nongnu.org/nongnu/sweeprolog-0.8.8.tar";
|
||||
sha256 = "0h9vn4kc1f1vxvzxv14hbv24skjmishg408s4d8g39bylhj5c5s4";
|
||||
};
|
||||
packageRequires = [ emacs ];
|
||||
meta = {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -17,7 +17,6 @@
|
||||
, curl
|
||||
, fmt_8
|
||||
, nlohmann_json
|
||||
, xlibsWrapper
|
||||
, yara
|
||||
}:
|
||||
|
||||
@@ -45,7 +44,7 @@ gcc12Stdenv.mkDerivation rec {
|
||||
hash = "sha256-SFv5ulyjm5Yf+3Gpx+A74so2YClCJx1sx0LE5fh5eG4=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ cmake llvm python3 perl pkg-config xlibsWrapper ];
|
||||
nativeBuildInputs = [ cmake llvm python3 perl pkg-config ];
|
||||
|
||||
buildInputs = [
|
||||
capstone
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
|
||||
mkDerivation rec {
|
||||
pname = "leo-editor";
|
||||
version = "6.6.4";
|
||||
version = "6.7.1";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "leo-editor";
|
||||
repo = "leo-editor";
|
||||
rev = version;
|
||||
sha256 = "sha256-NwqvlDG37OpWaLJHb6NqkRYvWwDzICKqfgIJRTBDnkI=";
|
||||
sha256 = "sha256-4sD/gN9cbgZ9Z5Xiyx2velX5q6J6vOQAeRor10Zamyw=";
|
||||
};
|
||||
|
||||
dontBuild = true;
|
||||
|
||||
@@ -16,11 +16,11 @@ let
|
||||
|
||||
in stdenv.mkDerivation rec {
|
||||
pname = "nano";
|
||||
version = "6.4";
|
||||
version = "7.0";
|
||||
|
||||
src = fetchurl {
|
||||
url = "mirror://gnu/nano/${pname}-${version}.tar.xz";
|
||||
sha256 = "QZmujKeKd5beVt4aQbgh3EeRLAMH6YFrVswxffNGYcA=";
|
||||
sha256 = "jdbqw4srh4bYJoHw4a/YT2t1IQ0XORtkQ8Q35FFVIUk=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ texinfo ] ++ optional enableNls gettext;
|
||||
|
||||
@@ -26,13 +26,13 @@ let
|
||||
in
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "neovim-unwrapped";
|
||||
version = "0.8.0";
|
||||
version = "0.8.1";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "neovim";
|
||||
repo = "neovim";
|
||||
rev = "v${version}";
|
||||
sha256 = "sha256-mVeVjkP8JpTi2aW59ZuzQPi5YvEySVAtxko7xxAx/es=";
|
||||
sha256 = "sha256-B2ZpwhdmdvPOnxVyJDfNzUT5rTVuBhJXyMwwzCl9Fac=";
|
||||
};
|
||||
|
||||
patches = [
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user