mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-07-13 21:50:33 +03:00
Merge remote-tracking branch 'origin/master' into staging-next
This commit is contained in:
commit
b3146d4446
8183 changed files with 9734 additions and 8649 deletions
|
@ -26,7 +26,7 @@ crystal.buildCrystalPackage rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "mint-lang";
|
owner = "mint-lang";
|
||||||
repo = "mint";
|
repo = "mint";
|
||||||
rev = version;
|
tag = version;
|
||||||
hash = "sha256-dFN9l5fgrM/TtOPqlQvUYgixE4KPr629aBmkwdDoq28=";
|
hash = "sha256-dFN9l5fgrM/TtOPqlQvUYgixE4KPr629aBmkwdDoq28=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ crystal.buildCrystalPackage rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "mint-lang";
|
owner = "mint-lang";
|
||||||
repo = "mint";
|
repo = "mint";
|
||||||
rev = version;
|
tag = version;
|
||||||
hash = "sha256-dFN9l5fgrM/TtOPqlQvUYgixE4KPr629aBmkwdDoq28=";
|
hash = "sha256-dFN9l5fgrM/TtOPqlQvUYgixE4KPr629aBmkwdDoq28=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ buildDartApplication rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "sass";
|
owner = "sass";
|
||||||
repo = pname;
|
repo = pname;
|
||||||
rev = version;
|
tag = version;
|
||||||
hash = "sha256-U6enz8yJcc4Wf8m54eYIAnVg/jsGi247Wy8lp1r1wg4=";
|
hash = "sha256-U6enz8yJcc4Wf8m54eYIAnVg/jsGi247Wy8lp1r1wg4=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ buildDubPackage rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "CyberShadow";
|
owner = "CyberShadow";
|
||||||
repo = "btdu";
|
repo = "btdu";
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
hash = "sha256-3sSZq+5UJH02IO0Y1yL3BLHDb4lk8k6awb5ZysBQciE=";
|
hash = "sha256-3sSZq+5UJH02IO0Y1yL3BLHDb4lk8k6awb5ZysBQciE=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ The following is an example expression using `buildGoModule`:
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "knqyf263";
|
owner = "knqyf263";
|
||||||
repo = "pet";
|
repo = "pet";
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
hash = "sha256-Gjw1dRrgM8D3G7v6WIM2+50r4HmTXvx0Xxme2fH9TlQ=";
|
hash = "sha256-Gjw1dRrgM8D3G7v6WIM2+50r4HmTXvx0Xxme2fH9TlQ=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -194,7 +194,7 @@ buildNpmPackage rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "jesec";
|
owner = "jesec";
|
||||||
repo = pname;
|
repo = pname;
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
hash = "sha256-BR+ZGkBBfd0dSQqAvujsbgsEPFYw/ThrylxUbOksYxM=";
|
hash = "sha256-BR+ZGkBBfd0dSQqAvujsbgsEPFYw/ThrylxUbOksYxM=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ rustPlatform.buildRustPackage rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "BurntSushi";
|
owner = "BurntSushi";
|
||||||
repo = pname;
|
repo = pname;
|
||||||
rev = version;
|
tag = version;
|
||||||
hash = "sha256-gyWnahj1A+iXUQlQ1O1H1u7K5euYQOld9qWm99Vjaeg=";
|
hash = "sha256-gyWnahj1A+iXUQlQ1O1H1u7K5euYQOld9qWm99Vjaeg=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -646,7 +646,7 @@ buildPythonPackage rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "Qiskit";
|
owner = "Qiskit";
|
||||||
repo = "retworkx";
|
repo = "retworkx";
|
||||||
rev = version;
|
tag = version;
|
||||||
hash = "sha256-11n30ldg3y3y6qxg3hbj837pnbwjkqw3nxq6frds647mmmprrd20=";
|
hash = "sha256-11n30ldg3y3y6qxg3hbj837pnbwjkqw3nxq6frds647mmmprrd20=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -984,7 +984,7 @@ rustPlatform.buildRustPackage rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "BurntSushi";
|
owner = "BurntSushi";
|
||||||
repo = "ripgrep";
|
repo = "ripgrep";
|
||||||
rev = version;
|
tag = version;
|
||||||
hash = "sha256-gyWnahj1A+iXUQlQ1O1H1u7K5euYQOld9qWm99Vjaeg=";
|
hash = "sha256-gyWnahj1A+iXUQlQ1O1H1u7K5euYQOld9qWm99Vjaeg=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -83,7 +83,7 @@ stdenv.mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "nixos";
|
owner = "nixos";
|
||||||
repo = pname;
|
repo = pname;
|
||||||
rev = version;
|
tag = version;
|
||||||
hash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
|
hash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -446,6 +446,7 @@ let
|
||||||
fixupOptionType
|
fixupOptionType
|
||||||
mkIf
|
mkIf
|
||||||
mkAssert
|
mkAssert
|
||||||
|
mkDefinition
|
||||||
mkMerge
|
mkMerge
|
||||||
mkOverride
|
mkOverride
|
||||||
mkOptionDefault
|
mkOptionDefault
|
||||||
|
|
|
@ -1097,10 +1097,16 @@ let
|
||||||
# Process mkMerge and mkIf properties.
|
# Process mkMerge and mkIf properties.
|
||||||
defs' = concatMap (
|
defs' = concatMap (
|
||||||
m:
|
m:
|
||||||
map (value: {
|
map (
|
||||||
inherit (m) file;
|
value:
|
||||||
inherit value;
|
if value._type or null == "definition" then
|
||||||
}) (addErrorContext "while evaluating definitions from `${m.file}':" (dischargeProperties m.value))
|
value
|
||||||
|
else
|
||||||
|
{
|
||||||
|
inherit (m) file;
|
||||||
|
inherit value;
|
||||||
|
}
|
||||||
|
) (addErrorContext "while evaluating definitions from `${m.file}':" (dischargeProperties m.value))
|
||||||
) defs;
|
) defs;
|
||||||
|
|
||||||
# Process mkOverride properties.
|
# Process mkOverride properties.
|
||||||
|
@ -1365,6 +1371,11 @@ let
|
||||||
inherit contents;
|
inherit contents;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Return a definition with file location information.
|
||||||
|
*/
|
||||||
|
mkDefinition = args@{ file, value, ... }: args // { _type = "definition"; };
|
||||||
|
|
||||||
mkOverride = priority: content: {
|
mkOverride = priority: content: {
|
||||||
_type = "override";
|
_type = "override";
|
||||||
inherit priority content;
|
inherit priority content;
|
||||||
|
@ -2095,6 +2106,7 @@ private
|
||||||
mkBefore
|
mkBefore
|
||||||
mkChangedOptionModule
|
mkChangedOptionModule
|
||||||
mkDefault
|
mkDefault
|
||||||
|
mkDefinition
|
||||||
mkDerivedConfig
|
mkDerivedConfig
|
||||||
mkFixStrictness
|
mkFixStrictness
|
||||||
mkForce
|
mkForce
|
||||||
|
|
|
@ -673,6 +673,14 @@ checkConfigError 'The option .conflictingPathOptionType. in .*/pathWith.nix. is
|
||||||
# types.pathWith { inStore = true; absolute = false; }
|
# types.pathWith { inStore = true; absolute = false; }
|
||||||
checkConfigError 'In pathWith, inStore means the path must be absolute' config.impossiblePathOptionType ./pathWith.nix
|
checkConfigError 'In pathWith, inStore means the path must be absolute' config.impossiblePathOptionType ./pathWith.nix
|
||||||
|
|
||||||
|
# mkDefinition
|
||||||
|
# check that mkDefinition 'file' is printed in the error message
|
||||||
|
checkConfigError 'Cannot merge definitions.*\n\s*- In .file.*\n\s*- In .other.*' config.conflict ./mkDefinition.nix
|
||||||
|
checkConfigError 'A definition for option .viaOptionDefault. is not of type .boolean.*' config.viaOptionDefault ./mkDefinition.nix
|
||||||
|
checkConfigOutput '^true$' config.viaConfig ./mkDefinition.nix
|
||||||
|
checkConfigOutput '^true$' config.mkMerge ./mkDefinition.nix
|
||||||
|
checkConfigOutput '^true$' config.mkForce ./mkDefinition.nix
|
||||||
|
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
====== module tests ======
|
====== module tests ======
|
||||||
$pass Pass
|
$pass Pass
|
||||||
|
|
71
lib/tests/modules/mkDefinition.nix
Normal file
71
lib/tests/modules/mkDefinition.nix
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
{ lib, ... }:
|
||||||
|
let
|
||||||
|
inherit (lib)
|
||||||
|
mkOption
|
||||||
|
mkDefinition
|
||||||
|
mkOptionDefault
|
||||||
|
;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
{
|
||||||
|
_file = "file";
|
||||||
|
options.conflict = mkOption {
|
||||||
|
default = 1;
|
||||||
|
};
|
||||||
|
config.conflict = mkDefinition {
|
||||||
|
file = "other";
|
||||||
|
value = mkOptionDefault 42;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
{
|
||||||
|
# Check that mkDefinition works within 'config'
|
||||||
|
options.viaConfig = mkOption { };
|
||||||
|
config.viaConfig = mkDefinition {
|
||||||
|
file = "other";
|
||||||
|
value = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
{
|
||||||
|
# Check mkMerge can wrap mkDefinitions
|
||||||
|
# Not the other way around
|
||||||
|
options.mkMerge = mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
};
|
||||||
|
config.mkMerge = lib.mkMerge [
|
||||||
|
(mkDefinition {
|
||||||
|
file = "a.nix";
|
||||||
|
value = true;
|
||||||
|
})
|
||||||
|
(mkDefinition {
|
||||||
|
file = "b.nix";
|
||||||
|
value = true;
|
||||||
|
})
|
||||||
|
];
|
||||||
|
}
|
||||||
|
{
|
||||||
|
# Check mkDefinition can use mkForce on the value
|
||||||
|
# Not the other way around
|
||||||
|
options.mkForce = mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = false;
|
||||||
|
};
|
||||||
|
config.mkForce = mkDefinition {
|
||||||
|
file = "other";
|
||||||
|
value = lib.mkForce true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
{
|
||||||
|
# Currently expects an error
|
||||||
|
# mkDefinition doesn't work on option default
|
||||||
|
# This is a limitation and might be resolved in the future
|
||||||
|
options.viaOptionDefault = mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = mkDefinition {
|
||||||
|
file = "other";
|
||||||
|
value = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
|
@ -3761,6 +3761,12 @@
|
||||||
githubId = 382011;
|
githubId = 382011;
|
||||||
name = "c4605";
|
name = "c4605";
|
||||||
};
|
};
|
||||||
|
c4f3z1n = {
|
||||||
|
name = "João Nogueira";
|
||||||
|
email = "shires.waking0d@icloud.com";
|
||||||
|
github = "c4f3z1n";
|
||||||
|
githubId = 22820003;
|
||||||
|
};
|
||||||
c4thebomb = {
|
c4thebomb = {
|
||||||
name = "Ceferino Patino";
|
name = "Ceferino Patino";
|
||||||
email = "c4patino@gmail.com";
|
email = "c4patino@gmail.com";
|
||||||
|
@ -6457,6 +6463,11 @@
|
||||||
github = "DrakeTDL";
|
github = "DrakeTDL";
|
||||||
githubId = 22124013;
|
githubId = 22124013;
|
||||||
};
|
};
|
||||||
|
drakon64 = {
|
||||||
|
name = "Adam Chance";
|
||||||
|
email = "nixpkgs@drakon.cloud";
|
||||||
|
githubId = 6444703;
|
||||||
|
};
|
||||||
dramaturg = {
|
dramaturg = {
|
||||||
email = "seb@ds.ag";
|
email = "seb@ds.ag";
|
||||||
github = "dramaturg";
|
github = "dramaturg";
|
||||||
|
|
|
@ -123,3 +123,65 @@ they were declared in separate modules. This can be done using
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Free-floating definitions {#sec-option-definitions-definitions}
|
||||||
|
|
||||||
|
:::{.note}
|
||||||
|
The module system internally transforms module syntax into definitions. This always happens internally.
|
||||||
|
:::
|
||||||
|
|
||||||
|
It is possible to create first class definitions which are not transformed _again_ into definitions by the module system.
|
||||||
|
|
||||||
|
Usually the file location of a definition is implicit and equal to the file it came from.
|
||||||
|
However, when manipulating definitions, it may be useful for them to be completely self-contained (or "free-floating").
|
||||||
|
|
||||||
|
A free-floating definition is created with `mkDefinition { file = ...; value = ...; }`.
|
||||||
|
|
||||||
|
Preserving the file location creates better error messages, for example when copying definitions from one option to another.
|
||||||
|
|
||||||
|
Other properties like `mkOverride` `mkMerge` `mkAfter` can be used in the `value` attribute but not on the entire definition.
|
||||||
|
|
||||||
|
This is what would work
|
||||||
|
|
||||||
|
```nix
|
||||||
|
mkDefinition {
|
||||||
|
value = mkForce 42;
|
||||||
|
file = "somefile.nix";
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
While this would NOT work.
|
||||||
|
|
||||||
|
```nix
|
||||||
|
mkForce (mkDefinition {
|
||||||
|
value = 42;
|
||||||
|
file = "somefile.nix";
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
The following shows an example configuration that yields an error with the custom position information:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{
|
||||||
|
_file = "file.nix";
|
||||||
|
options.foo = mkOption {
|
||||||
|
default = 13;
|
||||||
|
};
|
||||||
|
config.foo = lib.mkDefinition {
|
||||||
|
file = "custom place";
|
||||||
|
# mkOptionDefault creates a conflict with the option foo's `default = 1` on purpose
|
||||||
|
# So we see the error message below contains the conflicting values and different positions
|
||||||
|
value = lib.mkOptionDefault 42;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
evaluating the module yields the following error:
|
||||||
|
|
||||||
|
```
|
||||||
|
error: Cannot merge definitions of `foo'. Definition values:
|
||||||
|
- In `file.nix': 13
|
||||||
|
- In `custom place': 42
|
||||||
|
```
|
||||||
|
|
||||||
|
To set the file location for all definitions in a module, you may add the `_file` module syntax attribute, which has a similar effect to using `mkDefinition` on all definitions in the module, without the hassle.
|
||||||
|
|
|
@ -1667,6 +1667,9 @@
|
||||||
"sec-option-definitions-merging": [
|
"sec-option-definitions-merging": [
|
||||||
"index.html#sec-option-definitions-merging"
|
"index.html#sec-option-definitions-merging"
|
||||||
],
|
],
|
||||||
|
"sec-option-definitions-definitions": [
|
||||||
|
"index.html#sec-option-definitions-definitions"
|
||||||
|
],
|
||||||
"sec-assertions": [
|
"sec-assertions": [
|
||||||
"index.html#sec-assertions"
|
"index.html#sec-assertions"
|
||||||
],
|
],
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
- The Mattermost module ({option}`services.mattermost`) and packages (`mattermost` and `mmctl`) have been substantially updated:
|
- The Mattermost module ({option}`services.mattermost`) and packages (`mattermost` and `mmctl`) have been substantially updated:
|
||||||
- {option}`services.mattermost.preferNixConfig` now defaults to true if you advance {option}`system.stateVersion` to 25.05. This means that if you have {option}`services.mattermost.mutableConfig` set, NixOS will override your settings to those that you define in the module. It is recommended to leave this at the default, even if you used a mutable config before, because it will ensure that your Mattermost data directories are correct. If you moved your data directories, you may want to review the module changes before upgrading.
|
- {option}`services.mattermost.preferNixConfig` now defaults to true if you advance {option}`system.stateVersion` to 25.05. This means that if you have {option}`services.mattermost.mutableConfig` set, NixOS will override your settings to those that you define in the module. It is recommended to leave this at the default, even if you used a mutable config before, because it will ensure that your Mattermost data directories are correct. If you moved your data directories, you may want to review the module changes before upgrading.
|
||||||
- Mattermost telemetry reporting is now disabled by default, though security update notifications are enabled. Look at {option}`services.mattermost.telemetry` for options to control this behavior.
|
- Mattermost telemetry reporting is now disabled by default, though security update notifications are enabled. Look at {option}`services.mattermost.telemetry` for options to control this behavior.
|
||||||
|
- `pkgs.mattermost` has been updated from 9.11 to 10.5 to track the latest extended support release, since 9.11 will become end-of-life during the lifetime of NixOS 25.05.
|
||||||
- `pkgs.mattermostLatest` is now an option to track the latest (non-prerelease) Mattermost release. We test upgrade migrations from ESR releases (`pkgs.mattermost`) to `pkgs.mattermostLatest`.
|
- `pkgs.mattermostLatest` is now an option to track the latest (non-prerelease) Mattermost release. We test upgrade migrations from ESR releases (`pkgs.mattermost`) to `pkgs.mattermostLatest`.
|
||||||
- The Mattermost frontend is now built from source and can be overridden.
|
- The Mattermost frontend is now built from source and can be overridden.
|
||||||
- Note that the Mattermost derivation containing both the webapp and server is now wrapped to allow them to be built independently, so overrides to both webapp and server look like `mattermost.overrideAttrs (prev: { webapp = prev.webapp.override { ... }; server = prev.server.override { ... }; })` now.
|
- Note that the Mattermost derivation containing both the webapp and server is now wrapped to allow them to be built independently, so overrides to both webapp and server look like `mattermost.overrideAttrs (prev: { webapp = prev.webapp.override { ... }; server = prev.server.override { ... }; })` now.
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
{
|
{
|
||||||
x86_64-linux = "/nix/store/00a7rdfwhm6avqkgj68grddbzyz3h6ql-nix-2.24.13";
|
x86_64-linux = "/nix/store/kvqnqgjw3k0xmv3ypzajz3c5wf1pxnbs-nix-2.24.14";
|
||||||
i686-linux = "/nix/store/s6c620v60hfishzi1lbfpryk65lbvg8g-nix-2.24.13";
|
i686-linux = "/nix/store/292xy9z1vjmy0888bzadmj9fmq1ccapv-nix-2.24.14";
|
||||||
aarch64-linux = "/nix/store/7yg9is1shh3383iwi6qynz3vh91l1f9d-nix-2.24.13";
|
aarch64-linux = "/nix/store/qsy62z6rk31s8s937nvkcdhn0ds62yax-nix-2.24.14";
|
||||||
riscv64-linux = "/nix/store/fagjkrx5r6p52xp8qb5581bmnlgp01sn-nix-riscv64-unknown-linux-gnu-2.24.13";
|
riscv64-linux = "/nix/store/zvrzwzv534zcmhw4ai1hbc4iz229hk3p-nix-riscv64-unknown-linux-gnu-2.24.14";
|
||||||
x86_64-darwin = "/nix/store/ifby7rrgkkly5pzjnyac90lzvrak3i9y-nix-2.24.13";
|
x86_64-darwin = "/nix/store/jc7x6906wyy6csgf6br1gbwkw56nxm4l-nix-2.24.14";
|
||||||
aarch64-darwin = "/nix/store/b0rbdp6ba2fprprpgsw1a8pplzg0j324-nix-2.24.13";
|
aarch64-darwin = "/nix/store/sfrmn30fijs6qpfi7ckjkv2vdr4z590h-nix-2.24.14";
|
||||||
}
|
}
|
||||||
|
|
|
@ -361,6 +361,7 @@
|
||||||
./programs/zsh/zsh.nix
|
./programs/zsh/zsh.nix
|
||||||
./rename.nix
|
./rename.nix
|
||||||
./security/acme
|
./security/acme
|
||||||
|
./security/agnos.nix
|
||||||
./security/apparmor.nix
|
./security/apparmor.nix
|
||||||
./security/audit.nix
|
./security/audit.nix
|
||||||
./security/auditd.nix
|
./security/auditd.nix
|
||||||
|
|
|
@ -10,16 +10,24 @@ in
|
||||||
{
|
{
|
||||||
options.programs.amnezia-vpn = {
|
options.programs.amnezia-vpn = {
|
||||||
enable = lib.mkEnableOption "The AmneziaVPN client";
|
enable = lib.mkEnableOption "The AmneziaVPN client";
|
||||||
|
package = lib.mkPackageOption pkgs "amnezia-vpn" { };
|
||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
environment.systemPackages = [ pkgs.amnezia-vpn ];
|
environment.systemPackages = [ cfg.package ];
|
||||||
services.dbus.packages = [ pkgs.amnezia-vpn ];
|
services.dbus.packages = [ cfg.package ];
|
||||||
services.resolved.enable = true;
|
services.resolved.enable = true;
|
||||||
|
|
||||||
systemd = {
|
systemd = {
|
||||||
packages = [ pkgs.amnezia-vpn ];
|
packages = [ cfg.package ];
|
||||||
services."AmneziaVPN".wantedBy = [ "multi-user.target" ];
|
services."AmneziaVPN" = {
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
path = with pkgs; [
|
||||||
|
procps
|
||||||
|
iproute2
|
||||||
|
sudo
|
||||||
|
];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
314
nixos/modules/security/agnos.nix
Normal file
314
nixos/modules/security/agnos.nix
Normal file
|
@ -0,0 +1,314 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
cfg = config.security.agnos;
|
||||||
|
format = pkgs.formats.toml { };
|
||||||
|
name = "agnos";
|
||||||
|
stateDir = "/var/lib/${name}";
|
||||||
|
|
||||||
|
accountType =
|
||||||
|
let
|
||||||
|
inherit (lib) types mkOption;
|
||||||
|
in
|
||||||
|
types.submodule {
|
||||||
|
freeformType = format.type;
|
||||||
|
|
||||||
|
options = {
|
||||||
|
email = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = ''
|
||||||
|
Email associated with this account.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
private_key_path = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = ''
|
||||||
|
Path of the PEM-encoded private key for this account.
|
||||||
|
Currently, only RSA keys are supported.
|
||||||
|
|
||||||
|
If this path does not exist, then the behavior depends on `generateKeys.enable`.
|
||||||
|
When this option is `true`,
|
||||||
|
the key will be automatically generated and saved to this path.
|
||||||
|
When it is `false`, agnos will fail.
|
||||||
|
|
||||||
|
If a relative path is specified,
|
||||||
|
the key will be looked up (or generated and saved to) under `${stateDir}`.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
certificates = mkOption {
|
||||||
|
type = types.listOf certificateType;
|
||||||
|
description = ''
|
||||||
|
Certificates for agnos to issue or renew.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
certificateType =
|
||||||
|
let
|
||||||
|
inherit (lib) types literalExpression mkOption;
|
||||||
|
in
|
||||||
|
types.submodule {
|
||||||
|
freeformType = format.type;
|
||||||
|
|
||||||
|
options = {
|
||||||
|
domains = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
description = ''
|
||||||
|
Domains the certificate represents
|
||||||
|
'';
|
||||||
|
example = literalExpression ''["a.example.com", "b.example.com", "*b.example.com"]'';
|
||||||
|
};
|
||||||
|
fullchain_output_file = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = ''
|
||||||
|
Output path for the full chain including the acquired certificate.
|
||||||
|
If a relative path is specified, the file will be created in `${stateDir}`.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
key_output_file = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = ''
|
||||||
|
Output path for the certificate private key.
|
||||||
|
If a relative path is specified, the file will be created in `${stateDir}`.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.security.agnos =
|
||||||
|
let
|
||||||
|
inherit (lib) types mkEnableOption mkOption;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
enable = mkEnableOption name;
|
||||||
|
|
||||||
|
settings = mkOption {
|
||||||
|
description = "Settings";
|
||||||
|
type = types.submodule {
|
||||||
|
freeformType = format.type;
|
||||||
|
|
||||||
|
options = {
|
||||||
|
dns_listen_addr = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "0.0.0.0:53";
|
||||||
|
description = ''
|
||||||
|
Address for agnos to listen on.
|
||||||
|
Note that this needs to be reachable by the outside world,
|
||||||
|
and 53 is required in most situations
|
||||||
|
since `NS` records do not allow specifying the port.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
accounts = mkOption {
|
||||||
|
type = types.listOf accountType;
|
||||||
|
description = ''
|
||||||
|
A list of ACME accounts.
|
||||||
|
Each account is associated with an email address
|
||||||
|
and can be used to obtain an arbitrary amount of certificate
|
||||||
|
(subject to provider's rate limits,
|
||||||
|
see e.g. [Let's Encrypt Rate Limits](https://letsencrypt.org/docs/rate-limits/)).
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
generateKeys = {
|
||||||
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Enable automatic generation of account keys.
|
||||||
|
|
||||||
|
When this is `true`, a key will be generated for each account where
|
||||||
|
the file referred to by the `private_key` path does not exist yet.
|
||||||
|
|
||||||
|
Currently, only RSA keys can be generated.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
keySize = mkOption {
|
||||||
|
type = types.int;
|
||||||
|
default = 4096;
|
||||||
|
description = ''
|
||||||
|
Key size in bits to use when generating new keys.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
server = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
ACME Directory Resource URI. Defaults to Let's Encrypt's production endpoint,
|
||||||
|
`https://acme-v02.api.letsencrypt.org/directory`, if unset.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
serverCa = mkOption {
|
||||||
|
type = types.nullOr types.path;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
The root certificate (in PEM format) of the ACME server's HTTPS interface.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
persistent = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = ''
|
||||||
|
When `true`, use a persistent systemd timer.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
startAt = mkOption {
|
||||||
|
type = types.either types.str (types.listOf types.str);
|
||||||
|
default = "daily";
|
||||||
|
example = "02:00";
|
||||||
|
description = ''
|
||||||
|
How often or when to run agnos.
|
||||||
|
|
||||||
|
The format is described in
|
||||||
|
{manpage}`systemd.time(7)`.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
temporarilyOpenFirewall = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
When `true`, will open the port specified in `settings.dns_listen_addr`
|
||||||
|
before running the agnos service, and close it when agnos finishes running.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
group = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = name;
|
||||||
|
description = ''
|
||||||
|
Group to run Agnos as. The acquired certificates will be owned by this group.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
user = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = name;
|
||||||
|
description = ''
|
||||||
|
User to run Agnos as. The acquired certificates will be owned by this user.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config =
|
||||||
|
let
|
||||||
|
configFile = format.generate "agnos.toml" cfg.settings;
|
||||||
|
port = lib.toInt (lib.last (builtins.split ":" cfg.settings.dns_listen_addr));
|
||||||
|
|
||||||
|
useNftables = config.networking.nftables.enable;
|
||||||
|
|
||||||
|
# nftables implementation for temporarilyOpenFirewall
|
||||||
|
nftablesSetup = pkgs.writeShellScript "agnos-fw-setup" ''
|
||||||
|
${lib.getExe pkgs.nftables} add element inet nixos-fw temp-ports "{ tcp . ${toString port} }"
|
||||||
|
${lib.getExe pkgs.nftables} add element inet nixos-fw temp-ports "{ udp . ${toString port} }"
|
||||||
|
'';
|
||||||
|
nftablesTeardown = pkgs.writeShellScript "agnos-fw-teardown" ''
|
||||||
|
${lib.getExe pkgs.nftables} delete element inet nixos-fw temp-ports "{ tcp . ${toString port} }"
|
||||||
|
${lib.getExe pkgs.nftables} delete element inet nixos-fw temp-ports "{ udp . ${toString port} }"
|
||||||
|
'';
|
||||||
|
|
||||||
|
# iptables implementation for temporarilyOpenFirewall
|
||||||
|
helpers = ''
|
||||||
|
function ip46tables() {
|
||||||
|
${lib.getExe' pkgs.iptables "iptables"} -w "$@"
|
||||||
|
${lib.getExe' pkgs.iptables "ip6tables"} -w "$@"
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
fwFilter = ''--dport ${toString port} -j ACCEPT -m comment --comment "agnos"'';
|
||||||
|
iptablesSetup = pkgs.writeShellScript "agnos-fw-setup" ''
|
||||||
|
${helpers}
|
||||||
|
ip46tables -I INPUT 1 -p tcp ${fwFilter}
|
||||||
|
ip46tables -I INPUT 1 -p udp ${fwFilter}
|
||||||
|
'';
|
||||||
|
iptablesTeardown = pkgs.writeShellScript "agnos-fw-setup" ''
|
||||||
|
${helpers}
|
||||||
|
ip46tables -D INPUT -p tcp ${fwFilter}
|
||||||
|
ip46tables -D INPUT -p udp ${fwFilter}
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
lib.mkIf cfg.enable {
|
||||||
|
assertions = [
|
||||||
|
{
|
||||||
|
assertion = !cfg.temporarilyOpenFirewall || config.networking.firewall.enable;
|
||||||
|
message = "temporarilyOpenFirewall is only useful when firewall is enabled";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
systemd.services.agnos = {
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStartPre =
|
||||||
|
lib.optional cfg.generateKeys.enable ''
|
||||||
|
${pkgs.agnos}/bin/agnos-generate-accounts-keys \
|
||||||
|
--no-confirm \
|
||||||
|
--key-size ${toString cfg.generateKeys.keySize} \
|
||||||
|
${configFile}
|
||||||
|
''
|
||||||
|
++ lib.optional cfg.temporarilyOpenFirewall (
|
||||||
|
"+" + (if useNftables then nftablesSetup else iptablesSetup)
|
||||||
|
);
|
||||||
|
ExecStopPost = lib.optional cfg.temporarilyOpenFirewall (
|
||||||
|
"+" + (if useNftables then nftablesTeardown else iptablesTeardown)
|
||||||
|
);
|
||||||
|
ExecStart = ''
|
||||||
|
${pkgs.agnos}/bin/agnos \
|
||||||
|
${if cfg.server != null then "--acme-url=${cfg.server}" else "--no-staging"} \
|
||||||
|
${lib.optionalString (cfg.serverCa != null) "--acme-serv-ca=${cfg.serverCa}"} \
|
||||||
|
${configFile}
|
||||||
|
'';
|
||||||
|
Type = "oneshot";
|
||||||
|
User = cfg.user;
|
||||||
|
Group = cfg.group;
|
||||||
|
StateDirectory = name;
|
||||||
|
StateDirectoryMode = "0750";
|
||||||
|
WorkingDirectory = "${stateDir}";
|
||||||
|
|
||||||
|
# Allow binding privileged ports if necessary
|
||||||
|
CapabilityBoundingSet = lib.mkIf (port < 1024) [ "CAP_NET_BIND_SERVICE" ];
|
||||||
|
AmbientCapabilities = lib.mkIf (port < 1024) [ "CAP_NET_BIND_SERVICE" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
after = [
|
||||||
|
"firewall.target"
|
||||||
|
"network-online.target"
|
||||||
|
"nftables.service"
|
||||||
|
];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.timers.agnos = {
|
||||||
|
timerConfig = {
|
||||||
|
OnCalendar = cfg.startAt;
|
||||||
|
Persistent = cfg.persistent;
|
||||||
|
Unit = "agnos.service";
|
||||||
|
};
|
||||||
|
wantedBy = [ "timers.target" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
users.groups = lib.mkIf (cfg.group == name) {
|
||||||
|
${cfg.group} = { };
|
||||||
|
};
|
||||||
|
|
||||||
|
users.users = lib.mkIf (cfg.user == name) {
|
||||||
|
${cfg.user} = {
|
||||||
|
isSystemUser = true;
|
||||||
|
description = "Agnos service user";
|
||||||
|
group = cfg.group;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -147,34 +147,34 @@ let
|
||||||
else
|
else
|
||||||
throw "Invalid database driver: ${cfg.database.driver}";
|
throw "Invalid database driver: ${cfg.database.driver}";
|
||||||
|
|
||||||
mattermostPluginDerivations =
|
mattermostPluginDerivations = map (
|
||||||
with pkgs;
|
plugin:
|
||||||
map (
|
pkgs.stdenvNoCC.mkDerivation {
|
||||||
plugin:
|
name = "${cfg.package.name}-plugin";
|
||||||
stdenv.mkDerivation {
|
installPhase = ''
|
||||||
name = "mattermost-plugin";
|
runHook preInstall
|
||||||
installPhase = ''
|
mkdir -p $out/share
|
||||||
mkdir -p $out/share
|
ln -sf ${plugin} $out/share/plugin.tar.gz
|
||||||
cp ${plugin} $out/share/plugin.tar.gz
|
runHook postInstall
|
||||||
'';
|
'';
|
||||||
dontUnpack = true;
|
dontUnpack = true;
|
||||||
dontPatch = true;
|
dontPatch = true;
|
||||||
dontConfigure = true;
|
dontConfigure = true;
|
||||||
dontBuild = true;
|
dontBuild = true;
|
||||||
preferLocalBuild = true;
|
preferLocalBuild = true;
|
||||||
}
|
}
|
||||||
) cfg.plugins;
|
) cfg.plugins;
|
||||||
|
|
||||||
mattermostPlugins =
|
mattermostPlugins =
|
||||||
with pkgs;
|
|
||||||
if mattermostPluginDerivations == [ ] then
|
if mattermostPluginDerivations == [ ] then
|
||||||
null
|
null
|
||||||
else
|
else
|
||||||
stdenv.mkDerivation {
|
pkgs.stdenvNoCC.mkDerivation {
|
||||||
name = "${cfg.package.name}-plugins";
|
name = "${cfg.package.name}-plugins";
|
||||||
nativeBuildInputs = [ autoPatchelfHook ] ++ mattermostPluginDerivations;
|
nativeBuildInputs = [ pkgs.autoPatchelfHook ] ++ mattermostPluginDerivations;
|
||||||
buildInputs = [ cfg.package ];
|
buildInputs = [ cfg.package ];
|
||||||
installPhase = ''
|
installPhase = ''
|
||||||
|
runHook preInstall
|
||||||
mkdir -p $out
|
mkdir -p $out
|
||||||
plugins=(${
|
plugins=(${
|
||||||
escapeShellArgs (map (plugin: "${plugin}/share/plugin.tar.gz") mattermostPluginDerivations)
|
escapeShellArgs (map (plugin: "${plugin}/share/plugin.tar.gz") mattermostPluginDerivations)
|
||||||
|
@ -187,6 +187,7 @@ let
|
||||||
GZIP_OPT=-9 tar -C "$hash" -cvzf "$out/$hash.tar.gz" .
|
GZIP_OPT=-9 tar -C "$hash" -cvzf "$out/$hash.tar.gz" .
|
||||||
rm -rf "$hash"
|
rm -rf "$hash"
|
||||||
done
|
done
|
||||||
|
runHook postInstall
|
||||||
'';
|
'';
|
||||||
|
|
||||||
dontUnpack = true;
|
dontUnpack = true;
|
||||||
|
@ -254,8 +255,8 @@ let
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
mattermostConfJSON = pkgs.writeText "mattermost-config.json" (builtins.toJSON mattermostConf);
|
format = pkgs.formats.json { };
|
||||||
|
finalConfig = format.generate "mattermost-config.json" mattermostConf;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
|
@ -454,9 +455,9 @@ in
|
||||||
the options specified in services.mattermost will be generated
|
the options specified in services.mattermost will be generated
|
||||||
but won't be overwritten on changes or rebuilds.
|
but won't be overwritten on changes or rebuilds.
|
||||||
|
|
||||||
If this option is disabled, changes in the system console won't
|
If this option is disabled, persistent changes in the system
|
||||||
be possible (default). If an config.json is present, it will be
|
console won't be possible (the default). If a config.json is
|
||||||
overwritten!
|
present, it will be overwritten at service start!
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -480,7 +481,20 @@ in
|
||||||
description = ''
|
description = ''
|
||||||
Plugins to add to the configuration. Overrides any installed if non-null.
|
Plugins to add to the configuration. Overrides any installed if non-null.
|
||||||
This is a list of paths to .tar.gz files or derivations evaluating to
|
This is a list of paths to .tar.gz files or derivations evaluating to
|
||||||
.tar.gz files.
|
.tar.gz files. You can use `mattermost.buildPlugin` to build plugins;
|
||||||
|
see the NixOS documentation for more details.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
pluginsBundle = mkOption {
|
||||||
|
type = with types; nullOr package;
|
||||||
|
default = mattermostPlugins;
|
||||||
|
defaultText = ''
|
||||||
|
All entries in {config}`services.mattermost.plugins`, repacked
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
Derivation building to a directory of plugin tarballs.
|
||||||
|
This overrides {option}`services.mattermost.plugins` if provided.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -508,7 +522,8 @@ in
|
||||||
type = with types; attrsOf (either int str);
|
type = with types; attrsOf (either int str);
|
||||||
default = { };
|
default = { };
|
||||||
description = ''
|
description = ''
|
||||||
Extra environment variables to export to the Mattermost process, in the systemd unit.
|
Extra environment variables to export to the Mattermost process
|
||||||
|
from the systemd unit configuration.
|
||||||
'';
|
'';
|
||||||
example = {
|
example = {
|
||||||
MM_SERVICESETTINGS_SITEURL = "http://example.com";
|
MM_SERVICESETTINGS_SITEURL = "http://example.com";
|
||||||
|
@ -524,11 +539,11 @@ in
|
||||||
for mattermost (see [the Mattermost documentation](https://docs.mattermost.com/configure/configuration-settings.html#environment-variables)).
|
for mattermost (see [the Mattermost documentation](https://docs.mattermost.com/configure/configuration-settings.html#environment-variables)).
|
||||||
|
|
||||||
Settings defined in the environment file will overwrite settings
|
Settings defined in the environment file will overwrite settings
|
||||||
set via nix or via the {option}`services.mattermost.extraConfig`
|
set via Nix or via the {option}`services.mattermost.extraConfig`
|
||||||
option.
|
option.
|
||||||
|
|
||||||
Useful for setting config options without their value ending up in the
|
Useful for setting config options without their value ending up in the
|
||||||
(world-readable) nix store, e.g. for a database password.
|
(world-readable) Nix store, e.g. for a database password.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -639,13 +654,13 @@ in
|
||||||
if cfg.database.driver == "postgres" then
|
if cfg.database.driver == "postgres" then
|
||||||
{
|
{
|
||||||
sslmode = "disable";
|
sslmode = "disable";
|
||||||
connect_timeout = 30;
|
connect_timeout = 60;
|
||||||
}
|
}
|
||||||
else if cfg.database.driver == "mysql" then
|
else if cfg.database.driver == "mysql" then
|
||||||
{
|
{
|
||||||
charset = "utf8mb4,utf8";
|
charset = "utf8mb4,utf8";
|
||||||
writeTimeout = "30s";
|
writeTimeout = "60s";
|
||||||
readTimeout = "30s";
|
readTimeout = "60s";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw "Invalid database driver ${cfg.database.driver}";
|
throw "Invalid database driver ${cfg.database.driver}";
|
||||||
|
@ -653,13 +668,13 @@ in
|
||||||
if config.mattermost.database.driver == "postgres" then
|
if config.mattermost.database.driver == "postgres" then
|
||||||
{
|
{
|
||||||
sslmode = "disable";
|
sslmode = "disable";
|
||||||
connect_timeout = 30;
|
connect_timeout = 60;
|
||||||
}
|
}
|
||||||
else if config.mattermost.database.driver == "mysql" then
|
else if config.mattermost.database.driver == "mysql" then
|
||||||
{
|
{
|
||||||
charset = "utf8mb4,utf8";
|
charset = "utf8mb4,utf8";
|
||||||
writeTimeout = "30s";
|
writeTimeout = "60s";
|
||||||
readTimeout = "30s";
|
readTimeout = "60s";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw "Invalid database driver";
|
throw "Invalid database driver";
|
||||||
|
@ -687,7 +702,7 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
settings = mkOption {
|
settings = mkOption {
|
||||||
type = types.attrs;
|
inherit (format) type;
|
||||||
default = { };
|
default = { };
|
||||||
description = ''
|
description = ''
|
||||||
Additional configuration options as Nix attribute set in config.json schema.
|
Additional configuration options as Nix attribute set in config.json schema.
|
||||||
|
@ -786,7 +801,7 @@ in
|
||||||
"d= ${tempDir} 0750 ${cfg.user} ${cfg.group} - -"
|
"d= ${tempDir} 0750 ${cfg.user} ${cfg.group} - -"
|
||||||
|
|
||||||
# Ensure that pluginDir is a directory, as it could be a symlink on prior versions.
|
# Ensure that pluginDir is a directory, as it could be a symlink on prior versions.
|
||||||
"r- ${pluginDir} - - - - -"
|
# Don't remove or clean it out since it should be persistent, as this is where plugins are unpacked.
|
||||||
"d= ${pluginDir} 0750 ${cfg.user} ${cfg.group} - -"
|
"d= ${pluginDir} 0750 ${cfg.user} ${cfg.group} - -"
|
||||||
|
|
||||||
# Ensure that the plugin directories exist.
|
# Ensure that the plugin directories exist.
|
||||||
|
@ -801,15 +816,14 @@ in
|
||||||
"L+ ${cfg.dataDir}/client - - - - ${cfg.package}/client"
|
"L+ ${cfg.dataDir}/client - - - - ${cfg.package}/client"
|
||||||
]
|
]
|
||||||
++ (
|
++ (
|
||||||
if mattermostPlugins == null then
|
if cfg.pluginsBundle == null then
|
||||||
# Create the plugin tarball directory if it's a symlink.
|
# Create the plugin tarball directory to allow plugin uploads.
|
||||||
[
|
[
|
||||||
"r- ${cfg.dataDir}/plugins - - - - -"
|
|
||||||
"d= ${cfg.dataDir}/plugins 0750 ${cfg.user} ${cfg.group} - -"
|
"d= ${cfg.dataDir}/plugins 0750 ${cfg.user} ${cfg.group} - -"
|
||||||
]
|
]
|
||||||
else
|
else
|
||||||
# Symlink the plugin tarball directory, removing anything existing.
|
# Symlink the plugin tarball directory, removing anything existing, since it's managed by Nix.
|
||||||
[ "L+ ${cfg.dataDir}/plugins - - - - ${mattermostPlugins}" ]
|
[ "L+ ${cfg.dataDir}/plugins - - - - ${cfg.pluginsBundle}" ]
|
||||||
);
|
);
|
||||||
|
|
||||||
systemd.services.mattermost = rec {
|
systemd.services.mattermost = rec {
|
||||||
|
@ -836,7 +850,7 @@ in
|
||||||
configDir=${escapeShellArg cfg.configDir}
|
configDir=${escapeShellArg cfg.configDir}
|
||||||
logDir=${escapeShellArg cfg.logDir}
|
logDir=${escapeShellArg cfg.logDir}
|
||||||
package=${escapeShellArg cfg.package}
|
package=${escapeShellArg cfg.package}
|
||||||
nixConfig=${escapeShellArg mattermostConfJSON}
|
nixConfig=${escapeShellArg finalConfig}
|
||||||
''
|
''
|
||||||
+ optionalString (versionAtLeast config.system.stateVersion "25.05") ''
|
+ optionalString (versionAtLeast config.system.stateVersion "25.05") ''
|
||||||
# Migrate configs in the pre-25.05 directory structure.
|
# Migrate configs in the pre-25.05 directory structure.
|
||||||
|
|
209
nixos/tests/agnos.nix
Normal file
209
nixos/tests/agnos.nix
Normal file
|
@ -0,0 +1,209 @@
|
||||||
|
{
|
||||||
|
system ? builtins.currentSystem,
|
||||||
|
pkgs ? import ../.. { inherit system; },
|
||||||
|
lib ? pkgs.lib,
|
||||||
|
}:
|
||||||
|
|
||||||
|
let
|
||||||
|
inherit (import ../lib/testing-python.nix { inherit system pkgs; }) makeTest;
|
||||||
|
nodeIP = n: n.networking.primaryIPAddress;
|
||||||
|
dnsZone =
|
||||||
|
nodes:
|
||||||
|
pkgs.writeText "agnos.test.zone" ''
|
||||||
|
$TTL 604800
|
||||||
|
@ IN SOA ns1.agnos.test. root.agnos.test. (
|
||||||
|
3 ; Serial
|
||||||
|
604800 ; Refresh
|
||||||
|
86400 ; Retry
|
||||||
|
2419200 ; Expire
|
||||||
|
604800 ) ; Negative Cache TTL
|
||||||
|
;
|
||||||
|
; name servers - NS records
|
||||||
|
IN NS ns1.agnos.test.
|
||||||
|
|
||||||
|
; name servers - A records
|
||||||
|
ns1.agnos.test. IN A ${nodeIP nodes.dnsserver}
|
||||||
|
|
||||||
|
agnos-ns.agnos.test. IN A ${nodeIP nodes.server}
|
||||||
|
_acme-challenge.a.agnos.test. IN NS agnos-ns.agnos.test.
|
||||||
|
_acme-challenge.b.agnos.test. IN NS agnos-ns.agnos.test.
|
||||||
|
_acme-challenge.c.agnos.test. IN NS agnos-ns.agnos.test.
|
||||||
|
_acme-challenge.d.agnos.test. IN NS agnos-ns.agnos.test.
|
||||||
|
'';
|
||||||
|
|
||||||
|
mkTest =
|
||||||
|
{
|
||||||
|
name,
|
||||||
|
extraServerConfig ? { },
|
||||||
|
checkFirewallClosed ? true,
|
||||||
|
}:
|
||||||
|
makeTest {
|
||||||
|
inherit name;
|
||||||
|
meta = {
|
||||||
|
maintainers = with lib.maintainers; [ justinas ];
|
||||||
|
};
|
||||||
|
|
||||||
|
nodes = {
|
||||||
|
# The fake ACME server which will respond to client requests
|
||||||
|
acme =
|
||||||
|
{ nodes, pkgs, ... }:
|
||||||
|
{
|
||||||
|
imports = [ ./common/acme/server ];
|
||||||
|
environment.systemPackages = [ pkgs.netcat ];
|
||||||
|
networking.nameservers = lib.mkForce [ (nodeIP nodes.dnsserver) ];
|
||||||
|
};
|
||||||
|
|
||||||
|
# A fake DNS server which points _acme-challenge subdomains to "server"
|
||||||
|
dnsserver =
|
||||||
|
{ nodes, ... }:
|
||||||
|
{
|
||||||
|
networking.firewall.allowedTCPPorts = [ 53 ];
|
||||||
|
networking.firewall.allowedUDPPorts = [ 53 ];
|
||||||
|
services.bind = {
|
||||||
|
cacheNetworks = [ "192.168.1.0/24" ];
|
||||||
|
enable = true;
|
||||||
|
extraOptions = ''
|
||||||
|
dnssec-validation no;
|
||||||
|
'';
|
||||||
|
zones."agnos.test" = {
|
||||||
|
file = dnsZone nodes;
|
||||||
|
master = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# The server using agnos to request certificates
|
||||||
|
server =
|
||||||
|
{ nodes, ... }:
|
||||||
|
{
|
||||||
|
imports = [ extraServerConfig ];
|
||||||
|
|
||||||
|
networking.extraHosts = ''
|
||||||
|
${nodeIP nodes.acme} acme.test
|
||||||
|
'';
|
||||||
|
security.agnos = {
|
||||||
|
enable = true;
|
||||||
|
generateKeys.enable = true;
|
||||||
|
persistent = false;
|
||||||
|
server = "https://acme.test/dir";
|
||||||
|
serverCa = ./common/acme/server/ca.cert.pem;
|
||||||
|
temporarilyOpenFirewall = true;
|
||||||
|
|
||||||
|
settings.accounts = [
|
||||||
|
{
|
||||||
|
email = "webmaster@agnos.test";
|
||||||
|
# account with an existing private key
|
||||||
|
private_key_path = "${./common/acme/server/acme.test.key.pem}";
|
||||||
|
|
||||||
|
certificates = [
|
||||||
|
{
|
||||||
|
domains = [ "a.agnos.test" ];
|
||||||
|
# Absolute paths
|
||||||
|
fullchain_output_file = "/tmp/a.agnos.test.crt";
|
||||||
|
key_output_file = "/tmp/a.agnos.test.key";
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
domains = [
|
||||||
|
"b.agnos.test"
|
||||||
|
"*.b.agnos.test"
|
||||||
|
];
|
||||||
|
# Relative paths
|
||||||
|
fullchain_output_file = "b.agnos.test.crt";
|
||||||
|
key_output_file = "b.agnos.test.key";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
email = "webmaster2@agnos.test";
|
||||||
|
# account with a missing private key, should get generated
|
||||||
|
private_key_path = "webmaster2.key";
|
||||||
|
|
||||||
|
certificates = [
|
||||||
|
{
|
||||||
|
domains = [ "c.agnos.test" ];
|
||||||
|
# Absolute paths
|
||||||
|
fullchain_output_file = "/tmp/c.agnos.test.crt";
|
||||||
|
key_output_file = "/tmp/c.agnos.test.key";
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
domains = [
|
||||||
|
"d.agnos.test"
|
||||||
|
"*.d.agnos.test"
|
||||||
|
];
|
||||||
|
# Relative paths
|
||||||
|
fullchain_output_file = "d.agnos.test.crt";
|
||||||
|
key_output_file = "d.agnos.test.key";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
testScript = ''
|
||||||
|
def check_firewall_closed(caller):
|
||||||
|
"""
|
||||||
|
Check that TCP port 53 is closed again.
|
||||||
|
|
||||||
|
Since we do not set `networking.firewall.rejectPackets`,
|
||||||
|
"timed out" indicates a closed port,
|
||||||
|
while "connection refused" (after agnos has shut down) indicates an open port.
|
||||||
|
"""
|
||||||
|
|
||||||
|
out = caller.fail("nc -v -z -w 1 server 53 2>&1")
|
||||||
|
assert "Connection timed out" in out
|
||||||
|
|
||||||
|
start_all()
|
||||||
|
acme.wait_for_unit('pebble.service')
|
||||||
|
server.wait_for_unit('default.target')
|
||||||
|
|
||||||
|
# Test that agnos.timer is scheduled
|
||||||
|
server.succeed("systemctl status agnos.timer")
|
||||||
|
server.succeed('systemctl start agnos.service')
|
||||||
|
|
||||||
|
expected_perms = "640 agnos agnos"
|
||||||
|
outputs = [
|
||||||
|
"/tmp/a.agnos.test.crt",
|
||||||
|
"/tmp/a.agnos.test.key",
|
||||||
|
"/var/lib/agnos/b.agnos.test.crt",
|
||||||
|
"/var/lib/agnos/b.agnos.test.key",
|
||||||
|
"/var/lib/agnos/webmaster2.key",
|
||||||
|
"/tmp/c.agnos.test.crt",
|
||||||
|
"/tmp/c.agnos.test.key",
|
||||||
|
"/var/lib/agnos/d.agnos.test.crt",
|
||||||
|
"/var/lib/agnos/d.agnos.test.key",
|
||||||
|
]
|
||||||
|
for o in outputs:
|
||||||
|
out = server.succeed(f"stat -c '%a %U %G' {o}").strip()
|
||||||
|
assert out == expected_perms, \
|
||||||
|
f"Expected mode/owner/group to be '{expected_perms}', but it was '{out}'"
|
||||||
|
|
||||||
|
${lib.optionalString checkFirewallClosed "check_firewall_closed(acme)"}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
iptables = mkTest {
|
||||||
|
name = "iptables";
|
||||||
|
};
|
||||||
|
|
||||||
|
nftables = mkTest {
|
||||||
|
name = "nftables";
|
||||||
|
extraServerConfig = {
|
||||||
|
networking.nftables.enable = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
no-firewall = mkTest {
|
||||||
|
name = "no-firewall";
|
||||||
|
extraServerConfig = {
|
||||||
|
networking.firewall.enable = lib.mkForce false;
|
||||||
|
security.agnos.temporarilyOpenFirewall = lib.mkForce false;
|
||||||
|
};
|
||||||
|
checkFirewallClosed = false;
|
||||||
|
};
|
||||||
|
}
|
|
@ -177,6 +177,7 @@ in
|
||||||
agate = runTest ./web-servers/agate.nix;
|
agate = runTest ./web-servers/agate.nix;
|
||||||
agda = runTest ./agda.nix;
|
agda = runTest ./agda.nix;
|
||||||
age-plugin-tpm-decrypt = runTest ./age-plugin-tpm-decrypt.nix;
|
age-plugin-tpm-decrypt = runTest ./age-plugin-tpm-decrypt.nix;
|
||||||
|
agnos = discoverTests (import ./agnos.nix);
|
||||||
agorakit = runTest ./web-apps/agorakit.nix;
|
agorakit = runTest ./web-apps/agorakit.nix;
|
||||||
airsonic = runTest ./airsonic.nix;
|
airsonic = runTest ./airsonic.nix;
|
||||||
akkoma = runTestOn [ "x86_64-linux" "aarch64-linux" ] {
|
akkoma = runTestOn [ "x86_64-linux" "aarch64-linux" ] {
|
||||||
|
@ -338,6 +339,30 @@ in
|
||||||
containers-unified-hierarchy = handleTest ./containers-unified-hierarchy.nix { };
|
containers-unified-hierarchy = handleTest ./containers-unified-hierarchy.nix { };
|
||||||
convos = handleTest ./convos.nix { };
|
convos = handleTest ./convos.nix { };
|
||||||
corerad = handleTest ./corerad.nix { };
|
corerad = handleTest ./corerad.nix { };
|
||||||
|
cosmic = runTest {
|
||||||
|
imports = [ ./cosmic.nix ];
|
||||||
|
_module.args.testName = "cosmic";
|
||||||
|
_module.args.enableAutologin = false;
|
||||||
|
_module.args.enableXWayland = true;
|
||||||
|
};
|
||||||
|
cosmic-autologin = runTest {
|
||||||
|
imports = [ ./cosmic.nix ];
|
||||||
|
_module.args.testName = "cosmic-autologin";
|
||||||
|
_module.args.enableAutologin = true;
|
||||||
|
_module.args.enableXWayland = true;
|
||||||
|
};
|
||||||
|
cosmic-noxwayland = runTest {
|
||||||
|
imports = [ ./cosmic.nix ];
|
||||||
|
_module.args.testName = "cosmic-noxwayland";
|
||||||
|
_module.args.enableAutologin = false;
|
||||||
|
_module.args.enableXWayland = false;
|
||||||
|
};
|
||||||
|
cosmic-autologin-noxwayland = runTest {
|
||||||
|
imports = [ ./cosmic.nix ];
|
||||||
|
_module.args.testName = "cosmic-autologin-noxwayland";
|
||||||
|
_module.args.enableAutologin = true;
|
||||||
|
_module.args.enableXWayland = false;
|
||||||
|
};
|
||||||
coturn = handleTest ./coturn.nix { };
|
coturn = handleTest ./coturn.nix { };
|
||||||
couchdb = handleTest ./couchdb.nix { };
|
couchdb = handleTest ./couchdb.nix { };
|
||||||
crabfit = handleTest ./crabfit.nix { };
|
crabfit = handleTest ./crabfit.nix { };
|
||||||
|
@ -480,7 +505,7 @@ in
|
||||||
imports = [ ./firefox.nix ];
|
imports = [ ./firefox.nix ];
|
||||||
_module.args.firefoxPackage = pkgs.floorp;
|
_module.args.firefoxPackage = pkgs.floorp;
|
||||||
};
|
};
|
||||||
fluent-bit = handleTest ./fluent-bit.nix { };
|
fluent-bit = runTest ./fluent-bit.nix;
|
||||||
fluentd = handleTest ./fluentd.nix { };
|
fluentd = handleTest ./fluentd.nix { };
|
||||||
fluidd = handleTest ./fluidd.nix { };
|
fluidd = handleTest ./fluidd.nix { };
|
||||||
fontconfig-default-fonts = handleTest ./fontconfig-default-fonts.nix { };
|
fontconfig-default-fonts = handleTest ./fontconfig-default-fonts.nix { };
|
||||||
|
|
131
nixos/tests/cosmic.nix
Normal file
131
nixos/tests/cosmic.nix
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
testName,
|
||||||
|
enableAutologin,
|
||||||
|
enableXWayland,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
|
||||||
|
{
|
||||||
|
name = testName;
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
platforms = lib.platforms.linux;
|
||||||
|
maintainers = with lib.maintainers; [
|
||||||
|
thefossguy
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
nodes.machine = {
|
||||||
|
imports = [ ./common/user-account.nix ];
|
||||||
|
|
||||||
|
services = {
|
||||||
|
# For `cosmic-store` to be added to `environment.systemPackages`
|
||||||
|
# and for it to work correctly because Flatpak is a runtime
|
||||||
|
# dependency of `cosmic-store`.
|
||||||
|
flatpak.enable = true;
|
||||||
|
|
||||||
|
displayManager.cosmic-greeter.enable = true;
|
||||||
|
desktopManager.cosmic = {
|
||||||
|
enable = true;
|
||||||
|
xwayland.enable = enableXWayland;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.displayManager.autoLogin = lib.mkIf enableAutologin {
|
||||||
|
enable = true;
|
||||||
|
user = "alice";
|
||||||
|
};
|
||||||
|
|
||||||
|
environment.systemPackages = with config.node.pkgs; [
|
||||||
|
# These two packages are used to check if a window was opened
|
||||||
|
# under the COSMIC session or not. Kinda important.
|
||||||
|
# TODO: Move the check from the test module to
|
||||||
|
# `nixos/lib/test-driver/src/test_driver/machine.py` so more
|
||||||
|
# Wayland-only testing can be done using the existing testing
|
||||||
|
# infrastructure.
|
||||||
|
jq
|
||||||
|
lswt
|
||||||
|
];
|
||||||
|
|
||||||
|
# So far, all COSMIC tests launch a few GUI applications. In doing
|
||||||
|
# so, the default allocated memory to the guest of 1024M quickly
|
||||||
|
# poses a very high risk of an OOM-shutdown which is worse than an
|
||||||
|
# OOM-kill. Because now, the test failed, but not for a genuine
|
||||||
|
# reason, but an OOM-shutdown. That's an inconclusive failure
|
||||||
|
# which might possibly mask an actual failure. Not enabling
|
||||||
|
# systemd-oomd because we need said applications running for a
|
||||||
|
# few seconds. So instead, bump the allocated memory to the guest
|
||||||
|
# from 1024M to 4x; 4096M.
|
||||||
|
virtualisation.memorySize = 4096;
|
||||||
|
};
|
||||||
|
|
||||||
|
testScript =
|
||||||
|
{ nodes, ... }:
|
||||||
|
let
|
||||||
|
cfg = nodes.machine;
|
||||||
|
user = cfg.users.users.alice;
|
||||||
|
DISPLAY = lib.strings.optionalString enableXWayland (
|
||||||
|
if enableAutologin then "DISPLAY=:0" else "DISPLAY=:1"
|
||||||
|
);
|
||||||
|
in
|
||||||
|
''
|
||||||
|
#testName: ${testName}
|
||||||
|
''
|
||||||
|
+ (
|
||||||
|
if (enableAutologin) then
|
||||||
|
''
|
||||||
|
with subtest("cosmic-greeter initialisation"):
|
||||||
|
machine.wait_for_unit("graphical.target")
|
||||||
|
''
|
||||||
|
else
|
||||||
|
''
|
||||||
|
from time import sleep
|
||||||
|
|
||||||
|
machine.wait_for_unit("graphical.target")
|
||||||
|
machine.wait_until_succeeds("pgrep --uid ${toString cfg.users.users.cosmic-greeter.name} --full cosmic-greeter")
|
||||||
|
# Sleep for 10 seconds for ensuring that `greetd` loads the
|
||||||
|
# password prompt for the login screen properly.
|
||||||
|
sleep(10)
|
||||||
|
|
||||||
|
with subtest("cosmic-session login"):
|
||||||
|
machine.send_chars("${user.password}\n", delay=0.2)
|
||||||
|
''
|
||||||
|
)
|
||||||
|
+ ''
|
||||||
|
# _One_ of the final processes to start as part of the
|
||||||
|
# `cosmic-session` target is the Workspaces applet. So, wait
|
||||||
|
# for it to start. The process existing means that COSMIC
|
||||||
|
# now handles any opened windows from now on.
|
||||||
|
machine.wait_until_succeeds("pgrep --uid ${toString user.uid} --full 'cosmic-panel-button com.system76.CosmicWorkspaces'")
|
||||||
|
|
||||||
|
# The best way to test for Wayland and XWayland is to launch
|
||||||
|
# the GUI applications and see the results yourself.
|
||||||
|
with subtest("Launch applications"):
|
||||||
|
# key: binary_name
|
||||||
|
# value: "app-id" as reported by `lswt`
|
||||||
|
gui_apps_to_launch = {}
|
||||||
|
|
||||||
|
# We want to ensure that the first-party applications
|
||||||
|
# start/launch properly.
|
||||||
|
gui_apps_to_launch['cosmic-edit'] = 'com.system76.CosmicEdit'
|
||||||
|
gui_apps_to_launch['cosmic-files'] = 'com.system76.CosmicFiles'
|
||||||
|
gui_apps_to_launch['cosmic-player'] = 'com.system76.CosmicPlayer'
|
||||||
|
gui_apps_to_launch['cosmic-settings'] = 'com.system76.CosmicSettings'
|
||||||
|
gui_apps_to_launch['cosmic-store'] = 'com.system76.CosmicStore'
|
||||||
|
gui_apps_to_launch['cosmic-term'] = 'com.system76.CosmicTerm'
|
||||||
|
|
||||||
|
for gui_app, app_id in gui_apps_to_launch.items():
|
||||||
|
machine.succeed(f"su - ${user.name} -c 'WAYLAND_DISPLAY=wayland-1 XDG_RUNTIME_DIR=/run/user/${toString user.uid} ${DISPLAY} {gui_app} >&2 &'", timeout=5)
|
||||||
|
# Nix builds the following non-commented expression to the following:
|
||||||
|
# `su - alice -c 'WAYLAND_DISPLAY=wayland-1 XDG_RUNTIME_DIR=/run/user/1000 lswt --json | jq ".toplevels" | grep "^ \\"app-id\\": \\"{app_id}\\"$"' `
|
||||||
|
machine.wait_until_succeeds(f''''su - ${user.name} -c 'WAYLAND_DISPLAY=wayland-1 XDG_RUNTIME_DIR=/run/user/${toString user.uid} lswt --json | jq ".toplevels" | grep "^ \\"app-id\\": \\"{app_id}\\"$"' '''', timeout=30)
|
||||||
|
machine.succeed(f"pkill {gui_app}", timeout=5)
|
||||||
|
|
||||||
|
machine.succeed("echo 'test completed succeessfully' > /${testName}")
|
||||||
|
machine.copy_from_vm('/${testName}')
|
||||||
|
|
||||||
|
machine.shutdown()
|
||||||
|
'';
|
||||||
|
}
|
|
@ -9,7 +9,7 @@ let
|
||||||
src = pkgs.fetchFromGitHub {
|
src = pkgs.fetchFromGitHub {
|
||||||
owner = "giterlizzi";
|
owner = "giterlizzi";
|
||||||
repo = "dokuwiki-template-bootstrap3";
|
repo = "dokuwiki-template-bootstrap3";
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
hash = "sha256-B3Yd4lxdwqfCnfmZdp+i/Mzwn/aEuZ0ovagDxuR6lxo=";
|
hash = "sha256-B3Yd4lxdwqfCnfmZdp+i/Mzwn/aEuZ0ovagDxuR6lxo=";
|
||||||
};
|
};
|
||||||
installPhase = "mkdir -p $out; cp -R * $out/";
|
installPhase = "mkdir -p $out; cp -R * $out/";
|
||||||
|
|
|
@ -1,40 +1,56 @@
|
||||||
import ./make-test-python.nix (
|
# Regression test for https://github.com/NixOS/nixpkgs/pull/395128
|
||||||
{ lib, pkgs, ... }:
|
{
|
||||||
{
|
name = "fluent-bit";
|
||||||
name = "fluent-bit";
|
nodes.machine = {
|
||||||
|
services.fluent-bit = {
|
||||||
nodes.machine =
|
enable = true;
|
||||||
{ config, pkgs, ... }:
|
settings = {
|
||||||
{
|
pipeline = {
|
||||||
services.fluent-bit = {
|
inputs = [
|
||||||
enable = true;
|
{
|
||||||
settings = {
|
name = "systemd";
|
||||||
pipeline = {
|
systemd_filter = "_SYSTEMD_UNIT=fluent-bit-regression-395128.service";
|
||||||
inputs = [
|
}
|
||||||
{
|
];
|
||||||
name = "systemd";
|
outputs = [
|
||||||
systemd_filter = "_SYSTEMD_UNIT=fluent-bit.service";
|
{
|
||||||
}
|
name = "file";
|
||||||
];
|
path = "/var/log/fluent-bit";
|
||||||
outputs = [
|
file = "fluent-bit.out";
|
||||||
{
|
}
|
||||||
name = "file";
|
];
|
||||||
path = "/var/log/fluent-bit";
|
|
||||||
file = "fluent-bit.out";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
systemd.services.fluent-bit.serviceConfig.LogsDirectory = "fluent-bit";
|
|
||||||
};
|
};
|
||||||
|
};
|
||||||
|
systemd.services.fluent-bit.serviceConfig.LogsDirectory = "fluent-bit";
|
||||||
|
|
||||||
testScript = ''
|
# Logs get compressed when larger than 1024 bytes
|
||||||
start_all()
|
# Lets generate some logs that trigger that
|
||||||
|
# This causes libzstd to be dlopen'd by systemd which breaks fluent-bit 3.2.7+
|
||||||
|
# https://www.freedesktop.org/software/systemd/man/latest/journald.conf.html#Compress=
|
||||||
|
systemd.services.fluent-bit-regression-395128 = {
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
RemainAfterExit = true;
|
||||||
|
};
|
||||||
|
script = ''
|
||||||
|
for i in {1..20}; do
|
||||||
|
(head -c 1200 < /dev/zero | tr '\0' 'A') && echo
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
machine.wait_for_unit("fluent-bit.service")
|
testScript = ''
|
||||||
machine.wait_for_file("/var/log/fluent-bit/fluent-bit.out")
|
start_all()
|
||||||
'';
|
|
||||||
}
|
machine.wait_for_unit("fluent-bit.service")
|
||||||
)
|
|
||||||
|
with subtest("fluent-bit handles zstd-compressed journal logs"):
|
||||||
|
machine.succeed("systemctl start fluent-bit-regression-395128.service")
|
||||||
|
machine.succeed("systemctl show -p NRestarts fluent-bit.service | grep -q 'NRestarts=0'")
|
||||||
|
|
||||||
|
machine.wait_for_file("/var/log/fluent-bit/fluent-bit.out")
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ import ../make-test-python.nix (
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
system.stateVersion = lib.mkDefault "25.05";
|
system.stateVersion = lib.mkDefault (lib.versions.majorMinor lib.version);
|
||||||
|
|
||||||
services.mattermost = lib.recursiveUpdate {
|
services.mattermost = lib.recursiveUpdate {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
@ -63,7 +63,7 @@ import ../make-test-python.nix (
|
||||||
# Upgrade to the latest Mattermost.
|
# Upgrade to the latest Mattermost.
|
||||||
specialisation.latest.configuration = {
|
specialisation.latest.configuration = {
|
||||||
services.mattermost.package = lib.mkForce pkgs.mattermostLatest;
|
services.mattermost.package = lib.mkForce pkgs.mattermostLatest;
|
||||||
system.stateVersion = lib.mkVMOverride "25.05";
|
system.stateVersion = lib.mkVMOverride (lib.versions.majorMinor lib.version);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -90,57 +90,60 @@ import ../make-test-python.nix (
|
||||||
name = "mattermost";
|
name = "mattermost";
|
||||||
|
|
||||||
nodes = rec {
|
nodes = rec {
|
||||||
postgresMutable =
|
postgresMutable = makeMattermost {
|
||||||
|
mutableConfig = true;
|
||||||
|
preferNixConfig = false;
|
||||||
|
settings.SupportSettings.HelpLink = "https://search.nixos.org";
|
||||||
|
} { };
|
||||||
|
postgresMostlyMutable =
|
||||||
makeMattermost
|
makeMattermost
|
||||||
{
|
{
|
||||||
mutableConfig = true;
|
mutableConfig = true;
|
||||||
preferNixConfig = false;
|
preferNixConfig = true;
|
||||||
settings.SupportSettings.HelpLink = "https://search.nixos.org";
|
plugins = with pkgs; [
|
||||||
|
# Build the demo plugin.
|
||||||
|
(mattermost.buildPlugin {
|
||||||
|
pname = "mattermost-plugin-starter-template";
|
||||||
|
version = "0.1.0";
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "mattermost";
|
||||||
|
repo = "mattermost-plugin-starter-template";
|
||||||
|
# Newer versions have issues with their dependency lockfile.
|
||||||
|
rev = "7c98e89ac1a268ce8614bc665571b7bbc9a70df2";
|
||||||
|
hash = "sha256-uyfxB0GZ45qL9ssWUord0eKQC6S0TlCTtjTOXWtK4H0=";
|
||||||
|
};
|
||||||
|
vendorHash = "sha256-Jl4F9YkHNqiFP9/yeyi4vTntqxMk/J1zhEP6QLSvJQA=";
|
||||||
|
npmDepsHash = "sha256-z08nc4XwT+uQjQlZiUydJyh8mqeJoYdPFWuZpw9k99s=";
|
||||||
|
})
|
||||||
|
|
||||||
|
# Build the todos plugin.
|
||||||
|
(mattermost.buildPlugin {
|
||||||
|
pname = "mattermost-plugin-todo";
|
||||||
|
version = "0.8-pre";
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "mattermost-community";
|
||||||
|
repo = "mattermost-plugin-todo";
|
||||||
|
# 0.7.1 didn't work, seems to use an older set of node dependencies.
|
||||||
|
rev = "f25dc91ea401c9f0dcd4abcebaff10eb8b9836e5";
|
||||||
|
hash = "sha256-OM+m4rTqVtolvL5tUE8RKfclqzoe0Y38jLU60Pz7+HI=";
|
||||||
|
};
|
||||||
|
vendorHash = "sha256-5KpechSp3z/Nq713PXYruyNxveo6CwrCSKf2JaErbgg=";
|
||||||
|
npmDepsHash = "sha256-o2UOEkwb8Vx2lDWayNYgng0GXvmS6lp/ExfOq3peyMY=";
|
||||||
|
extraGoModuleAttrs = {
|
||||||
|
npmFlags = [ "--legacy-peer-deps" ];
|
||||||
|
};
|
||||||
|
})
|
||||||
|
];
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
# Last version to support the "old" config layout.
|
# Last version to support the "old" config layout.
|
||||||
system.stateVersion = lib.mkForce "24.11";
|
system.stateVersion = lib.mkForce "24.11";
|
||||||
|
|
||||||
# First version to support the "new" config layout.
|
# Supports the "new" config layout.
|
||||||
specialisation.upgrade.configuration.system.stateVersion = lib.mkVMOverride "25.05";
|
specialisation.upgrade.configuration.system.stateVersion = lib.mkVMOverride (
|
||||||
|
lib.versions.majorMinor lib.version
|
||||||
|
);
|
||||||
};
|
};
|
||||||
postgresMostlyMutable = makeMattermost {
|
|
||||||
mutableConfig = true;
|
|
||||||
plugins = with pkgs; [
|
|
||||||
# Build the demo plugin.
|
|
||||||
(mattermost.buildPlugin {
|
|
||||||
pname = "mattermost-plugin-starter-template";
|
|
||||||
version = "0.1.0";
|
|
||||||
src = fetchFromGitHub {
|
|
||||||
owner = "mattermost";
|
|
||||||
repo = "mattermost-plugin-starter-template";
|
|
||||||
# Newer versions have issues with their dependency lockfile.
|
|
||||||
rev = "7c98e89ac1a268ce8614bc665571b7bbc9a70df2";
|
|
||||||
hash = "sha256-uyfxB0GZ45qL9ssWUord0eKQC6S0TlCTtjTOXWtK4H0=";
|
|
||||||
};
|
|
||||||
vendorHash = "sha256-Jl4F9YkHNqiFP9/yeyi4vTntqxMk/J1zhEP6QLSvJQA=";
|
|
||||||
npmDepsHash = "sha256-z08nc4XwT+uQjQlZiUydJyh8mqeJoYdPFWuZpw9k99s=";
|
|
||||||
})
|
|
||||||
|
|
||||||
# Build the todos plugin.
|
|
||||||
(mattermost.buildPlugin {
|
|
||||||
pname = "mattermost-plugin-todo";
|
|
||||||
version = "0.8-pre";
|
|
||||||
src = fetchFromGitHub {
|
|
||||||
owner = "mattermost-community";
|
|
||||||
repo = "mattermost-plugin-todo";
|
|
||||||
# 0.7.1 didn't work, seems to use an older set of node dependencies.
|
|
||||||
rev = "f25dc91ea401c9f0dcd4abcebaff10eb8b9836e5";
|
|
||||||
hash = "sha256-OM+m4rTqVtolvL5tUE8RKfclqzoe0Y38jLU60Pz7+HI=";
|
|
||||||
};
|
|
||||||
vendorHash = "sha256-5KpechSp3z/Nq713PXYruyNxveo6CwrCSKf2JaErbgg=";
|
|
||||||
npmDepsHash = "sha256-o2UOEkwb8Vx2lDWayNYgng0GXvmS6lp/ExfOq3peyMY=";
|
|
||||||
extraGoModuleAttrs = {
|
|
||||||
npmFlags = [ "--legacy-peer-deps" ];
|
|
||||||
};
|
|
||||||
})
|
|
||||||
];
|
|
||||||
} { };
|
|
||||||
postgresImmutable = makeMattermost {
|
postgresImmutable = makeMattermost {
|
||||||
package = pkgs.mattermost.overrideAttrs (prev: {
|
package = pkgs.mattermost.overrideAttrs (prev: {
|
||||||
webapp = prev.webapp.overrideAttrs (prevWebapp: {
|
webapp = prev.webapp.overrideAttrs (prevWebapp: {
|
||||||
|
@ -343,9 +346,14 @@ import ../make-test-python.nix (
|
||||||
'';
|
'';
|
||||||
in
|
in
|
||||||
''
|
''
|
||||||
|
import sys
|
||||||
import shlex
|
import shlex
|
||||||
|
import threading
|
||||||
|
import queue
|
||||||
|
|
||||||
def wait_mattermost_up(node, site_name="${siteName}"):
|
def wait_mattermost_up(node, site_name="${siteName}"):
|
||||||
|
print(f"wait_mattermost_up({node.name!r}, site_name={site_name!r})", file=sys.stderr)
|
||||||
|
node.wait_for_unit("multi-user.target")
|
||||||
node.systemctl("start mattermost.service")
|
node.systemctl("start mattermost.service")
|
||||||
node.wait_for_unit("mattermost.service")
|
node.wait_for_unit("mattermost.service")
|
||||||
node.wait_for_open_port(8065)
|
node.wait_for_open_port(8065)
|
||||||
|
@ -353,20 +361,25 @@ import ../make-test-python.nix (
|
||||||
node.succeed(f"curl {shlex.quote('${url}')}/index.html | grep {shlex.quote(site_name)}")
|
node.succeed(f"curl {shlex.quote('${url}')}/index.html | grep {shlex.quote(site_name)}")
|
||||||
|
|
||||||
def restart_mattermost(node, site_name="${siteName}"):
|
def restart_mattermost(node, site_name="${siteName}"):
|
||||||
|
print(f"restart_mattermost({node.name!r}, site_name={site_name!r})", file=sys.stderr)
|
||||||
node.systemctl("restart mattermost.service")
|
node.systemctl("restart mattermost.service")
|
||||||
wait_mattermost_up(node, site_name)
|
wait_mattermost_up(node, site_name)
|
||||||
|
|
||||||
def expect_config(node, mattermost_version, *configs):
|
def expect_config(node, mattermost_version, *configs):
|
||||||
|
print(f"expect_config({node.name!r}, {mattermost_version!r}, *{configs!r})", file=sys.stderr)
|
||||||
for config in configs:
|
for config in configs:
|
||||||
node.succeed(f"${expectConfig} {shlex.quote(config)} {shlex.quote(mattermost_version)}")
|
node.succeed(f"${expectConfig} {shlex.quote(config)} {shlex.quote(mattermost_version)}")
|
||||||
|
|
||||||
def expect_plugins(node, jq_or_code):
|
def expect_plugins(node, jq_or_code):
|
||||||
|
print(f"expect_plugins({node.name!r}, {jq_or_code!r})", file=sys.stderr)
|
||||||
node.succeed(f"${expectPlugins} {shlex.quote(str(jq_or_code))}")
|
node.succeed(f"${expectPlugins} {shlex.quote(str(jq_or_code))}")
|
||||||
|
|
||||||
def ensure_post(node, fail_if_not_found=False):
|
def ensure_post(node, fail_if_not_found=False):
|
||||||
|
print(f"ensure_post({node.name!r}, fail_if_not_found={fail_if_not_found!r})", file=sys.stderr)
|
||||||
node.succeed(f"${ensurePost} {shlex.quote('${url}')} {1 if fail_if_not_found else 0}")
|
node.succeed(f"${ensurePost} {shlex.quote('${url}')} {1 if fail_if_not_found else 0}")
|
||||||
|
|
||||||
def set_config(node, *configs, nixos_version='25.05'):
|
def set_config(node, *configs, nixos_version='${lib.versions.majorMinor lib.version}'):
|
||||||
|
print(f"set_config({node.name!r}, *{configs!r}, nixos_version={nixos_version!r})", file=sys.stderr)
|
||||||
for config in configs:
|
for config in configs:
|
||||||
args = [shlex.quote("${setConfig}")]
|
args = [shlex.quote("${setConfig}")]
|
||||||
args.append(shlex.quote(config))
|
args.append(shlex.quote(config))
|
||||||
|
@ -374,8 +387,13 @@ import ../make-test-python.nix (
|
||||||
args.append(shlex.quote(str(nixos_version)))
|
args.append(shlex.quote(str(nixos_version)))
|
||||||
node.succeed(' '.join(args))
|
node.succeed(' '.join(args))
|
||||||
|
|
||||||
def run_mattermost_tests(mutableToplevel: str, mutable,
|
def switch_to_specialisation(node, toplevel: str, specialisation: str):
|
||||||
mostlyMutableToplevel: str, mostlyMutable,
|
print(f"switch_to_specialisation({node.name!r}, {toplevel!r}, {specialisation!r})", file=sys.stderr)
|
||||||
|
node.succeed(f"{toplevel}/specialisation/{specialisation}/bin/switch-to-configuration switch || true")
|
||||||
|
|
||||||
|
def run_mattermost_tests(shutdown_queue: queue.Queue,
|
||||||
|
mutableToplevel: str, mutable,
|
||||||
|
mostlyMutableToplevel: str, mostlyMutablePlugins: str, mostlyMutable,
|
||||||
immutableToplevel: str, immutable,
|
immutableToplevel: str, immutable,
|
||||||
environmentFileToplevel: str, environmentFile):
|
environmentFileToplevel: str, environmentFile):
|
||||||
esr, latest = '${pkgs.mattermost.version}', '${pkgs.mattermostLatest.version}'
|
esr, latest = '${pkgs.mattermost.version}', '${pkgs.mattermostLatest.version}'
|
||||||
|
@ -391,8 +409,7 @@ import ../make-test-python.nix (
|
||||||
set_config(
|
set_config(
|
||||||
mutable,
|
mutable,
|
||||||
'.SupportSettings.AboutLink = "https://mattermost.com"',
|
'.SupportSettings.AboutLink = "https://mattermost.com"',
|
||||||
'.SupportSettings.HelpLink = "https://nixos.org/nixos/manual"',
|
'.SupportSettings.HelpLink = "https://nixos.org/nixos/manual"'
|
||||||
nixos_version='24.11' # Default 'mutable' config is an old version
|
|
||||||
)
|
)
|
||||||
ensure_post(mutable)
|
ensure_post(mutable)
|
||||||
restart_mattermost(mutable)
|
restart_mattermost(mutable)
|
||||||
|
@ -401,23 +418,14 @@ import ../make-test-python.nix (
|
||||||
expect_config(mutable, esr, '.AboutLink == "https://mattermost.com" and .HelpLink == "https://nixos.org/nixos/manual"')
|
expect_config(mutable, esr, '.AboutLink == "https://mattermost.com" and .HelpLink == "https://nixos.org/nixos/manual"')
|
||||||
ensure_post(mutable, fail_if_not_found=True)
|
ensure_post(mutable, fail_if_not_found=True)
|
||||||
|
|
||||||
# Switch to the newer config
|
|
||||||
mutable.succeed(f"{mutableToplevel}/specialisation/upgrade/bin/switch-to-configuration switch")
|
|
||||||
wait_mattermost_up(mutable)
|
|
||||||
|
|
||||||
# AboutLink and HelpLink should be changed, still, and the post should still exist
|
|
||||||
expect_config(mutable, esr, '.AboutLink == "https://mattermost.com" and .HelpLink == "https://nixos.org/nixos/manual"')
|
|
||||||
ensure_post(mutable, fail_if_not_found=True)
|
|
||||||
|
|
||||||
# Switch to the latest Mattermost version
|
# Switch to the latest Mattermost version
|
||||||
mutable.succeed(f"{mutableToplevel}/specialisation/latest/bin/switch-to-configuration switch")
|
switch_to_specialisation(mutable, mutableToplevel, "latest")
|
||||||
wait_mattermost_up(mutable)
|
wait_mattermost_up(mutable)
|
||||||
|
|
||||||
# AboutLink and HelpLink should be changed, still, and the post should still exist
|
# AboutLink and HelpLink should be changed, still, and the post should still exist
|
||||||
expect_config(mutable, latest, '.AboutLink == "https://mattermost.com" and .HelpLink == "https://nixos.org/nixos/manual"')
|
expect_config(mutable, latest, '.AboutLink == "https://mattermost.com" and .HelpLink == "https://nixos.org/nixos/manual"')
|
||||||
ensure_post(mutable, fail_if_not_found=True)
|
ensure_post(mutable, fail_if_not_found=True)
|
||||||
|
shutdown_queue.put(mutable)
|
||||||
mutable.shutdown()
|
|
||||||
|
|
||||||
## Mostly mutable node tests ##
|
## Mostly mutable node tests ##
|
||||||
mostlyMutable.start()
|
mostlyMutable.start()
|
||||||
|
@ -434,13 +442,40 @@ import ../make-test-python.nix (
|
||||||
mostlyMutable,
|
mostlyMutable,
|
||||||
'.SupportSettings.AboutLink = "https://mattermost.com"',
|
'.SupportSettings.AboutLink = "https://mattermost.com"',
|
||||||
'.SupportSettings.HelpLink = "https://nixos.org/nixos/manual"',
|
'.SupportSettings.HelpLink = "https://nixos.org/nixos/manual"',
|
||||||
|
nixos_version='24.11' # Default 'mostlyMutable' config is an old version
|
||||||
|
)
|
||||||
|
ensure_post(mostlyMutable)
|
||||||
|
restart_mattermost(mostlyMutable)
|
||||||
|
|
||||||
|
# HelpLink should be changed but AboutLink should not, and the post should exist
|
||||||
|
expect_config(mostlyMutable, esr, '.AboutLink == "https://nixos.org" and .HelpLink == "https://nixos.org/nixos/manual"')
|
||||||
|
ensure_post(mostlyMutable, fail_if_not_found=True)
|
||||||
|
|
||||||
|
# Switch to the newer config and make sure the plugins directory is replaced with a directory,
|
||||||
|
# since it could have been a symlink on previous versions.
|
||||||
|
mostlyMutable.systemctl("stop mattermost.service")
|
||||||
|
mostlyMutable.succeed(f"[ ! -L /var/lib/mattermost/data/plugins ] && rm -rf /var/lib/mattermost/data/plugins && ln -s {mostlyMutablePlugins} /var/lib/mattermost/data/plugins || true")
|
||||||
|
mostlyMutable.succeed('[ -L /var/lib/mattermost/data/plugins ] && [ -d /var/lib/mattermost/data/plugins ]')
|
||||||
|
switch_to_specialisation(mostlyMutable, mostlyMutableToplevel, "upgrade")
|
||||||
|
wait_mattermost_up(mostlyMutable)
|
||||||
|
mostlyMutable.succeed('[ ! -L /var/lib/mattermost/data/plugins ] && [ -d /var/lib/mattermost/data/plugins ]')
|
||||||
|
|
||||||
|
# HelpLink should be changed, still, and the post should still exist
|
||||||
|
expect_config(mostlyMutable, esr, '.AboutLink == "https://nixos.org" and .HelpLink == "https://nixos.org/nixos/manual"')
|
||||||
|
ensure_post(mostlyMutable, fail_if_not_found=True)
|
||||||
|
|
||||||
|
# Edit the config and make a post
|
||||||
|
set_config(
|
||||||
|
mostlyMutable,
|
||||||
|
'.SupportSettings.AboutLink = "https://mattermost.com/foo"',
|
||||||
|
'.SupportSettings.HelpLink = "https://nixos.org/nixos/manual/bar"',
|
||||||
'.PluginSettings.PluginStates."com.mattermost.plugin-todo".Enable = true'
|
'.PluginSettings.PluginStates."com.mattermost.plugin-todo".Enable = true'
|
||||||
)
|
)
|
||||||
ensure_post(mostlyMutable)
|
ensure_post(mostlyMutable)
|
||||||
restart_mattermost(mostlyMutable)
|
restart_mattermost(mostlyMutable)
|
||||||
|
|
||||||
# AboutLink should be overridden by NixOS configuration; HelpLink should be what we set above
|
# AboutLink should be overridden by NixOS configuration; HelpLink should be what we set above
|
||||||
expect_config(mostlyMutable, esr, '.AboutLink == "https://nixos.org" and .HelpLink == "https://nixos.org/nixos/manual"')
|
expect_config(mostlyMutable, esr, '.AboutLink == "https://nixos.org" and .HelpLink == "https://nixos.org/nixos/manual/bar"')
|
||||||
|
|
||||||
# Single plugin that's now enabled.
|
# Single plugin that's now enabled.
|
||||||
expect_plugins(mostlyMutable, 'length == 1')
|
expect_plugins(mostlyMutable, 'length == 1')
|
||||||
|
@ -449,14 +484,14 @@ import ../make-test-python.nix (
|
||||||
ensure_post(mostlyMutable, fail_if_not_found=True)
|
ensure_post(mostlyMutable, fail_if_not_found=True)
|
||||||
|
|
||||||
# Switch to the latest Mattermost version
|
# Switch to the latest Mattermost version
|
||||||
mostlyMutable.succeed(f"{mostlyMutableToplevel}/specialisation/latest/bin/switch-to-configuration switch")
|
switch_to_specialisation(mostlyMutable, mostlyMutableToplevel, "latest")
|
||||||
wait_mattermost_up(mostlyMutable)
|
wait_mattermost_up(mostlyMutable)
|
||||||
|
|
||||||
# AboutLink should be overridden and the post should still exist
|
# AboutLink should be overridden and the post should still exist
|
||||||
expect_config(mostlyMutable, latest, '.AboutLink == "https://nixos.org" and .HelpLink == "https://nixos.org/nixos/manual"')
|
expect_config(mostlyMutable, latest, '.AboutLink == "https://nixos.org" and .HelpLink == "https://nixos.org/nixos/manual/bar"')
|
||||||
ensure_post(mostlyMutable, fail_if_not_found=True)
|
ensure_post(mostlyMutable, fail_if_not_found=True)
|
||||||
|
|
||||||
mostlyMutable.shutdown()
|
shutdown_queue.put(mostlyMutable)
|
||||||
|
|
||||||
## Immutable node tests ##
|
## Immutable node tests ##
|
||||||
immutable.start()
|
immutable.start()
|
||||||
|
@ -484,14 +519,14 @@ import ../make-test-python.nix (
|
||||||
ensure_post(immutable, fail_if_not_found=True)
|
ensure_post(immutable, fail_if_not_found=True)
|
||||||
|
|
||||||
# Switch to the latest Mattermost version
|
# Switch to the latest Mattermost version
|
||||||
immutable.succeed(f"{immutableToplevel}/specialisation/latest/bin/switch-to-configuration switch")
|
switch_to_specialisation(immutable, immutableToplevel, "latest")
|
||||||
wait_mattermost_up(immutable)
|
wait_mattermost_up(immutable)
|
||||||
|
|
||||||
# AboutLink and HelpLink should be changed, still, and the post should still exist
|
# AboutLink and HelpLink should be changed, still, and the post should still exist
|
||||||
expect_config(immutable, latest, '.AboutLink == "https://nixos.org" and .HelpLink == "https://search.nixos.org"')
|
expect_config(immutable, latest, '.AboutLink == "https://nixos.org" and .HelpLink == "https://search.nixos.org"')
|
||||||
ensure_post(immutable, fail_if_not_found=True)
|
ensure_post(immutable, fail_if_not_found=True)
|
||||||
|
|
||||||
immutable.shutdown()
|
shutdown_queue.put(immutable)
|
||||||
|
|
||||||
## Environment File node tests ##
|
## Environment File node tests ##
|
||||||
environmentFile.start()
|
environmentFile.start()
|
||||||
|
@ -503,36 +538,56 @@ import ../make-test-python.nix (
|
||||||
ensure_post(environmentFile, fail_if_not_found=True)
|
ensure_post(environmentFile, fail_if_not_found=True)
|
||||||
|
|
||||||
# Switch to the latest Mattermost version
|
# Switch to the latest Mattermost version
|
||||||
environmentFile.succeed(f"{environmentFileToplevel}/specialisation/latest/bin/switch-to-configuration switch")
|
switch_to_specialisation(environmentFile, environmentFileToplevel, "latest")
|
||||||
wait_mattermost_up(environmentFile)
|
wait_mattermost_up(environmentFile)
|
||||||
|
|
||||||
# AboutLink should be changed still, and the post should still exist
|
# AboutLink should be changed still, and the post should still exist
|
||||||
expect_config(environmentFile, latest, '.AboutLink == "https://nixos.org"')
|
expect_config(environmentFile, latest, '.AboutLink == "https://nixos.org"')
|
||||||
ensure_post(environmentFile, fail_if_not_found=True)
|
ensure_post(environmentFile, fail_if_not_found=True)
|
||||||
|
|
||||||
environmentFile.shutdown()
|
shutdown_queue.put(environmentFile)
|
||||||
|
|
||||||
run_mattermost_tests(
|
# Run shutdowns asynchronously so we can pipeline them.
|
||||||
"${nodes.mysqlMutable.system.build.toplevel}",
|
shutdown_queue: queue.Queue = queue.Queue()
|
||||||
mysqlMutable,
|
def shutdown_worker():
|
||||||
"${nodes.mysqlMostlyMutable.system.build.toplevel}",
|
while True:
|
||||||
mysqlMostlyMutable,
|
node = shutdown_queue.get()
|
||||||
"${nodes.mysqlImmutable.system.build.toplevel}",
|
print(f"Shutting down node {node.name!r} asynchronously", file=sys.stderr)
|
||||||
mysqlImmutable,
|
node.shutdown()
|
||||||
"${nodes.mysqlEnvironmentFile.system.build.toplevel}",
|
shutdown_queue.task_done()
|
||||||
mysqlEnvironmentFile
|
threading.Thread(target=shutdown_worker, daemon=True).start()
|
||||||
)
|
|
||||||
|
${pkgs.lib.optionalString pkgs.stdenv.isx86_64 ''
|
||||||
|
# Only run the MySQL tests on x86_64 so we don't have to debug MySQL ARM issues.
|
||||||
|
run_mattermost_tests(
|
||||||
|
shutdown_queue,
|
||||||
|
"${nodes.mysqlMutable.system.build.toplevel}",
|
||||||
|
mysqlMutable,
|
||||||
|
"${nodes.mysqlMostlyMutable.system.build.toplevel}",
|
||||||
|
"${nodes.mysqlMostlyMutable.services.mattermost.pluginsBundle}",
|
||||||
|
mysqlMostlyMutable,
|
||||||
|
"${nodes.mysqlImmutable.system.build.toplevel}",
|
||||||
|
mysqlImmutable,
|
||||||
|
"${nodes.mysqlEnvironmentFile.system.build.toplevel}",
|
||||||
|
mysqlEnvironmentFile
|
||||||
|
)
|
||||||
|
''}
|
||||||
|
|
||||||
run_mattermost_tests(
|
run_mattermost_tests(
|
||||||
|
shutdown_queue,
|
||||||
"${nodes.postgresMutable.system.build.toplevel}",
|
"${nodes.postgresMutable.system.build.toplevel}",
|
||||||
postgresMutable,
|
postgresMutable,
|
||||||
"${nodes.postgresMostlyMutable.system.build.toplevel}",
|
"${nodes.postgresMostlyMutable.system.build.toplevel}",
|
||||||
|
"${nodes.postgresMostlyMutable.services.mattermost.pluginsBundle}",
|
||||||
postgresMostlyMutable,
|
postgresMostlyMutable,
|
||||||
"${nodes.postgresImmutable.system.build.toplevel}",
|
"${nodes.postgresImmutable.system.build.toplevel}",
|
||||||
postgresImmutable,
|
postgresImmutable,
|
||||||
"${nodes.postgresEnvironmentFile.system.build.toplevel}",
|
"${nodes.postgresEnvironmentFile.system.build.toplevel}",
|
||||||
postgresEnvironmentFile
|
postgresEnvironmentFile
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Drain the queue
|
||||||
|
shutdown_queue.join()
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -21,7 +21,7 @@ let
|
||||||
airwave-src = fetchFromGitHub {
|
airwave-src = fetchFromGitHub {
|
||||||
owner = "phantom-code";
|
owner = "phantom-code";
|
||||||
repo = "airwave";
|
repo = "airwave";
|
||||||
rev = version;
|
tag = version;
|
||||||
sha256 = "1ban59skw422mak3cp57lj27hgq5d3a4f6y79ysjnamf8rpz9x4s";
|
sha256 = "1ban59skw422mak3cp57lj27hgq5d3a4f6y79ysjnamf8rpz9x4s";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,7 @@ stdenv.mkDerivation rec {
|
||||||
# result in an empty archive. See https://tracker.ardour.org/view.php?id=7328 for more info.
|
# result in an empty archive. See https://tracker.ardour.org/view.php?id=7328 for more info.
|
||||||
src = fetchgit {
|
src = fetchgit {
|
||||||
url = "git://git.ardour.org/ardour/ardour.git";
|
url = "git://git.ardour.org/ardour/ardour.git";
|
||||||
rev = version;
|
tag = version;
|
||||||
hash = "sha256-cmYt6fGYuuVs6YhAXaO9AG6TrYLDVUaE1/iC67rt76I=";
|
hash = "sha256-cmYt6fGYuuVs6YhAXaO9AG6TrYLDVUaE1/iC67rt76I=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ stdenv.mkDerivation rec {
|
||||||
# result in an empty archive. See https://tracker.ardour.org/view.php?id=7328 for more info.
|
# result in an empty archive. See https://tracker.ardour.org/view.php?id=7328 for more info.
|
||||||
src = fetchgit {
|
src = fetchgit {
|
||||||
url = "git://git.ardour.org/ardour/ardour.git";
|
url = "git://git.ardour.org/ardour/ardour.git";
|
||||||
rev = version;
|
tag = version;
|
||||||
hash = "sha256-z+rIWFVua1IG4GZ8kH3quKaBbN+I7Yr62vukJZk6KAg=";
|
hash = "sha256-z+rIWFVua1IG4GZ8kH3quKaBbN+I7Yr62vukJZk6KAg=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ stdenv.mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "zevv";
|
owner = "zevv";
|
||||||
repo = pname;
|
repo = pname;
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
sha256 = "0prhqibivxzmz90k79zpwx3c97h8wa61rk5ihi9a5651mnc46mna";
|
sha256 = "0prhqibivxzmz90k79zpwx3c97h8wa61rk5ihi9a5651mnc46mna";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -143,7 +143,7 @@ stdenv.mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "cmus";
|
owner = "cmus";
|
||||||
repo = "cmus";
|
repo = "cmus";
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
hash = "sha256-8hgibGtkiwzenMI9YImIApRmw2EzTwE6RhglALpUkp4=";
|
hash = "sha256-8hgibGtkiwzenMI9YImIApRmw2EzTwE6RhglALpUkp4=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ stdenv.mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "jketterl";
|
owner = "jketterl";
|
||||||
repo = pname;
|
repo = pname;
|
||||||
rev = version;
|
tag = version;
|
||||||
sha256 = "sha256-JzaVBFl3JsFNDm4gy1qOKA9uAjUjNeMiI39l5gfH0aE=";
|
sha256 = "sha256-JzaVBFl3JsFNDm4gy1qOKA9uAjUjNeMiI39l5gfH0aE=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ stdenv.mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "CsoundQt";
|
owner = "CsoundQt";
|
||||||
repo = "CsoundQt";
|
repo = "CsoundQt";
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
hash = "sha256-ZdQwWRAr6AKLmZ/L0lSxIlvWRLoZIKinn7BAQiR+luk=";
|
hash = "sha256-ZdQwWRAr6AKLmZ/L0lSxIlvWRLoZIKinn7BAQiR+luk=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -80,7 +80,7 @@ clangStdenv.mkDerivation {
|
||||||
owner = "DeaDBeeF-Player";
|
owner = "DeaDBeeF-Player";
|
||||||
repo = "deadbeef";
|
repo = "deadbeef";
|
||||||
fetchSubmodules = true;
|
fetchSubmodules = true;
|
||||||
rev = version;
|
tag = version;
|
||||||
hash = "sha256-qa0ULmE15lV2vkyXPNW9kSISQZEANrjwJwykTiifk5Q=";
|
hash = "sha256-qa0ULmE15lV2vkyXPNW9kSISQZEANrjwJwykTiifk5Q=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ stdenv.mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "saivert";
|
owner = "saivert";
|
||||||
repo = "ddb_misc_headerbar_GTK3";
|
repo = "ddb_misc_headerbar_GTK3";
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
sha256 = "1v1schvnps7ypjqgcbqi74a45w8r2gbhrawz7filym22h1qr9wn0";
|
sha256 = "1v1schvnps7ypjqgcbqi74a45w8r2gbhrawz7filym22h1qr9wn0";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ stdenv.mkDerivation {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "DeaDBeeF-Player";
|
owner = "DeaDBeeF-Player";
|
||||||
repo = pname;
|
repo = pname;
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
hash = "sha256-f6iHgwLdzQJJEquyuUQGWFfOfpjH/Hxh9IqQ5HkYrog=";
|
hash = "sha256-f6iHgwLdzQJJEquyuUQGWFfOfpjH/Hxh9IqQ5HkYrog=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ stdenv.mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "vovochka404";
|
owner = "vovochka404";
|
||||||
repo = "deadbeef-statusnotifier-plugin";
|
repo = "deadbeef-statusnotifier-plugin";
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
sha256 = "sha256-6WEbY59vPNrL3W5GUwFQJimmSS+td8Ob+G46fPAxfV4=";
|
sha256 = "sha256-6WEbY59vPNrL3W5GUwFQJimmSS+td8Ob+G46fPAxfV4=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ mkDerivation rec {
|
||||||
|
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
sha256 = "09fcyjm0hg3y51fnjax88m93im39nbynxj79ffdknsazmqw9ac0h";
|
sha256 = "09fcyjm0hg3y51fnjax88m93im39nbynxj79ffdknsazmqw9ac0h";
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
repo = "dfasma";
|
repo = "dfasma";
|
||||||
owner = "gillesdegottex";
|
owner = "gillesdegottex";
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,7 +21,7 @@ stdenv.mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "complexlogic";
|
owner = "complexlogic";
|
||||||
repo = "EasyAudioSync";
|
repo = "EasyAudioSync";
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
hash = "sha256-UCOL4DzynKjNDvS0HZ4/K+Wn5lOqHZ0bNop0zqJl5kc=";
|
hash = "sha256-UCOL4DzynKjNDvS0HZ4/K+Wn5lOqHZ0bNop0zqJl5kc=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ stdenv.mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "espeak-ng";
|
owner = "espeak-ng";
|
||||||
repo = "espeak-ng";
|
repo = "espeak-ng";
|
||||||
rev = version;
|
tag = version;
|
||||||
hash = "sha256-aAJ+k+kkOS6k835mEW7BvgAIYGhUHxf7Q4P5cKO8XTk=";
|
hash = "sha256-aAJ+k+kkOS6k835mEW7BvgAIYGhUHxf7Q4P5cKO8XTk=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ let
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "grame-cncm";
|
owner = "grame-cncm";
|
||||||
repo = "faust";
|
repo = "faust";
|
||||||
rev = version;
|
tag = version;
|
||||||
hash = "sha256-Rn+Cjpk4vttxARrkDSnpKdBdSRtgElsit8zu1BA8Jd4=";
|
hash = "sha256-Rn+Cjpk4vttxARrkDSnpKdBdSRtgElsit8zu1BA8Jd4=";
|
||||||
fetchSubmodules = true;
|
fetchSubmodules = true;
|
||||||
};
|
};
|
||||||
|
|
|
@ -32,7 +32,7 @@ stdenv.mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "grame-cncm";
|
owner = "grame-cncm";
|
||||||
repo = "faustlive";
|
repo = "faustlive";
|
||||||
rev = version;
|
tag = version;
|
||||||
hash = "sha256-RqtdDkP63l/30sL5PDocvpar5TI4LdKfeeliSNeOHog=";
|
hash = "sha256-RqtdDkP63l/30sL5PDocvpar5TI4LdKfeeliSNeOHog=";
|
||||||
fetchSubmodules = true;
|
fetchSubmodules = true;
|
||||||
};
|
};
|
||||||
|
|
|
@ -29,7 +29,7 @@ stdenv.mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "flacon";
|
owner = "flacon";
|
||||||
repo = "flacon";
|
repo = "flacon";
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
sha256 = "sha256-r9SdQg6JTMoGxO2xUtkkBe5F5cajnsndZEq20BjJGuU=";
|
sha256 = "sha256-r9SdQg6JTMoGxO2xUtkkBe5F5cajnsndZEq20BjJGuU=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "gillesdegottex";
|
owner = "gillesdegottex";
|
||||||
repo = "fmit";
|
repo = "fmit";
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
sha256 = "1q062pfwz2vr9hbfn29fv54ip3jqfd9r99nhpr8w7mn1csy38azx";
|
sha256 = "1q062pfwz2vr9hbfn29fv54ip3jqfd9r99nhpr8w7mn1csy38azx";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ stdenv.mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "8bitbubsy";
|
owner = "8bitbubsy";
|
||||||
repo = "ft2-clone";
|
repo = "ft2-clone";
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
hash = "sha256-Xb4LHoon56P6OmHvd7RkODrOc4MDa0+U8npypGhcyw4=";
|
hash = "sha256-Xb4LHoon56P6OmHvd7RkODrOc4MDa0+U8npypGhcyw4=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ stdenv.mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "GrandOrgue";
|
owner = "GrandOrgue";
|
||||||
repo = "grandorgue";
|
repo = "grandorgue";
|
||||||
rev = version;
|
tag = version;
|
||||||
fetchSubmodules = true;
|
fetchSubmodules = true;
|
||||||
hash = "sha256-9H7YpTtv9Y36Nc0WCyRy/ohpOQ3WVUd9gMahnGhANRc=";
|
hash = "sha256-9H7YpTtv9Y36Nc0WCyRy/ohpOQ3WVUd9gMahnGhANRc=";
|
||||||
};
|
};
|
||||||
|
|
|
@ -26,7 +26,7 @@ stdenv.mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "hydrogen-music";
|
owner = "hydrogen-music";
|
||||||
repo = pname;
|
repo = pname;
|
||||||
rev = version;
|
tag = version;
|
||||||
sha256 = "sha256-OMd8t043JVfMEfRjLdcE/R/4ymGp2yennkCjyX75r8Q=";
|
sha256 = "sha256-OMd8t043JVfMEfRjLdcE/R/4ymGp2yennkCjyX75r8Q=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "kampfschlaefer";
|
owner = "kampfschlaefer";
|
||||||
repo = "jackmix";
|
repo = "jackmix";
|
||||||
rev = version;
|
tag = version;
|
||||||
sha256 = "0p59411vk38lccn24r7nih10jpgg9i46yc26zpc3x13amxwwpd4h";
|
sha256 = "0p59411vk38lccn24r7nih10jpgg9i46yc26zpc3x13amxwwpd4h";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ stdenv.mkDerivation (finalAttrs: {
|
||||||
owner = "Audio4Linux";
|
owner = "Audio4Linux";
|
||||||
repo = "JDSP4Linux";
|
repo = "JDSP4Linux";
|
||||||
fetchSubmodules = true;
|
fetchSubmodules = true;
|
||||||
rev = finalAttrs.version;
|
tag = finalAttrs.version;
|
||||||
hash = "sha256-eVndqIqJ3DRceuFMT++g2riXq0CL5r+TWbvzvaYIfZ8=";
|
hash = "sha256-eVndqIqJ3DRceuFMT++g2riXq0CL5r+TWbvzvaYIfZ8=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ stdenv.mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "swh";
|
owner = "swh";
|
||||||
repo = "ladspa";
|
repo = "ladspa";
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
sha256 = "sha256-eOtIhNcuItREUShI8JRlBVKfMfovpdfIYu+m37v4KLE=";
|
sha256 = "sha256-eOtIhNcuItREUShI8JRlBVKfMfovpdfIYu+m37v4KLE=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ rustPlatform.buildRustPackage rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "librespot-org";
|
owner = "librespot-org";
|
||||||
repo = "librespot";
|
repo = "librespot";
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
sha256 = "sha256-dGQDRb7fgIkXelZKa+PdodIs9DxbgEMlVGJjK/hU3Mo=";
|
sha256 = "sha256-dGQDRb7fgIkXelZKa+PdodIs9DxbgEMlVGJjK/hU3Mo=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ stdenv.mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "Goli4thus";
|
owner = "Goli4thus";
|
||||||
repo = "linvstmanager";
|
repo = "linvstmanager";
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
hash = "sha256-K6eugimMy/MZgHYkg+zfF8DDqUuqqoeymxHtcFGu2Uk=";
|
hash = "sha256-K6eugimMy/MZgHYkg+zfF8DDqUuqqoeymxHtcFGu2Uk=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "LMMS";
|
owner = "LMMS";
|
||||||
repo = "lmms";
|
repo = "lmms";
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
sha256 = "006hwv1pbh3y5whsxkjk20hsbgwkzr4dawz43afq1gil69y7xpda";
|
sha256 = "006hwv1pbh3y5whsxkjk20hsbgwkzr4dawz43afq1gil69y7xpda";
|
||||||
fetchSubmodules = true;
|
fetchSubmodules = true;
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,7 +16,7 @@ stdenv.mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "charlesfleche";
|
owner = "charlesfleche";
|
||||||
repo = "lpd8editor";
|
repo = "lpd8editor";
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
hash = "sha256-lRp2RhNiIf1VrryfKqYFSbKG3pktw3M7B49fXVoj+C8=";
|
hash = "sha256-lRp2RhNiIf1VrryfKqYFSbKG3pktw3M7B49fXVoj+C8=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ stdenv.mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "magnetophon";
|
owner = "magnetophon";
|
||||||
repo = "VoiceOfFaust";
|
repo = "VoiceOfFaust";
|
||||||
rev = version;
|
tag = version;
|
||||||
sha256 = "sha256-vB8+ymvNuuovFXwOJ3BTIj5mGzCGa1+yhYs4nWMYIxU=";
|
sha256 = "sha256-vB8+ymvNuuovFXwOJ3BTIj5mGzCGa1+yhYs4nWMYIxU=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ stdenv.mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "magnetophon";
|
owner = "magnetophon";
|
||||||
repo = "faustCompressors";
|
repo = "faustCompressors";
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
sha256 = "144f6g17q4m50kxzdncsfzdyycdfprnpwdaxcwgxj4jky1xsha1d";
|
sha256 = "144f6g17q4m50kxzdncsfzdyycdfprnpwdaxcwgxj4jky1xsha1d";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ stdenv.mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "trummerschlunk";
|
owner = "trummerschlunk";
|
||||||
repo = "master_me";
|
repo = "master_me";
|
||||||
rev = version;
|
tag = version;
|
||||||
fetchSubmodules = true;
|
fetchSubmodules = true;
|
||||||
hash = "sha256-FG3X1dOF9KRHHSnd5/zP+GrYCB2O0y+tnI5/l9tNhyE=";
|
hash = "sha256-FG3X1dOF9KRHHSnd5/zP+GrYCB2O0y+tnI5/l9tNhyE=";
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,7 +21,7 @@ mkDerivation rec {
|
||||||
src = fetchFromGitLab {
|
src = fetchFromGitLab {
|
||||||
owner = "ColinDuquesnoy";
|
owner = "ColinDuquesnoy";
|
||||||
repo = "MellowPlayer";
|
repo = "MellowPlayer";
|
||||||
rev = version;
|
tag = version;
|
||||||
hash = "sha256-rsF2xQet7U8d4oGU/HgghvE3vvmkxjlGXPBlLD9mWTk=";
|
hash = "sha256-rsF2xQet7U8d4oGU/HgghvE3vvmkxjlGXPBlLD9mWTk=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ stdenv.mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "brummer10";
|
owner = "brummer10";
|
||||||
repo = pname;
|
repo = pname;
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
sha256 = "1s805jgb9msxfq9047s7pxrngizb00w8sm4z94iii80ba65rd20x";
|
sha256 = "1s805jgb9msxfq9047s7pxrngizb00w8sm4z94iii80ba65rd20x";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ rustPlatform.buildRustPackage rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "mrene";
|
owner = "mrene";
|
||||||
repo = "minidsp-rs";
|
repo = "minidsp-rs";
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
hash = "sha256-8bKP9/byVRKj1P1MP3ZVg8yw0WaNB0BcqarCti7B8CA=";
|
hash = "sha256-8bKP9/byVRKj1P1MP3ZVg8yw0WaNB0BcqarCti7B8CA=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,7 @@ stdenv.mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "mixxxdj";
|
owner = "mixxxdj";
|
||||||
repo = "mixxx";
|
repo = "mixxx";
|
||||||
rev = version;
|
tag = version;
|
||||||
hash = "sha256-1ZE2hVwacZve0+IOQs+htK/kl7zFsOWkh/KcrnI6u/M=";
|
hash = "sha256-1ZE2hVwacZve0+IOQs+htK/kl7zFsOWkh/KcrnI6u/M=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ pythonPackages.buildPythonApplication rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "pimusicbox";
|
owner = "pimusicbox";
|
||||||
repo = pname;
|
repo = pname;
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
sha256 = "1lzarazq67gciyn6r8cdms0f7j0ayyfwhpf28z93ydb280mfrrb9";
|
sha256 = "1lzarazq67gciyn6r8cdms0f7j0ayyfwhpf28z93ydb280mfrrb9";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ pythonPackages.buildPythonApplication rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "mopidy";
|
owner = "mopidy";
|
||||||
repo = "mopidy-soundcloud";
|
repo = "mopidy-soundcloud";
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
sha256 = "sha256-1Qqbfw6NZ+2K1w+abMBfWo0RAmIRbNyIErEmalmWJ0s=";
|
sha256 = "sha256-1Qqbfw6NZ+2K1w+abMBfWo0RAmIRbNyIErEmalmWJ0s=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ pythonPackages.buildPythonApplication rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "Prior99";
|
owner = "Prior99";
|
||||||
repo = pname;
|
repo = pname;
|
||||||
rev = version;
|
tag = version;
|
||||||
sha256 = "0c5ghhhrj5v3yp4zmll9ari6r5c6ha8c1izwqshvadn40b02q7xz";
|
sha256 = "0c5ghhhrj5v3yp4zmll9ari6r5c6ha8c1izwqshvadn40b02q7xz";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ python.pkgs.buildPythonApplication rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "jmcdo29";
|
owner = "jmcdo29";
|
||||||
repo = "mopidy-ytmusic";
|
repo = "mopidy-ytmusic";
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
hash = "sha256-2o4fDtaIxRDvIiAGV/9qK/00BmYXasBUwW03fxFcDAU=";
|
hash = "sha256-2o4fDtaIxRDvIiAGV/9qK/00BmYXasBUwW03fxFcDAU=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ stdenv.mkDerivation (finalAttrs: {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "muse-sequencer";
|
owner = "muse-sequencer";
|
||||||
repo = "muse";
|
repo = "muse";
|
||||||
rev = finalAttrs.version;
|
tag = finalAttrs.version;
|
||||||
hash = "sha256-LxibuqopMHuKEfTWXSEXc1g3wTm2F3NQRiV71FHvaY0=";
|
hash = "sha256-LxibuqopMHuKEfTWXSEXc1g3wTm2F3NQRiV71FHvaY0=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ stdenv.mkDerivation (finalAttrs: {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "janbar";
|
owner = "janbar";
|
||||||
repo = "noson-app";
|
repo = "noson-app";
|
||||||
rev = finalAttrs.version;
|
tag = finalAttrs.version;
|
||||||
hash = "sha256-hCVGi+++6CcTRMXeRKH8xRncm/Gl83GgU3aAIPI/yGU=";
|
hash = "sha256-hCVGi+++6CcTRMXeRKH8xRncm/Gl83GgU3aAIPI/yGU=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ stdenv.mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "pianobooster";
|
owner = "pianobooster";
|
||||||
repo = "PianoBooster";
|
repo = "PianoBooster";
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
hash = "sha256-1WOlAm/HXSL6QK0Kd1mnFEZxxpMseTG+6WzgMNWt+RA=";
|
hash = "sha256-1WOlAm/HXSL6QK0Kd1mnFEZxxpMseTG+6WzgMNWt+RA=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ stdenv.mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "portaloffreedom";
|
owner = "portaloffreedom";
|
||||||
repo = pname;
|
repo = pname;
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
sha256 = "sha256-WvQFmoEaxnkI61wPldSnMAoPAxNtI399hdHb/9bkPqc=";
|
sha256 = "sha256-WvQFmoEaxnkI61wPldSnMAoPAxNtI399hdHb/9bkPqc=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ stdenv.mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "audoban";
|
owner = "audoban";
|
||||||
repo = "PlayBar2";
|
repo = "PlayBar2";
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
sha256 = "0iv2m4flgaz2r0k7f6l0ca8p6cw8j8j2gin1gci2pg3l5g5khbch";
|
sha256 = "0iv2m4flgaz2r0k7f6l0ca8p6cw8j8j2gin1gci2pg3l5g5khbch";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ stdenv.mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "davy7125";
|
owner = "davy7125";
|
||||||
repo = "polyphone";
|
repo = "polyphone";
|
||||||
rev = version;
|
tag = version;
|
||||||
hash = "sha256-43EswCgNJv11Ov+4vmj2vS/yJ2atyzkRmk/SoCKYD/0=";
|
hash = "sha256-43EswCgNJv11Ov+4vmj2vS/yJ2atyzkRmk/SoCKYD/0=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "pragha-music-player";
|
owner = "pragha-music-player";
|
||||||
repo = "pragha";
|
repo = "pragha";
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
sha256 = "sha256-C4zh2NHqP4bwKMi5s+3AfEtKqxRlzL66H8OyNonGzxE=";
|
sha256 = "sha256-C4zh2NHqP4bwKMi5s+3AfEtKqxRlzL66H8OyNonGzxE=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "projectM-visualizer";
|
owner = "projectM-visualizer";
|
||||||
repo = "projectM";
|
repo = "projectM";
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
sha256 = "sha256-oEfOx93JyR94II5NkUCvMwqxuV7ktpOHZ8PNMLCiqDw=";
|
sha256 = "sha256-oEfOx93JyR94II5NkUCvMwqxuV7ktpOHZ8PNMLCiqDw=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ stdenv.mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "ebruck";
|
owner = "ebruck";
|
||||||
repo = pname;
|
repo = pname;
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
sha256 = "sha256-/0GlQdSsIPKGrDT9CgxvaH8TpAbqxFduwL2A2+BSrEI=";
|
sha256 = "sha256-/0GlQdSsIPKGrDT9CgxvaH8TpAbqxFduwL2A2+BSrEI=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ mkDerivation rec {
|
||||||
src = fetchFromGitLab {
|
src = fetchFromGitLab {
|
||||||
owner = "luciocarreras";
|
owner = "luciocarreras";
|
||||||
repo = "sayonara-player";
|
repo = "sayonara-player";
|
||||||
rev = version;
|
tag = version;
|
||||||
hash = "sha256-ZcuWe1dsLJS4/nLXSSKB7wzPU9COFyE4vPSwZIo0bgI=";
|
hash = "sha256-ZcuWe1dsLJS4/nLXSSKB7wzPU9COFyE4vPSwZIo0bgI=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ stdenv.mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "ahlstromcj";
|
owner = "ahlstromcj";
|
||||||
repo = "seq66";
|
repo = "seq66";
|
||||||
rev = version;
|
tag = version;
|
||||||
hash = "sha256-9cEvwJTH6Iwi4aZQHTjQ/DhUtKYw2QC1Oq+D1/tpE90=";
|
hash = "sha256-9cEvwJTH6Iwi4aZQHTjQ/DhUtKYw2QC1Oq+D1/tpE90=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "agateau";
|
owner = "agateau";
|
||||||
repo = "sfxr-qt";
|
repo = "sfxr-qt";
|
||||||
rev = version;
|
tag = version;
|
||||||
hash = "sha256-JAWDk7mGkPtQ5yaA6UT9hlAy770MHrTBhBP9G8UqFKg=";
|
hash = "sha256-JAWDk7mGkPtQ5yaA6UT9hlAy770MHrTBhBP9G8UqFKg=";
|
||||||
fetchSubmodules = true;
|
fetchSubmodules = true;
|
||||||
};
|
};
|
||||||
|
|
|
@ -20,7 +20,7 @@ let
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "x42";
|
owner = "x42";
|
||||||
repo = "sisco.lv2";
|
repo = "sisco.lv2";
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
sha256 = "1r6g29yqbdqgkh01x6d3nvmvc58rk2dp94fd0qyyizq37a1qplj1";
|
sha256 = "1r6g29yqbdqgkh01x6d3nvmvc58rk2dp94fd0qyyizq37a1qplj1";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ stdenv.mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "badaix";
|
owner = "badaix";
|
||||||
repo = "snapcast";
|
repo = "snapcast";
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
hash = "sha256-EJgpZz4PnXfge0rkVH1F7cah+i9AvDJVSUVqL7qChDM=";
|
hash = "sha256-EJgpZz4PnXfge0rkVH1F7cah+i9AvDJVSUVqL7qChDM=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ stdenv.mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "sonic-pi-net";
|
owner = "sonic-pi-net";
|
||||||
repo = pname;
|
repo = pname;
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
hash = "sha256-JMextQY0jLShWmqRQoVAbqIzDhA1mOzI7vfsG7+jjX0=";
|
hash = "sha256-JMextQY0jLShWmqRQoVAbqIzDhA1mOzI7vfsG7+jjX0=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ stdenv.mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "alexkay";
|
owner = "alexkay";
|
||||||
repo = "spek";
|
repo = "spek";
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
sha256 = "sha256-VYt2so2k3Rk3sLSV1Tf1G2pESYiXygrKr9Koop8ChCg=";
|
sha256 = "sha256-VYt2so2k3Rk3sLSV1Tf1G2pESYiXygrKr9Koop8ChCg=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ stdenv.mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "jonaski";
|
owner = "jonaski";
|
||||||
repo = pname;
|
repo = pname;
|
||||||
rev = version;
|
tag = version;
|
||||||
hash = "sha256-EJE6GDyXYMjJUQeTRgmjd0HX3hf4ajSRGsv/2s2oItc=";
|
hash = "sha256-EJE6GDyXYMjJUQeTRgmjd0HX3hf4ajSRGsv/2s2oItc=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ stdenv.mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "martchus";
|
owner = "martchus";
|
||||||
repo = pname;
|
repo = pname;
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
hash = "sha256-VRQV4bTPG4VFhRHFJamUnYd04ZCaNpaxU27Jcl6Chc4=";
|
hash = "sha256-VRQV4bTPG4VFhRHFJamUnYd04ZCaNpaxU27Jcl6Chc4=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ stdenv.mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "linuxmint";
|
owner = "linuxmint";
|
||||||
repo = "timeshift";
|
repo = "timeshift";
|
||||||
rev = version;
|
tag = version;
|
||||||
hash = "sha256-umMekxP9bvV01KzfIh2Zxa9Xb+tR5x+tG9dOnBIOkjY=";
|
hash = "sha256-umMekxP9bvV01KzfIh2Zxa9Xb+tR5x+tG9dOnBIOkjY=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ rustPlatform.buildRustPackage rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "Revertron";
|
owner = "Revertron";
|
||||||
repo = "Alfis";
|
repo = "Alfis";
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
hash = "sha256-ettStNktSDZnYNN/IWqTB1Ou1g1QEGFabS4EatnDLaE=";
|
hash = "sha256-ettStNktSDZnYNN/IWqTB1Ou1g1QEGFabS4EatnDLaE=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "bitcoin-ABC";
|
owner = "bitcoin-ABC";
|
||||||
repo = "bitcoin-abc";
|
repo = "bitcoin-abc";
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
hash = "sha256-+9uBmmdQ/shWYnJ7tM+Y8OgqYcQHHI2qeMw2tl1lE+w=";
|
hash = "sha256-+9uBmmdQ/shWYnJ7tM+Y8OgqYcQHHI2qeMw2tl1lE+w=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ stdenv.mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "digibyte-core";
|
owner = "digibyte-core";
|
||||||
repo = pname;
|
repo = pname;
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
sha256 = "zPwnC2qd28fA1saG4nysPlKU1nnXhfuSG3DpCY6T+kM=";
|
sha256 = "zPwnC2qd28fA1saG4nysPlKU1nnXhfuSG3DpCY6T+kM=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ rustPlatform.buildRustPackage rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "romanz";
|
owner = "romanz";
|
||||||
repo = pname;
|
repo = pname;
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
hash = "sha256-Xo7aqP4tIh/kYthPucscxnl+ZtVioEja4TTFdH0Q350=";
|
hash = "sha256-Xo7aqP4tIh/kYthPucscxnl+ZtVioEja4TTFdH0Q350=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ stdenv.mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "cculianu";
|
owner = "cculianu";
|
||||||
repo = "Fulcrum";
|
repo = "Fulcrum";
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
sha256 = "sha256-+hBc7jW1MVLVjYXNOV7QvFJJpZ5RzW5/c9NdqOXrsj0=";
|
sha256 = "sha256-+hBc7jW1MVLVjYXNOV7QvFJJpZ5RzW5/c9NdqOXrsj0=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ stdenv.mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "gridcoin-community";
|
owner = "gridcoin-community";
|
||||||
repo = "Gridcoin-Research";
|
repo = "Gridcoin-Research";
|
||||||
rev = "${version}";
|
tag = version;
|
||||||
hash = "sha256-nupZB4nNbitpf5EBCNy0e+ovjayAszup/r7qxbxA5jI=";
|
hash = "sha256-nupZB4nNbitpf5EBCNy0e+ovjayAszup/r7qxbxA5jI=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ stdenv.mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "Groestlcoin";
|
owner = "Groestlcoin";
|
||||||
repo = "groestlcoin";
|
repo = "groestlcoin";
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
sha256 = "0kl7nq62362clgzxwwd5c256xnaar4ilxcvbralazxg47zv95r11";
|
sha256 = "0kl7nq62362clgzxwwd5c256xnaar4ilxcvbralazxg47zv95r11";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ rustPlatform.buildRustPackage rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "sigp";
|
owner = "sigp";
|
||||||
repo = "lighthouse";
|
repo = "lighthouse";
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
hash = "sha256-8jHNm/MGpHGOt52rLMXLMWIVn8AXqnpAr+Wvk7DH6gc=";
|
hash = "sha256-8jHNm/MGpHGOt52rLMXLMWIVn8AXqnpAr+Wvk7DH6gc=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ stdenv.mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "monero-project";
|
owner = "monero-project";
|
||||||
repo = "monero";
|
repo = "monero";
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
hash = "sha256-nDiFJjhsISYM8kTgJUaPYL44iyccnz5+Pd5beBh+lsM=";
|
hash = "sha256-nDiFJjhsISYM8kTgJUaPYL44iyccnz5+Pd5beBh+lsM=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ stdenv.mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "monero-project";
|
owner = "monero-project";
|
||||||
repo = "monero-gui";
|
repo = "monero-gui";
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
hash = "sha256-wnU24EmZig2W/psy4OhaQVy2WwR0CgljlyYwOg4bzwM=";
|
hash = "sha256-wnU24EmZig2W/psy4OhaQVy2WwR0CgljlyYwOg4bzwM=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ buildGoModule rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "ethereum-optimism";
|
owner = "ethereum-optimism";
|
||||||
repo = "op-geth";
|
repo = "op-geth";
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
hash = "sha256-AKVwwvt77FZlm7089EeayYVRYLo7c3v6LFVpsQN68Zk=";
|
hash = "sha256-AKVwwvt77FZlm7089EeayYVRYLo7c3v6LFVpsQN68Zk=";
|
||||||
fetchSubmodules = true;
|
fetchSubmodules = true;
|
||||||
};
|
};
|
||||||
|
|
|
@ -15,7 +15,7 @@ rustPlatform.buildRustPackage rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "AleoHQ";
|
owner = "AleoHQ";
|
||||||
repo = "snarkOS";
|
repo = "snarkOS";
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
sha256 = "sha256-+z9dgg5HdR+Gomug03gI1zdCU6t4SBHkl1Pxoq69wrc=";
|
sha256 = "sha256-+z9dgg5HdR+Gomug03gI1zdCU6t4SBHkl1Pxoq69wrc=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ let
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "talaia-labs";
|
owner = "talaia-labs";
|
||||||
repo = "rust-teos";
|
repo = "rust-teos";
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
hash = "sha256-UrzH9xmhVq12TcSUQ1AihCG1sNGcy/N8LDsZINVKFkY=";
|
hash = "sha256-UrzH9xmhVq12TcSUQ1AihCG1sNGcy/N8LDsZINVKFkY=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ rustPlatform.buildRustPackage.override { inherit stdenv; } rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "zcash";
|
owner = "zcash";
|
||||||
repo = "zcash";
|
repo = "zcash";
|
||||||
rev = "v${version}";
|
tag = "v${version}";
|
||||||
hash = "sha256-XGq/cYUo43FcpmRDO2YiNLCuEQLsTFLBFC4M1wM29l8=";
|
hash = "sha256-XGq/cYUo43FcpmRDO2YiNLCuEQLsTFLBFC4M1wM29l8=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ rustPlatform.buildRustPackage rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "rharish101";
|
owner = "rharish101";
|
||||||
repo = "ReGreet";
|
repo = "ReGreet";
|
||||||
rev = version;
|
tag = version;
|
||||||
hash = "sha256-f8Xvno5QqmWz4SUiFYDvs8lFU1ZaqQ8gpTaVzWxW4T8=";
|
hash = "sha256-f8Xvno5QqmWz4SUiFYDvs8lFU1ZaqQ8gpTaVzWxW4T8=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ stdenv.mkDerivation rec {
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "canonical";
|
owner = "canonical";
|
||||||
repo = pname;
|
repo = pname;
|
||||||
rev = version;
|
tag = version;
|
||||||
sha256 = "sha256-ttNlhWD0Ran4d3QvZ+PxbFbSUGMkfrRm+hJdQxIDJvM=";
|
sha256 = "sha256-ttNlhWD0Ran4d3QvZ+PxbFbSUGMkfrRm+hJdQxIDJvM=";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue