Merge commit e9f00bd893 into haskell-updates
This commit is contained in:
@@ -661,6 +661,12 @@ If you have any problems with formatting, please ping the [formatting team](http
|
||||
As an exception, an explicit conditional expression with null can be used when fixing a important bug without triggering a mass rebuild.
|
||||
If this is done a follow up pull request _should_ be created to change the code to `lib.optional(s)`.
|
||||
|
||||
- Any style choices not covered here but that can be expressed as general rules should be left at the discretion of the authors of changes and _not_ commented in reviews.
|
||||
The purpose of this is:
|
||||
- to avoid churn as contributors with different style preferences undo each other's changes,
|
||||
- to ensure that style rules are written down and consistent (and can thus be followed when authoring changes, reducing review cycles),
|
||||
- and to encourage reviews to focus on more impactful considerations.
|
||||
|
||||
# Practical contributing advice
|
||||
|
||||
To contribute effectively and efficiently, you need to be aware of how the process generally works.
|
||||
|
||||
+6
-6
@@ -9,9 +9,9 @@
|
||||
},
|
||||
"branch": "nixpkgs-unstable",
|
||||
"submodules": false,
|
||||
"revision": "a1f79a1770d05af18111fbbe2a3ab2c42c0f6cd0",
|
||||
"url": "https://github.com/NixOS/nixpkgs/archive/a1f79a1770d05af18111fbbe2a3ab2c42c0f6cd0.tar.gz",
|
||||
"hash": "06lqp08pfgnsn8kb4kdpjmmjyhj4bgniv7yf9bjczg4kn25l1dz6"
|
||||
"revision": "e57b3b16ad8758fd681511a078f35c416a8cc939",
|
||||
"url": "https://github.com/NixOS/nixpkgs/archive/e57b3b16ad8758fd681511a078f35c416a8cc939.tar.gz",
|
||||
"hash": "04zp6jjd4xr6jfps84p8yh5ym5962mii4825fn75lqk14sz4rq56"
|
||||
},
|
||||
"treefmt-nix": {
|
||||
"type": "Git",
|
||||
@@ -22,9 +22,9 @@
|
||||
},
|
||||
"branch": "main",
|
||||
"submodules": false,
|
||||
"revision": "128222dc911b8e2e18939537bed1762b7f3a04aa",
|
||||
"url": "https://github.com/numtide/treefmt-nix/archive/128222dc911b8e2e18939537bed1762b7f3a04aa.tar.gz",
|
||||
"hash": "1p81chik0sb8aligng579m4h0klnndxv76z0p4gyhr4g3s9cydpw"
|
||||
"revision": "5eda4ee8121f97b218f7cc73f5172098d458f1d1",
|
||||
"url": "https://github.com/numtide/treefmt-nix/archive/5eda4ee8121f97b218f7cc73f5172098d458f1d1.tar.gz",
|
||||
"hash": "1vqns9hjhmbnhdq2xvcmdxng11jrmcn9lpk2ncfh1f969z9lj8y9"
|
||||
}
|
||||
},
|
||||
"version": 5
|
||||
|
||||
@@ -75,7 +75,7 @@ Here is a simple package example.
|
||||
ppx_let,
|
||||
}:
|
||||
|
||||
buildDunePackage rec {
|
||||
buildDunePackage (finalAttrs: {
|
||||
pname = "angstrom";
|
||||
version = "0.15.0";
|
||||
|
||||
@@ -84,20 +84,22 @@ buildDunePackage rec {
|
||||
src = fetchFromGitHub {
|
||||
owner = "inhabitedtype";
|
||||
repo = "angstrom";
|
||||
tag = version;
|
||||
tag = finalAttrs.version;
|
||||
hash = "sha256-MK8o+iPGANEhrrTc1Kz9LBilx2bDPQt7Pp5P2libucI=";
|
||||
};
|
||||
|
||||
checkInputs = [
|
||||
alcotest
|
||||
ppx_let
|
||||
];
|
||||
buildInputs = [ ocaml-syntax-shims ];
|
||||
|
||||
propagatedBuildInputs = [
|
||||
bigstringaf
|
||||
result
|
||||
];
|
||||
|
||||
doCheck = lib.versionAtLeast ocaml.version "4.05";
|
||||
checkInputs = [
|
||||
alcotest
|
||||
ppx_let
|
||||
];
|
||||
|
||||
meta = {
|
||||
homepage = "https://github.com/inhabitedtype/angstrom";
|
||||
@@ -105,7 +107,7 @@ buildDunePackage rec {
|
||||
license = lib.licenses.bsd3;
|
||||
maintainers = with lib.maintainers; [ sternenseemann ];
|
||||
};
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
Here is a second example, this time using a source archive generated with `dune-release`. It is a good idea to use this archive when it is available as it will usually contain substituted variables such as a `%%VERSION%%` field. This library does not depend on any other OCaml library and no tests are run after building it.
|
||||
@@ -117,14 +119,14 @@ Here is a second example, this time using a source archive generated with `dune-
|
||||
buildDunePackage,
|
||||
}:
|
||||
|
||||
buildDunePackage rec {
|
||||
buildDunePackage (finalAtts: {
|
||||
pname = "wtf8";
|
||||
version = "1.0.2";
|
||||
|
||||
minimalOCamlVersion = "4.02";
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://github.com/flowtype/ocaml-wtf8/releases/download/v${version}/wtf8-v${version}.tbz";
|
||||
url = "https://github.com/flowtype/ocaml-wtf8/releases/download/v${finalAtts.version}/wtf8-v${finalAtts.version}.tbz";
|
||||
hash = "sha256-d5/3KUBAWRj8tntr4RkJ74KWW7wvn/B/m1nx0npnzyc=";
|
||||
};
|
||||
|
||||
@@ -134,7 +136,7 @@ buildDunePackage rec {
|
||||
license = lib.licenses.mit;
|
||||
maintainers = [ lib.maintainers.eqyiel ];
|
||||
};
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
The build will automatically fail if two distinct versions of the same library
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
- The official Nix formatter `nixfmt` is now stable and available as `pkgs.nixfmt`, deprecating the temporary `pkgs.nixfmt-rfc-style` attribute. The classic `nixfmt` will stay available for some more time as `pkgs.nixfmt-classic`.
|
||||
- The default GHC version has been updated from 9.8 to 9.10.
|
||||
`haskellPackages` correspondingly uses Stackage LTS 24 (instead of LTS 23) as a baseline.
|
||||
- Added `nixos-init`, a Rust-based bashless initialization system for systemd initrd. This allows to build NixOS systems without any interpreter. Enable via `system.nixos-init.enable = true;`.
|
||||
|
||||
## Backward Incompatibilities {#sec-nixpkgs-release-25.11-incompatibilities}
|
||||
|
||||
@@ -64,16 +65,22 @@
|
||||
|
||||
- Derivations setting both `separateDebugInfo` and one of `allowedReferences`, `allowedRequisites`, `disallowedReferences` or `disallowedRequisites` must now set `__structuredAttrs` to `true`. The effect of reference whitelisting or blacklisting will be disabled on the `debug` output created by `separateDebugInfo`.
|
||||
|
||||
- `k2pdfopt` has been removed, as it's broken.
|
||||
|
||||
- `victoriametrics` no longer contains VictoriaLogs components. These have been separated into the new package `victorialogs`.
|
||||
|
||||
- `mx-puppet-discord` was removed from Nixpkgs along with its NixOS module as it was unmaintained and was the only user of sha1 hashes in tree.
|
||||
|
||||
- `gradience` has been removed because it was archived upstream.
|
||||
|
||||
- `kbd` package's `outputs` now include a `man` and `scripts` outputs. The `unicode_start` and `unicode_stop` Bash scripts are now part of the `scripts` output, allowing most usages of the `kbd` package to not pull in `bash`.
|
||||
|
||||
- `spidermonkey_91` has been removed, as it has been EOL since September 2022.
|
||||
|
||||
- `hiawata` has been removed, due to lack of active development upstream, lack of maintainership downstream and upcoming security issues.
|
||||
|
||||
- `forgejo` main program has been renamed to `bin/forgejo` from the previous `bin/gitea`.
|
||||
|
||||
- `cudaPackages.cudatoolkit-legacy-runfile` has been removed.
|
||||
|
||||
- `conduwuit` was removed due to upstream ceasing development and deleting their repository. For existing data, a migration to `matrix-conduit`, `matrix-continuwuity` or `matrix-tuwunel` may be possible.
|
||||
@@ -94,6 +101,8 @@
|
||||
|
||||
- `purple-matrix` has been removed, since it has been unmaintained since April 2022 and upstream does not recommend using it anymore.
|
||||
|
||||
- `sublime-music` has been removed because upstream has announced it is no longer maintained. Upstream suggests using `supersonic` instead.
|
||||
|
||||
- The default Android NDK version has been raised to 27, and the default SDK version to 35.
|
||||
NDK 21–26 have been removed, as they are end‐of‐life.
|
||||
|
||||
@@ -152,6 +161,8 @@
|
||||
|
||||
- `telegram-desktop` packages now uses `Telegram` for its binary. The previous name was `telegram-desktop`. This is due to [an upstream decision](https://github.com/telegramdesktop/tdesktop/commit/56ff5808a3d766f892bc3c3305afb106b629ef6f) to make the name consistent with other platforms.
|
||||
|
||||
- `hsd` has been upgraded to version 8. See [their changelog](https://github.com/handshake-org/hsd/blob/v8.0.0/docs/release-notes/release-notes-8.x.md) for important instructions before upgrading.
|
||||
|
||||
- `podofo` has been updated from `0.9.8` to `1.0.0`. These releases are by nature very incompatible due to major API changes. The legacy versions can be found under `podofo_0_10` and `podofo_0_9`.
|
||||
Changelog: https://github.com/podofo/podofo/blob/1.0.0/CHANGELOG.md, API-Migration-Guide: https://github.com/podofo/podofo/blob/1.0.0/API-MIGRATION.md.
|
||||
|
||||
@@ -275,3 +286,5 @@
|
||||
- `neovim`: Added support for the `vim.o.exrc` option, the `VIMINIT` environment variable, and sourcing of `sysinit.vim`.
|
||||
|
||||
See the neovim help page [`:help startup`](https://neovim.io/doc/user/starting.html#startup) for more information, as well as [the nixpkgs neovim wrapper documentation](#neovim-custom-configuration).
|
||||
|
||||
- `cloudflare-ddns`: Added package cloudflare-ddns.
|
||||
|
||||
+8
-8
@@ -1131,7 +1131,7 @@ let
|
||||
defsFinal' =
|
||||
let
|
||||
# Process mkMerge and mkIf properties.
|
||||
defs' = concatMap (
|
||||
defsNormalized = concatMap (
|
||||
m:
|
||||
map (
|
||||
value:
|
||||
@@ -1146,19 +1146,19 @@ let
|
||||
) defs;
|
||||
|
||||
# Process mkOverride properties.
|
||||
defs'' = filterOverrides' defs';
|
||||
defsFiltered = filterOverrides' defsNormalized;
|
||||
|
||||
# Sort mkOrder properties.
|
||||
defs''' =
|
||||
defsSorted =
|
||||
# Avoid sorting if we don't have to.
|
||||
if any (def: def.value._type or "" == "order") defs''.values then
|
||||
sortProperties defs''.values
|
||||
if any (def: def.value._type or "" == "order") defsFiltered.values then
|
||||
sortProperties defsFiltered.values
|
||||
else
|
||||
defs''.values;
|
||||
defsFiltered.values;
|
||||
in
|
||||
{
|
||||
values = defs''';
|
||||
inherit (defs'') highestPrio;
|
||||
values = defsSorted;
|
||||
inherit (defsFiltered) highestPrio;
|
||||
};
|
||||
defsFinal = defsFinal'.values;
|
||||
|
||||
|
||||
@@ -210,6 +210,9 @@ checkConfigError 'A definition for option .intStrings\.badTagTypeError\.left. is
|
||||
checkConfigError 'A definition for option .nested\.right\.left. is not of type .signed integer.' config.nested.right.left ./types-attrTag.nix
|
||||
checkConfigError 'In attrTag, each tag value must be an option, but tag int was a bare type, not wrapped in mkOption.' config.opt.int ./types-attrTag-wrong-decl.nix
|
||||
|
||||
# types
|
||||
checkConfigOutput '"ok"' config.assertions ./types.nix
|
||||
|
||||
# types.pathInStore
|
||||
checkConfigOutput '".*/store/0lz9p8xhf89kb1c1kk6jxrzskaiygnlh-bash-5.2-p15.drv"' config.pathInStore.ok1 ./types.nix
|
||||
checkConfigOutput '".*/store/0fb3ykw9r5hpayd05sr0cizwadzq1d8q-bash-5.2-p15"' config.pathInStore.ok2 ./types.nix
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# Run with:
|
||||
# cd nixpkgs
|
||||
# ./lib/tests/modules.sh
|
||||
{ lib, ... }:
|
||||
let
|
||||
inherit (builtins)
|
||||
@@ -7,10 +10,12 @@ let
|
||||
types
|
||||
mkOption
|
||||
;
|
||||
|
||||
in
|
||||
{
|
||||
options = {
|
||||
pathInStore = mkOption { type = types.lazyAttrsOf types.pathInStore; };
|
||||
assertions = mkOption { };
|
||||
};
|
||||
config = {
|
||||
pathInStore.ok1 = "${storeDir}/0lz9p8xhf89kb1c1kk6jxrzskaiygnlh-bash-5.2-p15.drv";
|
||||
@@ -21,5 +26,459 @@ in
|
||||
pathInStore.bad3 = "${storeDir}/";
|
||||
pathInStore.bad4 = "${storeDir}/.links"; # technically true, but not reasonable
|
||||
pathInStore.bad5 = "/foo/bar";
|
||||
|
||||
assertions =
|
||||
with lib.types;
|
||||
|
||||
assert str.description == "string";
|
||||
assert int.description == "signed integer";
|
||||
assert (attrsOf str).description == "attribute set of string";
|
||||
assert (attrsOf (attrsOf str)).description == "attribute set of attribute set of string";
|
||||
assert
|
||||
(oneOf [
|
||||
(attrsOf str)
|
||||
int
|
||||
bool
|
||||
]).description == "(attribute set of string) or signed integer or boolean";
|
||||
assert
|
||||
(enum [
|
||||
true
|
||||
null
|
||||
false
|
||||
]).description == "one of true, <null>, false";
|
||||
assert
|
||||
(submodule { freeformType = attrsOf str; }).description
|
||||
== "open submodule of attribute set of string";
|
||||
# Comprehensive type constructor description tests
|
||||
assert (attrsOf int).description == "attribute set of signed integer";
|
||||
assert (attrsOf bool).description == "attribute set of boolean";
|
||||
assert (attrsOf (either int str)).description == "attribute set of (signed integer or string)";
|
||||
assert (attrsOf (nullOr str)).description == "attribute set of (null or string)";
|
||||
assert (attrsOf (listOf str)).description == "attribute set of list of string";
|
||||
assert (attrsOf (attrsOf int)).description == "attribute set of attribute set of signed integer";
|
||||
assert (attrsOf ints.positive).description == "attribute set of (positive integer, meaning >0)";
|
||||
|
||||
# Test type constructors as attrsOf item types
|
||||
assert
|
||||
(attrsOf (enum [
|
||||
"a"
|
||||
"b"
|
||||
])).description == "attribute set of (one of \"a\", \"b\")";
|
||||
assert
|
||||
(attrsOf (strMatching "[0-9]+")).description
|
||||
== "attribute set of string matching the pattern [0-9]+";
|
||||
assert (attrsOf (nonEmptyListOf str)).description == "attribute set of non-empty (list of string)"; # TODO: reduce parentheses?
|
||||
assert
|
||||
(attrsOf (oneOf [
|
||||
str
|
||||
int
|
||||
])).description == "attribute set of (string or signed integer)";
|
||||
assert
|
||||
(attrsOf (coercedTo str abort int)).description
|
||||
== "attribute set of (signed integer or string convertible to it)";
|
||||
assert
|
||||
(attrsOf (functionTo str)).description == "attribute set of function that evaluates to a(n) string";
|
||||
assert
|
||||
(attrsOf (passwdEntry str)).description
|
||||
== "attribute set of (string, not containing newlines or colons)";
|
||||
assert (attrsOf (uniq str)).description == "attribute set of string";
|
||||
assert (attrsOf (unique { message = "test"; } str)).description == "attribute set of string";
|
||||
assert
|
||||
(attrsOf (pathWith {
|
||||
absolute = true;
|
||||
})).description == "attribute set of absolute path";
|
||||
assert
|
||||
(attrsOf (separatedString ",")).description == "attribute set of strings concatenated with \",\"";
|
||||
assert (attrsOf (loaOf str)).description == "attribute set of attribute set of string";
|
||||
assert (attrsOf (lazyAttrsOf str)).description == "attribute set of lazy attribute set of string";
|
||||
assert (attrsOf (submodule { })).description == "attribute set of (submodule)"; # FIXME: extra parentheses around submodule
|
||||
assert
|
||||
(attrsOf (submodule {
|
||||
freeformType = attrsOf str;
|
||||
})).description == "attribute set of (open submodule of attribute set of string)";
|
||||
assert (attrsOf (addCheck str (x: true))).description == "attribute set of string";
|
||||
assert (attrsOf (enum [ ])).description == "attribute set of impossible (empty enum)";
|
||||
assert
|
||||
(attrsOf ints.u32).description
|
||||
== "attribute set of 32 bit unsigned integer; between 0 and 4294967295 (both inclusive)";
|
||||
assert
|
||||
(attrsOf numbers.positive).description
|
||||
== "attribute set of (positive integer or floating point number, meaning >0)";
|
||||
|
||||
assert (attrsWith { elemType = str; }).description == "attribute set of string";
|
||||
assert (attrsWith { elemType = int; }).description == "attribute set of signed integer";
|
||||
assert (attrsWith { elemType = bool; }).description == "attribute set of boolean";
|
||||
assert
|
||||
(attrsWith { elemType = either int str; }).description
|
||||
== "attribute set of (signed integer or string)";
|
||||
assert (attrsWith { elemType = nullOr str; }).description == "attribute set of (null or string)";
|
||||
assert (attrsWith { elemType = listOf str; }).description == "attribute set of list of string";
|
||||
assert
|
||||
(attrsWith { elemType = attrsOf int; }).description
|
||||
== "attribute set of attribute set of signed integer";
|
||||
assert
|
||||
(attrsWith { elemType = ints.positive; }).description
|
||||
== "attribute set of (positive integer, meaning >0)";
|
||||
assert
|
||||
(attrsWith {
|
||||
elemType = str;
|
||||
lazy = true;
|
||||
}).description == "lazy attribute set of string";
|
||||
# Additional attrsWith tests are covered above
|
||||
assert
|
||||
(attrsWith {
|
||||
elemType = str;
|
||||
lazy = false;
|
||||
}).description == "attribute set of string";
|
||||
assert (coercedTo str abort int).description == "signed integer or string convertible to it";
|
||||
assert (coercedTo int abort str).description == "string or signed integer convertible to it";
|
||||
assert (coercedTo bool abort str).description == "string or boolean convertible to it";
|
||||
assert
|
||||
(coercedTo (either int str) abort str).description
|
||||
== "string or (signed integer or string) convertible to it";
|
||||
assert
|
||||
(coercedTo (nullOr str) abort str).description == "string or (null or string) convertible to it";
|
||||
assert
|
||||
(coercedTo (listOf str) abort str).description == "string or (list of string) convertible to it";
|
||||
assert
|
||||
(coercedTo (attrsOf int) abort str).description
|
||||
== "string or (attribute set of signed integer) convertible to it";
|
||||
assert
|
||||
(coercedTo ints.positive abort str).description
|
||||
== "string or (positive integer, meaning >0) convertible to it";
|
||||
assert
|
||||
(coercedTo (listOf str) abort (attrsOf str)).description
|
||||
== "(attribute set of string) or (list of string) convertible to it";
|
||||
# Additional coercedTo tests covered above
|
||||
assert (either str int).description == "string or signed integer";
|
||||
assert (either int str).description == "signed integer or string";
|
||||
assert (either bool str).description == "boolean or string";
|
||||
assert (either (either int str) bool).description == "signed integer or string or boolean";
|
||||
assert (either (nullOr str) int).description == "null or string or signed integer";
|
||||
assert (either (listOf str) int).description == "(list of string) or signed integer";
|
||||
assert (either (attrsOf int) str).description == "(attribute set of signed integer) or string";
|
||||
assert (either ints.positive str).description == "positive integer, meaning >0, or string";
|
||||
assert (either (either bool str) int).description == "boolean or string or signed integer";
|
||||
|
||||
# Test type constructors as either bool t
|
||||
assert (either bool str).description == "boolean or string";
|
||||
assert (either bool int).description == "boolean or signed integer";
|
||||
assert
|
||||
(either bool (enum [
|
||||
"a"
|
||||
"b"
|
||||
])).description == "boolean or one of \"a\", \"b\"";
|
||||
assert
|
||||
(either bool (strMatching "[0-9]+")).description == "boolean or string matching the pattern [0-9]+";
|
||||
assert (either bool (nonEmptyListOf str)).description == "boolean or non-empty (list of string)"; # TODO: reduce parentheses?
|
||||
assert
|
||||
(either bool (oneOf [
|
||||
str
|
||||
int
|
||||
])).description == "boolean or string or signed integer";
|
||||
assert
|
||||
(either bool (coercedTo str abort int)).description
|
||||
== "boolean or (signed integer or string convertible to it)";
|
||||
assert
|
||||
(either bool (functionTo str)).description == "boolean or function that evaluates to a(n) string";
|
||||
assert
|
||||
(either bool (passwdEntry str)).description
|
||||
== "boolean or (string, not containing newlines or colons)";
|
||||
assert (either bool (uniq str)).description == "boolean or string";
|
||||
assert (either bool (unique { message = "test"; } str)).description == "boolean or string";
|
||||
assert
|
||||
(either bool (pathWith {
|
||||
absolute = true;
|
||||
})).description == "boolean or absolute path";
|
||||
assert
|
||||
(either bool (separatedString ",")).description == "boolean or strings concatenated with \",\"";
|
||||
assert (either bool (attrsOf str)).description == "boolean or attribute set of string";
|
||||
assert (either bool (listOf str)).description == "boolean or list of string";
|
||||
assert (either bool (nullOr str)).description == "boolean or null or string";
|
||||
assert (either bool (lazyAttrsOf str)).description == "boolean or lazy attribute set of string";
|
||||
assert (either bool (submodule { })).description == "boolean or (submodule)"; # FIXME: extra parentheses around submodule
|
||||
assert (either bool ints.positive).description == "boolean or (positive integer, meaning >0)";
|
||||
assert
|
||||
(either bool numbers.positive).description
|
||||
== "boolean or (positive integer or floating point number, meaning >0)";
|
||||
|
||||
# Test type constructors as either t bool
|
||||
assert (either str bool).description == "string or boolean";
|
||||
assert (either int bool).description == "signed integer or boolean";
|
||||
assert
|
||||
(either (enum [
|
||||
"a"
|
||||
"b"
|
||||
]) bool).description == "one of \"a\", \"b\" or boolean";
|
||||
assert
|
||||
(either (strMatching "[0-9]+") bool).description == "string matching the pattern [0-9]+ or boolean";
|
||||
assert (either (nonEmptyListOf str) bool).description == "(non-empty (list of string)) or boolean"; # TODO: reduce parentheses?
|
||||
assert
|
||||
(either (oneOf [
|
||||
str
|
||||
int
|
||||
]) bool).description == "string or signed integer or boolean";
|
||||
assert
|
||||
(either (coercedTo str abort int) bool).description
|
||||
== "(signed integer or string convertible to it) or boolean";
|
||||
assert
|
||||
(either (functionTo str) bool).description == "(function that evaluates to a(n) string) or boolean";
|
||||
assert
|
||||
(either (passwdEntry str) bool).description
|
||||
== "string, not containing newlines or colons, or boolean";
|
||||
assert (either (uniq str) bool).description == "string or boolean";
|
||||
assert (either (unique { message = "test"; } str) bool).description == "string or boolean";
|
||||
assert (either (pathWith { absolute = true; }) bool).description == "absolute path or boolean";
|
||||
assert
|
||||
(either (separatedString ",") bool).description == "strings concatenated with \",\" or boolean";
|
||||
assert (either (attrsOf str) bool).description == "(attribute set of string) or boolean";
|
||||
assert (either (listOf str) bool).description == "(list of string) or boolean";
|
||||
assert (either (nullOr str) bool).description == "null or string or boolean";
|
||||
assert (either (lazyAttrsOf str) bool).description == "(lazy attribute set of string) or boolean";
|
||||
assert (either (submodule { }) bool).description == "(submodule) or boolean"; # FIXME: extra parentheses around submodule
|
||||
assert (either ints.positive bool).description == "positive integer, meaning >0, or boolean";
|
||||
assert
|
||||
(either numbers.positive bool).description
|
||||
== "positive integer or floating point number, meaning >0, or boolean";
|
||||
|
||||
# Additional either tests covered above";
|
||||
assert (enum [ ]).description == "impossible (empty enum)";
|
||||
assert (enum [ "single" ]).description == "value \"single\" (singular enum)";
|
||||
assert
|
||||
(enum [
|
||||
"a"
|
||||
"b"
|
||||
]).description == "one of \"a\", \"b\"";
|
||||
assert
|
||||
(enum [
|
||||
true
|
||||
false
|
||||
]).description == "one of true, false";
|
||||
assert
|
||||
(enum [
|
||||
1
|
||||
2
|
||||
3
|
||||
]).description == "one of 1, 2, 3";
|
||||
assert (enum [ null ]).description == "value <null> (singular enum)";
|
||||
assert (functionTo str).description == "function that evaluates to a(n) string";
|
||||
assert (functionTo int).description == "function that evaluates to a(n) signed integer";
|
||||
assert (functionTo bool).description == "function that evaluates to a(n) boolean";
|
||||
assert
|
||||
(functionTo (either int str)).description
|
||||
== "function that evaluates to a(n) (signed integer or string)";
|
||||
assert (functionTo (nullOr str)).description == "function that evaluates to a(n) (null or string)";
|
||||
assert (functionTo (listOf str)).description == "function that evaluates to a(n) list of string";
|
||||
assert
|
||||
(functionTo (attrsOf int)).description
|
||||
== "function that evaluates to a(n) attribute set of signed integer";
|
||||
assert
|
||||
(functionTo ints.positive).description
|
||||
== "function that evaluates to a(n) (positive integer, meaning >0)";
|
||||
assert (lazyAttrsOf str).description == "lazy attribute set of string";
|
||||
assert (lazyAttrsOf int).description == "lazy attribute set of signed integer";
|
||||
assert (lazyAttrsOf bool).description == "lazy attribute set of boolean";
|
||||
assert
|
||||
(lazyAttrsOf (either int str)).description == "lazy attribute set of (signed integer or string)";
|
||||
assert (lazyAttrsOf (nullOr str)).description == "lazy attribute set of (null or string)";
|
||||
assert (lazyAttrsOf (listOf str)).description == "lazy attribute set of list of string";
|
||||
assert
|
||||
(lazyAttrsOf (attrsOf int)).description == "lazy attribute set of attribute set of signed integer";
|
||||
assert
|
||||
(lazyAttrsOf ints.positive).description == "lazy attribute set of (positive integer, meaning >0)";
|
||||
assert (listOf str).description == "list of string";
|
||||
assert (listOf int).description == "list of signed integer";
|
||||
assert (listOf bool).description == "list of boolean";
|
||||
assert (listOf (either int str)).description == "list of (signed integer or string)";
|
||||
assert (listOf (nullOr str)).description == "list of (null or string)";
|
||||
assert (listOf (listOf str)).description == "list of list of string";
|
||||
assert (listOf (attrsOf int)).description == "list of attribute set of signed integer";
|
||||
assert (listOf ints.positive).description == "list of (positive integer, meaning >0)";
|
||||
assert (loaOf str).description == "attribute set of string";
|
||||
assert (loaOf int).description == "attribute set of signed integer";
|
||||
assert (loaOf bool).description == "attribute set of boolean";
|
||||
assert (loaOf (either int str)).description == "attribute set of (signed integer or string)";
|
||||
assert (loaOf (nullOr str)).description == "attribute set of (null or string)";
|
||||
assert (loaOf (listOf str)).description == "attribute set of list of string";
|
||||
assert (loaOf (attrsOf int)).description == "attribute set of attribute set of signed integer";
|
||||
assert (loaOf ints.positive).description == "attribute set of (positive integer, meaning >0)";
|
||||
assert (nonEmptyListOf str).description == "non-empty (list of string)"; # TODO: reduce parentheses?
|
||||
assert (nonEmptyListOf int).description == "non-empty (list of signed integer)"; # TODO: reduce parentheses?
|
||||
assert (nonEmptyListOf bool).description == "non-empty (list of boolean)"; # TODO: reduce parentheses?
|
||||
assert
|
||||
(nonEmptyListOf (either int str)).description == "non-empty (list of (signed integer or string))"; # TODO: reduce parentheses?
|
||||
assert (nonEmptyListOf (nullOr str)).description == "non-empty (list of (null or string))"; # TODO: reduce parentheses?
|
||||
assert (nonEmptyListOf (listOf str)).description == "non-empty (list of list of string)"; # TODO: reduce parentheses?
|
||||
assert
|
||||
(nonEmptyListOf (attrsOf int)).description
|
||||
== "non-empty (list of attribute set of signed integer)"; # TODO: reduce parentheses?
|
||||
assert
|
||||
(nonEmptyListOf ints.positive).description == "non-empty (list of (positive integer, meaning >0))"; # TODO: reduce parentheses?
|
||||
assert (nullOr str).description == "null or string";
|
||||
assert (nullOr int).description == "null or signed integer";
|
||||
assert (nullOr bool).description == "null or boolean";
|
||||
assert (nullOr (either int str)).description == "null or signed integer or string";
|
||||
assert (nullOr (nullOr str)).description == "null or null or string";
|
||||
assert (nullOr (listOf str)).description == "null or (list of string)";
|
||||
assert (nullOr (attrsOf int)).description == "null or (attribute set of signed integer)";
|
||||
assert (nullOr ints.positive).description == "null or (positive integer, meaning >0)";
|
||||
assert (oneOf [ str ]).description == "string";
|
||||
assert (oneOf [ int ]).description == "signed integer";
|
||||
assert (oneOf [ bool ]).description == "boolean";
|
||||
assert (oneOf [ (either int str) ]).description == "signed integer or string";
|
||||
assert (oneOf [ (nullOr str) ]).description == "null or string";
|
||||
assert (oneOf [ (listOf str) ]).description == "list of string";
|
||||
assert (oneOf [ (attrsOf int) ]).description == "attribute set of signed integer";
|
||||
assert (oneOf [ ints.positive ]).description == "positive integer, meaning >0";
|
||||
assert
|
||||
(oneOf [
|
||||
str
|
||||
int
|
||||
]).description == "string or signed integer";
|
||||
assert
|
||||
(oneOf [
|
||||
str
|
||||
int
|
||||
bool
|
||||
]).description == "string or signed integer or boolean";
|
||||
assert
|
||||
(oneOf [
|
||||
(listOf str)
|
||||
int
|
||||
bool
|
||||
]).description == "(list of string) or signed integer or boolean";
|
||||
assert
|
||||
(oneOf [
|
||||
ints.positive
|
||||
str
|
||||
]).description == "positive integer, meaning >0, or string";
|
||||
assert (passwdEntry str).description == "string, not containing newlines or colons";
|
||||
assert (passwdEntry int).description == "signed integer, not containing newlines or colons";
|
||||
assert (passwdEntry bool).description == "boolean, not containing newlines or colons";
|
||||
assert
|
||||
(passwdEntry (either int str)).description
|
||||
== "(signed integer or string), not containing newlines or colons";
|
||||
assert
|
||||
(passwdEntry (nullOr str)).description == "(null or string), not containing newlines or colons";
|
||||
assert
|
||||
(passwdEntry (listOf str)).description == "(list of string), not containing newlines or colons";
|
||||
assert
|
||||
(passwdEntry (attrsOf int)).description
|
||||
== "(attribute set of signed integer), not containing newlines or colons";
|
||||
assert
|
||||
(passwdEntry ints.positive).description
|
||||
== "(positive integer, meaning >0), not containing newlines or colons";
|
||||
assert (pathWith { }).description == "path";
|
||||
assert (pathWith { absolute = true; }).description == "absolute path";
|
||||
assert (pathWith { inStore = true; }).description == "path in the Nix store";
|
||||
assert
|
||||
(pathWith {
|
||||
absolute = true;
|
||||
inStore = true;
|
||||
}).description == "absolute path in the Nix store";
|
||||
assert (pathWith { absolute = false; }).description == "relative path";
|
||||
assert (pathWith { absolute = null; }).description == "path";
|
||||
assert (pathWith { inStore = false; }).description == "path not in the Nix store";
|
||||
assert (pathWith { inStore = null; }).description == "path";
|
||||
assert (separatedString "").description == "Concatenated string";
|
||||
assert (separatedString ",").description == "strings concatenated with \",\"";
|
||||
assert (separatedString "\n").description == ''strings concatenated with "\n"'';
|
||||
assert (separatedString ":").description == "strings concatenated with \":\"";
|
||||
assert (strMatching "[a-z]+").description == "string matching the pattern [a-z]+";
|
||||
assert
|
||||
(strMatching "[0-9]{3}-[0-9]{2}-[0-9]{4}").description
|
||||
== "string matching the pattern [0-9]{3}-[0-9]{2}-[0-9]{4}";
|
||||
assert (strMatching ".*\\.txt").description == "string matching the pattern .*\\.txt";
|
||||
assert
|
||||
(submodule { freeformType = attrsOf int; }).description
|
||||
== "open submodule of attribute set of signed integer";
|
||||
assert
|
||||
(submodule { freeformType = attrsOf bool; }).description
|
||||
== "open submodule of attribute set of boolean";
|
||||
assert
|
||||
(submodule { freeformType = attrsOf (either int str); }).description
|
||||
== "open submodule of attribute set of (signed integer or string)";
|
||||
assert
|
||||
(submodule { freeformType = attrsOf (nullOr str); }).description
|
||||
== "open submodule of attribute set of (null or string)";
|
||||
assert (submodule { freeformType = listOf str; }).description == "open submodule of list of string";
|
||||
assert
|
||||
(submodule { freeformType = attrsOf ints.positive; }).description
|
||||
== "open submodule of attribute set of (positive integer, meaning >0)";
|
||||
assert
|
||||
(submodule { freeformType = lazyAttrsOf str; }).description
|
||||
== "open submodule of lazy attribute set of string";
|
||||
assert
|
||||
(submodule { freeformType = lazyAttrsOf int; }).description
|
||||
== "open submodule of lazy attribute set of signed integer";
|
||||
assert
|
||||
(submodule { freeformType = lazyAttrsOf (listOf str); }).description
|
||||
== "open submodule of lazy attribute set of list of string";
|
||||
assert (submodule { }).description == "submodule";
|
||||
assert (submodule [ { options.foo = mkOption { type = str; }; } ]).description == "submodule";
|
||||
assert (submodule [ ]).description == "submodule";
|
||||
assert
|
||||
(submodule [ { freeformType = attrsOf str; } ]).description
|
||||
== "open submodule of attribute set of string";
|
||||
assert
|
||||
(submodule [ { freeformType = lazyAttrsOf str; } ]).description
|
||||
== "open submodule of lazy attribute set of string";
|
||||
assert
|
||||
(submodule [ { freeformType = lazyAttrsOf int; } ]).description
|
||||
== "open submodule of lazy attribute set of signed integer";
|
||||
assert
|
||||
(submodule [ { freeformType = lazyAttrsOf (either int str); } ]).description
|
||||
== "open submodule of lazy attribute set of (signed integer or string)";
|
||||
assert
|
||||
(submoduleWith { modules = [ { freeformType = attrsOf str; } ]; }).description
|
||||
== "open submodule of attribute set of string";
|
||||
assert
|
||||
(submoduleWith { modules = [ { freeformType = attrsOf int; } ]; }).description
|
||||
== "open submodule of attribute set of signed integer";
|
||||
assert
|
||||
(submoduleWith { modules = [ { freeformType = attrsOf bool; } ]; }).description
|
||||
== "open submodule of attribute set of boolean";
|
||||
assert
|
||||
(submoduleWith { modules = [ { freeformType = attrsOf (either int str); } ]; }).description
|
||||
== "open submodule of attribute set of (signed integer or string)";
|
||||
assert
|
||||
(submoduleWith { modules = [ { freeformType = attrsOf (nullOr str); } ]; }).description
|
||||
== "open submodule of attribute set of (null or string)";
|
||||
assert
|
||||
(submoduleWith { modules = [ { freeformType = listOf str; } ]; }).description
|
||||
== "open submodule of list of string";
|
||||
assert
|
||||
(submoduleWith { modules = [ { freeformType = lazyAttrsOf str; } ]; }).description
|
||||
== "open submodule of lazy attribute set of string";
|
||||
assert
|
||||
(submoduleWith { modules = [ { freeformType = lazyAttrsOf int; } ]; }).description
|
||||
== "open submodule of lazy attribute set of signed integer";
|
||||
assert
|
||||
(submoduleWith { modules = [ { freeformType = lazyAttrsOf (either int str); } ]; }).description
|
||||
== "open submodule of lazy attribute set of (signed integer or string)";
|
||||
assert
|
||||
(submoduleWith { modules = [ { freeformType = attrsOf ints.positive; } ]; }).description
|
||||
== "open submodule of attribute set of (positive integer, meaning >0)";
|
||||
assert (submoduleWith { modules = [ ]; }).description == "submodule";
|
||||
assert
|
||||
(submoduleWith {
|
||||
modules = [ ];
|
||||
description = "custom";
|
||||
}).description == "custom";
|
||||
assert
|
||||
(submoduleWith {
|
||||
modules = [ ];
|
||||
description = "custom module";
|
||||
}).description == "custom module";
|
||||
assert (uniq str).description == "string";
|
||||
assert (uniq (either int str)).description == "signed integer or string";
|
||||
assert (uniq (listOf str)).description == "list of string";
|
||||
assert (unique { message = "test"; } str).description == "string";
|
||||
assert (unique { message = ""; } (either int str)).description == "signed integer or string";
|
||||
assert (unique { message = "custom"; } (listOf str)).description == "list of string";
|
||||
assert (unique { message = "test"; } (either int str)).description == "signed integer or string";
|
||||
assert (unique { message = "test"; } (listOf str)).description == "list of string";
|
||||
# done
|
||||
"ok";
|
||||
};
|
||||
}
|
||||
|
||||
+8
-1
@@ -1247,7 +1247,14 @@ let
|
||||
let
|
||||
docsEval = base.extendModules { modules = [ noCheckForDocsModule ]; };
|
||||
in
|
||||
docsEval._module.freeformType.description or name;
|
||||
if docsEval._module.freeformType ? description then
|
||||
"open ${name} of ${
|
||||
optionDescriptionPhrase (
|
||||
class: class == "noun" || class == "composite"
|
||||
) docsEval._module.freeformType
|
||||
}"
|
||||
else
|
||||
name;
|
||||
inherit check;
|
||||
merge = {
|
||||
__functor =
|
||||
|
||||
@@ -3510,12 +3510,6 @@
|
||||
githubId = 52386117;
|
||||
name = "Blusk";
|
||||
};
|
||||
bmanuel = {
|
||||
name = "Benjamin Manuel";
|
||||
email = "ben@benmanuel.com";
|
||||
github = "bmanuel";
|
||||
githubId = 3662307;
|
||||
};
|
||||
bmilanov = {
|
||||
name = "Biser Milanov";
|
||||
email = "bmilanov11+nixpkgs@gmail.com";
|
||||
@@ -4775,6 +4769,12 @@
|
||||
name = "Alex Zero";
|
||||
keys = [ { fingerprint = "A0AA 4646 B8F6 9D45 4553 5A88 A515 50ED B450 302C"; } ];
|
||||
};
|
||||
cizniarova = {
|
||||
email = "gabriel.hosquet@epitech.eu";
|
||||
github = "Ciznia";
|
||||
githubId = 114656678;
|
||||
name = "Gabriel Hosquet";
|
||||
};
|
||||
cizra = {
|
||||
email = "todurov+nix@gmail.com";
|
||||
github = "cizra";
|
||||
@@ -9782,12 +9782,6 @@
|
||||
githubId = 95086304;
|
||||
name = "Guilherme Lima";
|
||||
};
|
||||
GuillaumeDesforges = {
|
||||
email = "aceus02@gmail.com";
|
||||
github = "GuillaumeDesforges";
|
||||
githubId = 1882000;
|
||||
name = "Guillaume Desforges";
|
||||
};
|
||||
guillaumekoenig = {
|
||||
email = "guillaume.edward.koenig@gmail.com";
|
||||
github = "guillaumekoenig";
|
||||
@@ -10131,10 +10125,11 @@
|
||||
name = "Heisfer";
|
||||
};
|
||||
HeitorAugustoLN = {
|
||||
email = "IAm.HeitorALN@proton.me";
|
||||
email = "nixpkgs.woven713@passmail.net";
|
||||
github = "HeitorAugustoLN";
|
||||
githubId = 44377258;
|
||||
name = "Heitor Augusto";
|
||||
matrix = "@heitoraugusto:matrix.org";
|
||||
};
|
||||
heitorPB = {
|
||||
email = "heitorpbittencourt@gmail.com";
|
||||
@@ -11790,12 +11785,6 @@
|
||||
githubId = 4599384;
|
||||
name = "Jack Baldry";
|
||||
};
|
||||
jdehaas = {
|
||||
email = "qqlq@nullptr.club";
|
||||
github = "jeroendehaas";
|
||||
githubId = 117874;
|
||||
name = "Jeroen de Haas";
|
||||
};
|
||||
jdelStrother = {
|
||||
email = "me@delstrother.com";
|
||||
github = "jdelStrother";
|
||||
@@ -13337,6 +13326,14 @@
|
||||
matrix = "@kenran_:matrix.org";
|
||||
name = "Johannes Maier";
|
||||
};
|
||||
kenshineto = {
|
||||
name = "Freya Murphy";
|
||||
email = "contact@freyacat.org";
|
||||
matrix = "@freya:freya.cat";
|
||||
github = "kenshineto";
|
||||
githubId = 28487599;
|
||||
keys = [ { fingerprint = "D9AF 0A42 09B7 C2DE 11A8 84BF ACBC 5536 60D9 993D"; } ];
|
||||
};
|
||||
kentjames = {
|
||||
email = "jameschristopherkent@gmail.com";
|
||||
github = "KentJames";
|
||||
@@ -14406,12 +14403,11 @@
|
||||
name = "Leiser Fernández Gallo";
|
||||
};
|
||||
leixb = {
|
||||
email = "abone9999+nixpkgs@gmail.com";
|
||||
email = "abone9999@gmail.com";
|
||||
matrix = "@leix_b:matrix.org";
|
||||
github = "Leixb";
|
||||
githubId = 17183803;
|
||||
name = "Aleix Boné";
|
||||
keys = [ { fingerprint = "63D3 F436 EDE8 7E1F 1292 24AF FC03 5BB2 BB28 E15D"; } ];
|
||||
};
|
||||
lejonet = {
|
||||
email = "daniel@kuehn.se";
|
||||
@@ -15491,6 +15487,11 @@
|
||||
githubId = 1809783;
|
||||
name = "Marco Maggesi";
|
||||
};
|
||||
magicquark = {
|
||||
name = "magicquark";
|
||||
github = "magicquark";
|
||||
githubId = 198001825;
|
||||
};
|
||||
magistau = {
|
||||
name = "Mg. Tau";
|
||||
email = "nix@alice-carroll.pet";
|
||||
@@ -16580,13 +16581,6 @@
|
||||
githubId = 71893;
|
||||
name = "Michael Maclean";
|
||||
};
|
||||
mglolenstine = {
|
||||
email = "mglolenstine@gmail.com";
|
||||
github = "MGlolenstine";
|
||||
githubId = 9406770;
|
||||
matrix = "@mglolenstine:matrix.org";
|
||||
name = "MGlolenstine";
|
||||
};
|
||||
mgregoire = {
|
||||
email = "gregoire@martinache.net";
|
||||
github = "M-Gregoire";
|
||||
@@ -20763,6 +20757,12 @@
|
||||
githubId = 20863431;
|
||||
name = "Prithak S.";
|
||||
};
|
||||
priyaananthasankar = {
|
||||
name = "Priya Ananthasankar";
|
||||
github = "priyaananthasankar";
|
||||
githubId = 10415876;
|
||||
email = "priyagituniverse@gmail.com";
|
||||
};
|
||||
ProducerMatt = {
|
||||
name = "Matthew Pherigo";
|
||||
email = "ProducerMatt42@gmail.com";
|
||||
@@ -22919,6 +22919,12 @@
|
||||
githubId = 92817635;
|
||||
name = "Sanskar Gurdasani";
|
||||
};
|
||||
santosh = {
|
||||
email = "santoshxshrestha@gmail.com";
|
||||
name = "Santosh Shrestha";
|
||||
github = "santoshxshrestha";
|
||||
githubId = 182977126;
|
||||
};
|
||||
sarahec = {
|
||||
email = "seclark@nextquestion.net";
|
||||
github = "sarahec";
|
||||
@@ -23714,6 +23720,12 @@
|
||||
githubId = 114918019;
|
||||
name = "Shourya Goel";
|
||||
};
|
||||
shokerplz = {
|
||||
name = "Ivan Kovalev";
|
||||
email = "ivan@ikovalev.nl";
|
||||
github = "shokerplz";
|
||||
githubId = 28829931;
|
||||
};
|
||||
shortcord = {
|
||||
name = "Short Cord";
|
||||
email = "short@shortcord.com";
|
||||
@@ -26964,6 +26976,12 @@
|
||||
githubId = 1525767;
|
||||
name = "Vaibhav Sagar";
|
||||
};
|
||||
vaisriv = {
|
||||
email = "vai.sriv@icloud.com";
|
||||
github = "vaisriv";
|
||||
githubId = 46390109;
|
||||
name = "Vai";
|
||||
};
|
||||
valebes = {
|
||||
email = "valebes@gmail.com";
|
||||
github = "valebes";
|
||||
@@ -28266,12 +28284,6 @@
|
||||
githubId = 5121426;
|
||||
name = "Albert Safin";
|
||||
};
|
||||
y0no = {
|
||||
email = "y0no@y0no.fr";
|
||||
github = "y0no";
|
||||
githubId = 2242427;
|
||||
name = "Yoann Ono";
|
||||
};
|
||||
yah = {
|
||||
email = "yah@singularpoint.cc";
|
||||
github = "wangxiaoerYah";
|
||||
|
||||
@@ -315,13 +315,6 @@ with lib.maintainers;
|
||||
enableFeatureFreezePing = true;
|
||||
};
|
||||
|
||||
deepin = {
|
||||
members = [ wineee ];
|
||||
scope = "Maintain deepin desktop environment and related packages.";
|
||||
shortName = "DDE";
|
||||
enableFeatureFreezePing = true;
|
||||
};
|
||||
|
||||
deshaw = {
|
||||
# Verify additions to this team with at least one already existing member of the team.
|
||||
members = [
|
||||
@@ -674,6 +667,7 @@ with lib.maintainers;
|
||||
members = [
|
||||
euank
|
||||
frederictobiasc
|
||||
heywoodlh
|
||||
marcusramberg
|
||||
mic92
|
||||
rorosen
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
- Syncthing has been updated to version 2.0.0.
|
||||
|
||||
- COSMIC DE has been updated to the beta version, bringing it closer to its first stable release. This includes updates to its core components, applications, and overall stability.
|
||||
|
||||
## New Modules {#sec-release-25.11-new-modules}
|
||||
|
||||
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
|
||||
@@ -48,6 +50,8 @@
|
||||
|
||||
- [LibreTranslate](https://libretranslate.com), a free and open source machine translation API. Available as [services.libretranslate](#opt-services.libretranslate.enable).
|
||||
|
||||
- [Linyaps](https://linyaps.org.cn/), a cross-distribution package manager with sandboxed apps and shared runtime. Available as [services.linyaps](#opt-services.linyaps.enable).
|
||||
|
||||
- [tlsrpt-reporter](https://github.com/sys4/tlsrpt-reporter), an application suite to generate and deliver TLSRPT reports. Available as [services.tlsrpt](#opt-services.tlsrpt.enable).
|
||||
|
||||
- [Chhoto URL](https://github.com/SinTan1729/chhoto-url), a simple, blazingly fast, selfhosted URL shortener with no unnecessary features, written in Rust. Available as [services.chhoto-url](#opt-services.chhoto-url.enable).
|
||||
@@ -114,6 +118,8 @@
|
||||
|
||||
- [SuiteNumérique Meet](https://github.com/suitenumerique/meet) is an open source alternative to Google Meet and Zoom powered by LiveKit: HD video calls, screen sharing, and chat features. Built with Django and React. Available as [services.lasuite-meet](#opt-services.lasuite-meet.enable).
|
||||
|
||||
- [Prometheus Storagebox Exporter](https://github.com/fleaz/prometheus-storagebox-exporter), a Prometheus exporter for Hetzner storage boxes.
|
||||
|
||||
- [lemurs](https://github.com/coastalwhite/lemurs), a customizable TUI display/login manager. Available at [services.displayManager.lemurs](#opt-services.displayManager.lemurs.enable).
|
||||
|
||||
- [paisa](https://github.com/ananthakumaran/paisa), a personal finance tracker and dashboard. Available as [services.paisa](#opt-services.paisa.enable).
|
||||
@@ -132,6 +138,8 @@
|
||||
|
||||
- [Sshwifty](https://github.com/nirui/sshwifty), a Telnet and SSH client for your browser. Available as [services.sshwifty](#opt-services.sshwifty.enable).
|
||||
|
||||
- [nvme-rs](https://github.com/liberodark/nvme-rs), NVMe monitoring [services.nvme-rs](#opt-services.nvme-rs.enable).
|
||||
|
||||
## Backward Incompatibilities {#sec-release-25.11-incompatibilities}
|
||||
|
||||
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
|
||||
@@ -168,6 +176,8 @@
|
||||
|
||||
- The default `kops` version is now 1.33.0 and versions 1.30 and older have been dropped. See [Upgrading Kubernetes](https://kops.sigs.k8s.io/tutorial/upgrading-kubernetes/) for instructions on how to update kOps.
|
||||
|
||||
- `programs.skim.fuzzyCompletions` has been removed in favor of adding the completions to the package itself.
|
||||
|
||||
- `Prosody` has been updated to major release 13 which removed some obsoleted modules and brought a couple of major and breaking changes:
|
||||
- The `http_files` module is now disabled by default because it now requires `http_files_dir` to be configured.
|
||||
- The `vcard_muc` module has been removed and got replaced by the inbuilt `muc_vcard` module.
|
||||
@@ -260,6 +270,8 @@
|
||||
|
||||
- Due to [deprecation of gnome-session X11 support](https://blogs.gnome.org/alatiera/2025/06/08/the-x11-session-removal/), `services.desktopManager.pantheon` now defaults to pantheon-wayland session. The X11 session has been removed, see [this issue](https://github.com/elementary/session-settings/issues/91) for details.
|
||||
|
||||
- `bcachefs` file systems will now use the out-of-tree module for supported kernels. The in-tree module is unmaintained and users are strongly recommended to switch to kernels that support the out-of-tree module.
|
||||
|
||||
- `services.gitea` supports sending notifications with sendmail again. To do this, activate the parameter `services.gitea.mailerUseSendmail` and configure SMTP server.
|
||||
|
||||
- `networking.wireless.networks.<name>` now has an option to specify SSID, hence allowing duplicated SSID setup. The BSSID option is added along side with this.
|
||||
@@ -309,6 +321,8 @@
|
||||
|
||||
- `services.pds` has been renamed to `services.bluesky-pds`.
|
||||
|
||||
- `services.xserver.desktopManager.deepin` and associated packages have been removed due to being unmaintained. See issue [#422090](https://github.com/NixOS/nixpkgs/issues/422090) for more details.
|
||||
|
||||
- The new option [networking.ipips](#opt-networking.ipips) has been added to create IP within IP kind of tunnels (including 4in6, ip6ip6 and ipip).
|
||||
With the existing [networking.sits](#opt-networking.sits) option (6in4), it is now possible to create all combinations of IPv4 and IPv6 encapsulation.
|
||||
|
||||
@@ -326,6 +340,8 @@
|
||||
- `services.varnish.http_address` has been superseeded by `services.varnish.listen` which is now
|
||||
structured config for all of varnish's `-a` variations.
|
||||
|
||||
- `services.nginx.recommendedProxySettings` now sets `X-Forwarded-Server` to the hostname of nginx instead of the original host.
|
||||
|
||||
- [](#opt-services.gnome.gnome-keyring.enable) does not ship with an SSH agent anymore, as this is now handled by the `gcr_4` package instead of `gnome-keyring`. A new module has been added to support this, under [](#opt-services.gnome.gcr-ssh-agent.enable) (its default value has been set to [](#opt-services.gnome.gnome-keyring.enable) to ensure a smooth transition). See the [relevant upstream PR](https://gitlab.gnome.org/GNOME/gcr/-/merge_requests/67) for more details.
|
||||
|
||||
- The `nettools` package (ifconfig, arp, mii-tool, netstat, route) is not installed by default anymore. The suite is unmaintained and users should migrate to `iproute2` and `ethtool` instead.
|
||||
|
||||
@@ -63,7 +63,8 @@ in
|
||||
type = with lib.types; nullOr int;
|
||||
description = ''
|
||||
Maximum total amount of memory (in bytes) that can be stored in the zram
|
||||
swap devices.
|
||||
swap devices. If set, the smaller one of this option and memoryPercent would
|
||||
be used.
|
||||
This doesn't define how much memory will be used by the zram swap devices.
|
||||
'';
|
||||
};
|
||||
|
||||
@@ -541,6 +541,7 @@
|
||||
./services/databases/tigerbeetle.nix
|
||||
./services/databases/victorialogs.nix
|
||||
./services/databases/victoriametrics.nix
|
||||
./services/databases/victoriatraces.nix
|
||||
./services/desktops/accountsservice.nix
|
||||
./services/desktops/ayatana-indicators.nix
|
||||
./services/desktops/bamf.nix
|
||||
@@ -1501,6 +1502,7 @@
|
||||
./services/system/localtimed.nix
|
||||
./services/system/nix-daemon.nix
|
||||
./services/system/nscd.nix
|
||||
./services/system/nvme-rs.nix
|
||||
./services/system/saslauthd.nix
|
||||
./services/system/self-deploy.nix
|
||||
./services/system/swapspace.nix
|
||||
@@ -1803,6 +1805,7 @@
|
||||
./system/activation/activatable-system.nix
|
||||
./system/activation/activation-script.nix
|
||||
./system/activation/bootspec.nix
|
||||
./system/activation/nixos-init.nix
|
||||
./system/activation/pre-switch-check.nix
|
||||
./system/activation/specialisation.nix
|
||||
./system/activation/switchable-system.nix
|
||||
|
||||
@@ -8,38 +8,37 @@ let
|
||||
inherit (lib)
|
||||
mkEnableOption
|
||||
mkPackageOption
|
||||
optional
|
||||
mkRemovedOptionModule
|
||||
optionalString
|
||||
mkIf
|
||||
;
|
||||
cfg = config.programs.skim;
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
(mkRemovedOptionModule [ "programs" "skim" "fuzzyCompletion" ]
|
||||
"programs.skim.fuzzyCompletion has been removed. Completions are now included in the package itself."
|
||||
)
|
||||
];
|
||||
|
||||
options = {
|
||||
programs.skim = {
|
||||
fuzzyCompletion = mkEnableOption "fuzzy completion with skim";
|
||||
enable = mkEnableOption "skim fuzzy finder";
|
||||
keybindings = mkEnableOption "skim keybindings";
|
||||
package = mkPackageOption pkgs "skim" { };
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
environment.systemPackages = optional (cfg.keybindings || cfg.fuzzyCompletion) cfg.package;
|
||||
config = mkIf cfg.enable {
|
||||
environment.systemPackages = [ cfg.package ];
|
||||
|
||||
programs.bash.interactiveShellInit =
|
||||
optionalString cfg.fuzzyCompletion ''
|
||||
source ${cfg.package}/share/skim/completion.bash
|
||||
''
|
||||
+ optionalString cfg.keybindings ''
|
||||
source ${cfg.package}/share/skim/key-bindings.bash
|
||||
'';
|
||||
programs.bash.interactiveShellInit = optionalString cfg.keybindings ''
|
||||
source ${cfg.package}/share/skim/key-bindings.bash
|
||||
'';
|
||||
|
||||
programs.zsh.interactiveShellInit =
|
||||
optionalString cfg.fuzzyCompletion ''
|
||||
source ${cfg.package}/share/skim/completion.zsh
|
||||
''
|
||||
+ optionalString cfg.keybindings ''
|
||||
source ${cfg.package}/share/skim/key-bindings.zsh
|
||||
'';
|
||||
programs.zsh.interactiveShellInit = optionalString cfg.keybindings ''
|
||||
source ${cfg.package}/share/skim/key-bindings.zsh
|
||||
'';
|
||||
|
||||
programs.fish.interactiveShellInit = optionalString cfg.keybindings ''
|
||||
source ${cfg.package}/share/skim/key-bindings.fish && skim_key_bindings
|
||||
|
||||
@@ -77,7 +77,7 @@ in
|
||||
'';
|
||||
};
|
||||
services.openssh.authorizedKeysCommand = "/etc/ssh/authorized_keys_command_google_oslogin %u";
|
||||
services.openssh.authorizedKeysCommandUser = "nobody";
|
||||
services.openssh.authorizedKeysCommandUser = "root";
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -190,7 +190,7 @@ in
|
||||
}
|
||||
'';
|
||||
|
||||
"openldap/ldap.conf".source = ldapConf;
|
||||
"ldap.conf".source = ldapConf;
|
||||
};
|
||||
|
||||
environment.etc."chromium/policies/managed/freeipa.json" = mkIf cfg.chromiumSupport {
|
||||
|
||||
@@ -0,0 +1,173 @@
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
utils,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib)
|
||||
escapeShellArgs
|
||||
getBin
|
||||
hasPrefix
|
||||
literalExpression
|
||||
mkBefore
|
||||
mkEnableOption
|
||||
mkIf
|
||||
mkOption
|
||||
mkPackageOption
|
||||
optionalString
|
||||
types
|
||||
;
|
||||
cfg = config.services.victoriatraces;
|
||||
startCLIList = [
|
||||
"${cfg.package}/bin/victoria-traces"
|
||||
"-storageDataPath=/var/lib/${cfg.stateDir}"
|
||||
"-httpListenAddr=${cfg.listenAddress}"
|
||||
]
|
||||
++ lib.optionals (cfg.basicAuthUsername != null) [
|
||||
"-httpAuth.username=${cfg.basicAuthUsername}"
|
||||
]
|
||||
++ lib.optionals (cfg.basicAuthPasswordFile != null) [
|
||||
"-httpAuth.password=file://%d/basic_auth_password"
|
||||
];
|
||||
in
|
||||
{
|
||||
options.services.victoriatraces = {
|
||||
enable = mkEnableOption "VictoriaTraces is an open source distributed traces storage and query engine from VictoriaMetrics";
|
||||
package = mkPackageOption pkgs "victoriatraces" { };
|
||||
listenAddress = mkOption {
|
||||
default = ":10428";
|
||||
type = types.str;
|
||||
description = ''
|
||||
TCP address to listen for incoming http requests.
|
||||
'';
|
||||
};
|
||||
stateDir = mkOption {
|
||||
type = types.str;
|
||||
default = "victoriatraces";
|
||||
description = ''
|
||||
Directory below `/var/lib` to store VictoriaTraces data.
|
||||
This directory will be created automatically using systemd's StateDirectory mechanism.
|
||||
'';
|
||||
};
|
||||
retentionPeriod = mkOption {
|
||||
type = types.str;
|
||||
default = "7d";
|
||||
example = "30d";
|
||||
description = ''
|
||||
Retention period for trace data. Data older than retentionPeriod is automatically deleted.
|
||||
'';
|
||||
};
|
||||
basicAuthUsername = lib.mkOption {
|
||||
default = null;
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
description = ''
|
||||
Basic Auth username used to protect VictoriaTraces instance by authorization
|
||||
'';
|
||||
};
|
||||
|
||||
basicAuthPasswordFile = lib.mkOption {
|
||||
default = null;
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
description = ''
|
||||
File that contains the Basic Auth password used to protect VictoriaTraces instance by authorization
|
||||
'';
|
||||
};
|
||||
extraOptions = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
example = literalExpression ''
|
||||
[
|
||||
"-loggerLevel=WARN"
|
||||
"-retention.maxDiskSpaceUsageBytes=1073741824"
|
||||
]
|
||||
'';
|
||||
description = ''
|
||||
Extra options to pass to VictoriaTraces. See {command}`victoria-traces -help` for
|
||||
possible options.
|
||||
'';
|
||||
};
|
||||
};
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
assertions = [
|
||||
{
|
||||
assertion =
|
||||
(cfg.basicAuthUsername == null && cfg.basicAuthPasswordFile == null)
|
||||
|| (cfg.basicAuthUsername != null && cfg.basicAuthPasswordFile != null);
|
||||
message = "Both basicAuthUsername and basicAuthPasswordFile must be set together to enable basicAuth functionality, or neither should be set.";
|
||||
}
|
||||
];
|
||||
|
||||
systemd.services.victoriatraces = {
|
||||
description = "VictoriaTraces distributed traces database";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
startLimitBurst = 5;
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = lib.concatStringsSep " " [
|
||||
(escapeShellArgs (startCLIList ++ [ "-retentionPeriod=${cfg.retentionPeriod}" ]))
|
||||
(utils.escapeSystemdExecArgs cfg.extraOptions)
|
||||
];
|
||||
DynamicUser = true;
|
||||
LoadCredential = lib.optional (
|
||||
cfg.basicAuthPasswordFile != null
|
||||
) "basic_auth_password:${cfg.basicAuthPasswordFile}";
|
||||
RestartSec = 1;
|
||||
Restart = "on-failure";
|
||||
RuntimeDirectory = "victoriatraces";
|
||||
RuntimeDirectoryMode = "0700";
|
||||
StateDirectory = cfg.stateDir;
|
||||
StateDirectoryMode = "0700";
|
||||
|
||||
# Increase the limit to avoid errors like 'too many open files' when handling many trace spans
|
||||
LimitNOFILE = 1048576;
|
||||
|
||||
# Hardening
|
||||
DeviceAllow = [ "/dev/null rw" ];
|
||||
DevicePolicy = "strict";
|
||||
LockPersonality = true;
|
||||
MemoryDenyWriteExecute = true;
|
||||
NoNewPrivileges = true;
|
||||
PrivateDevices = true;
|
||||
PrivateTmp = true;
|
||||
PrivateUsers = true;
|
||||
ProtectClock = true;
|
||||
ProtectControlGroups = true;
|
||||
ProtectHome = true;
|
||||
ProtectHostname = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectProc = "invisible";
|
||||
ProtectSystem = "full";
|
||||
RemoveIPC = true;
|
||||
RestrictAddressFamilies = [
|
||||
"AF_INET"
|
||||
"AF_INET6"
|
||||
"AF_UNIX"
|
||||
];
|
||||
RestrictNamespaces = true;
|
||||
RestrictRealtime = true;
|
||||
RestrictSUIDSGID = true;
|
||||
SystemCallArchitectures = "native";
|
||||
SystemCallFilter = [
|
||||
"@system-service"
|
||||
"~@privileged"
|
||||
];
|
||||
};
|
||||
|
||||
postStart =
|
||||
let
|
||||
bindAddr = (optionalString (hasPrefix ":" cfg.listenAddress) "127.0.0.1") + cfg.listenAddress;
|
||||
in
|
||||
mkBefore ''
|
||||
until ${getBin pkgs.curl}/bin/curl -s -o /dev/null http://${bindAddr}/ping; do
|
||||
sleep 1;
|
||||
done
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -26,6 +26,7 @@ let
|
||||
cosmic-files
|
||||
config.services.displayManager.cosmic-greeter.package
|
||||
cosmic-idle
|
||||
cosmic-initial-setup
|
||||
cosmic-launcher
|
||||
cosmic-notifications
|
||||
cosmic-osd
|
||||
@@ -103,6 +104,8 @@ in
|
||||
services.graphical-desktop.enable = true;
|
||||
|
||||
xdg = {
|
||||
# Required for cosmic-osd
|
||||
sounds.enable = true;
|
||||
icons.fallbackCursorThemes = lib.mkDefault [ "Cosmic" ];
|
||||
|
||||
portal = {
|
||||
|
||||
@@ -113,9 +113,9 @@ You can install them like any other package:
|
||||
```nix
|
||||
{
|
||||
environment.systemPackages = [
|
||||
gnomeExtensions.dash-to-dock
|
||||
gnomeExtensions.gsconnect
|
||||
gnomeExtensions.mpris-indicator-button
|
||||
pkgs.gnomeExtensions.dash-to-dock
|
||||
pkgs.gnomeExtensions.gsconnect
|
||||
pkgs.gnomeExtensions.mpris-indicator-button
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
@@ -29,7 +29,7 @@ in
|
||||
settings = {
|
||||
default_session = {
|
||||
user = "cosmic-greeter";
|
||||
command = ''${lib.getExe' pkgs.coreutils "env"} XCURSOR_THEME="''${XCURSOR_THEME:-Pop}" systemd-cat -t cosmic-greeter ${lib.getExe pkgs.cosmic-comp} ${lib.getExe cfg.package}'';
|
||||
command = ''${lib.getExe' pkgs.coreutils "env"} XCURSOR_THEME="''${XCURSOR_THEME:-Pop}" ${lib.getExe' cfg.package "cosmic-greeter-start"}'';
|
||||
};
|
||||
initial_session = lib.mkIf (cfgAutoLogin.enable && (cfgAutoLogin.user != null)) {
|
||||
user = cfgAutoLogin.user;
|
||||
|
||||
@@ -41,6 +41,11 @@ in
|
||||
description = "Set server port of openrgb.";
|
||||
};
|
||||
|
||||
startupProfile = lib.mkOption {
|
||||
type = lib.types.nullOr (lib.types.str);
|
||||
default = null;
|
||||
description = "The profile file to load from \"/var/lib/OpenRGB\" at startup.";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
@@ -61,7 +66,9 @@ in
|
||||
serviceConfig = {
|
||||
StateDirectory = "OpenRGB";
|
||||
WorkingDirectory = "/var/lib/OpenRGB";
|
||||
ExecStart = "${cfg.package}/bin/openrgb --server --server-port ${toString cfg.server.port}";
|
||||
ExecStart =
|
||||
"${cfg.package}/bin/openrgb --server --server-port ${toString cfg.server.port}"
|
||||
+ lib.optionalString (builtins.isString cfg.startupProfile) " --profile ${lib.escapeShellArg cfg.startupProfile}";
|
||||
Restart = "always";
|
||||
};
|
||||
};
|
||||
|
||||
@@ -42,8 +42,6 @@ in
|
||||
options = {
|
||||
enable = mkEnableOption "Wyoming Piper server";
|
||||
|
||||
piper = mkPackageOption pkgs "piper-tts" { };
|
||||
|
||||
voice = mkOption {
|
||||
type = str;
|
||||
example = "en-us-ryan-medium";
|
||||
@@ -159,8 +157,6 @@ in
|
||||
"/var/lib/wyoming/piper"
|
||||
"--uri"
|
||||
options.uri
|
||||
"--piper"
|
||||
(lib.getExe options.piper)
|
||||
"--voice"
|
||||
options.voice
|
||||
"--speaker"
|
||||
@@ -169,7 +165,7 @@ in
|
||||
options.lengthScale
|
||||
"--noise-scale"
|
||||
options.noiseScale
|
||||
"--noise-w"
|
||||
"--noise-w-scale"
|
||||
options.noiseWidth
|
||||
]
|
||||
++ lib.optionals options.streaming [
|
||||
|
||||
@@ -809,7 +809,7 @@ in
|
||||
default = "";
|
||||
type = lib.types.lines;
|
||||
description = ''
|
||||
Entries for the transport map, cf. man-page {manpage}`transport(8)`.
|
||||
Entries for the transport map, cf. man-page {manpage}`transport(5)`.
|
||||
'';
|
||||
};
|
||||
|
||||
|
||||
@@ -49,6 +49,13 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
showBanner = mkOption {
|
||||
description = "Whether to add the Cockpit banner to the issue and motd files.";
|
||||
type = types.bool;
|
||||
default = true;
|
||||
example = false;
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
description = "Port where cockpit will listen.";
|
||||
type = types.port;
|
||||
@@ -62,16 +69,28 @@ in
|
||||
};
|
||||
};
|
||||
};
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
# expose cockpit-bridge system-wide
|
||||
environment.systemPackages = [ cfg.package ];
|
||||
|
||||
# allow cockpit to find its plugins
|
||||
environment.pathsToLink = [ "/share/cockpit" ];
|
||||
|
||||
# generate cockpit settings
|
||||
environment.etc."cockpit/cockpit.conf".source = settingsFormat.generate "cockpit.conf" cfg.settings;
|
||||
environment.etc = {
|
||||
# generate cockpit settings
|
||||
"cockpit/cockpit.conf".source = settingsFormat.generate "cockpit.conf" cfg.settings;
|
||||
|
||||
# Add "Web console: ..." line to issue and MOTD
|
||||
"issue.d/cockpit.issue" = {
|
||||
enable = cfg.showBanner;
|
||||
source = "/run/cockpit/issue";
|
||||
};
|
||||
"motd.d/cockpit" = {
|
||||
enable = cfg.showBanner;
|
||||
source = "/run/cockpit/issue";
|
||||
};
|
||||
};
|
||||
|
||||
security.pam.services.cockpit = {
|
||||
startSession = true;
|
||||
@@ -80,11 +99,26 @@ in
|
||||
networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ cfg.port ];
|
||||
|
||||
systemd.packages = [ cfg.package ];
|
||||
systemd.sockets.cockpit.wantedBy = [ "multi-user.target" ];
|
||||
systemd.sockets.cockpit.listenStreams = [
|
||||
"" # workaround so it doesn't listen on both ports caused by the runtime merging
|
||||
(toString cfg.port)
|
||||
];
|
||||
|
||||
systemd.sockets.cockpit = {
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
listenStreams = [
|
||||
"" # workaround so it doesn't listen on both ports caused by the runtime merging
|
||||
(toString cfg.port)
|
||||
];
|
||||
};
|
||||
|
||||
# Enable connecting to remote hosts from the login page
|
||||
systemd.services = mkIf (cfg.settings ? LoginTo -> cfg.settings.LoginTo) {
|
||||
"cockpit-wsinstance-http".path = [
|
||||
config.programs.ssh.package
|
||||
cfg.package
|
||||
];
|
||||
"cockpit-wsinstance-https@".path = [
|
||||
config.programs.ssh.package
|
||||
cfg.package
|
||||
];
|
||||
};
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
# From $out/lib/tmpfiles.d/cockpit-tmpfiles.conf
|
||||
|
||||
@@ -25,7 +25,7 @@ let
|
||||
in
|
||||
{
|
||||
options.services.loki = {
|
||||
enable = mkEnableOption "loki";
|
||||
enable = mkEnableOption "Grafana Loki";
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
@@ -49,7 +49,7 @@ in
|
||||
type = types.path;
|
||||
default = "/var/lib/loki";
|
||||
description = ''
|
||||
Specify the directory for Loki.
|
||||
Specify the data directory for Loki.
|
||||
'';
|
||||
};
|
||||
|
||||
@@ -58,6 +58,10 @@ in
|
||||
default = { };
|
||||
description = ''
|
||||
Specify the configuration for Loki in Nix.
|
||||
|
||||
See [documentation of Grafana Loki](https://grafana.com/docs/loki/latest/configure/) for all available options.
|
||||
|
||||
Cannot be specified together with {option}`services.loki.configFile`.
|
||||
'';
|
||||
};
|
||||
|
||||
@@ -66,6 +70,8 @@ in
|
||||
default = null;
|
||||
description = ''
|
||||
Specify a configuration file that Loki should use.
|
||||
|
||||
Cannot be specified together with {option}`services.loki.configuration`.
|
||||
'';
|
||||
};
|
||||
|
||||
|
||||
@@ -124,6 +124,7 @@ let
|
||||
"snmp"
|
||||
"sql"
|
||||
"statsd"
|
||||
"storagebox"
|
||||
"surfboard"
|
||||
"systemd"
|
||||
"tibber"
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
options,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.storagebox;
|
||||
inherit (lib) mkPackageOption;
|
||||
in
|
||||
{
|
||||
port = 9509;
|
||||
extraOpts = {
|
||||
package = mkPackageOption pkgs "prometheus-storagebox-exporter" { };
|
||||
tokenFile = lib.mkOption {
|
||||
type = lib.types.pathWith {
|
||||
inStore = false;
|
||||
absolute = true;
|
||||
};
|
||||
description = "File that contains the Hetzner API token to use.";
|
||||
};
|
||||
|
||||
};
|
||||
serviceOpts = {
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
script = ''
|
||||
export HETZNER_TOKEN=$(< "''${CREDENTIALS_DIRECTORY}/token")
|
||||
exec ${lib.getExe cfg.package}
|
||||
'';
|
||||
|
||||
environment = {
|
||||
LISTEN_ADDR = "${toString cfg.listenAddress}:${toString cfg.port}";
|
||||
};
|
||||
|
||||
serviceConfig = {
|
||||
DynamicUser = true;
|
||||
Restart = "always";
|
||||
RestartSec = "10s";
|
||||
LoadCredential = [
|
||||
"token:${cfg.tokenFile}"
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -86,7 +86,7 @@ in
|
||||
checkPhase = optionalString cfg.checkConfig ''
|
||||
ln -s $out bird.conf
|
||||
${cfg.preCheckConfig}
|
||||
bird -d -p -c bird.conf
|
||||
bird -d -p -c bird.conf || { exit=$?; cat -n bird.conf; exit $exit; }
|
||||
'';
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,327 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.services.cloudflare-ddns;
|
||||
|
||||
boolToString = b: if b then "true" else "false";
|
||||
formatList = l: lib.concatStringsSep "," l;
|
||||
formatDuration = d: d.String;
|
||||
in
|
||||
{
|
||||
options.services.cloudflare-ddns = {
|
||||
enable = lib.mkEnableOption "Cloudflare Dynamic DNS service";
|
||||
|
||||
package = lib.mkPackageOption pkgs "cloudflare-ddns" { };
|
||||
|
||||
credentialsFile = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
description = ''
|
||||
Path to a file containing the Cloudflare API authentication token.
|
||||
The file content should be in the format `CLOUDFLARE_API_TOKEN=YOUR_SECRET_TOKEN`.
|
||||
The service user `${cfg.user}` needs read access to this file.
|
||||
Ensure permissions are secure (e.g., `0400` or `0440`) and ownership is appropriate
|
||||
(e.g., `owner = root`, `group = ${cfg.group}`).
|
||||
Using `CLOUDFLARE_API_TOKEN` is preferred over the deprecated `CF_API_TOKEN`.
|
||||
'';
|
||||
example = "/run/secrets/cloudflare-ddns-token";
|
||||
};
|
||||
|
||||
domains = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
description = ''
|
||||
List of domain names (FQDNs) to manage. Wildcards like `*.example.com` are supported.
|
||||
These domains will be managed for both IPv4 and IPv6 unless overridden by
|
||||
`ip4Domains` or `ip6Domains`, or if the respective providers are disabled.
|
||||
This corresponds to the `DOMAINS` environment variable.
|
||||
'';
|
||||
example = [
|
||||
"home.example.com"
|
||||
"*.dynamic.example.org"
|
||||
];
|
||||
};
|
||||
|
||||
ip4Domains = lib.mkOption {
|
||||
type = lib.types.nullOr (lib.types.listOf lib.types.str);
|
||||
default = null;
|
||||
description = ''
|
||||
Explicit list of domains to manage only for IPv4. If set, overrides `domains` for IPv4.
|
||||
Corresponds to the `IP4_DOMAINS` environment variable.
|
||||
'';
|
||||
example = [ "ipv4.example.com" ];
|
||||
};
|
||||
|
||||
ip6Domains = lib.mkOption {
|
||||
type = lib.types.nullOr (lib.types.listOf lib.types.str);
|
||||
default = null;
|
||||
description = ''
|
||||
Explicit list of domains to manage only for IPv6. If set, overrides `domains` for IPv6.
|
||||
Corresponds to the `IP6_DOMAINS` environment variable.
|
||||
'';
|
||||
example = [ "ipv6.example.com" ];
|
||||
};
|
||||
|
||||
wafLists = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
description = ''
|
||||
List of WAF IP Lists to manage, in the format `account-id/list-name`.
|
||||
(Experimental feature as of cloudflare-ddns 1.14.0).
|
||||
'';
|
||||
example = [ "YOUR_ACCOUNT_ID/allowed_dynamic_ips" ];
|
||||
};
|
||||
|
||||
provider = {
|
||||
ipv4 = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "cloudflare.trace";
|
||||
description = ''
|
||||
IP detection provider for IPv4. Common values: `cloudflare.trace`, `cloudflare.doh`, `local`, `url:URL`, `none`.
|
||||
Use `none` to disable IPv4 updates.
|
||||
See cloudflare-ddns documentation for all options.
|
||||
'';
|
||||
};
|
||||
ipv6 = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "cloudflare.trace";
|
||||
description = ''
|
||||
IP detection provider for IPv6. Common values: `cloudflare.trace`, `cloudflare.doh`, `local`, `url:URL`, `none`.
|
||||
Use `none` to disable IPv6 updates.
|
||||
See cloudflare-ddns documentation for all options.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
updateCron = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "@every 5m";
|
||||
description = ''
|
||||
Cron expression for how often to check and update IPs.
|
||||
Use "@once" to run only once and then exit.
|
||||
'';
|
||||
example = "@hourly";
|
||||
};
|
||||
|
||||
updateOnStart = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Whether to perform an update check immediately on service start.";
|
||||
};
|
||||
|
||||
deleteOnStop = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to delete the managed DNS records and clear WAF lists when the service is stopped gracefully.
|
||||
Warning: Setting this to true with `updateCron = "@once"` will cause immediate deletion.
|
||||
'';
|
||||
};
|
||||
|
||||
cacheExpiration = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "6h";
|
||||
description = ''
|
||||
Duration for which API responses (like Zone ID, Record IDs) are cached.
|
||||
Uses Go's duration format (e.g., "6h", "1h30m").
|
||||
'';
|
||||
};
|
||||
|
||||
ttl = lib.mkOption {
|
||||
type = lib.types.ints.positive;
|
||||
default = 1;
|
||||
description = ''
|
||||
Time To Live (TTL) for the DNS records in seconds.
|
||||
Must be 1 (for automatic) or between 30 and 86400.
|
||||
'';
|
||||
};
|
||||
|
||||
proxied = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "false";
|
||||
description = ''
|
||||
Whether the managed DNS records should be proxied through Cloudflare ('orange cloud').
|
||||
Accepts boolean values (`true`, `false`) or a domain expression.
|
||||
See cloudflare-ddns documentation for expression syntax (e.g., "is(a.com) || sub(b.org)").
|
||||
'';
|
||||
example = "true";
|
||||
};
|
||||
|
||||
recordComment = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "";
|
||||
description = "Comment to add to managed DNS records.";
|
||||
};
|
||||
|
||||
wafListDescription = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "";
|
||||
description = "Description for managed WAF lists (used when creating or verifying lists).";
|
||||
};
|
||||
|
||||
detectionTimeout = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "5s";
|
||||
description = "Timeout for detecting the public IP address.";
|
||||
};
|
||||
|
||||
updateTimeout = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "30s";
|
||||
description = "Timeout for updating records via the Cloudflare API.";
|
||||
};
|
||||
|
||||
healthchecks = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = "URL for Healthchecks.io monitoring endpoint (optional).";
|
||||
example = "https://hc-ping.com/your-uuid";
|
||||
};
|
||||
|
||||
uptimeKuma = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = "URL for Uptime Kuma push monitor endpoint (optional).";
|
||||
example = "https://status.example.com/api/push/tag?status=up&msg=OK&ping=";
|
||||
};
|
||||
|
||||
shoutrrr = lib.mkOption {
|
||||
type = lib.types.nullOr (lib.types.listOf lib.types.str);
|
||||
default = null;
|
||||
description = "List of Shoutrrr notification service URLs (optional).";
|
||||
example = [
|
||||
"discord://token@id"
|
||||
"gotify://host/token"
|
||||
];
|
||||
};
|
||||
|
||||
user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "cloudflare-ddns";
|
||||
description = "User account under which the service runs.";
|
||||
};
|
||||
|
||||
group = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "cloudflare-ddns";
|
||||
description = "Group under which the service runs.";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion = cfg.ttl == 1 || (cfg.ttl >= 30 && cfg.ttl <= 86400);
|
||||
message = "services.cloudflare-ddns.ttl must be 1 or between 30 and 86400";
|
||||
}
|
||||
{
|
||||
assertion = cfg.updateCron == "@once" -> !cfg.deleteOnStop;
|
||||
message = "services.cloudflare-ddns.deleteOnStop cannot be true when updateCron is \"@once\"";
|
||||
}
|
||||
{
|
||||
assertion =
|
||||
cfg.domains != [ ] || cfg.ip4Domains != null || cfg.ip6Domains != null || cfg.wafLists != [ ];
|
||||
message = "services.cloudflare-ddns requires at least one domain (domains, ip4Domains, ip6Domains) or WAF list (wafLists) to be specified";
|
||||
}
|
||||
{
|
||||
assertion = cfg.provider.ipv4 != "none" || cfg.provider.ipv6 != "none";
|
||||
message = "services.cloudflare-ddns requires at least one provider (ipv4 or ipv6) to be enabled (not 'none')";
|
||||
}
|
||||
];
|
||||
|
||||
users.users.${cfg.user} = {
|
||||
description = "Cloudflare DDNS service user";
|
||||
isSystemUser = true;
|
||||
group = cfg.group;
|
||||
home = "/var/lib/${cfg.user}";
|
||||
};
|
||||
|
||||
users.groups.${cfg.group} = { };
|
||||
|
||||
systemd.tmpfiles.settings."cloudflare-ddns" = {
|
||||
"/var/lib/${cfg.user}".d = {
|
||||
mode = "0750";
|
||||
user = cfg.user;
|
||||
group = cfg.group;
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.cloudflare-ddns = {
|
||||
description = "Cloudflare Dynamic DNS Client Service (favonia)";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network-online.target" ];
|
||||
wants = [ "network-online.target" ];
|
||||
|
||||
serviceConfig = {
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
|
||||
WorkingDirectory = "/var/lib/${cfg.user}";
|
||||
|
||||
EnvironmentFile = cfg.credentialsFile;
|
||||
|
||||
Environment =
|
||||
let
|
||||
toEnv = name: value: "${name}=\"${toString value}\"";
|
||||
toEnvList = name: value: "${name}=\"${formatList value}\"";
|
||||
toEnvDuration = name: value: "${name}=\"${formatDuration value}\"";
|
||||
toEnvBool = name: value: "${name}=\"${boolToString value}\"";
|
||||
toEnvMaybe =
|
||||
pred: name: value:
|
||||
lib.optionalString pred (toEnv name value);
|
||||
toEnvMaybeList =
|
||||
pred: name: value:
|
||||
lib.optionalString pred (toEnvList name value);
|
||||
in
|
||||
lib.filter (envVar: envVar != "") [
|
||||
(toEnvList "DOMAINS" cfg.domains)
|
||||
(toEnvMaybeList (cfg.ip4Domains != null) "IP4_DOMAINS" cfg.ip4Domains)
|
||||
(toEnvMaybeList (cfg.ip6Domains != null) "IP6_DOMAINS" cfg.ip6Domains)
|
||||
|
||||
(toEnv "IP4_PROVIDER" cfg.provider.ipv4)
|
||||
(toEnv "IP6_PROVIDER" cfg.provider.ipv6)
|
||||
|
||||
(toEnvMaybeList (cfg.wafLists != [ ]) "WAF_LISTS" cfg.wafLists)
|
||||
(toEnvMaybe (cfg.wafListDescription != "") "WAF_LIST_DESCRIPTION" cfg.wafListDescription)
|
||||
|
||||
(toEnv "UPDATE_CRON" cfg.updateCron)
|
||||
(toEnvBool "UPDATE_ON_START" cfg.updateOnStart)
|
||||
(toEnvBool "DELETE_ON_STOP" cfg.deleteOnStop)
|
||||
(toEnv "CACHE_EXPIRATION" cfg.cacheExpiration)
|
||||
|
||||
(toEnv "TTL" cfg.ttl)
|
||||
(toEnv "PROXIED" cfg.proxied)
|
||||
(toEnvMaybe (cfg.recordComment != "") "RECORD_COMMENT" cfg.recordComment)
|
||||
|
||||
(toEnv "DETECTION_TIMEOUT" cfg.detectionTimeout)
|
||||
(toEnv "UPDATE_TIMEOUT" cfg.updateTimeout)
|
||||
|
||||
(toEnvMaybe (cfg.healthchecks != null) "HEALTHCHECKS" cfg.healthchecks)
|
||||
(toEnvMaybe (cfg.uptimeKuma != null) "UPTIMEKUMA" cfg.uptimeKuma)
|
||||
(toEnvMaybeList (cfg.shoutrrr != null) "SHOUTRRR" (lib.concatStringsSep "\n" cfg.shoutrrr))
|
||||
];
|
||||
|
||||
ExecStart = lib.getExe cfg.package;
|
||||
|
||||
Restart = "on-failure";
|
||||
RestartSec = "30s";
|
||||
|
||||
ProtectSystem = "strict";
|
||||
ProtectHome = true;
|
||||
PrivateTmp = true;
|
||||
PrivateDevices = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectControlGroups = true;
|
||||
NoNewPrivileges = true;
|
||||
RestrictAddressFamilies = [
|
||||
"AF_INET"
|
||||
"AF_INET6"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1334,26 +1334,21 @@ in
|
||||
# we check if wirelessInterfaces is empty as that means all interfaces implicit
|
||||
shouldWarn = wirelessEnabled && (wirelessInterfaces == [ ] || hasInterfaceConflict);
|
||||
in
|
||||
if shouldWarn then
|
||||
[
|
||||
''
|
||||
Some wireless interface is configured for both for client and access point mode:
|
||||
this is not allowed. Either specify `networking.wireless.interfaces` and exclude
|
||||
those from `services.hostapd.radios` or make sure to not run the `wpa_supplicant`
|
||||
and `hostapd` services simultaneously.
|
||||
''
|
||||
]
|
||||
else
|
||||
[ ];
|
||||
lib.optional shouldWarn ''
|
||||
Some wireless interface is configured for both for client and access point mode:
|
||||
this is not allowed. Either specify `networking.wireless.interfaces` and exclude
|
||||
those from `services.hostapd.radios` or make sure to not run the `wpa_supplicant`
|
||||
and `hostapd` services simultaneously.
|
||||
''
|
||||
++ lib.optional config.networking.wireless.iwd.enable ''
|
||||
hostapd and iwd do conflict,
|
||||
use `networking.wireless.enable` in combination with `networking.wireless.interfaces` to avoid it.
|
||||
'';
|
||||
assertions = [
|
||||
{
|
||||
assertion = cfg.radios != { };
|
||||
message = "At least one radio must be configured with hostapd!";
|
||||
}
|
||||
{
|
||||
assertion = !config.networking.wireless.iwd.enable;
|
||||
message = "hostapd and iwd conflict, use `networking.wireless.enable` in combination with `networking.wireless.interfaces`";
|
||||
}
|
||||
]
|
||||
# Radio warnings
|
||||
++ (concatLists (
|
||||
|
||||
@@ -518,6 +518,7 @@ let
|
||||
pid_file = 1;
|
||||
queue_qos0_messages = 1;
|
||||
retain_available = 1;
|
||||
retain_expiry_interval = 1;
|
||||
set_tcp_nodelay = 1;
|
||||
sys_interval = 1;
|
||||
upgrade_outgoing_qos = 1;
|
||||
|
||||
@@ -15,6 +15,7 @@ let
|
||||
comment = list.description;
|
||||
};
|
||||
payloads = map makePayload cfg.lists;
|
||||
macvendorURL = lib.strings.escapeShellArg cfg.macvendorURL;
|
||||
in
|
||||
''
|
||||
# Can't use -u (unset) because api.sh uses API_URL before it is set
|
||||
@@ -22,8 +23,10 @@ in
|
||||
pihole="${lib.getExe pihole}"
|
||||
jq="${lib.getExe pkgs.jq}"
|
||||
|
||||
${lib.getExe pkgs.curl} --retry 3 --retry-delay 5 "${macvendorURL}" -o "${cfg.settings.files.macvendor}" || echo "Failed to download MAC database from ${macvendorURL}"
|
||||
|
||||
# If the database doesn't exist, it needs to be created with gravity.sh
|
||||
if [ ! -f '${cfg.stateDirectory}'/gravity.db ]; then
|
||||
if [ ! -f '${cfg.settings.files.gravity}' ]; then
|
||||
$pihole -g
|
||||
# Send SIGRTMIN to FTL, which makes it reload the database, opening the newly created one
|
||||
${lib.getExe' pkgs.procps "kill"} -s SIGRTMIN $(systemctl show --property MainPID --value ${config.systemd.services.pihole-ftl.name})
|
||||
|
||||
@@ -118,6 +118,14 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
macvendorURL = mkOption {
|
||||
type = types.str;
|
||||
default = "https://ftl.pi-hole.net/macvendor.db";
|
||||
description = ''
|
||||
URL from which to download the macvendor.db file.
|
||||
'';
|
||||
};
|
||||
|
||||
pihole = mkOption {
|
||||
type = types.package;
|
||||
default = piholeScript;
|
||||
@@ -260,7 +268,7 @@ in
|
||||
files = {
|
||||
database = "${cfg.stateDirectory}/pihole-FTL.db";
|
||||
gravity = "${cfg.stateDirectory}/gravity.db";
|
||||
macvendor = "${cfg.stateDirectory}/gravity.db";
|
||||
macvendor = "${cfg.stateDirectory}/macvendor.db";
|
||||
log.ftl = "${cfg.logDirectory}/FTL.log";
|
||||
log.dnsmasq = "${cfg.logDirectory}/pihole.log";
|
||||
log.webserver = "${cfg.logDirectory}/webserver.log";
|
||||
|
||||
@@ -594,7 +594,7 @@ in
|
||||
]
|
||||
++ lib.optionals (cfg.settings.capi.credentialsFile != null) [
|
||||
''
|
||||
if ! grep -q password "${cfg.settings.capi.credentialsFile}" ]; then
|
||||
if ! ${lib.getExe pkgs.gnugrep} -q password "${cfg.settings.capi.credentialsFile}" ]; then
|
||||
${lib.getExe cscli} capi register
|
||||
fi
|
||||
''
|
||||
@@ -770,7 +770,7 @@ in
|
||||
serviceConfig = {
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
Type = "simple";
|
||||
Type = "notify";
|
||||
RestartSec = 60;
|
||||
LimitNOFILE = 65536;
|
||||
NoNewPrivileges = true;
|
||||
|
||||
@@ -0,0 +1,204 @@
|
||||
{
|
||||
config,
|
||||
options,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (lib) types;
|
||||
cfg = config.services.nvme-rs;
|
||||
opt = options.services.nvme-rs;
|
||||
settingsFormat = pkgs.formats.toml { };
|
||||
in
|
||||
{
|
||||
options.services.nvme-rs = {
|
||||
enable = lib.mkEnableOption "nvme-rs, a monitoring service";
|
||||
|
||||
package = lib.mkPackageOption pkgs "nvme-rs" { };
|
||||
|
||||
settings = lib.mkOption {
|
||||
type = types.submodule {
|
||||
freeformType = settingsFormat.type;
|
||||
options = {
|
||||
check_interval_secs = lib.mkOption {
|
||||
type = types.int;
|
||||
default = 3600;
|
||||
description = "Check interval in seconds";
|
||||
example = 86400;
|
||||
};
|
||||
|
||||
thresholds = lib.mkOption {
|
||||
type = types.submodule {
|
||||
freeformType = settingsFormat.type;
|
||||
options = {
|
||||
temp_warning = lib.mkOption {
|
||||
type = types.int;
|
||||
default = 55;
|
||||
description = "Temperature warning threshold (°C)";
|
||||
};
|
||||
|
||||
temp_critical = lib.mkOption {
|
||||
type = types.int;
|
||||
default = 65;
|
||||
description = "Temperature critical threshold (°C)";
|
||||
};
|
||||
|
||||
wear_warning = lib.mkOption {
|
||||
type = types.int;
|
||||
default = 20;
|
||||
description = "Wear warning threshold (%)";
|
||||
};
|
||||
|
||||
wear_critical = lib.mkOption {
|
||||
type = types.int;
|
||||
default = 50;
|
||||
description = "Wear critical threshold (%)";
|
||||
};
|
||||
|
||||
spare_warning = lib.mkOption {
|
||||
type = types.int;
|
||||
default = 50;
|
||||
description = "Available spare warning threshold (%)";
|
||||
};
|
||||
|
||||
error_threshold = lib.mkOption {
|
||||
type = types.int;
|
||||
default = 100;
|
||||
description = "Error count warning threshold";
|
||||
};
|
||||
};
|
||||
};
|
||||
default = { };
|
||||
description = "Threshold configuration for NVMe monitoring";
|
||||
};
|
||||
|
||||
email = lib.mkOption {
|
||||
type = types.nullOr (
|
||||
types.submodule {
|
||||
freeformType = settingsFormat.type;
|
||||
options = {
|
||||
smtp_server = lib.mkOption {
|
||||
type = types.str;
|
||||
default = "smtp.gmail.com";
|
||||
description = "SMTP server address";
|
||||
example = "mail.example.com";
|
||||
};
|
||||
|
||||
smtp_port = lib.mkOption {
|
||||
type = types.port;
|
||||
default = 587;
|
||||
description = "SMTP server port";
|
||||
};
|
||||
|
||||
smtp_username = lib.mkOption {
|
||||
type = types.str;
|
||||
description = "SMTP username";
|
||||
example = "your-email@gmail.com";
|
||||
};
|
||||
|
||||
smtp_password_file = lib.mkOption {
|
||||
type = types.path;
|
||||
description = "File containing SMTP password";
|
||||
example = "/run/secrets/smtp-password";
|
||||
};
|
||||
|
||||
from = lib.mkOption {
|
||||
type = types.str;
|
||||
description = "Sender email address";
|
||||
example = "nvme-monitor@example.com";
|
||||
};
|
||||
|
||||
to = lib.mkOption {
|
||||
type = types.str;
|
||||
description = "Recipient email address";
|
||||
example = "admin@example.com";
|
||||
};
|
||||
|
||||
use_tls = lib.mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Use TLS for SMTP connection";
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
default = null;
|
||||
description = "Email notification configuration";
|
||||
};
|
||||
};
|
||||
};
|
||||
default = { };
|
||||
description = ''
|
||||
Configuration for nvme-rs in TOML format.
|
||||
See the config.toml example for all available options.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
services.nvme-rs.settings = opt.settings.default;
|
||||
|
||||
systemd.services.nvme-rs = {
|
||||
description = "NVMe health monitoring service";
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
serviceConfig =
|
||||
let
|
||||
settingsWithoutNull =
|
||||
if cfg.settings.email == null then lib.removeAttrs cfg.settings [ "email" ] else cfg.settings;
|
||||
configFile = settingsFormat.generate "nvme-rs.toml" settingsWithoutNull;
|
||||
in
|
||||
{
|
||||
ExecStart = lib.escapeShellArgs [
|
||||
"${lib.getExe cfg.package}"
|
||||
"daemon"
|
||||
"--config"
|
||||
"${configFile}"
|
||||
];
|
||||
|
||||
DynamicUser = true;
|
||||
SupplementaryGroups = [ "disk" ];
|
||||
CapabilityBoundingSet = [ "CAP_SYS_ADMIN" ];
|
||||
AmbientCapabilities = [ "CAP_SYS_ADMIN" ];
|
||||
LimitCORE = 0;
|
||||
LimitNOFILE = 65535;
|
||||
LockPersonality = true;
|
||||
MemorySwapMax = 0;
|
||||
MemoryZSwapMax = 0;
|
||||
PrivateTmp = true;
|
||||
ProcSubset = "pid";
|
||||
ProtectClock = true;
|
||||
ProtectControlGroups = true;
|
||||
ProtectHome = true;
|
||||
ProtectHostname = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectProc = "invisible";
|
||||
ProtectSystem = "strict";
|
||||
Restart = "on-failure";
|
||||
RestartSec = "10s";
|
||||
RestrictAddressFamilies = [
|
||||
"AF_INET"
|
||||
"AF_INET6"
|
||||
"AF_UNIX"
|
||||
];
|
||||
RestrictNamespaces = true;
|
||||
RestrictRealtime = true;
|
||||
SystemCallArchitectures = "native";
|
||||
SystemCallFilter = [
|
||||
"@system-service"
|
||||
"@resources"
|
||||
"~@privileged"
|
||||
];
|
||||
NoNewPrivileges = true;
|
||||
UMask = "0077";
|
||||
};
|
||||
};
|
||||
|
||||
environment.systemPackages = [ cfg.package ];
|
||||
};
|
||||
}
|
||||
@@ -39,6 +39,18 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
extraOptions = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
example = [
|
||||
"--log-level"
|
||||
"debug"
|
||||
];
|
||||
description = ''
|
||||
Specifies extra command line arguments to pass to mealie (Gunicorn).
|
||||
'';
|
||||
};
|
||||
|
||||
credentialsFile = lib.mkOption {
|
||||
type = with lib.types; nullOr path;
|
||||
default = null;
|
||||
@@ -84,7 +96,7 @@ in
|
||||
DynamicUser = true;
|
||||
User = "mealie";
|
||||
ExecStartPre = "${pkg}/libexec/init_db";
|
||||
ExecStart = "${lib.getExe pkg} -b ${cfg.listenAddress}:${builtins.toString cfg.port}";
|
||||
ExecStart = "${lib.getExe pkg} -b ${cfg.listenAddress}:${builtins.toString cfg.port} ${lib.escapeShellArgs cfg.extraOptions}";
|
||||
EnvironmentFile = lib.mkIf (cfg.credentialsFile != null) cfg.credentialsFile;
|
||||
StateDirectory = "mealie";
|
||||
StandardOutput = "journal";
|
||||
|
||||
@@ -702,7 +702,6 @@ in
|
||||
FORCE_HTTPS = builtins.toString cfg.forceHttps;
|
||||
ENABLE_UPDATES = builtins.toString cfg.enableUpdateCheck;
|
||||
WEB_CONCURRENCY = builtins.toString cfg.concurrency;
|
||||
MAXIMUM_IMPORT_SIZE = builtins.toString cfg.maximumImportSize;
|
||||
DEBUG = cfg.debugOutput;
|
||||
GOOGLE_ANALYTICS_ID = lib.optionalString (cfg.googleAnalyticsId != null) cfg.googleAnalyticsId;
|
||||
SENTRY_DSN = lib.optionalString (cfg.sentryDsn != null) cfg.sentryDsn;
|
||||
@@ -715,6 +714,7 @@ in
|
||||
RATE_LIMITER_DURATION_WINDOW = builtins.toString cfg.rateLimiter.durationWindow;
|
||||
|
||||
FILE_STORAGE = cfg.storage.storageType;
|
||||
FILE_STORAGE_IMPORT_MAX_SIZE = builtins.toString cfg.maximumImportSize;
|
||||
FILE_STORAGE_UPLOAD_MAX_SIZE = builtins.toString cfg.storage.uploadMaxSize;
|
||||
FILE_STORAGE_LOCAL_ROOT_DIR = cfg.storage.localRootDir;
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ let
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-Host $host;
|
||||
proxy_set_header X-Forwarded-Server $host;
|
||||
proxy_set_header X-Forwarded-Server $hostname;
|
||||
'';
|
||||
|
||||
proxyCachePathConfig = concatStringsSep "\n" (
|
||||
|
||||
@@ -16,9 +16,7 @@ in
|
||||
services.xserver.windowManager.bspwm = {
|
||||
enable = mkEnableOption "bspwm";
|
||||
|
||||
package = mkPackageOption pkgs "bspwm" {
|
||||
example = "bspwm-unstable";
|
||||
};
|
||||
package = mkPackageOption pkgs "bspwm" { };
|
||||
configFile = mkOption {
|
||||
type = with types; nullOr path;
|
||||
example = literalExpression ''"''${pkgs.bspwm}/share/doc/bspwm/examples/bspwmrc"'';
|
||||
@@ -30,9 +28,7 @@ in
|
||||
};
|
||||
|
||||
sxhkd = {
|
||||
package = mkPackageOption pkgs "sxhkd" {
|
||||
example = "sxhkd-unstable";
|
||||
};
|
||||
package = mkPackageOption pkgs "sxhkd" { };
|
||||
configFile = mkOption {
|
||||
type = with types; nullOr path;
|
||||
example = literalExpression ''"''${pkgs.bspwm}/share/doc/bspwm/examples/sxhkdrc"'';
|
||||
@@ -52,9 +48,11 @@ in
|
||||
start = ''
|
||||
export _JAVA_AWT_WM_NONREPARENTING=1
|
||||
SXHKD_SHELL=/bin/sh ${cfg.sxhkd.package}/bin/sxhkd ${
|
||||
optionalString (cfg.sxhkd.configFile != null) "-c \"${cfg.sxhkd.configFile}\""
|
||||
optionalString (cfg.sxhkd.configFile != null) "-c ${escapeShellArg cfg.sxhkd.configFile}"
|
||||
} &
|
||||
${cfg.package}/bin/bspwm ${
|
||||
optionalString (cfg.configFile != null) "-c ${escapeShellArg cfg.configFile}"
|
||||
} &
|
||||
${cfg.package}/bin/bspwm ${optionalString (cfg.configFile != null) "-c \"${cfg.configFile}\""} &
|
||||
waitPID=$!
|
||||
'';
|
||||
};
|
||||
@@ -62,9 +60,6 @@ in
|
||||
};
|
||||
|
||||
imports = [
|
||||
(mkRemovedOptionModule [ "services" "xserver" "windowManager" "bspwm-unstable" "enable" ]
|
||||
"Use services.xserver.windowManager.bspwm.enable and set services.xserver.windowManager.bspwm.package to pkgs.bspwm-unstable to use the unstable version of bspwm."
|
||||
)
|
||||
(mkRemovedOptionModule [
|
||||
"services"
|
||||
"xserver"
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
cfg = config.system.nixos-init;
|
||||
in
|
||||
{
|
||||
options.system.nixos-init = {
|
||||
enable = lib.mkEnableOption ''
|
||||
nixos-init, a system for bashless initialization.
|
||||
|
||||
This doesn't use any `activationScripts`. Anything set in these options is
|
||||
a no-op here.
|
||||
'';
|
||||
|
||||
package = lib.mkPackageOption pkgs "nixos-init" { };
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion = config.boot.initrd.systemd.enable;
|
||||
message = "nixos-init can only be used with systemd initrd";
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -14,12 +14,15 @@ let
|
||||
${
|
||||
if config.boot.initrd.enable && config.boot.initrd.systemd.enable then
|
||||
''
|
||||
cp ${config.system.build.bootStage2} $out/prepare-root
|
||||
substituteInPlace $out/prepare-root --subst-var-by systemConfig $out
|
||||
# This must not be a symlink or the abs_path of the grub builder for the tests
|
||||
# will resolve the symlink and we end up with a path that doesn't point to a
|
||||
# system closure.
|
||||
cp "$systemd/lib/systemd/systemd" $out/init
|
||||
|
||||
${lib.optionalString (!config.system.nixos-init.enable) ''
|
||||
cp ${config.system.build.bootStage2} $out/prepare-root
|
||||
substituteInPlace $out/prepare-root --subst-var-by systemConfig $out
|
||||
''}
|
||||
''
|
||||
else
|
||||
''
|
||||
|
||||
@@ -8,6 +8,7 @@ import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import warnings
|
||||
import json
|
||||
from typing import NamedTuple, Any, Sequence
|
||||
@@ -64,7 +65,10 @@ class SystemIdentifier(NamedTuple):
|
||||
|
||||
def copy_if_not_exists(source: Path, dest: Path) -> None:
|
||||
if not dest.exists():
|
||||
shutil.copyfile(source, dest)
|
||||
tmpfd, tmppath = tempfile.mkstemp(dir=dest.parent, prefix=dest.name, suffix='.tmp.')
|
||||
shutil.copyfile(source, tmppath)
|
||||
os.fsync(tmpfd)
|
||||
shutil.move(tmppath, dest)
|
||||
|
||||
|
||||
def generation_dir(profile: str | None, generation: int) -> Path:
|
||||
|
||||
@@ -562,7 +562,12 @@ in
|
||||
"${pkgs.glibc}/lib/libnss_files.so.2"
|
||||
|
||||
# Resolving sysroot symlinks without code exec
|
||||
"${pkgs.chroot-realpath}/bin/chroot-realpath"
|
||||
"${config.system.nixos-init.package}/bin/chroot-realpath"
|
||||
# Find the etc paths
|
||||
"${config.system.nixos-init.package}/bin/find-etc"
|
||||
]
|
||||
++ lib.optionals config.system.nixos-init.enable [
|
||||
"${config.system.nixos-init.package}/bin/initrd-init"
|
||||
]
|
||||
++ jobScripts
|
||||
++ map (c: builtins.removeAttrs c [ "text" ]) (builtins.attrValues cfg.contents);
|
||||
@@ -594,7 +599,7 @@ in
|
||||
) cfg.automounts
|
||||
);
|
||||
|
||||
services.initrd-find-nixos-closure = {
|
||||
services.initrd-find-nixos-closure = lib.mkIf (!config.system.nixos-init.enable) {
|
||||
description = "Find NixOS closure";
|
||||
|
||||
unitConfig = {
|
||||
@@ -615,7 +620,12 @@ in
|
||||
script = # bash
|
||||
''
|
||||
set -uo pipefail
|
||||
export PATH="/bin:${cfg.package.util-linux}/bin:${pkgs.chroot-realpath}/bin"
|
||||
export PATH="/bin:${
|
||||
lib.makeBinPath [
|
||||
cfg.package.util-linux
|
||||
config.system.nixos-init.package
|
||||
]
|
||||
}"
|
||||
|
||||
# Figure out what closure to boot
|
||||
closure=
|
||||
@@ -670,7 +680,7 @@ in
|
||||
}
|
||||
];
|
||||
|
||||
services.initrd-nixos-activation = {
|
||||
services.initrd-nixos-activation = lib.mkIf (!config.system.nixos-init.enable) {
|
||||
after = [ "initrd-switch-root.target" ];
|
||||
requiredBy = [ "initrd-switch-root.service" ];
|
||||
before = [ "initrd-switch-root.service" ];
|
||||
@@ -697,17 +707,46 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
# This will either call systemctl with the new init as the last parameter (which
|
||||
# is the case when not booting a NixOS system) or with an empty string, causing
|
||||
# systemd to bypass its verification code that checks whether the next file is a systemd
|
||||
# and using its compiled-in value
|
||||
services.initrd-switch-root.serviceConfig = {
|
||||
EnvironmentFile = "-/etc/switch-root.conf";
|
||||
ExecStart = [
|
||||
""
|
||||
''systemctl --no-block switch-root /sysroot "''${NEW_INIT}"''
|
||||
];
|
||||
};
|
||||
services.initrd-switch-root =
|
||||
if config.system.nixos-init.enable then
|
||||
{
|
||||
path = [
|
||||
cfg.package
|
||||
cfg.package.util-linux
|
||||
config.system.nixos-init.package
|
||||
];
|
||||
environment = {
|
||||
FIRMWARE = "${config.hardware.firmware}/lib/firmware";
|
||||
MODPROBE_BINARY = "${pkgs.kmod}/bin/modprobe";
|
||||
NIX_STORE_MOUNT_OPTS = lib.concatStringsSep "," config.boot.nixStoreMountOpts;
|
||||
}
|
||||
// lib.optionalAttrs (config.environment.usrbinenv != null) {
|
||||
ENV_BINARY = config.environment.usrbinenv;
|
||||
}
|
||||
// lib.optionalAttrs (config.environment.binsh != null) {
|
||||
SH_BINARY = config.environment.binsh;
|
||||
};
|
||||
serviceConfig = {
|
||||
ExecStart = [
|
||||
""
|
||||
"${config.system.nixos-init.package}/bin/initrd-init"
|
||||
];
|
||||
};
|
||||
}
|
||||
else
|
||||
# This will either call systemctl with the new init as the last parameter (which
|
||||
# is the case when not booting a NixOS system) or with an empty string, causing
|
||||
# systemd to bypass its verification code that checks whether the next file is a systemd
|
||||
# and using its compiled-in value
|
||||
{
|
||||
serviceConfig = {
|
||||
EnvironmentFile = "-/etc/switch-root.conf";
|
||||
ExecStart = [
|
||||
""
|
||||
''systemctl --no-block switch-root /sysroot "''${NEW_INIT}"''
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
services.panic-on-fail = {
|
||||
wantedBy = [ "emergency.target" ];
|
||||
|
||||
@@ -144,15 +144,10 @@
|
||||
{
|
||||
initrd-find-etc = {
|
||||
description = "Find the path to the etc metadata image and based dir";
|
||||
requires = [
|
||||
config.boot.initrd.systemd.services.initrd-find-nixos-closure.name
|
||||
];
|
||||
after = [
|
||||
config.boot.initrd.systemd.services.initrd-find-nixos-closure.name
|
||||
];
|
||||
before = [ "shutdown.target" ];
|
||||
conflicts = [ "shutdown.target" ];
|
||||
requiredBy = [ "initrd.target" ];
|
||||
path = [ config.system.nixos-init.package ];
|
||||
unitConfig = {
|
||||
DefaultDependencies = false;
|
||||
RequiresMountsFor = "/sysroot/nix/store";
|
||||
@@ -160,20 +155,8 @@
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
ExecStart = "${config.system.nixos-init.package}/bin/find-etc";
|
||||
};
|
||||
|
||||
script = # bash
|
||||
''
|
||||
set -uo pipefail
|
||||
|
||||
closure="$(realpath /nixos-closure)"
|
||||
|
||||
metadata_image="$(${pkgs.chroot-realpath}/bin/chroot-realpath /sysroot "$closure/etc-metadata-image")"
|
||||
ln -s "/sysroot$metadata_image" /etc-metadata-image
|
||||
|
||||
basedir="$(${pkgs.chroot-realpath}/bin/chroot-realpath /sysroot "$closure/etc-basedir")"
|
||||
ln -s "/sysroot$basedir" /etc-basedir
|
||||
'';
|
||||
};
|
||||
}
|
||||
];
|
||||
|
||||
@@ -175,25 +175,6 @@ let
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
assertions = [
|
||||
{
|
||||
assertion =
|
||||
let
|
||||
kernel = config.boot.kernelPackages.kernel;
|
||||
in
|
||||
(
|
||||
kernel.kernelAtLeast "6.7"
|
||||
|| (lib.elem (kernel.structuredExtraConfig.BCACHEFS_FS or null) [
|
||||
lib.kernel.module
|
||||
lib.kernel.yes
|
||||
(lib.kernel.option lib.kernel.yes)
|
||||
])
|
||||
);
|
||||
|
||||
message = "Linux 6.7-rc1 at minimum or a custom linux kernel with bcachefs support is required";
|
||||
}
|
||||
];
|
||||
in
|
||||
|
||||
{
|
||||
@@ -230,7 +211,32 @@ in
|
||||
config = lib.mkIf (config.boot.supportedFilesystems.bcachefs or false) (
|
||||
lib.mkMerge [
|
||||
{
|
||||
inherit assertions;
|
||||
assertions = [
|
||||
{
|
||||
assertion =
|
||||
let
|
||||
kernel = config.boot.kernelPackages.kernel;
|
||||
in
|
||||
(
|
||||
kernel.kernelAtLeast "6.7"
|
||||
|| (lib.elem (kernel.structuredExtraConfig.BCACHEFS_FS or null) [
|
||||
lib.kernel.module
|
||||
lib.kernel.yes
|
||||
(lib.kernel.option lib.kernel.yes)
|
||||
])
|
||||
);
|
||||
|
||||
message = "Linux 6.7-rc1 at minimum or a custom linux kernel with bcachefs support is required";
|
||||
}
|
||||
];
|
||||
|
||||
warnings = lib.mkIf config.boot.kernelPackages.bcachefs.meta.broken [
|
||||
''
|
||||
Using unmaintained in-tree bcachefs kernel module. This
|
||||
will be removed in 26.05. Please use a kernel supported
|
||||
by the out-of-tree module package.
|
||||
''
|
||||
];
|
||||
|
||||
# Bcachefs upstream recommends using the latest kernel
|
||||
boot.kernelPackages = lib.mkDefault pkgs.linuxPackages_latest;
|
||||
@@ -239,6 +245,10 @@ in
|
||||
system.fsPackages = [ cfg.package ];
|
||||
services.udev.packages = [ cfg.package ];
|
||||
|
||||
boot.extraModulePackages = lib.optionals (!config.boot.kernelPackages.bcachefs.meta.broken) [
|
||||
config.boot.kernelPackages.bcachefs
|
||||
];
|
||||
|
||||
systemd = {
|
||||
packages = [ cfg.package ];
|
||||
services = lib.mapAttrs' (mkUnits "") (
|
||||
@@ -248,7 +258,6 @@ in
|
||||
}
|
||||
|
||||
(lib.mkIf ((config.boot.initrd.supportedFilesystems.bcachefs or false) || (bootFs != { })) {
|
||||
inherit assertions;
|
||||
boot.initrd.availableKernelModules = [
|
||||
"bcachefs"
|
||||
"sha256"
|
||||
|
||||
@@ -134,6 +134,7 @@ let
|
||||
INCUS_LXC_HOOK = "${cfg.lxcPackage}/share/lxc/hooks";
|
||||
INCUS_LXC_TEMPLATE_CONFIG = "${pkgs.lxcfs}/share/lxc/config";
|
||||
INCUS_USBIDS_PATH = "${pkgs.hwdata}/share/hwdata/usb.ids";
|
||||
INCUS_AGENT_PATH = "${cfg.package}/share/agent";
|
||||
PATH = lib.mkForce serverBinPath;
|
||||
}
|
||||
(lib.mkIf (cfg.ui.enable) { "INCUS_UI" = cfg.ui.package; })
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
{ lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
name = "nixos-init";
|
||||
|
||||
meta.maintainers = with lib.maintainers; [ nikstur ];
|
||||
|
||||
nodes.machine =
|
||||
{ modulesPath, ... }:
|
||||
{
|
||||
imports = [
|
||||
"${modulesPath}/profiles/perlless.nix"
|
||||
];
|
||||
virtualisation.mountHostNixStore = false;
|
||||
virtualisation.useNixStoreImage = true;
|
||||
|
||||
system.nixos-init.enable = true;
|
||||
# Forcibly set this to only these specific values.
|
||||
boot.nixStoreMountOpts = lib.mkForce [
|
||||
"nodev"
|
||||
"nosuid"
|
||||
];
|
||||
};
|
||||
|
||||
testScript =
|
||||
{ nodes, ... }: # python
|
||||
''
|
||||
with subtest("init"):
|
||||
with subtest("/nix/store is mounted with the correct options"):
|
||||
findmnt_output = machine.succeed("findmnt --direction backward --first-only --noheadings --output OPTIONS /nix/store").strip()
|
||||
print(findmnt_output)
|
||||
t.assertIn("nodev", findmnt_output)
|
||||
t.assertIn("nosuid", findmnt_output)
|
||||
|
||||
t.assertEqual("${nodes.machine.system.build.toplevel}", machine.succeed("readlink /run/booted-system").strip())
|
||||
|
||||
with subtest("activation"):
|
||||
t.assertEqual("${nodes.machine.system.build.toplevel}", machine.succeed("readlink /run/current-system").strip())
|
||||
t.assertEqual("${nodes.machine.hardware.firmware}/lib/firmware", machine.succeed("cat /sys/module/firmware_class/parameters/path").strip())
|
||||
t.assertEqual("${pkgs.kmod}/bin/modprobe", machine.succeed("cat /proc/sys/kernel/modprobe").strip())
|
||||
t.assertEqual("${nodes.machine.environment.usrbinenv}", machine.succeed("readlink /usr/bin/env").strip())
|
||||
t.assertEqual("${nodes.machine.environment.binsh}", machine.succeed("readlink /bin/sh").strip())
|
||||
|
||||
machine.wait_for_unit("multi-user.target")
|
||||
with subtest("systemd state passing"):
|
||||
systemd_analyze_output = machine.succeed("systemd-analyze")
|
||||
print(systemd_analyze_output)
|
||||
t.assertIn("(initrd)", systemd_analyze_output, "systemd-analyze has no information about the initrd")
|
||||
|
||||
ps_output = machine.succeed("ps ax -o command | grep systemd | head -n 1")
|
||||
print(ps_output)
|
||||
t.assertIn("--deserialize", ps_output, "--deserialize flag wasn't passed to systemd")
|
||||
'';
|
||||
}
|
||||
@@ -190,6 +190,7 @@ in
|
||||
activation-etc-overlay-mutable = runTest ./activation/etc-overlay-mutable.nix;
|
||||
activation-lib = pkgs.callPackage ../modules/system/activation/lib/test.nix { };
|
||||
activation-nix-channel = runTest ./activation/nix-channel.nix;
|
||||
activation-nixos-init = runTest ./activation/nixos-init.nix;
|
||||
activation-perlless = runTest ./activation/perlless.nix;
|
||||
activation-var = runTest ./activation/var.nix;
|
||||
actual = runTest ./actual.nix;
|
||||
@@ -429,6 +430,7 @@ in
|
||||
cyrus-imap = runTest ./cyrus-imap.nix;
|
||||
dae = runTest ./dae.nix;
|
||||
darling-dmg = runTest ./darling-dmg.nix;
|
||||
dashy = runTest ./web-apps/dashy.nix;
|
||||
davis = runTest ./davis.nix;
|
||||
db-rest = runTest ./db-rest.nix;
|
||||
dconf = runTest ./dconf.nix;
|
||||
@@ -746,6 +748,7 @@ in
|
||||
invoiceplane = runTest ./invoiceplane.nix;
|
||||
iodine = runTest ./iodine.nix;
|
||||
iosched = runTest ./iosched.nix;
|
||||
ipget = runTest ./ipget.nix;
|
||||
ipv6 = runTest ./ipv6.nix;
|
||||
iscsi-multipath-root = runTest ./iscsi-multipath-root.nix;
|
||||
iscsi-root = runTest ./iscsi-root.nix;
|
||||
@@ -1073,6 +1076,7 @@ in
|
||||
ntpd = runTest ./ntpd.nix;
|
||||
ntpd-rs = runTest ./ntpd-rs.nix;
|
||||
nvidia-container-toolkit = runTest ./nvidia-container-toolkit.nix;
|
||||
nvme-rs = runTest ./nvme-rs.nix;
|
||||
nvmetcfg = runTest ./nvmetcfg.nix;
|
||||
nyxt = runTest ./nyxt.nix;
|
||||
nzbget = runTest ./nzbget.nix;
|
||||
@@ -1584,6 +1588,7 @@ in
|
||||
vengi-tools = runTest ./vengi-tools.nix;
|
||||
victorialogs = import ./victorialogs { inherit runTest; };
|
||||
victoriametrics = import ./victoriametrics { inherit runTest; };
|
||||
victoriatraces = import ./victoriatraces { inherit runTest; };
|
||||
vikunja = runTest ./vikunja.nix;
|
||||
virtualbox = handleTestOn [ "x86_64-linux" ] ./virtualbox.nix { };
|
||||
vm-variant = handleTest ./vm-variant.nix { };
|
||||
|
||||
@@ -17,7 +17,7 @@ in
|
||||
{ ... }:
|
||||
{
|
||||
virtualisation = {
|
||||
diskSize = 3072;
|
||||
diskSize = 4000;
|
||||
docker.enable = true;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -57,19 +57,19 @@ in
|
||||
type = "custom";
|
||||
status = {
|
||||
source = "script";
|
||||
cmd = "/bin/sh -c 'echo charger status A'";
|
||||
cmd = "/bin/sh -c 'echo A'";
|
||||
};
|
||||
enabled = {
|
||||
source = "script";
|
||||
cmd = "/bin/sh -c 'echo charger enabled state false'";
|
||||
cmd = "/bin/sh -c 'echo false'";
|
||||
};
|
||||
enable = {
|
||||
source = "script";
|
||||
cmd = "/bin/sh -c 'echo set charger enabled state true'";
|
||||
cmd = "/bin/sh -c 'echo true'";
|
||||
};
|
||||
maxcurrent = {
|
||||
source = "script";
|
||||
cmd = "/bin/sh -c 'echo set charger max current 7200'";
|
||||
cmd = "/bin/sh -c 'echo 7200'";
|
||||
};
|
||||
}
|
||||
];
|
||||
|
||||
@@ -176,7 +176,7 @@ let
|
||||
+ "Please contact your site administrator.'"
|
||||
)
|
||||
server.succeed(
|
||||
"su -l forgejo -c 'GITEA_WORK_DIR=/var/lib/forgejo gitea admin user create "
|
||||
"su -l forgejo -c 'GITEA_WORK_DIR=/var/lib/forgejo forgejo admin user create "
|
||||
+ "--username test --password totallysafe --email test@localhost --must-change-password=false'"
|
||||
)
|
||||
|
||||
@@ -223,7 +223,7 @@ let
|
||||
|
||||
with subtest("Testing runner registration and action workflow"):
|
||||
server.succeed(
|
||||
"su -l forgejo -c 'GITEA_WORK_DIR=/var/lib/forgejo gitea actions generate-runner-token' | sed 's/^/TOKEN=/' | tee /var/lib/forgejo/runner_token"
|
||||
"su -l forgejo -c 'GITEA_WORK_DIR=/var/lib/forgejo forgejo actions generate-runner-token' | sed 's/^/TOKEN=/' | tee /var/lib/forgejo/runner_token"
|
||||
)
|
||||
server.succeed("${serverSystem}/specialisation/runner/bin/switch-to-configuration test")
|
||||
server.wait_for_unit("gitea-runner-test.service")
|
||||
|
||||
@@ -774,7 +774,7 @@ let
|
||||
config.boot.bootspec.package
|
||||
]
|
||||
++ optionals clevisTest [ pkgs.klibc ]
|
||||
++ optional systemdStage1 pkgs.chroot-realpath;
|
||||
++ optional systemdStage1 config.system.nixos-init.package;
|
||||
|
||||
nix.settings = {
|
||||
substituters = mkForce [ ];
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
{ lib, ... }:
|
||||
{
|
||||
name = "ipget";
|
||||
meta.maintainers = with lib.maintainers; [
|
||||
Luflosi
|
||||
];
|
||||
|
||||
nodes.machine =
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
services.kubo.enable = true;
|
||||
environment.systemPackages = with pkgs; [ ipget ];
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
start_all()
|
||||
|
||||
with subtest("Add file to IPFS"):
|
||||
ipfs_hash = machine.succeed(
|
||||
"echo -n fnord | ipfs add --quieter"
|
||||
)
|
||||
|
||||
with subtest("Download the file with ipget"):
|
||||
machine.succeed(f"ipget --output file.txt /ipfs/{ipfs_hash}")
|
||||
contents = machine.succeed("cat file.txt")
|
||||
assert contents == "fnord", f"Unexpected file contents: {contents}"
|
||||
'';
|
||||
}
|
||||
@@ -4,10 +4,10 @@
|
||||
# 3. jenkins service not started on slave node
|
||||
# 4. declarative jobs can be added and removed
|
||||
|
||||
{ pkgs, ... }:
|
||||
{ config, lib, ... }:
|
||||
{
|
||||
name = "jenkins";
|
||||
meta = with pkgs.lib.maintainers; {
|
||||
meta = with lib.maintainers; {
|
||||
maintainers = [
|
||||
bjornfor
|
||||
];
|
||||
@@ -60,7 +60,7 @@
|
||||
};
|
||||
|
||||
specialisation.noJenkinsJobs.configuration = {
|
||||
services.jenkins.jobBuilder.nixJobs = pkgs.lib.mkForce [ ];
|
||||
services.jenkins.jobBuilder.nixJobs = lib.mkForce [ ];
|
||||
};
|
||||
|
||||
# should have no effect
|
||||
@@ -89,6 +89,7 @@
|
||||
testScript =
|
||||
{ nodes, ... }:
|
||||
let
|
||||
pkgs = config.node.pkgs;
|
||||
configWithoutJobs = "${nodes.master.system.build.toplevel}/specialisation/noJenkinsJobs";
|
||||
jenkinsPort = nodes.master.services.jenkins.port;
|
||||
jenkinsUrl = "http://localhost:${toString jenkinsPort}";
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
{ lib, pkgs, ... }:
|
||||
{
|
||||
name = "nvme-rs";
|
||||
|
||||
meta = {
|
||||
maintainers = with lib.maintainers; [ liberodark ];
|
||||
};
|
||||
|
||||
nodes = {
|
||||
monitor =
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
virtualisation = {
|
||||
emptyDiskImages = [
|
||||
512
|
||||
512
|
||||
];
|
||||
};
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
nvme-rs
|
||||
jq
|
||||
];
|
||||
|
||||
services.nvme-rs = {
|
||||
enable = true;
|
||||
package = pkgs.nvme-rs;
|
||||
settings = {
|
||||
check_interval_secs = 60;
|
||||
|
||||
thresholds = {
|
||||
temp_warning = 50;
|
||||
temp_critical = 60;
|
||||
wear_warning = 15;
|
||||
wear_critical = 40;
|
||||
spare_warning = 60;
|
||||
error_threshold = 100;
|
||||
};
|
||||
|
||||
email = {
|
||||
smtp_server = "mail";
|
||||
smtp_port = 25;
|
||||
smtp_username = "nvme-monitor@example.com";
|
||||
smtp_password_file = "/run/secrets/smtp-password";
|
||||
from = "NVMe Monitor <nvme-monitor@example.com>";
|
||||
to = "admin@example.com";
|
||||
use_tls = false;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
"f /run/secrets/smtp-password 0600 root root - testpassword"
|
||||
];
|
||||
|
||||
networking.firewall.enable = false;
|
||||
};
|
||||
|
||||
mail =
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
services.postfix = {
|
||||
enable = true;
|
||||
hostname = "mail";
|
||||
domain = "example.com";
|
||||
|
||||
networks = [ "0.0.0.0/0" ];
|
||||
relayDomains = [ "example.com" ];
|
||||
localRecipients = [ "admin" ];
|
||||
|
||||
settings = {
|
||||
main = {
|
||||
inet_interfaces = "all";
|
||||
inet_protocols = "ipv4";
|
||||
smtpd_recipient_restrictions = "permit_mynetworks";
|
||||
smtpd_relay_restrictions = "permit_mynetworks";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
users.users.admin = {
|
||||
isNormalUser = true;
|
||||
home = "/home/admin";
|
||||
};
|
||||
|
||||
networking.firewall = {
|
||||
allowedTCPPorts = [ 25 ];
|
||||
};
|
||||
};
|
||||
|
||||
client =
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
virtualisation = {
|
||||
emptyDiskImages = [ 256 ];
|
||||
};
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
nvme-rs
|
||||
jq
|
||||
];
|
||||
|
||||
environment.etc."nvme-rs/config.toml".text = ''
|
||||
check_interval_secs = 3600
|
||||
|
||||
[thresholds]
|
||||
temp_warning = 55
|
||||
temp_critical = 65
|
||||
wear_warning = 20
|
||||
wear_critical = 50
|
||||
spare_warning = 50
|
||||
error_threshold = 5000
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
testScript =
|
||||
{ nodes, ... }:
|
||||
''
|
||||
import json
|
||||
|
||||
start_all()
|
||||
|
||||
for machine in [monitor, mail, client]:
|
||||
machine.wait_for_unit("multi-user.target")
|
||||
|
||||
mail.wait_for_unit("postfix.service")
|
||||
mail.wait_for_open_port(25)
|
||||
|
||||
client.succeed("nvme-rs check || true")
|
||||
client.succeed("nvme-rs check --config /etc/nvme-rs/config.toml || true")
|
||||
|
||||
output = client.succeed("nvme-rs check --format json || echo '[]'")
|
||||
data = json.loads(output)
|
||||
assert isinstance(data, list), "JSON output should be a list"
|
||||
|
||||
monitor.wait_for_unit("nvme-rs.service")
|
||||
monitor.succeed("systemctl is-active nvme-rs.service")
|
||||
|
||||
config_path = monitor.succeed(
|
||||
"systemctl status nvme-rs | grep -oE '/nix/store[^ ]*nvme-rs.toml' | head -1"
|
||||
).strip()
|
||||
|
||||
if config_path:
|
||||
monitor.succeed(f"grep 'check_interval_secs = 60' {config_path}")
|
||||
monitor.succeed(f"grep 'temp_warning = 50' {config_path}")
|
||||
monitor.succeed(f"grep 'smtp_server = \"mail\"' {config_path}")
|
||||
|
||||
logs = monitor.succeed("journalctl -u nvme-rs.service -n 20 --no-pager")
|
||||
assert "Starting NVMe monitor daemon" in logs or "Check interval" in logs
|
||||
|
||||
monitor.succeed("test -f /run/secrets/smtp-password")
|
||||
|
||||
monitor.succeed("nc -zv mail 25")
|
||||
monitor.fail("nvme-rs daemon --config /nonexistent.toml 2>&1 | grep -E 'Failed to read'")
|
||||
'';
|
||||
}
|
||||
+10
-39
@@ -1,15 +1,4 @@
|
||||
{ pkgs, lib, ... }:
|
||||
let
|
||||
accessKey = "BKIKJAA5BMMU2RHO6IBB";
|
||||
secretKey = "V7f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12";
|
||||
secretKeyFile = pkgs.writeText "outline-secret-key" ''
|
||||
${secretKey}
|
||||
'';
|
||||
rootCredentialsFile = pkgs.writeText "minio-credentials-full" ''
|
||||
MINIO_ROOT_USER=${accessKey}
|
||||
MINIO_ROOT_PASSWORD=${secretKey}
|
||||
'';
|
||||
in
|
||||
{ lib, ... }:
|
||||
{
|
||||
name = "outline";
|
||||
|
||||
@@ -17,37 +6,19 @@ in
|
||||
|
||||
node.pkgsReadOnly = false;
|
||||
|
||||
nodes.outline =
|
||||
{ pkgs, config, ... }:
|
||||
{
|
||||
nixpkgs.config.allowUnfree = true;
|
||||
environment.systemPackages = [ pkgs.minio-client ];
|
||||
services.outline = {
|
||||
enable = true;
|
||||
forceHttps = false;
|
||||
storage = {
|
||||
inherit accessKey secretKeyFile;
|
||||
uploadBucketUrl = "http://localhost:9000";
|
||||
uploadBucketName = "outline";
|
||||
region = config.services.minio.region;
|
||||
};
|
||||
};
|
||||
services.minio = {
|
||||
enable = true;
|
||||
inherit rootCredentialsFile;
|
||||
nodes.outline = {
|
||||
virtualisation.memorySize = 2 * 1024;
|
||||
nixpkgs.config.allowUnfree = true;
|
||||
services.outline = {
|
||||
enable = true;
|
||||
forceHttps = false;
|
||||
storage = {
|
||||
storageType = "local";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
machine.wait_for_unit("minio.service")
|
||||
machine.wait_for_open_port(9000)
|
||||
|
||||
# Create a test bucket on the server
|
||||
machine.succeed(
|
||||
"mc alias set minio http://localhost:9000 ${accessKey} ${secretKey} --api s3v4"
|
||||
)
|
||||
machine.succeed("mc mb minio/outline")
|
||||
|
||||
outline.wait_for_unit("outline.service")
|
||||
outline.wait_for_open_port(3000)
|
||||
outline.succeed("curl --fail http://localhost:3000/")
|
||||
|
||||
@@ -16,7 +16,7 @@ let
|
||||
nodes.machine =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
environment.systemPackages = [ pkgs.pg-dump-anon ];
|
||||
environment.systemPackages = [ (pkgs.pg-dump-anon.override { postgresql = package; }) ];
|
||||
services.postgresql = {
|
||||
inherit package;
|
||||
enable = true;
|
||||
@@ -39,7 +39,7 @@ let
|
||||
create table player(id serial, name text, points int);
|
||||
insert into player(id,name,points) values (1,'Foo', 23);
|
||||
insert into player(id,name,points) values (2,'Bar',42);
|
||||
security label for anon on column player.name is 'MASKED WITH FUNCTION anon.fake_last_name();';
|
||||
security label for anon on column player.name is 'MASKED WITH FUNCTION anon.fake_last_name()';
|
||||
security label for anon on column player.points is 'MASKED WITH VALUE NULL';
|
||||
''}"
|
||||
)
|
||||
@@ -61,7 +61,7 @@ let
|
||||
COPY public.player ...
|
||||
1,Shields,
|
||||
2,Salazar,
|
||||
\.
|
||||
\\.
|
||||
|
||||
in the given dump (the commas are tabs in case of pg_dump).
|
||||
Extract the CSV lines and split by `sep`.
|
||||
|
||||
@@ -1615,6 +1615,21 @@ let
|
||||
'';
|
||||
};
|
||||
|
||||
storagebox = {
|
||||
exporterConfig = {
|
||||
enable = true;
|
||||
tokenFile = "/tmp/faketoken";
|
||||
};
|
||||
exporterTest = ''
|
||||
succeed(
|
||||
'echo faketoken > /tmp/faketoken'
|
||||
)
|
||||
wait_for_unit("prometheus-storagebox-exporter.service")
|
||||
wait_for_open_port(9509)
|
||||
succeed("curl -sSf localhost:9509/metrics | grep 'process_open_fds'")
|
||||
'';
|
||||
};
|
||||
|
||||
snmp = {
|
||||
exporterConfig = {
|
||||
enable = true;
|
||||
|
||||
@@ -36,10 +36,6 @@ let
|
||||
|
||||
darktile.pkg = p: p.darktile;
|
||||
|
||||
eterm.pkg = p: p.eterm;
|
||||
eterm.executable = "Eterm";
|
||||
eterm.pinkValue = "#D40055";
|
||||
|
||||
germinal.pkg = p: p.germinal;
|
||||
|
||||
ghostty.pkg = p: p.ghostty;
|
||||
@@ -70,8 +66,6 @@ let
|
||||
|
||||
mlterm.pkg = p: p.mlterm;
|
||||
|
||||
mrxvt.pkg = p: p.mrxvt;
|
||||
|
||||
qterminal.pkg = p: p.lxqt.qterminal;
|
||||
qterminal.kill = true;
|
||||
|
||||
|
||||
@@ -369,8 +369,7 @@ in
|
||||
"journalctl -o cat -u vector.service | grep 'component_type=dnstap' | grep 'Listening... path=\"${dnstapSocket}\"'"
|
||||
)
|
||||
|
||||
machine.wait_for_file("${dnstapSocket}")
|
||||
machine.succeed("test 770 -eq $(stat -c '%a' ${dnstapSocket})")
|
||||
machine.wait_for_open_unix_socket("${dnstapSocket}")
|
||||
|
||||
dnsclient.systemctl("start network-online.target")
|
||||
dnsclient.wait_for_unit("network-online.target")
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
{ runTest }:
|
||||
{
|
||||
service-endpoints = runTest ./service-endpoints.nix;
|
||||
otlp-ingestion = runTest ./otlp-ingestion.nix;
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
{ lib, pkgs, ... }:
|
||||
let
|
||||
# Simple protobuf trace
|
||||
traceGenerator = pkgs.writeScriptBin "trace-generator" ''
|
||||
#!${
|
||||
pkgs.python3.withPackages (
|
||||
ps: with ps; [
|
||||
requests
|
||||
protobuf
|
||||
opentelemetry-proto
|
||||
opentelemetry-api
|
||||
opentelemetry-sdk
|
||||
opentelemetry-exporter-otlp-proto-http
|
||||
]
|
||||
)
|
||||
}/bin/python3
|
||||
|
||||
import time
|
||||
from opentelemetry import trace
|
||||
from opentelemetry.sdk.trace import TracerProvider
|
||||
from opentelemetry.sdk.trace.export import BatchSpanProcessor
|
||||
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
|
||||
from opentelemetry.sdk.resources import Resource
|
||||
|
||||
resource = Resource.create({
|
||||
"service.name": "test-service",
|
||||
"service.version": "1.0.0"
|
||||
})
|
||||
|
||||
provider = TracerProvider(resource=resource)
|
||||
|
||||
otlp_exporter = OTLPSpanExporter(
|
||||
endpoint="http://localhost:10428/insert/opentelemetry/v1/traces",
|
||||
headers={},
|
||||
)
|
||||
|
||||
provider.add_span_processor(BatchSpanProcessor(otlp_exporter))
|
||||
trace.set_tracer_provider(provider)
|
||||
|
||||
tracer = trace.get_tracer("test-tracer", "1.0.0")
|
||||
|
||||
# Test span
|
||||
with tracer.start_as_current_span("test-span") as span:
|
||||
span.set_attribute("http.method", "GET")
|
||||
span.set_attribute("http.url", "/test")
|
||||
time.sleep(0.1)
|
||||
|
||||
provider.force_flush()
|
||||
|
||||
print("Test trace sent")
|
||||
'';
|
||||
in
|
||||
{
|
||||
name = "victoriatraces-otlp-ingestion";
|
||||
meta.maintainers = with lib.maintainers; [ cmacrae ];
|
||||
|
||||
nodes.machine =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
services.victoriatraces = {
|
||||
enable = true;
|
||||
retentionPeriod = "1d";
|
||||
};
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
curl
|
||||
jq
|
||||
traceGenerator
|
||||
];
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
machine.wait_for_unit("victoriatraces.service")
|
||||
machine.wait_for_open_port(10428)
|
||||
machine.succeed("curl --fail http://localhost:10428/")
|
||||
machine.succeed("trace-generator")
|
||||
|
||||
# Wait for trace to be indexed
|
||||
machine.wait_until_succeeds("""
|
||||
curl -s 'http://localhost:10428/select/jaeger/api/services' | \
|
||||
jq -e '.data[] | select(. == "test-service")'
|
||||
""", timeout=10)
|
||||
|
||||
# Query for traces from our test service
|
||||
machine.succeed("""
|
||||
curl -s 'http://localhost:10428/select/jaeger/api/traces?service=test-service' | \
|
||||
jq -e '.data[0].spans[0].operationName' | grep -q 'test-span'
|
||||
""")
|
||||
|
||||
# Verify the trace has the expected attributes
|
||||
machine.succeed("""
|
||||
curl -s 'http://localhost:10428/select/jaeger/api/traces?service=test-service' | \
|
||||
jq -e '.data[0].spans[0].tags[] | select(.key == "http.method") | .value == "GET"'
|
||||
""")
|
||||
'';
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
{ lib, ... }:
|
||||
{
|
||||
name = "victoriatraces-service-endpoints";
|
||||
meta.maintainers = with lib.maintainers; [ cmacrae ];
|
||||
|
||||
nodes.machine =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
services.victoriatraces = {
|
||||
enable = true;
|
||||
extraOptions = [
|
||||
"-loggerLevel=WARN"
|
||||
];
|
||||
};
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
curl
|
||||
jq
|
||||
];
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
machine.wait_for_unit("victoriatraces.service")
|
||||
machine.wait_for_open_port(10428)
|
||||
|
||||
with subtest("Service endpoints are accessible"):
|
||||
machine.succeed("curl --fail http://localhost:10428/")
|
||||
machine.succeed("curl --fail http://localhost:10428/select/vmui")
|
||||
machine.succeed("curl --fail http://localhost:10428/metrics | grep -E '^(vm_|process_)'")
|
||||
machine.succeed("curl --fail http://localhost:10428/select/jaeger/api/services")
|
||||
|
||||
with subtest("OTLP trace ingestion endpoint accepts requests"):
|
||||
machine.succeed("curl --fail -X POST http://localhost:10428/insert/opentelemetry/v1/traces -H 'Content-Type: application/x-protobuf'")
|
||||
machine.succeed("test -d /var/lib/victoriatraces")
|
||||
'';
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
{ pkgs, lib, ... }:
|
||||
let
|
||||
|
||||
customSettings = {
|
||||
pageInfo = {
|
||||
title = "My Custom Dashy Title";
|
||||
};
|
||||
|
||||
sections = [
|
||||
{
|
||||
name = "My Section";
|
||||
items = [
|
||||
{
|
||||
name = "NixOS";
|
||||
url = "https://nixos.org";
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
customSettingsYaml = (pkgs.formats.yaml_1_1 { }).generate "custom-conf.yaml" customSettings;
|
||||
in
|
||||
{
|
||||
name = "dashy";
|
||||
meta.maintainers = [ lib.maintainers.therealgramdalf ];
|
||||
|
||||
defaults =
|
||||
{ config, ... }:
|
||||
{
|
||||
services.dashy = {
|
||||
enable = true;
|
||||
virtualHost = {
|
||||
enableNginx = true;
|
||||
domain = "dashy.local";
|
||||
};
|
||||
};
|
||||
|
||||
networking.extraHosts = "127.0.0.1 dashy.local";
|
||||
|
||||
services.nginx.virtualHosts."${config.services.dashy.virtualHost.domain}".listen = [
|
||||
{
|
||||
addr = "127.0.0.1";
|
||||
port = 80;
|
||||
}
|
||||
];
|
||||
};
|
||||
nodes = {
|
||||
machine = { };
|
||||
|
||||
machine-custom = {
|
||||
services.dashy.settings = customSettings;
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
start_all()
|
||||
machine.wait_for_unit("nginx.service")
|
||||
machine.wait_for_open_port(80)
|
||||
|
||||
actual = machine.succeed("curl -v --stderr - http://dashy.local/", timeout=10)
|
||||
expected = "<title>Dashy</title>"
|
||||
assert expected in actual, \
|
||||
f"unexpected reply from Dashy, expected: '{expected}' got: '{actual}'"
|
||||
|
||||
machine_custom.wait_for_unit("nginx.service")
|
||||
machine_custom.wait_for_open_port(80)
|
||||
|
||||
actual_custom = machine_custom.succeed("curl -s --stderr - http://dashy.local/conf.yml", timeout=10).strip()
|
||||
expected_custom = machine_custom.succeed("cat ${customSettingsYaml}").strip()
|
||||
|
||||
assert expected_custom == actual_custom, \
|
||||
f"unexpected reply from Dashy, expected: '{expected_custom}' got: '{actual_custom}'"
|
||||
'';
|
||||
}
|
||||
@@ -24,7 +24,7 @@ stdenv.mkDerivation rec {
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "zevv";
|
||||
repo = pname;
|
||||
repo = "bucklespring";
|
||||
rev = "v${version}";
|
||||
sha256 = "0prhqibivxzmz90k79zpwx3c97h8wa61rk5ihi9a5651mnc46mna";
|
||||
};
|
||||
|
||||
@@ -14,7 +14,7 @@ stdenv.mkDerivation rec {
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "jketterl";
|
||||
repo = pname;
|
||||
repo = "codecserver";
|
||||
rev = version;
|
||||
sha256 = "sha256-JzaVBFl3JsFNDm4gy1qOKA9uAjUjNeMiI39l5gfH0aE=";
|
||||
};
|
||||
|
||||
@@ -8,17 +8,14 @@
|
||||
glib,
|
||||
}:
|
||||
|
||||
let
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "deadbeef-mpris2-plugin";
|
||||
version = "1.16";
|
||||
in
|
||||
stdenv.mkDerivation {
|
||||
inherit pname version;
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "DeaDBeeF-Player";
|
||||
repo = pname;
|
||||
rev = "v${version}";
|
||||
repo = "deadbeef-mpris2-plugin";
|
||||
rev = "v${finalAttrs.version}";
|
||||
hash = "sha256-f6iHgwLdzQJJEquyuUQGWFfOfpjH/Hxh9IqQ5HkYrog=";
|
||||
};
|
||||
|
||||
@@ -39,4 +36,4 @@ stdenv.mkDerivation {
|
||||
platforms = platforms.linux;
|
||||
maintainers = [ ];
|
||||
};
|
||||
}
|
||||
})
|
||||
|
||||
@@ -28,16 +28,17 @@
|
||||
sonicSupport ? true,
|
||||
speechPlayerSupport ? true,
|
||||
ucdSupport ? false,
|
||||
buildPackages,
|
||||
}:
|
||||
|
||||
let
|
||||
version = "1.52.0";
|
||||
version = "1.52.0.1-unstable-2025-09-09";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "espeak-ng";
|
||||
repo = "espeak-ng";
|
||||
tag = version;
|
||||
hash = "sha256-mmh5QPSVD5YQ0j16R+bEL5vcyWLtTNOJ/irBNzWY3ro=";
|
||||
rev = "0d451f8c1c6ae837418b823bd9c4cbc574ea9ff5";
|
||||
hash = "sha256-wpPi+YjSLhsEWfE3KEbL4A7o48qtz9fLRZ/u4xGOM2g=";
|
||||
};
|
||||
|
||||
ucd-tools = stdenv.mkDerivation {
|
||||
@@ -59,22 +60,14 @@ in
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "espeak-ng";
|
||||
version = "1.52.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "espeak-ng";
|
||||
repo = "espeak-ng";
|
||||
tag = version;
|
||||
hash = "sha256-mmh5QPSVD5YQ0j16R+bEL5vcyWLtTNOJ/irBNzWY3ro=";
|
||||
};
|
||||
inherit version src;
|
||||
|
||||
patches = [
|
||||
# https://github.com/espeak-ng/espeak-ng/pull/2274
|
||||
./libsonic.patch
|
||||
(fetchpatch {
|
||||
name = "espeak-ng-text-to-phonemes-with-terminator.patch";
|
||||
url = "https://github.com/espeak-ng/espeak-ng/commit/2108b1e8ae02f49cc909894a1024efdfde6682fd.patch";
|
||||
hash = "sha256-XjEc1r7F88xZOfeUey0R6Xv6vu4Wy8GtWxXFG2NTf9g=";
|
||||
name = "libsonic.patch";
|
||||
url = "https://github.com/espeak-ng/espeak-ng/commit/83e646e711af608fafa8c01dd812cd29e073f644.patch";
|
||||
hash = "sha256-UHuURyqRy/JVYYJH5EI5J2cpBfCNeTE24sMmheb+D2Q=";
|
||||
})
|
||||
]
|
||||
++ lib.optionals mbrolaSupport [
|
||||
@@ -98,6 +91,10 @@ stdenv.mkDerivation rec {
|
||||
ronn
|
||||
makeWrapper
|
||||
which
|
||||
]
|
||||
# Provide a native espeak-ng when cross compiling so intonations can be built
|
||||
++ lib.optionals (stdenv.hostPlatform != stdenv.buildPlatform) [
|
||||
buildPackages.espeak-ng
|
||||
];
|
||||
|
||||
buildInputs =
|
||||
@@ -113,6 +110,10 @@ stdenv.mkDerivation rec {
|
||||
(lib.cmakeBool "USE_LIBSONIC" sonicSupport)
|
||||
(lib.cmakeBool "USE_MBROLA" mbrolaSupport)
|
||||
(lib.cmakeBool "USE_SPEECHPLAYER" speechPlayerSupport)
|
||||
]
|
||||
# Point CMake to the native build’s binary dir when cross compiling
|
||||
++ lib.optionals (stdenv.hostPlatform != stdenv.buildPlatform) [
|
||||
"-DNativeBuild_DIR=${buildPackages.espeak-ng}/bin/"
|
||||
];
|
||||
|
||||
postInstall = lib.optionalString stdenv.hostPlatform.isLinux ''
|
||||
@@ -127,7 +128,7 @@ stdenv.mkDerivation rec {
|
||||
meta = {
|
||||
description = "Speech synthesizer that supports more than hundred languages and accents";
|
||||
homepage = "https://github.com/espeak-ng/espeak-ng";
|
||||
changelog = "https://github.com/espeak-ng/espeak-ng/blob/${src.tag}/ChangeLog.md";
|
||||
changelog = "https://github.com/espeak-ng/espeak-ng/blob/${src.rev}/ChangeLog.md";
|
||||
license = lib.licenses.gpl3Plus;
|
||||
maintainers = with lib.maintainers; [ aske ];
|
||||
platforms = lib.platforms.all;
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
diff --git a/cmake/deps.cmake b/cmake/deps.cmake
|
||||
index b63ced21..2cd1727b 100644
|
||||
--- a/cmake/deps.cmake
|
||||
+++ b/cmake/deps.cmake
|
||||
@@ -13,20 +13,22 @@ endif(PTHREAD_LIB)
|
||||
if (MBROLA_BIN)
|
||||
set(HAVE_MBROLA ON)
|
||||
endif(MBROLA_BIN)
|
||||
-if (SONIC_LIB AND SONIC_INC)
|
||||
- set(HAVE_LIBSONIC ON)
|
||||
-else()
|
||||
- FetchContent_Declare(sonic-git
|
||||
- GIT_REPOSITORY https://github.com/waywardgeek/sonic.git
|
||||
- GIT_TAG fbf75c3d6d846bad3bb3d456cbc5d07d9fd8c104
|
||||
- )
|
||||
- FetchContent_MakeAvailable(sonic-git)
|
||||
- FetchContent_GetProperties(sonic-git)
|
||||
- add_library(sonic OBJECT ${sonic-git_SOURCE_DIR}/sonic.c)
|
||||
- target_include_directories(sonic PUBLIC ${sonic-git_SOURCE_DIR})
|
||||
- set(HAVE_LIBSONIC ON)
|
||||
- set(SONIC_LIB sonic)
|
||||
- set(SONIC_INC ${sonic-git_SOURCE_DIR})
|
||||
+if (USE_LIBSONIC)
|
||||
+ if (SONIC_LIB AND SONIC_INC)
|
||||
+ set(HAVE_LIBSONIC ON)
|
||||
+ else()
|
||||
+ FetchContent_Declare(sonic-git
|
||||
+ GIT_REPOSITORY https://github.com/waywardgeek/sonic.git
|
||||
+ GIT_TAG fbf75c3d6d846bad3bb3d456cbc5d07d9fd8c104
|
||||
+ )
|
||||
+ FetchContent_MakeAvailable(sonic-git)
|
||||
+ FetchContent_GetProperties(sonic-git)
|
||||
+ add_library(sonic OBJECT ${sonic-git_SOURCE_DIR}/sonic.c)
|
||||
+ target_include_directories(sonic PUBLIC ${sonic-git_SOURCE_DIR})
|
||||
+ set(HAVE_LIBSONIC ON)
|
||||
+ set(SONIC_LIB sonic)
|
||||
+ set(SONIC_INC ${sonic-git_SOURCE_DIR})
|
||||
+ endif()
|
||||
endif()
|
||||
if (PCAUDIO_LIB AND PCAUDIO_INC)
|
||||
set(HAVE_LIBPCAUDIO ON)
|
||||
@@ -12,13 +12,13 @@
|
||||
wxGTK,
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
stdenv.mkDerivation {
|
||||
pname = "freqtweak";
|
||||
version = "unstable-2019-08-03";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "essej";
|
||||
repo = pname;
|
||||
repo = "freqtweak";
|
||||
rev = "d4205337558d36657a4ee6b3afb29358aa18c0fd";
|
||||
sha256 = "10cq27mdgrrc54a40al9ahi0wqd0p2c1wxbdg518q8pzfxaxs5fi";
|
||||
};
|
||||
|
||||
@@ -14,7 +14,7 @@ buildPythonApplication rec {
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "manolomartinez";
|
||||
repo = pname;
|
||||
repo = "greg";
|
||||
tag = "v${version}";
|
||||
sha256 = "sha256-o4+tXVJTgT52JyJOC+Glr2cvZjbTaZL8TIsmz+A4vE4=";
|
||||
};
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
qtbase,
|
||||
libjack2,
|
||||
}:
|
||||
mkDerivation rec {
|
||||
mkDerivation {
|
||||
pname = "jack_autoconnect";
|
||||
|
||||
# It does not have any versions (yet?)
|
||||
@@ -15,7 +15,7 @@ mkDerivation rec {
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "kripton";
|
||||
repo = pname;
|
||||
repo = "jack_autoconnect";
|
||||
rev = "fe0c8f69149e30979e067646f80b9d326341c02b";
|
||||
sha256 = "sha256-imvNc498Q2W9RKmiOoNepSoJzIv2tGvFG6hx+seiifw=";
|
||||
};
|
||||
|
||||
@@ -20,7 +20,7 @@ stdenv.mkDerivation rec {
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "portaloffreedom";
|
||||
repo = pname;
|
||||
repo = "pipecontrol";
|
||||
rev = "v${version}";
|
||||
sha256 = "sha256-WvQFmoEaxnkI61wPldSnMAoPAxNtI399hdHb/9bkPqc=";
|
||||
};
|
||||
|
||||
@@ -22,8 +22,8 @@ pythonPackages.buildPythonApplication rec {
|
||||
version = "1.6.2";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = pname;
|
||||
repo = pname;
|
||||
owner = "pithos";
|
||||
repo = "pithos";
|
||||
tag = version;
|
||||
hash = "sha256-3j6IoMi30BQ8WHK4BxbsW+/3XZx7rBFd47EBENa2GiQ=";
|
||||
};
|
||||
|
||||
@@ -54,7 +54,7 @@ stdenv.mkDerivation rec {
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "ebruck";
|
||||
repo = pname;
|
||||
repo = "radiotray-ng";
|
||||
tag = "v${version}";
|
||||
hash = "sha256-rRD/IfVnOxowr2mO2BB2hcHK5ByZSmTbcgYdULogYUs=";
|
||||
};
|
||||
|
||||
@@ -38,17 +38,17 @@ let
|
||||
in
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "reaper";
|
||||
version = "7.45";
|
||||
version = "7.46";
|
||||
|
||||
src = fetchurl {
|
||||
url = url_for_platform version stdenv.hostPlatform.qemuArch;
|
||||
hash =
|
||||
if stdenv.hostPlatform.isDarwin then
|
||||
"sha256-plXLOJcQbZlSGPgNdjNEPS2pZ9almrmNzxYfhOZGXjg="
|
||||
"sha256-uGWeaRl01rH7+RrMoqAv85EiKJ3/qUFiQVt1zILVJTQ="
|
||||
else
|
||||
{
|
||||
x86_64-linux = "sha256-pOPL8HoAAFNDq6L3SC/OygDtqqYVvfkWwVA6qv1xZPs=";
|
||||
aarch64-linux = "sha256-rclLjAiG8aLsVinghpPZJiPU4Iq5jQ6s2H0+du+a9Ts=";
|
||||
x86_64-linux = "sha256-8XEy7IXjjw7WbPxpxFP30ivMgi0/iWbtljuYCQ2BzDI=";
|
||||
aarch64-linux = "sha256-H+lvnpaKESad0DI9l1AexFxgwPi9EidVR1Gh6oITjHQ=";
|
||||
}
|
||||
.${stdenv.hostPlatform.system};
|
||||
};
|
||||
|
||||
@@ -24,13 +24,13 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "snapcast";
|
||||
version = "0.32.3";
|
||||
version = "0.33.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "badaix";
|
||||
repo = "snapcast";
|
||||
rev = "v${version}";
|
||||
hash = "sha256-pGON2Nh7GgcGvMUNI3nWstm5Q9R+VW9eEi4IE6KkFBo=";
|
||||
hash = "sha256-YJwRY9OLoRiRRJVFnXw9AEsDo2W8elpH4LIUScKjpT0=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
|
||||
@@ -52,14 +52,14 @@ stdenv.mkDerivation rec {
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "sonic-pi-net";
|
||||
repo = pname;
|
||||
repo = "sonic-pi";
|
||||
rev = "v${version}";
|
||||
hash = "sha256-JMextQY0jLShWmqRQoVAbqIzDhA1mOzI7vfsG7+jjX0=";
|
||||
};
|
||||
|
||||
mixFodDeps = beamPackages.fetchMixDeps {
|
||||
inherit version;
|
||||
pname = "mix-deps-${pname}";
|
||||
pname = "mix-deps-sonic-pi";
|
||||
mixEnv = "test";
|
||||
src = "${src}/app/server/beam/tau";
|
||||
hash = "sha256-7wqFI3f0CRVrXK2IUguqHNANwKMmTak/Xh9nr624TXc=";
|
||||
|
||||
@@ -71,8 +71,8 @@ stdenv.mkDerivation rec {
|
||||
version = "3.0.6";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = pname;
|
||||
repo = pname;
|
||||
owner = "zynaddsubfx";
|
||||
repo = "zynaddsubfx";
|
||||
tag = version;
|
||||
fetchSubmodules = true;
|
||||
hash = "sha256-0siAx141DZx39facXWmKbsi0rHBNpobApTdey07EcXg=";
|
||||
|
||||
@@ -44,7 +44,7 @@ stdenv.mkDerivation rec {
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "canonical";
|
||||
repo = pname;
|
||||
repo = "lightdm";
|
||||
rev = version;
|
||||
sha256 = "sha256-ttNlhWD0Ran4d3QvZ+PxbFbSUGMkfrRm+hJdQxIDJvM=";
|
||||
};
|
||||
|
||||
@@ -24,8 +24,8 @@ let
|
||||
sha256Hash = "sha256-S8KK/EGev0v03fVywIkD6Ym3LrciGKXJVorzyZ1ljdQ=";
|
||||
};
|
||||
latestVersion = {
|
||||
version = "2025.1.4.4"; # "Android Studio Narwhal 4 Feature Drop | 2025.1.4 Canary 4"
|
||||
sha256Hash = "sha256-Cp5oZiCJJDffZRAg7CPNNR82Mn6k4QpjQtqMiokFAws=";
|
||||
version = "2025.1.4.5"; # "Android Studio Narwhal 4 Feature Drop | 2025.1.4 Canary 5"
|
||||
sha256Hash = "sha256-gfhlcvqMDZPOmKgfp4XNrq9rucN1ZnY6WuBZYHYspGg=";
|
||||
};
|
||||
in
|
||||
{
|
||||
|
||||
@@ -25,10 +25,6 @@ lib.packagesFromDirectoryRecursive {
|
||||
|
||||
elpaca = callPackage ./manual-packages/elpaca { inherit (pkgs) git; };
|
||||
|
||||
emacs-application-framework = callPackage ./manual-packages/emacs-application-framework {
|
||||
inherit (pkgs) git;
|
||||
};
|
||||
|
||||
lsp-bridge = callPackage ./manual-packages/lsp-bridge {
|
||||
inherit (pkgs)
|
||||
basedpyright
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
fetchFromGitHub,
|
||||
# Dependencies
|
||||
aria2,
|
||||
# Java Script dependency
|
||||
# JavaScript dependency
|
||||
nodejs,
|
||||
fetchNpmDeps,
|
||||
npmHooks,
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
# Dependencies
|
||||
delta,
|
||||
ripgrep,
|
||||
# Java Script dependency
|
||||
# JavaScript dependency
|
||||
nodejs,
|
||||
fetchNpmDeps,
|
||||
npmHooks,
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
lib,
|
||||
melpaBuild,
|
||||
fetchFromGitHub,
|
||||
# Java Script dependency
|
||||
# JavaScript dependency
|
||||
nodejs,
|
||||
fetchNpmDeps,
|
||||
npmHooks,
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
lib,
|
||||
melpaBuild,
|
||||
fetchFromGitHub,
|
||||
# Java Script dependency
|
||||
# JavaScript dependency
|
||||
nodejs,
|
||||
fetchNpmDeps,
|
||||
npmHooks,
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
lib,
|
||||
melpaBuild,
|
||||
fetchFromGitHub,
|
||||
# Java Script dependency
|
||||
# JavaScript dependency
|
||||
nodejs,
|
||||
fetchNpmDeps,
|
||||
npmHooks,
|
||||
|
||||
-2
@@ -10,7 +10,6 @@
|
||||
# Emacs dependencies
|
||||
all-the-icons,
|
||||
# Other dependencies
|
||||
git,
|
||||
nodejs,
|
||||
wmctrl,
|
||||
xdotool,
|
||||
@@ -45,7 +44,6 @@ let
|
||||
otherPackageLists = [
|
||||
(
|
||||
[
|
||||
git
|
||||
nodejs
|
||||
wmctrl
|
||||
]
|
||||
@@ -357,6 +357,9 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
]
|
||||
++ lib.optionals withNS [
|
||||
librsvg
|
||||
]
|
||||
++ lib.optionals (variant == "macport") [
|
||||
librsvg
|
||||
];
|
||||
|
||||
# Emacs needs to find movemail at run time, see info (emacs) Movemail
|
||||
|
||||
@@ -11,10 +11,10 @@
|
||||
"clion": {
|
||||
"update-channel": "CLion RELEASE",
|
||||
"url-template": "https://download.jetbrains.com/cpp/CLion-{version}.tar.gz",
|
||||
"version": "2025.2.1",
|
||||
"sha256": "f50e1a1e5172f652efdb7d72dc8c2a6222564671983b0c8b03caa68c56630648",
|
||||
"url": "https://download.jetbrains.com/cpp/CLion-2025.2.1.tar.gz",
|
||||
"build_number": "252.25557.127"
|
||||
"version": "2025.2.2",
|
||||
"sha256": "47b84f1c853a63586743b28834dfd6b949672f3b0a7a67435907a7ef51730606",
|
||||
"url": "https://download.jetbrains.com/cpp/CLion-2025.2.2.tar.gz",
|
||||
"build_number": "252.26199.153"
|
||||
},
|
||||
"datagrip": {
|
||||
"update-channel": "DataGrip RELEASE",
|
||||
@@ -35,34 +35,34 @@
|
||||
"gateway": {
|
||||
"update-channel": "Gateway RELEASE",
|
||||
"url-template": "https://download.jetbrains.com/idea/gateway/JetBrainsGateway-{version}.tar.gz",
|
||||
"version": "2025.2.1",
|
||||
"sha256": "bf96140b50e890215104f0806f5f160161a2889ebf7362a3b936ca0eb304bf67",
|
||||
"url": "https://download.jetbrains.com/idea/gateway/JetBrainsGateway-2025.2.1.tar.gz",
|
||||
"build_number": "252.25557.133"
|
||||
"version": "2025.2.2",
|
||||
"sha256": "d1e8c8c61da42adcc9300a2a005830db386698912071eace9813a5c170a9fff8",
|
||||
"url": "https://download.jetbrains.com/idea/gateway/JetBrainsGateway-2025.2.2.tar.gz",
|
||||
"build_number": "252.26199.160"
|
||||
},
|
||||
"goland": {
|
||||
"update-channel": "GoLand RELEASE",
|
||||
"url-template": "https://download.jetbrains.com/go/goland-{version}.tar.gz",
|
||||
"version": "2025.2.1.2",
|
||||
"sha256": "66cb93202b9c4bc34688838a8c39e0d0ed876d01ca651d9f2b0d455139b27169",
|
||||
"url": "https://download.jetbrains.com/go/goland-2025.2.1.2.tar.gz",
|
||||
"build_number": "252.25557.189"
|
||||
"version": "2025.2.2",
|
||||
"sha256": "e5816136312a419b67cdfab203bd30e305cb2f8952eea76445e908c01f3113c0",
|
||||
"url": "https://download.jetbrains.com/go/goland-2025.2.2.tar.gz",
|
||||
"build_number": "252.26199.158"
|
||||
},
|
||||
"idea-community": {
|
||||
"update-channel": "IntelliJ IDEA RELEASE",
|
||||
"url-template": "https://download.jetbrains.com/idea/ideaIC-{version}.tar.gz",
|
||||
"version": "2025.2.1",
|
||||
"sha256": "fc76fe8b6693b18d5d7385bb005f415287dbd5897b313287b9ef56dd0df9d5bd",
|
||||
"url": "https://download.jetbrains.com/idea/ideaIC-2025.2.1.tar.gz",
|
||||
"build_number": "252.25557.131"
|
||||
"version": "2025.2.2",
|
||||
"sha256": "3f1adc095bf78f0949e3f62f6cf02be0c5c9e6528271f16caa3baa041e637664",
|
||||
"url": "https://download.jetbrains.com/idea/ideaIC-2025.2.2.tar.gz",
|
||||
"build_number": "252.26199.169"
|
||||
},
|
||||
"idea-ultimate": {
|
||||
"update-channel": "IntelliJ IDEA RELEASE",
|
||||
"url-template": "https://download.jetbrains.com/idea/ideaIU-{version}.tar.gz",
|
||||
"version": "2025.2.1",
|
||||
"sha256": "ac36d03153894f393fb65c05f57be4722c2a2374d03b7374b37baf856705d5fd",
|
||||
"url": "https://download.jetbrains.com/idea/ideaIU-2025.2.1.tar.gz",
|
||||
"build_number": "252.25557.131"
|
||||
"version": "2025.2.2",
|
||||
"sha256": "7150ece389a4bc8649f68b103018edeeb09205559671549410ded11de523da62",
|
||||
"url": "https://download.jetbrains.com/idea/ideaIU-2025.2.2.tar.gz",
|
||||
"build_number": "252.26199.169"
|
||||
},
|
||||
"mps": {
|
||||
"update-channel": "MPS RELEASE",
|
||||
@@ -75,10 +75,10 @@
|
||||
"phpstorm": {
|
||||
"update-channel": "PhpStorm RELEASE",
|
||||
"url-template": "https://download.jetbrains.com/webide/PhpStorm-{version}.tar.gz",
|
||||
"version": "2025.2.1",
|
||||
"sha256": "0cc9235210dc09fb54602f176de881c4f2b6852d7a5f2ae9f7750d83a3ffa8f6",
|
||||
"url": "https://download.jetbrains.com/webide/PhpStorm-2025.2.1.tar.gz",
|
||||
"build_number": "252.25557.128",
|
||||
"version": "2025.2.2",
|
||||
"sha256": "1010c4cfed0d74a0088c80e966c0ea75ed1238dc5b8ae25111e8be3e06bde741",
|
||||
"url": "https://download.jetbrains.com/webide/PhpStorm-2025.2.2.tar.gz",
|
||||
"build_number": "252.26199.163",
|
||||
"version-major-minor": "2022.3"
|
||||
},
|
||||
"pycharm-community": {
|
||||
@@ -100,34 +100,34 @@
|
||||
"rider": {
|
||||
"update-channel": "Rider RELEASE",
|
||||
"url-template": "https://download.jetbrains.com/rider/JetBrains.Rider-{version}.tar.gz",
|
||||
"version": "2025.2.1",
|
||||
"sha256": "bdccdc837ab6683082bef1ab76b7699ee3ed44ec6fe037db5be7161837ca0701",
|
||||
"url": "https://download.jetbrains.com/rider/JetBrains.Rider-2025.2.1.tar.gz",
|
||||
"build_number": "252.25557.182"
|
||||
"version": "2025.2.2",
|
||||
"sha256": "1ebffac91d70f8ce64567955de35738bb52d5e81b45d8c67dd494ff3fa0301df",
|
||||
"url": "https://download.jetbrains.com/rider/JetBrains.Rider-2025.2.2.tar.gz",
|
||||
"build_number": "252.26199.154"
|
||||
},
|
||||
"ruby-mine": {
|
||||
"update-channel": "RubyMine RELEASE",
|
||||
"url-template": "https://download.jetbrains.com/ruby/RubyMine-{version}.tar.gz",
|
||||
"version": "2025.2.1",
|
||||
"sha256": "fbed517b4c60623c04b045dd6cfff08105783a56dd1b831b164a72aa2ead6a38",
|
||||
"url": "https://download.jetbrains.com/ruby/RubyMine-2025.2.1.tar.gz",
|
||||
"build_number": "252.25557.135"
|
||||
"version": "2025.2.2",
|
||||
"sha256": "f103c2c5ab074aace1ce4678d32fa80d8521a25bb6497130d1185662244cf46d",
|
||||
"url": "https://download.jetbrains.com/ruby/RubyMine-2025.2.2.tar.gz",
|
||||
"build_number": "252.26199.157"
|
||||
},
|
||||
"rust-rover": {
|
||||
"update-channel": "RustRover RELEASE",
|
||||
"url-template": "https://download.jetbrains.com/rustrover/RustRover-{version}.tar.gz",
|
||||
"version": "2025.2.1",
|
||||
"sha256": "19fde47a5c3c8e1b21b402c3351018eed64e2cff575f32a86c884168b522074a",
|
||||
"url": "https://download.jetbrains.com/rustrover/RustRover-2025.2.1.tar.gz",
|
||||
"build_number": "252.25557.134"
|
||||
"version": "2025.2.2",
|
||||
"sha256": "cc2cfd0af3967a5ce65af5064ccac03bfb2ee2a1ed7e18e8a2c1a009a6d3721c",
|
||||
"url": "https://download.jetbrains.com/rustrover/RustRover-2025.2.2.tar.gz",
|
||||
"build_number": "252.26199.159"
|
||||
},
|
||||
"webstorm": {
|
||||
"update-channel": "WebStorm RELEASE",
|
||||
"url-template": "https://download.jetbrains.com/webstorm/WebStorm-{version}.tar.gz",
|
||||
"version": "2025.2.1",
|
||||
"sha256": "8d03ae22e4bac309edbf58310b4fc758fedaee5dc065467eeda005fac5217d2b",
|
||||
"url": "https://download.jetbrains.com/webstorm/WebStorm-2025.2.1.tar.gz",
|
||||
"build_number": "252.25557.126"
|
||||
"version": "2025.2.2",
|
||||
"sha256": "8bb3bed5c670514ced8614b29848c5d3b7ff4f4e86056cf5cdc5930951c87ff6",
|
||||
"url": "https://download.jetbrains.com/webstorm/WebStorm-2025.2.2.tar.gz",
|
||||
"build_number": "252.26199.162"
|
||||
},
|
||||
"writerside": {
|
||||
"update-channel": "Writerside EAP",
|
||||
@@ -150,10 +150,10 @@
|
||||
"clion": {
|
||||
"update-channel": "CLion RELEASE",
|
||||
"url-template": "https://download.jetbrains.com/cpp/CLion-{version}-aarch64.tar.gz",
|
||||
"version": "2025.2.1",
|
||||
"sha256": "7fff28163607d3a6da7eceb788829cb81ac03e90f694d7b2c0a47b2821b47f4a",
|
||||
"url": "https://download.jetbrains.com/cpp/CLion-2025.2.1-aarch64.tar.gz",
|
||||
"build_number": "252.25557.127"
|
||||
"version": "2025.2.2",
|
||||
"sha256": "b8749bbec247544767023a25b9e955a9cd462c573e1d08a24ef68c864d5d6859",
|
||||
"url": "https://download.jetbrains.com/cpp/CLion-2025.2.2-aarch64.tar.gz",
|
||||
"build_number": "252.26199.153"
|
||||
},
|
||||
"datagrip": {
|
||||
"update-channel": "DataGrip RELEASE",
|
||||
@@ -174,34 +174,34 @@
|
||||
"gateway": {
|
||||
"update-channel": "Gateway RELEASE",
|
||||
"url-template": "https://download.jetbrains.com/idea/gateway/JetBrainsGateway-{version}-aarch64.tar.gz",
|
||||
"version": "2025.2.1",
|
||||
"sha256": "8c4a8c0d15f5afbb17f0ea54e4455f4d69407536459d0d4986fce966e8ae9290",
|
||||
"url": "https://download.jetbrains.com/idea/gateway/JetBrainsGateway-2025.2.1-aarch64.tar.gz",
|
||||
"build_number": "252.25557.133"
|
||||
"version": "2025.2.2",
|
||||
"sha256": "331407afc012f97b5a80fcfced59e256222549038bfe028c7d00b0b4793ebc4a",
|
||||
"url": "https://download.jetbrains.com/idea/gateway/JetBrainsGateway-2025.2.2-aarch64.tar.gz",
|
||||
"build_number": "252.26199.160"
|
||||
},
|
||||
"goland": {
|
||||
"update-channel": "GoLand RELEASE",
|
||||
"url-template": "https://download.jetbrains.com/go/goland-{version}-aarch64.tar.gz",
|
||||
"version": "2025.2.1.2",
|
||||
"sha256": "c8059924c4e92756905114c6e6806c59d070b332c87bc966237474363f212876",
|
||||
"url": "https://download.jetbrains.com/go/goland-2025.2.1.2-aarch64.tar.gz",
|
||||
"build_number": "252.25557.189"
|
||||
"version": "2025.2.2",
|
||||
"sha256": "5873b53e586c1f376ec6e159c962be3400f0be964f8f0d542b55b4a99ff6c870",
|
||||
"url": "https://download.jetbrains.com/go/goland-2025.2.2-aarch64.tar.gz",
|
||||
"build_number": "252.26199.158"
|
||||
},
|
||||
"idea-community": {
|
||||
"update-channel": "IntelliJ IDEA RELEASE",
|
||||
"url-template": "https://download.jetbrains.com/idea/ideaIC-{version}-aarch64.tar.gz",
|
||||
"version": "2025.2.1",
|
||||
"sha256": "ca454bcfe40196adacf12c726d8d44876d8a03c88884f7a08715e5562a45d1a2",
|
||||
"url": "https://download.jetbrains.com/idea/ideaIC-2025.2.1-aarch64.tar.gz",
|
||||
"build_number": "252.25557.131"
|
||||
"version": "2025.2.2",
|
||||
"sha256": "3ea855820772e36be4b37dd9e503e4fee9b1877dcb614b5baa36819370fa0208",
|
||||
"url": "https://download.jetbrains.com/idea/ideaIC-2025.2.2-aarch64.tar.gz",
|
||||
"build_number": "252.26199.169"
|
||||
},
|
||||
"idea-ultimate": {
|
||||
"update-channel": "IntelliJ IDEA RELEASE",
|
||||
"url-template": "https://download.jetbrains.com/idea/ideaIU-{version}-aarch64.tar.gz",
|
||||
"version": "2025.2.1",
|
||||
"sha256": "bf292cf0a2822c4b697e4d1e6a7c049c6b91f8cab3d457259d52fd65bbdcdea9",
|
||||
"url": "https://download.jetbrains.com/idea/ideaIU-2025.2.1-aarch64.tar.gz",
|
||||
"build_number": "252.25557.131"
|
||||
"version": "2025.2.2",
|
||||
"sha256": "d40c5fa210a28a23b9e1d736057a711b41c785e32841f5a27969074feee5df4d",
|
||||
"url": "https://download.jetbrains.com/idea/ideaIU-2025.2.2-aarch64.tar.gz",
|
||||
"build_number": "252.26199.169"
|
||||
},
|
||||
"mps": {
|
||||
"update-channel": "MPS RELEASE",
|
||||
@@ -214,10 +214,10 @@
|
||||
"phpstorm": {
|
||||
"update-channel": "PhpStorm RELEASE",
|
||||
"url-template": "https://download.jetbrains.com/webide/PhpStorm-{version}-aarch64.tar.gz",
|
||||
"version": "2025.2.1",
|
||||
"sha256": "68f4d7f3ca81e25023a08a34d1163fdcf0ef8f803cbdd9bc81efdcadd2ccf7ae",
|
||||
"url": "https://download.jetbrains.com/webide/PhpStorm-2025.2.1-aarch64.tar.gz",
|
||||
"build_number": "252.25557.128",
|
||||
"version": "2025.2.2",
|
||||
"sha256": "edc147816c4fed704206d3ca03e7fcdefde23208599d7732eb0a22af2af6f2ff",
|
||||
"url": "https://download.jetbrains.com/webide/PhpStorm-2025.2.2-aarch64.tar.gz",
|
||||
"build_number": "252.26199.163",
|
||||
"version-major-minor": "2022.3"
|
||||
},
|
||||
"pycharm-community": {
|
||||
@@ -239,34 +239,34 @@
|
||||
"rider": {
|
||||
"update-channel": "Rider RELEASE",
|
||||
"url-template": "https://download.jetbrains.com/rider/JetBrains.Rider-{version}-aarch64.tar.gz",
|
||||
"version": "2025.2.1",
|
||||
"sha256": "14c5cc877b213d7da53eea0585c1ebd13c5f43316a39ed9e6a1a745246fe42cb",
|
||||
"url": "https://download.jetbrains.com/rider/JetBrains.Rider-2025.2.1-aarch64.tar.gz",
|
||||
"build_number": "252.25557.182"
|
||||
"version": "2025.2.2",
|
||||
"sha256": "36523ab3b94d1ee1b92794476870727faa1ca29fbd365b7c3239f199399f6dbe",
|
||||
"url": "https://download.jetbrains.com/rider/JetBrains.Rider-2025.2.2-aarch64.tar.gz",
|
||||
"build_number": "252.26199.154"
|
||||
},
|
||||
"ruby-mine": {
|
||||
"update-channel": "RubyMine RELEASE",
|
||||
"url-template": "https://download.jetbrains.com/ruby/RubyMine-{version}-aarch64.tar.gz",
|
||||
"version": "2025.2.1",
|
||||
"sha256": "2dc93b1eb3d40eea193eb313632f13440fa34add912a1ab0ad201349811bbcb8",
|
||||
"url": "https://download.jetbrains.com/ruby/RubyMine-2025.2.1-aarch64.tar.gz",
|
||||
"build_number": "252.25557.135"
|
||||
"version": "2025.2.2",
|
||||
"sha256": "f75616b41eff86d75f51dadb49f1033ff9af021f1d9ca354fc8f99eca251c4ac",
|
||||
"url": "https://download.jetbrains.com/ruby/RubyMine-2025.2.2-aarch64.tar.gz",
|
||||
"build_number": "252.26199.157"
|
||||
},
|
||||
"rust-rover": {
|
||||
"update-channel": "RustRover RELEASE",
|
||||
"url-template": "https://download.jetbrains.com/rustrover/RustRover-{version}-aarch64.tar.gz",
|
||||
"version": "2025.2.1",
|
||||
"sha256": "60d22c93e3924f3defa51ace317fc6f715a6a5ef4e8ec18f1f361e6aa1d2a9d5",
|
||||
"url": "https://download.jetbrains.com/rustrover/RustRover-2025.2.1-aarch64.tar.gz",
|
||||
"build_number": "252.25557.134"
|
||||
"version": "2025.2.2",
|
||||
"sha256": "d76cb3f3d7affbd9cab937e813f44bafdd2675160b909f27baa7fac042de0765",
|
||||
"url": "https://download.jetbrains.com/rustrover/RustRover-2025.2.2-aarch64.tar.gz",
|
||||
"build_number": "252.26199.159"
|
||||
},
|
||||
"webstorm": {
|
||||
"update-channel": "WebStorm RELEASE",
|
||||
"url-template": "https://download.jetbrains.com/webstorm/WebStorm-{version}-aarch64.tar.gz",
|
||||
"version": "2025.2.1",
|
||||
"sha256": "ce335848f4771392c971d054b4a378a98ee6f77347c1e64d0631981715a034e3",
|
||||
"url": "https://download.jetbrains.com/webstorm/WebStorm-2025.2.1-aarch64.tar.gz",
|
||||
"build_number": "252.25557.126"
|
||||
"version": "2025.2.2",
|
||||
"sha256": "aa8eaa8bb200a6fce42582cb37235f3abf77ca7bcad2c9b98c318686c45772e1",
|
||||
"url": "https://download.jetbrains.com/webstorm/WebStorm-2025.2.2-aarch64.tar.gz",
|
||||
"build_number": "252.26199.162"
|
||||
},
|
||||
"writerside": {
|
||||
"update-channel": "Writerside EAP",
|
||||
@@ -289,10 +289,10 @@
|
||||
"clion": {
|
||||
"update-channel": "CLion RELEASE",
|
||||
"url-template": "https://download.jetbrains.com/cpp/CLion-{version}.dmg",
|
||||
"version": "2025.2.1",
|
||||
"sha256": "1cc896ae584c51009674f12d9c43d481b108b8e59243e60b094e7a967bb64652",
|
||||
"url": "https://download.jetbrains.com/cpp/CLion-2025.2.1.dmg",
|
||||
"build_number": "252.25557.127"
|
||||
"version": "2025.2.2",
|
||||
"sha256": "f9c42a3417db66bc88fc039829840662a650fdf79fc02619c5d6fd8a633f6606",
|
||||
"url": "https://download.jetbrains.com/cpp/CLion-2025.2.2.dmg",
|
||||
"build_number": "252.26199.153"
|
||||
},
|
||||
"datagrip": {
|
||||
"update-channel": "DataGrip RELEASE",
|
||||
@@ -313,34 +313,34 @@
|
||||
"gateway": {
|
||||
"update-channel": "Gateway RELEASE",
|
||||
"url-template": "https://download.jetbrains.com/idea/gateway/JetBrainsGateway-{version}.dmg",
|
||||
"version": "2025.2.1",
|
||||
"sha256": "4f48557a9a1ded6a88bc6bf17d65879f54b2314142c65e65d844df92d770de03",
|
||||
"url": "https://download.jetbrains.com/idea/gateway/JetBrainsGateway-2025.2.1.dmg",
|
||||
"build_number": "252.25557.133"
|
||||
"version": "2025.2.2",
|
||||
"sha256": "1be3476dc9065e9b95f399cb24ff2e5793e09a390bf541695bc932a9f46a2321",
|
||||
"url": "https://download.jetbrains.com/idea/gateway/JetBrainsGateway-2025.2.2.dmg",
|
||||
"build_number": "252.26199.160"
|
||||
},
|
||||
"goland": {
|
||||
"update-channel": "GoLand RELEASE",
|
||||
"url-template": "https://download.jetbrains.com/go/goland-{version}.dmg",
|
||||
"version": "2025.2.1.2",
|
||||
"sha256": "e3c8195cbf54ac77d6f715b1d6ed3c91f3b5288c0bdd67b254ebb938019e4271",
|
||||
"url": "https://download.jetbrains.com/go/goland-2025.2.1.2.dmg",
|
||||
"build_number": "252.25557.189"
|
||||
"version": "2025.2.2",
|
||||
"sha256": "d23f16afaa67f120ce987b59280805f01025e5b971d85544f33f0960035f3a1c",
|
||||
"url": "https://download.jetbrains.com/go/goland-2025.2.2.dmg",
|
||||
"build_number": "252.26199.158"
|
||||
},
|
||||
"idea-community": {
|
||||
"update-channel": "IntelliJ IDEA RELEASE",
|
||||
"url-template": "https://download.jetbrains.com/idea/ideaIC-{version}.dmg",
|
||||
"version": "2025.2.1",
|
||||
"sha256": "48d3f6523cc6fe94ad8020357b6de5e977fb2a49c8041773ffae7f946d418224",
|
||||
"url": "https://download.jetbrains.com/idea/ideaIC-2025.2.1.dmg",
|
||||
"build_number": "252.25557.131"
|
||||
"version": "2025.2.2",
|
||||
"sha256": "112bfa1e1c065ec641f1a242e95b63d4fed1b7dfa1d7b57b6591d8230531adae",
|
||||
"url": "https://download.jetbrains.com/idea/ideaIC-2025.2.2.dmg",
|
||||
"build_number": "252.26199.169"
|
||||
},
|
||||
"idea-ultimate": {
|
||||
"update-channel": "IntelliJ IDEA RELEASE",
|
||||
"url-template": "https://download.jetbrains.com/idea/ideaIU-{version}.dmg",
|
||||
"version": "2025.2.1",
|
||||
"sha256": "a768de8ff17cfb940d402ed907777e50c669e770ccd7515613086cd6d35f81d4",
|
||||
"url": "https://download.jetbrains.com/idea/ideaIU-2025.2.1.dmg",
|
||||
"build_number": "252.25557.131"
|
||||
"version": "2025.2.2",
|
||||
"sha256": "7e7b672525e29554e503eecc656de025a96b680d1ee223dfbfd762a1ca6430dd",
|
||||
"url": "https://download.jetbrains.com/idea/ideaIU-2025.2.2.dmg",
|
||||
"build_number": "252.26199.169"
|
||||
},
|
||||
"mps": {
|
||||
"update-channel": "MPS RELEASE",
|
||||
@@ -353,10 +353,10 @@
|
||||
"phpstorm": {
|
||||
"update-channel": "PhpStorm RELEASE",
|
||||
"url-template": "https://download.jetbrains.com/webide/PhpStorm-{version}.dmg",
|
||||
"version": "2025.2.1",
|
||||
"sha256": "8ea7143923c6f18c130e8d85530c423fa4eea5a81543094af9ad4c8155a26215",
|
||||
"url": "https://download.jetbrains.com/webide/PhpStorm-2025.2.1.dmg",
|
||||
"build_number": "252.25557.128",
|
||||
"version": "2025.2.2",
|
||||
"sha256": "60413cba4c4492a51af0dd3a439a615a08ec5fbc31c28ee7bb1af8638708eb05",
|
||||
"url": "https://download.jetbrains.com/webide/PhpStorm-2025.2.2.dmg",
|
||||
"build_number": "252.26199.163",
|
||||
"version-major-minor": "2022.3"
|
||||
},
|
||||
"pycharm-community": {
|
||||
@@ -378,34 +378,34 @@
|
||||
"rider": {
|
||||
"update-channel": "Rider RELEASE",
|
||||
"url-template": "https://download.jetbrains.com/rider/JetBrains.Rider-{version}.dmg",
|
||||
"version": "2025.2.1",
|
||||
"sha256": "37feeae3929be95bd6f405c6d5760af7d2e43bff55e03a4256c1232b61714809",
|
||||
"url": "https://download.jetbrains.com/rider/JetBrains.Rider-2025.2.1.dmg",
|
||||
"build_number": "252.25557.182"
|
||||
"version": "2025.2.2",
|
||||
"sha256": "ccc7b35691ceb87e3b3103909617e1616c36dcc69cb73c1f7668591c6256ba35",
|
||||
"url": "https://download.jetbrains.com/rider/JetBrains.Rider-2025.2.2.dmg",
|
||||
"build_number": "252.26199.154"
|
||||
},
|
||||
"ruby-mine": {
|
||||
"update-channel": "RubyMine RELEASE",
|
||||
"url-template": "https://download.jetbrains.com/ruby/RubyMine-{version}.dmg",
|
||||
"version": "2025.2.1",
|
||||
"sha256": "389d7e790bc745126e838191d14984acaf7f3beae4ef7d669c0fed1219b8a8e6",
|
||||
"url": "https://download.jetbrains.com/ruby/RubyMine-2025.2.1.dmg",
|
||||
"build_number": "252.25557.135"
|
||||
"version": "2025.2.2",
|
||||
"sha256": "9ced0e4a5ebb0e47821d25a7b8d9a2c4a9a8ad821ffefa9b429821379da8486e",
|
||||
"url": "https://download.jetbrains.com/ruby/RubyMine-2025.2.2.dmg",
|
||||
"build_number": "252.26199.157"
|
||||
},
|
||||
"rust-rover": {
|
||||
"update-channel": "RustRover RELEASE",
|
||||
"url-template": "https://download.jetbrains.com/rustrover/RustRover-{version}.dmg",
|
||||
"version": "2025.2.1",
|
||||
"sha256": "9143fa9bfcab98ed2a5215c006bb6bf5521ee5c9a9f08f6f321d0a873cfb39cc",
|
||||
"url": "https://download.jetbrains.com/rustrover/RustRover-2025.2.1.dmg",
|
||||
"build_number": "252.25557.134"
|
||||
"version": "2025.2.2",
|
||||
"sha256": "bcb442e4d22a71cd312cae2821187da82f9c58cdd03e5343a070b12af6a11f85",
|
||||
"url": "https://download.jetbrains.com/rustrover/RustRover-2025.2.2.dmg",
|
||||
"build_number": "252.26199.159"
|
||||
},
|
||||
"webstorm": {
|
||||
"update-channel": "WebStorm RELEASE",
|
||||
"url-template": "https://download.jetbrains.com/webstorm/WebStorm-{version}.dmg",
|
||||
"version": "2025.2.1",
|
||||
"sha256": "38ba2b01c688d838f5cb533eb9d575223135eb753d7f38865aaf4d27b56b5bf5",
|
||||
"url": "https://download.jetbrains.com/webstorm/WebStorm-2025.2.1.dmg",
|
||||
"build_number": "252.25557.126"
|
||||
"version": "2025.2.2",
|
||||
"sha256": "74af775f515e7cc847ee572cf7720498e6afec3387af285a6685337272c61611",
|
||||
"url": "https://download.jetbrains.com/webstorm/WebStorm-2025.2.2.dmg",
|
||||
"build_number": "252.26199.162"
|
||||
},
|
||||
"writerside": {
|
||||
"update-channel": "Writerside EAP",
|
||||
@@ -428,10 +428,10 @@
|
||||
"clion": {
|
||||
"update-channel": "CLion RELEASE",
|
||||
"url-template": "https://download.jetbrains.com/cpp/CLion-{version}-aarch64.dmg",
|
||||
"version": "2025.2.1",
|
||||
"sha256": "d8256fee77311192ffcb45d9efa5fa57fb2ea83a22925f49bc5880106f7b9ee4",
|
||||
"url": "https://download.jetbrains.com/cpp/CLion-2025.2.1-aarch64.dmg",
|
||||
"build_number": "252.25557.127"
|
||||
"version": "2025.2.2",
|
||||
"sha256": "4dceb6ba2ae1d2fcaaa7f76090bbb18664da30d371d2e950afdffb0f9589ce7e",
|
||||
"url": "https://download.jetbrains.com/cpp/CLion-2025.2.2-aarch64.dmg",
|
||||
"build_number": "252.26199.153"
|
||||
},
|
||||
"datagrip": {
|
||||
"update-channel": "DataGrip RELEASE",
|
||||
@@ -452,34 +452,34 @@
|
||||
"gateway": {
|
||||
"update-channel": "Gateway RELEASE",
|
||||
"url-template": "https://download.jetbrains.com/idea/gateway/JetBrainsGateway-{version}-aarch64.dmg",
|
||||
"version": "2025.2.1",
|
||||
"sha256": "94bb0fb41eaaea744173fe321b7e17cac898088eb7738c68b8d271ca437dee80",
|
||||
"url": "https://download.jetbrains.com/idea/gateway/JetBrainsGateway-2025.2.1-aarch64.dmg",
|
||||
"build_number": "252.25557.133"
|
||||
"version": "2025.2.2",
|
||||
"sha256": "1d9be57de8075eeefcc81ef249b15a60762f82909ca4002846dce13acedba56d",
|
||||
"url": "https://download.jetbrains.com/idea/gateway/JetBrainsGateway-2025.2.2-aarch64.dmg",
|
||||
"build_number": "252.26199.160"
|
||||
},
|
||||
"goland": {
|
||||
"update-channel": "GoLand RELEASE",
|
||||
"url-template": "https://download.jetbrains.com/go/goland-{version}-aarch64.dmg",
|
||||
"version": "2025.2.1.2",
|
||||
"sha256": "2c174e4fbd1485f3e402b9e0b693d196b8e38bc7b7bba2c33896391181c92940",
|
||||
"url": "https://download.jetbrains.com/go/goland-2025.2.1.2-aarch64.dmg",
|
||||
"build_number": "252.25557.189"
|
||||
"version": "2025.2.2",
|
||||
"sha256": "38dd5a302eba4ee5f92c5c5aa810b449b72301c89d209139e75c0efb6bdff919",
|
||||
"url": "https://download.jetbrains.com/go/goland-2025.2.2-aarch64.dmg",
|
||||
"build_number": "252.26199.158"
|
||||
},
|
||||
"idea-community": {
|
||||
"update-channel": "IntelliJ IDEA RELEASE",
|
||||
"url-template": "https://download.jetbrains.com/idea/ideaIC-{version}-aarch64.dmg",
|
||||
"version": "2025.2.1",
|
||||
"sha256": "dcafd8e623819b0696044d23874423f905224462844155a3c282fd4f62a7d578",
|
||||
"url": "https://download.jetbrains.com/idea/ideaIC-2025.2.1-aarch64.dmg",
|
||||
"build_number": "252.25557.131"
|
||||
"version": "2025.2.2",
|
||||
"sha256": "cc83bbb9531522085d2892499ddb5cb87909291d58ee3e34c06b131aeb2413fe",
|
||||
"url": "https://download.jetbrains.com/idea/ideaIC-2025.2.2-aarch64.dmg",
|
||||
"build_number": "252.26199.169"
|
||||
},
|
||||
"idea-ultimate": {
|
||||
"update-channel": "IntelliJ IDEA RELEASE",
|
||||
"url-template": "https://download.jetbrains.com/idea/ideaIU-{version}-aarch64.dmg",
|
||||
"version": "2025.2.1",
|
||||
"sha256": "96523081d1d686425b166698870a4467600724faac060a938a05838b0b9f8a9c",
|
||||
"url": "https://download.jetbrains.com/idea/ideaIU-2025.2.1-aarch64.dmg",
|
||||
"build_number": "252.25557.131"
|
||||
"version": "2025.2.2",
|
||||
"sha256": "c93ef0205c18f8b9fd127df2d5f3486e3ad190a0408c374e1795aeaa7899dc8a",
|
||||
"url": "https://download.jetbrains.com/idea/ideaIU-2025.2.2-aarch64.dmg",
|
||||
"build_number": "252.26199.169"
|
||||
},
|
||||
"mps": {
|
||||
"update-channel": "MPS RELEASE",
|
||||
@@ -492,10 +492,10 @@
|
||||
"phpstorm": {
|
||||
"update-channel": "PhpStorm RELEASE",
|
||||
"url-template": "https://download.jetbrains.com/webide/PhpStorm-{version}-aarch64.dmg",
|
||||
"version": "2025.2.1",
|
||||
"sha256": "9da242618b2f540d8fc34937743e2ebcd71af6341420474b0bf9285464a81a68",
|
||||
"url": "https://download.jetbrains.com/webide/PhpStorm-2025.2.1-aarch64.dmg",
|
||||
"build_number": "252.25557.128",
|
||||
"version": "2025.2.2",
|
||||
"sha256": "08c30cee02829ebca2956a5dc84221322cbd0ce02f33fb023d3d340cdcc2dac3",
|
||||
"url": "https://download.jetbrains.com/webide/PhpStorm-2025.2.2-aarch64.dmg",
|
||||
"build_number": "252.26199.163",
|
||||
"version-major-minor": "2022.3"
|
||||
},
|
||||
"pycharm-community": {
|
||||
@@ -517,34 +517,34 @@
|
||||
"rider": {
|
||||
"update-channel": "Rider RELEASE",
|
||||
"url-template": "https://download.jetbrains.com/rider/JetBrains.Rider-{version}-aarch64.dmg",
|
||||
"version": "2025.2.1",
|
||||
"sha256": "80f3f99311e8f225a6475b81dab014b13dd1782a59c6dc8abe5e5d3e614489b3",
|
||||
"url": "https://download.jetbrains.com/rider/JetBrains.Rider-2025.2.1-aarch64.dmg",
|
||||
"build_number": "252.25557.182"
|
||||
"version": "2025.2.2",
|
||||
"sha256": "f6d1a148123519c33d2ec8822e7d83856af68cbb518ac822c638bbd4b1127ad2",
|
||||
"url": "https://download.jetbrains.com/rider/JetBrains.Rider-2025.2.2-aarch64.dmg",
|
||||
"build_number": "252.26199.154"
|
||||
},
|
||||
"ruby-mine": {
|
||||
"update-channel": "RubyMine RELEASE",
|
||||
"url-template": "https://download.jetbrains.com/ruby/RubyMine-{version}-aarch64.dmg",
|
||||
"version": "2025.2.1",
|
||||
"sha256": "27c6648ec738e29bdd22fab0ed46a321ed6c8354348cb39ac3ae863c4ffe4c78",
|
||||
"url": "https://download.jetbrains.com/ruby/RubyMine-2025.2.1-aarch64.dmg",
|
||||
"build_number": "252.25557.135"
|
||||
"version": "2025.2.2",
|
||||
"sha256": "4fa2260b6ca45a3e21bd3aa64517cb5216113a4177ec2b7808f9883cf4a071b5",
|
||||
"url": "https://download.jetbrains.com/ruby/RubyMine-2025.2.2-aarch64.dmg",
|
||||
"build_number": "252.26199.157"
|
||||
},
|
||||
"rust-rover": {
|
||||
"update-channel": "RustRover RELEASE",
|
||||
"url-template": "https://download.jetbrains.com/rustrover/RustRover-{version}-aarch64.dmg",
|
||||
"version": "2025.2.1",
|
||||
"sha256": "469b4b7c42aa808a5f9d94315f4cc412ad74ef76ff51654d441ef16c5063dc27",
|
||||
"url": "https://download.jetbrains.com/rustrover/RustRover-2025.2.1-aarch64.dmg",
|
||||
"build_number": "252.25557.134"
|
||||
"version": "2025.2.2",
|
||||
"sha256": "a673c45f2183d28ac6ac37df9a8cd7084af432793f505589164096a425fa7801",
|
||||
"url": "https://download.jetbrains.com/rustrover/RustRover-2025.2.2-aarch64.dmg",
|
||||
"build_number": "252.26199.159"
|
||||
},
|
||||
"webstorm": {
|
||||
"update-channel": "WebStorm RELEASE",
|
||||
"url-template": "https://download.jetbrains.com/webstorm/WebStorm-{version}-aarch64.dmg",
|
||||
"version": "2025.2.1",
|
||||
"sha256": "dd3220a9458cd1574a96a75922e5439689f494516af9f5e76c5b74ffb37ec488",
|
||||
"url": "https://download.jetbrains.com/webstorm/WebStorm-2025.2.1-aarch64.dmg",
|
||||
"build_number": "252.25557.126"
|
||||
"version": "2025.2.2",
|
||||
"sha256": "68fbdbb3abd2ef5ae69d8371f72fd61e39f4331e7b9aacb792a7b6b7b6d05e8f",
|
||||
"url": "https://download.jetbrains.com/webstorm/WebStorm-2025.2.2-aarch64.dmg",
|
||||
"build_number": "252.26199.162"
|
||||
},
|
||||
"writerside": {
|
||||
"update-channel": "Writerside EAP",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -67,11 +67,6 @@ let
|
||||
passthru = (oldAttrs.passthru or { }) // {
|
||||
unwrapped = xeus-cling-unwrapped;
|
||||
};
|
||||
|
||||
meta.badPlatforms = [
|
||||
# fatal error: 'stdlib.h' file not found
|
||||
lib.systems.inspect.patterns.isDarwin
|
||||
];
|
||||
});
|
||||
|
||||
mkKernelSpec = std: {
|
||||
|
||||
@@ -13,7 +13,7 @@ python3Packages.buildPythonApplication rec {
|
||||
format = "other";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
repo = pname;
|
||||
repo = "manuskript";
|
||||
owner = "olivierkes";
|
||||
tag = version;
|
||||
hash = "sha256-jOhbN6lMx04q60S0VOABmSNE/x9Er9exFYvWJe2INlE=";
|
||||
@@ -29,15 +29,15 @@ python3Packages.buildPythonApplication rec {
|
||||
|
||||
patchPhase = ''
|
||||
substituteInPlace manuskript/ui/welcome.py \
|
||||
--replace sample-projects $out/share/${pname}/sample-projects
|
||||
--replace sample-projects $out/share/manuskript/sample-projects
|
||||
'';
|
||||
|
||||
buildPhase = "";
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out/share/${pname}
|
||||
mkdir -p $out/share/manuskript
|
||||
cp -av bin/ i18n/ libs/ manuskript/ resources/ icons/ $out
|
||||
cp -r sample-projects/ $out/share/${pname}
|
||||
cp -r sample-projects/ $out/share/manuskript
|
||||
'';
|
||||
|
||||
postFixup = ''
|
||||
|
||||
@@ -21,7 +21,7 @@ stdenv.mkDerivation rec {
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "lbellonda";
|
||||
repo = pname;
|
||||
repo = "qxmledit";
|
||||
rev = version;
|
||||
hash = "sha256-UzN5U+aC/uKokSdeUG2zv8+mkaH4ndYZ0sfzkpQ3l1M=";
|
||||
};
|
||||
|
||||
@@ -33,7 +33,7 @@ stdenv.mkDerivation rec {
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "mapeditor";
|
||||
repo = pname;
|
||||
repo = "tiled";
|
||||
rev = "v${version}";
|
||||
sha256 = "sha256-9oUKn51MQcsStgIJrp9XW5YAIpAUcO0kzfGnYA3gz/E=";
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+5
-3
@@ -17,7 +17,11 @@ let
|
||||
pname = "LanguageClient-neovim-bin";
|
||||
inherit version src;
|
||||
|
||||
cargoHash = "sha256-1tfeowqvjEjMXIfrhr388YhlZrk3ns+Y/2odQnkLw7k=";
|
||||
cargoPatches = [
|
||||
./traitobject.patch
|
||||
];
|
||||
|
||||
cargoHash = "sha256-43alR84MktYTmsKeUMm4gK8AjUIkGqcsuFeQPusBKD0=";
|
||||
};
|
||||
in
|
||||
vimUtils.buildVimPlugin {
|
||||
@@ -47,7 +51,5 @@ vimUtils.buildVimPlugin {
|
||||
homepage = "https://github.com/autozimu/LanguageClient-neovim/";
|
||||
changelog = "https://github.com/autozimu/LanguageClient-neovim/releases/tag/${src.tag}";
|
||||
license = lib.licenses.mit;
|
||||
# Rust build error
|
||||
broken = true;
|
||||
};
|
||||
}
|
||||
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
--- a/Cargo.lock
|
||||
+++ b/Cargo.lock
|
||||
@@ -1026,9 +1028,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "traitobject"
|
||||
-version = "0.1.0"
|
||||
+version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
-checksum = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079"
|
||||
+checksum = "04a79e25382e2e852e8da874249358d382ebaf259d0d34e75d8db16a7efabbc7"
|
||||
|
||||
[[package]]
|
||||
name = "treediff"
|
||||
|
||||
@@ -12,12 +12,12 @@
|
||||
pkgs,
|
||||
}:
|
||||
let
|
||||
version = "0.0.27-unstable-2025-09-11";
|
||||
version = "0.0.27-unstable-2025-09-18";
|
||||
src = fetchFromGitHub {
|
||||
owner = "yetone";
|
||||
repo = "avante.nvim";
|
||||
rev = "56951378f10b25f8bb0f5bb516b8d778a1e498a7";
|
||||
hash = "sha256-jLAzTLvhQLyG1zeTGBE02CwVCjtrC7V1LZhGUjNgD8w=";
|
||||
rev = "44db8eba870f6c123da5efa70384b2889f3e3495";
|
||||
hash = "sha256-x2lb7k/qfERXYMdM+Upf6kmsYS3Qp9iz2KEvzvgb8P4=";
|
||||
};
|
||||
avante-nvim-lib = rustPlatform.buildRustPackage {
|
||||
pname = "avante-nvim-lib";
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
}:
|
||||
vimUtils.buildVimPlugin {
|
||||
pname = "sonarlint.nvim";
|
||||
version = "0-unstable-2025-08-02";
|
||||
version = "0-unstable-2025-09-18";
|
||||
|
||||
src = fetchFromGitLab {
|
||||
owner = "schrieveslaach";
|
||||
repo = "sonarlint.nvim";
|
||||
rev = "5c3e0bb647be90cec844022991f33d50b6838964";
|
||||
hash = "sha256-lER6vBhiLK8/S2iJOc4jaDUMqkc9d2VLcj3GqbiZANs=";
|
||||
rev = "dc5702556f90eedce587233f3c1a0ae671ea3648";
|
||||
hash = "sha256-IBXQ9ijAG8TdnwkSTNbBtzziQC5bbCbkAmC8gM7G5E4=";
|
||||
};
|
||||
|
||||
passthru.updateScript = nix-update-script {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user