Merge branch 'master' into meshcentral
This commit is contained in:
commit
15ffca434e
1
.github/labeler.yml
vendored
1
.github/labeler.yml
vendored
@ -70,6 +70,7 @@
|
||||
|
||||
"6.topic: nixos":
|
||||
- nixos/**/*
|
||||
- pkgs/os-specific/linux/nixos-rebuild/**/*
|
||||
|
||||
"6.topic: ocaml":
|
||||
- doc/languages-frameworks/ocaml.section.md
|
||||
|
@ -520,7 +520,7 @@ If you do need to do create this sort of patch file, one way to do so is with gi
|
||||
4. Use git to create a diff, and pipe the output to a patch file:
|
||||
|
||||
```ShellSession
|
||||
$ git diff > nixpkgs/pkgs/the/package/0001-changes.patch
|
||||
$ git diff -a > nixpkgs/pkgs/the/package/0001-changes.patch
|
||||
```
|
||||
|
||||
If a patch is available online but does not cleanly apply, it can be modified in some fixed ways by using additional optional arguments for `fetchpatch`:
|
||||
@ -537,7 +537,13 @@ Note that because the checksum is computed after applying these effects, using o
|
||||
|
||||
Tests are important to ensure quality and make reviews and automatic updates easy.
|
||||
|
||||
Nix package tests are a lightweight alternative to [NixOS module tests](https://nixos.org/manual/nixos/stable/#sec-nixos-tests). They can be used to create simple integration tests for packages while the module tests are used to test services or programs with a graphical user interface on a NixOS VM. Unittests that are included in the source code of a package should be executed in the `checkPhase`.
|
||||
The following types of tests exists:
|
||||
|
||||
* [NixOS **module tests**](https://nixos.org/manual/nixos/stable/#sec-nixos-tests), which spawn one or more NixOS VMs. They exercise both NixOS modules and the packaged programs used within them. For example, a NixOS module test can start a web server VM running the `nginx` module, and a client VM running `curl` or a graphical `firefox`, and test that they can talk to each other and display the correct content.
|
||||
* Nix **package tests** are a lightweight alternative to NixOS module tests. They should be used to create simple integration tests for packages, but cannot test NixOS services, and some programs with graphical user interfaces may also be difficult to test with them.
|
||||
* The **`checkPhase` of a package**, which should execute the unit tests that are included in the source code of a package.
|
||||
|
||||
Here in the nixpkgs manual we describe mostly _package tests_; for _module tests_ head over to the corresponding [section in the NixOS manual](https://nixos.org/manual/nixos/stable/#sec-nixos-tests).
|
||||
|
||||
### Writing package tests {#ssec-package-tests-writing}
|
||||
|
||||
@ -568,7 +574,7 @@ let
|
||||
inherit (phoronix-test-suite) pname version;
|
||||
in
|
||||
|
||||
runCommand "${pname}-tests" { meta.timeout = 3; }
|
||||
runCommand "${pname}-tests" { meta.timeout = 60; }
|
||||
''
|
||||
# automatic initial setup to prevent interactive questions
|
||||
${phoronix-test-suite}/bin/phoronix-test-suite enterprise-setup >/dev/null
|
||||
@ -602,3 +608,23 @@ Here are examples of package tests:
|
||||
- [Spacy annotation test](https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/python-modules/spacy/annotation-test/default.nix)
|
||||
- [Libtorch test](https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/libraries/science/math/libtorch/test/default.nix)
|
||||
- [Multiple tests for nanopb](https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/libraries/nanopb/default.nix)
|
||||
|
||||
### Linking NixOS module tests to a package {#ssec-nixos-tests-linking}
|
||||
|
||||
Like [package tests](#ssec-package-tests-writing) as shown above, [NixOS module tests](https://nixos.org/manual/nixos/stable/#sec-nixos-tests) can also be linked to a package, so that the tests can be easily run when changing the related package.
|
||||
|
||||
For example, assuming we're packaging `nginx`, we can link its module test via `passthru.tests`:
|
||||
|
||||
```nix
|
||||
{ stdenv, lib, nixosTests }:
|
||||
|
||||
stdenv.mkDerivation {
|
||||
...
|
||||
|
||||
passthru.tests = {
|
||||
nginx = nixosTests.nginx;
|
||||
};
|
||||
|
||||
...
|
||||
}
|
||||
```
|
||||
|
@ -144,7 +144,7 @@ rustPlatform.buildRustPackage rec {
|
||||
outputHashes = {
|
||||
"finalfusion-0.14.0" = "17f4bsdzpcshwh74w5z119xjy2if6l2wgyjy56v621skr2r8y904";
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
# ...
|
||||
}
|
||||
|
@ -26,22 +26,22 @@ let
|
||||
|
||||
# Linux
|
||||
"aarch64-linux" "armv5tel-linux" "armv6l-linux" "armv7a-linux"
|
||||
"armv7l-linux" "i686-linux" "mipsel-linux" "powerpc64-linux"
|
||||
"powerpc64le-linux" "riscv32-linux" "riscv64-linux" "x86_64-linux"
|
||||
"m68k-linux" "s390-linux"
|
||||
"armv7l-linux" "i686-linux" "m68k-linux" "mipsel-linux"
|
||||
"powerpc64-linux" "powerpc64le-linux" "riscv32-linux"
|
||||
"riscv64-linux" "s390-linux" "x86_64-linux"
|
||||
|
||||
# MMIXware
|
||||
"mmix-mmixware"
|
||||
|
||||
# NetBSD
|
||||
"aarch64-netbsd" "armv6l-netbsd" "armv7a-netbsd" "armv7l-netbsd"
|
||||
"i686-netbsd" "mipsel-netbsd" "powerpc-netbsd" "riscv32-netbsd"
|
||||
"riscv64-netbsd" "x86_64-netbsd"
|
||||
"i686-netbsd" "m68k-netbsd" "mipsel-netbsd" "powerpc-netbsd"
|
||||
"riscv32-netbsd" "riscv64-netbsd" "x86_64-netbsd"
|
||||
|
||||
# none
|
||||
"aarch64-none" "arm-none" "armv6l-none" "avr-none" "i686-none" "msp430-none"
|
||||
"or1k-none" "powerpc-none" "riscv32-none" "riscv64-none" "vc4-none" "m68k-none"
|
||||
"s390-none" "x86_64-none"
|
||||
"aarch64-none" "arm-none" "armv6l-none" "avr-none" "i686-none"
|
||||
"msp430-none" "or1k-none" "m68k-none" "powerpc-none"
|
||||
"riscv32-none" "riscv64-none" "s390-none" "vc4-none" "x86_64-none"
|
||||
|
||||
# OpenBSD
|
||||
"i686-openbsd" "x86_64-openbsd"
|
||||
|
@ -127,9 +127,10 @@ rec {
|
||||
|
||||
# GNU build systems assume that older NetBSD architectures are using a.out.
|
||||
gnuNetBSDDefaultExecFormat = cpu:
|
||||
if (cpu.family == "x86" && cpu.bits == 32) ||
|
||||
(cpu.family == "arm" && cpu.bits == 32) ||
|
||||
(cpu.family == "sparc" && cpu.bits == 32)
|
||||
if (cpu.family == "arm" && cpu.bits == 32) ||
|
||||
(cpu.family == "sparc" && cpu.bits == 32) ||
|
||||
(cpu.family == "m68k" && cpu.bits == 32) ||
|
||||
(cpu.family == "x86" && cpu.bits == 32)
|
||||
then execFormats.aout
|
||||
else execFormats.elf;
|
||||
|
||||
|
@ -315,6 +315,12 @@ rec {
|
||||
# Disable OABI to have seccomp_filter (required for systemd)
|
||||
# https://github.com/raspberrypi/firmware/issues/651
|
||||
OABI_COMPAT n
|
||||
|
||||
# >=5.12 fails with:
|
||||
# drivers/net/ethernet/micrel/ks8851_common.o: in function `ks8851_probe_common':
|
||||
# ks8851_common.c:(.text+0x179c): undefined reference to `__this_module'
|
||||
# See: https://lore.kernel.org/netdev/20210116164828.40545-1-marex@denx.de/T/
|
||||
KS8851_MLL y
|
||||
'';
|
||||
};
|
||||
gcc = {
|
||||
|
@ -29,7 +29,7 @@ with lib.systems.doubles; lib.runTests {
|
||||
testgnu = mseteq gnu (linux /* ++ kfreebsd ++ ... */);
|
||||
testillumos = mseteq illumos [ "x86_64-solaris" ];
|
||||
testlinux = mseteq linux [ "aarch64-linux" "armv5tel-linux" "armv6l-linux" "armv7a-linux" "armv7l-linux" "i686-linux" "mipsel-linux" "riscv32-linux" "riscv64-linux" "x86_64-linux" "powerpc64-linux" "powerpc64le-linux" "m68k-linux" "s390-linux" ];
|
||||
testnetbsd = mseteq netbsd [ "aarch64-netbsd" "armv6l-netbsd" "armv7a-netbsd" "armv7l-netbsd" "i686-netbsd" "mipsel-netbsd" "powerpc-netbsd" "riscv32-netbsd" "riscv64-netbsd" "x86_64-netbsd" ];
|
||||
testnetbsd = mseteq netbsd [ "aarch64-netbsd" "armv6l-netbsd" "armv7a-netbsd" "armv7l-netbsd" "i686-netbsd" "m68k-netbsd" "mipsel-netbsd" "powerpc-netbsd" "riscv32-netbsd" "riscv64-netbsd" "x86_64-netbsd" ];
|
||||
testopenbsd = mseteq openbsd [ "i686-openbsd" "x86_64-openbsd" ];
|
||||
testwindows = mseteq windows [ "i686-cygwin" "x86_64-cygwin" "i686-windows" "x86_64-windows" ];
|
||||
testunix = mseteq unix (linux ++ darwin ++ freebsd ++ openbsd ++ netbsd ++ illumos ++ cygwin ++ redox);
|
||||
|
@ -4541,6 +4541,12 @@
|
||||
githubId = 592849;
|
||||
name = "Ilya Kolpakov";
|
||||
};
|
||||
ilyakooo0 = {
|
||||
name = "Ilya Kostyuchenko";
|
||||
email = "ilyakooo0@gmail.com";
|
||||
github = "ilyakooo0";
|
||||
githubId = 6209627;
|
||||
};
|
||||
imalison = {
|
||||
email = "IvanMalison@gmail.com";
|
||||
github = "IvanMalison";
|
||||
@ -7477,6 +7483,12 @@
|
||||
email = "natedevv@gmail.com";
|
||||
name = "Nathan Moore";
|
||||
};
|
||||
nathanruiz = {
|
||||
email = "nathanruiz@protonmail.com";
|
||||
github = "nathanruiz";
|
||||
githubId = 18604892;
|
||||
name = "Nathan Ruiz";
|
||||
};
|
||||
nathan-gs = {
|
||||
email = "nathan@nathan.gs";
|
||||
github = "nathan-gs";
|
||||
@ -11686,6 +11698,12 @@
|
||||
githubId = 3705333;
|
||||
name = "Dmitry V.";
|
||||
};
|
||||
yayayayaka = {
|
||||
email = "nixpkgs@uwu.is";
|
||||
github = "yayayayaka";
|
||||
githubId = 73759599;
|
||||
name = "Lara A.";
|
||||
};
|
||||
yegortimoshenko = {
|
||||
email = "yegortimoshenko@riseup.net";
|
||||
github = "yegortimoshenko";
|
||||
|
@ -12,10 +12,10 @@
|
||||
# ~/.cabal/config file.
|
||||
|
||||
# e.g. username: maralorn
|
||||
# password-command: pass hackage.haskell.org (this can be any command, but not an arbitrary shell expression.)
|
||||
# password-command: pass hackage.haskell.org (this can be any command, but not an arbitrary shell expression. Like cabal we only read the first output line and ignore the rest.)
|
||||
# Those fields are specified under `upload` on the `cabal` man page.
|
||||
|
||||
package_list="$(nix-build -A haskell.package-list)/nixos-hackage-packages.csv"
|
||||
username=$(grep "^username:" ~/.cabal/config | sed "s/^username: //")
|
||||
password_command=$(grep "^password-command:" ~/.cabal/config | sed "s/^password-command: //")
|
||||
curl -u "$username:$($password_command)" --digest -H "Content-type: text/csv" -T "$package_list" http://hackage.haskell.org/distro/NixOS/packages.csv
|
||||
curl -u "$username:$($password_command | head -n1)" --digest -H "Content-type: text/csv" -T "$package_list" http://hackage.haskell.org/distro/NixOS/packages.csv
|
||||
|
@ -78,10 +78,11 @@ mpack,,,,,
|
||||
moonscript,,,,,arobyn
|
||||
nvim-client,,,,,
|
||||
penlight,,,,,
|
||||
plenary.nvim,,,,lua5_1,
|
||||
rapidjson,,,,,
|
||||
readline,,,,,
|
||||
say,,,,,
|
||||
std__debug,std._debug,,,,
|
||||
std-_debug,std._debug,,,,
|
||||
std_normalize,std.normalize,,,,
|
||||
stdlib,,,,,vyp
|
||||
vstruct,,,,,
|
||||
|
|
@ -89,6 +89,10 @@ function convert_pkg() {
|
||||
echo "Skipping comment ${*}" >&2
|
||||
return
|
||||
fi
|
||||
|
||||
# Normalize package name
|
||||
nix_pkg_name_normalized=$(sed 's/\./-/' <(echo "$nix_pkg_name"))
|
||||
|
||||
if [ -z "$lua_pkg_name" ]; then
|
||||
echo "Using nix_name as lua_pkg_name for '$nix_pkg_name'" >&2
|
||||
lua_pkg_name="$nix_pkg_name"
|
||||
@ -111,7 +115,7 @@ function convert_pkg() {
|
||||
luarocks_args+=("$pkg_version")
|
||||
fi
|
||||
echo "Running 'luarocks ${luarocks_args[*]}'" >&2
|
||||
if drv="$nix_pkg_name = $(luarocks "${luarocks_args[@]}")"; then
|
||||
if drv="$nix_pkg_name_normalized = $(luarocks "${luarocks_args[@]}")"; then
|
||||
echo "$drv"
|
||||
else
|
||||
echo "Failed to convert $nix_pkg_name" >&2
|
||||
|
@ -162,6 +162,7 @@ with lib.maintainers; {
|
||||
ralith
|
||||
mjlbach
|
||||
dandellion
|
||||
sumnerevans
|
||||
];
|
||||
scope = "Maintain the ecosystem around Matrix, a decentralized messenger.";
|
||||
};
|
||||
|
@ -0,0 +1,6 @@
|
||||
# Linking NixOS tests to packages {#sec-linking-nixos-tests-to-packages}
|
||||
|
||||
You can link NixOS module tests to the packages that they exercised,
|
||||
so that the tests can be run automatically during code review when the package gets changed.
|
||||
This is
|
||||
[described in the nixpkgs manual](https://nixos.org/manual/nixpkgs/stable/#ssec-nixos-tests-linking).
|
@ -16,4 +16,5 @@ xlink:href="https://github.com/NixOS/nixpkgs/tree/master/nixos/tests">nixos/test
|
||||
<xi:include href="../from_md/development/writing-nixos-tests.section.xml" />
|
||||
<xi:include href="../from_md/development/running-nixos-tests.section.xml" />
|
||||
<xi:include href="../from_md/development/running-nixos-tests-interactively.section.xml" />
|
||||
<xi:include href="../from_md/development/linking-nixos-tests-to-packages.section.xml" />
|
||||
</chapter>
|
||||
|
@ -0,0 +1,10 @@
|
||||
<section xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="sec-linking-nixos-tests-to-packages">
|
||||
<title>Linking NixOS tests to packages</title>
|
||||
<para>
|
||||
You can link NixOS module tests to the packages that they exercised,
|
||||
so that the tests can be run automatically during code review when
|
||||
the package gets changed. This is
|
||||
<link xlink:href="https://nixos.org/manual/nixpkgs/stable/#ssec-nixos-tests-linking">described
|
||||
in the nixpkgs manual</link>.
|
||||
</para>
|
||||
</section>
|
@ -125,6 +125,21 @@
|
||||
<link linkend="opt-services.prometheus.exporters.buildkite-agent.enable">services.prometheus.exporters.buildkite-agent</link>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<link xlink:href="https://github.com/prometheus/influxdb_exporter">influxdb-exporter</link>
|
||||
a Prometheus exporter that exports metrics received on an
|
||||
InfluxDB compatible endpoint is now available as
|
||||
<link linkend="opt-services.prometheus.exporters.influxdb.enable">services.prometheus.exporters.influxdb</link>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<link xlink:href="https://github.com/matrix-discord/mx-puppet-discord">mx-puppet-discord</link>,
|
||||
a discord puppeting bridge for matrix. Available as
|
||||
<link linkend="opt-services.mx-puppet-discord.enable">services.mx-puppet-discord</link>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<link xlink:href="https://www.meshcommander.com/meshcentral2/overview">MeshCentral</link>,
|
||||
@ -564,6 +579,51 @@
|
||||
6.0.0 to 9.0.0
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>tt-rss</literal> was upgraded to the commit on
|
||||
2021-06-21, which has breaking changes. If you use
|
||||
<literal>services.tt-rss.extraConfig</literal> you should
|
||||
migrate to the <literal>putenv</literal>-style configuration.
|
||||
See
|
||||
<link xlink:href="https://community.tt-rss.org/t/rip-config-php-hello-classes-config-php/4337">this
|
||||
Discourse post</link> in the tt-rss forums for more details.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The following Visual Studio Code extensions were renamed to
|
||||
keep the naming convention uniform.
|
||||
</para>
|
||||
<itemizedlist spacing="compact">
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>bbenoist.Nix</literal> ->
|
||||
<literal>bbenoist.nix</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>CoenraadS.bracket-pair-colorizer</literal> ->
|
||||
<literal>coenraads.bracket-pair-colorizer</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>golang.Go</literal> ->
|
||||
<literal>golang.go</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>services.uptimed</literal> now uses
|
||||
<literal>/var/lib/uptimed</literal> as its stateDirectory
|
||||
instead of <literal>/var/spool/uptimed</literal>. Make sure to
|
||||
move all files to the new directory.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
<section xml:id="sec-release-21.11-notable-changes">
|
||||
|
@ -39,6 +39,10 @@ pt-services.clipcat.enable).
|
||||
|
||||
- [buildkite-agent-metrics](https://github.com/buildkite/buildkite-agent-metrics), a command-line tool for collecting Buildkite agent metrics, now has a Prometheus exporter available as [services.prometheus.exporters.buildkite-agent](#opt-services.prometheus.exporters.buildkite-agent.enable).
|
||||
|
||||
- [influxdb-exporter](https://github.com/prometheus/influxdb_exporter) a Prometheus exporter that exports metrics received on an InfluxDB compatible endpoint is now available as [services.prometheus.exporters.influxdb](#opt-services.prometheus.exporters.influxdb.enable).
|
||||
|
||||
- [mx-puppet-discord](https://github.com/matrix-discord/mx-puppet-discord), a discord puppeting bridge for matrix. Available as [services.mx-puppet-discord](#opt-services.mx-puppet-discord.enable).
|
||||
|
||||
- [MeshCentral](https://www.meshcommander.com/meshcentral2/overview), a remote administration service ("TeamViewer but self-hosted and with more features") is now available with a package and a module: [services.meshcentral.enable](#opt-services.meshcentral.enable)
|
||||
|
||||
## Backward Incompatibilities {#sec-release-21.11-incompatibilities}
|
||||
@ -144,6 +148,15 @@ pt-services.clipcat.enable).
|
||||
|
||||
- the `mingw-64` package has been upgraded from 6.0.0 to 9.0.0
|
||||
|
||||
- `tt-rss` was upgraded to the commit on 2021-06-21, which has breaking changes. If you use `services.tt-rss.extraConfig` you should migrate to the `putenv`-style configuration. See [this Discourse post](https://community.tt-rss.org/t/rip-config-php-hello-classes-config-php/4337) in the tt-rss forums for more details.
|
||||
|
||||
- The following Visual Studio Code extensions were renamed to keep the naming convention uniform.
|
||||
- `bbenoist.Nix` -> `bbenoist.nix`
|
||||
- `CoenraadS.bracket-pair-colorizer` -> `coenraads.bracket-pair-colorizer`
|
||||
- `golang.Go` -> `golang.go`
|
||||
|
||||
- `services.uptimed` now uses `/var/lib/uptimed` as its stateDirectory instead of `/var/spool/uptimed`. Make sure to move all files to the new directory.
|
||||
|
||||
## Other Notable Changes {#sec-release-21.11-notable-changes}
|
||||
|
||||
- The setting [`services.openssh.logLevel`](options.html#opt-services.openssh.logLevel) `"VERBOSE"` `"INFO"`. This brings NixOS in line with upstream and other Linux distributions, and reduces log spam on servers due to bruteforcing botnets.
|
||||
|
@ -130,9 +130,12 @@ rec {
|
||||
|
||||
nodeHostNames = map (c: c.config.system.name) (lib.attrValues nodes);
|
||||
|
||||
# TODO: This is an implementation error and needs fixing
|
||||
# the testing famework cannot legitimately restrict hostnames further
|
||||
# beyond RFC1035
|
||||
invalidNodeNames = lib.filter
|
||||
(node: builtins.match "^[A-z_]([A-z0-9_]+)?$" node == null)
|
||||
(builtins.attrNames nodes);
|
||||
nodeHostNames;
|
||||
|
||||
testScript' =
|
||||
# Call the test script with the computed nodes.
|
||||
@ -146,7 +149,9 @@ rec {
|
||||
Cannot create machines out of (${lib.concatStringsSep ", " invalidNodeNames})!
|
||||
All machines are referenced as python variables in the testing framework which will break the
|
||||
script when special characters are used.
|
||||
Please stick to alphanumeric chars and underscores as separation.
|
||||
|
||||
This is an IMPLEMENTATION ERROR and needs to be fixed. Meanwhile,
|
||||
please stick to alphanumeric chars and underscores as separation.
|
||||
''
|
||||
else lib.warnIf skipLint "Linting is disabled" (runCommand testDriverName
|
||||
{
|
||||
|
@ -35,6 +35,14 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
hardware.wirelessRegulatoryDatabase = mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Load the wireless regulatory database at boot.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -58,6 +66,7 @@ in {
|
||||
++ optionals (versionOlder config.boot.kernelPackages.kernel.version "4.13") [
|
||||
rtl8723bs-firmware
|
||||
];
|
||||
hardware.wirelessRegulatoryDatabase = true;
|
||||
})
|
||||
(mkIf cfg.enableAllFirmware {
|
||||
assertions = [{
|
||||
@ -75,5 +84,8 @@ in {
|
||||
b43FirmwareCutter
|
||||
] ++ optional (pkgs.stdenv.hostPlatform.isi686 || pkgs.stdenv.hostPlatform.isx86_64) facetimehd-firmware;
|
||||
})
|
||||
(mkIf cfg.wirelessRegulatoryDatabase {
|
||||
hardware.firmware = [ pkgs.wireless-regdb ];
|
||||
})
|
||||
];
|
||||
}
|
||||
|
@ -654,7 +654,11 @@ in
|
||||
];
|
||||
|
||||
fileSystems."/" =
|
||||
{ fsType = "tmpfs";
|
||||
# This module is often over-layed onto an existing host config
|
||||
# that defines `/`. We use mkOverride 60 to override standard
|
||||
# values, but at the same time leave room for mkForce values
|
||||
# targeted at the image build.
|
||||
{ fsType = mkOverride 60 "tmpfs";
|
||||
options = [ "mode=0755" ];
|
||||
};
|
||||
|
||||
|
@ -30,7 +30,11 @@ with lib;
|
||||
else [ pkgs.grub2 pkgs.syslinux ]);
|
||||
|
||||
fileSystems."/" =
|
||||
{ fsType = "tmpfs";
|
||||
# This module is often over-layed onto an existing host config
|
||||
# that defines `/`. We use mkOverride 60 to override standard
|
||||
# values, but at the same time leave room for mkForce values
|
||||
# targeted at the image build.
|
||||
{ fsType = mkOverride 60 "tmpfs";
|
||||
options = [ "mode=0755" ];
|
||||
};
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
x86_64-linux = "/nix/store/qsgz2hhn6mzlzp53a7pwf9z2pq3l5z6h-nix-2.3.14";
|
||||
i686-linux = "/nix/store/1yw40bj04lykisw2jilq06lir3k9ga4a-nix-2.3.14";
|
||||
aarch64-linux = "/nix/store/32yzwmynmjxfrkb6y6l55liaqdrgkj4a-nix-2.3.14";
|
||||
x86_64-darwin = "/nix/store/06j0vi2d13w4l0p3jsigq7lk4x6gkycj-nix-2.3.14";
|
||||
aarch64-darwin = "/nix/store/77wi7vpbrghw5rgws25w30bwb8yggnk9-nix-2.3.14";
|
||||
x86_64-linux = "/nix/store/jhbxh1jwjc3hjhzs9y2hifdn0rmnfwaj-nix-2.3.15";
|
||||
i686-linux = "/nix/store/9pspwnkdrgzma1l4xlv7arhwa56y16di-nix-2.3.15";
|
||||
aarch64-linux = "/nix/store/72aqi5g7f4fhgvgafbcqwcpqjgnczj48-nix-2.3.15";
|
||||
x86_64-darwin = "/nix/store/6p6qwp73dgfkqhynmxrzbx1lcfgfpqal-nix-2.3.15";
|
||||
aarch64-darwin = "/nix/store/dmq2vksdhssgfl822shd0ky3x5x0klh4-nix-2.3.15";
|
||||
}
|
||||
|
@ -187,6 +187,7 @@ in
|
||||
#seeks = 148; # removed 2020-06-21
|
||||
prosody = 149;
|
||||
i2pd = 150;
|
||||
systemd-coredump = 151;
|
||||
systemd-network = 152;
|
||||
systemd-resolve = 153;
|
||||
systemd-timesync = 154;
|
||||
|
@ -103,9 +103,10 @@ in
|
||||
''
|
||||
NAME=NixOS
|
||||
ID=nixos
|
||||
VERSION="${cfg.version} (${cfg.codeName})"
|
||||
VERSION="${cfg.release} (${cfg.codeName})"
|
||||
VERSION_CODENAME=${toLower cfg.codeName}
|
||||
VERSION_ID="${cfg.version}"
|
||||
VERSION_ID="${cfg.release}"
|
||||
BUILD_ID="${cfg.version}"
|
||||
PRETTY_NAME="NixOS ${cfg.release} (${cfg.codeName})"
|
||||
LOGO="nix-snowflake"
|
||||
HOME_URL="https://nixos.org/"
|
||||
|
@ -520,6 +520,7 @@
|
||||
./services/misc/logkeys.nix
|
||||
./services/misc/leaps.nix
|
||||
./services/misc/lidarr.nix
|
||||
./services/misc/libreddit.nix
|
||||
./services/misc/lifecycled.nix
|
||||
./services/misc/mame.nix
|
||||
./services/misc/matrix-appservice-discord.nix
|
||||
@ -530,6 +531,7 @@
|
||||
./services/misc/mediatomb.nix
|
||||
./services/misc/metabase.nix
|
||||
./services/misc/mwlib.nix
|
||||
./services/misc/mx-puppet-discord.nix
|
||||
./services/misc/n8n.nix
|
||||
./services/misc/nix-daemon.nix
|
||||
./services/misc/nix-gc.nix
|
||||
@ -634,6 +636,7 @@
|
||||
./services/network-filesystems/glusterfs.nix
|
||||
./services/network-filesystems/kbfs.nix
|
||||
./services/network-filesystems/ipfs.nix
|
||||
./services/network-filesystems/litestream/default.nix
|
||||
./services/network-filesystems/netatalk.nix
|
||||
./services/network-filesystems/nfsd.nix
|
||||
./services/network-filesystems/openafs/client.nix
|
||||
@ -961,6 +964,7 @@
|
||||
./services/web-apps/moodle.nix
|
||||
./services/web-apps/nextcloud.nix
|
||||
./services/web-apps/nexus.nix
|
||||
./services/web-apps/node-red.nix
|
||||
./services/web-apps/plantuml-server.nix
|
||||
./services/web-apps/plausible.nix
|
||||
./services/web-apps/pgpkeyserver-lite.nix
|
||||
|
@ -60,6 +60,45 @@ in {
|
||||
sha256 = "02r440xcdsgi137k5lmmvp0z5w5fmk8g9mysq5pnysq1wl8sj6mw";
|
||||
};
|
||||
};
|
||||
|
||||
corefile = mkOption {
|
||||
description = ''
|
||||
Custom coredns corefile configuration.
|
||||
|
||||
See: <link xlink:href="https://coredns.io/manual/toc/#configuration"/>.
|
||||
'';
|
||||
type = types.str;
|
||||
default = ''
|
||||
.:${toString ports.dns} {
|
||||
errors
|
||||
health :${toString ports.health}
|
||||
kubernetes ${cfg.clusterDomain} in-addr.arpa ip6.arpa {
|
||||
pods insecure
|
||||
fallthrough in-addr.arpa ip6.arpa
|
||||
}
|
||||
prometheus :${toString ports.metrics}
|
||||
forward . /etc/resolv.conf
|
||||
cache 30
|
||||
loop
|
||||
reload
|
||||
loadbalance
|
||||
}'';
|
||||
defaultText = ''
|
||||
.:${toString ports.dns} {
|
||||
errors
|
||||
health :${toString ports.health}
|
||||
kubernetes ''${config.services.kubernetes.addons.dns.clusterDomain} in-addr.arpa ip6.arpa {
|
||||
pods insecure
|
||||
fallthrough in-addr.arpa ip6.arpa
|
||||
}
|
||||
prometheus :${toString ports.metrics}
|
||||
forward . /etc/resolv.conf
|
||||
cache 30
|
||||
loop
|
||||
reload
|
||||
loadbalance
|
||||
}'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
@ -151,20 +190,7 @@ in {
|
||||
namespace = "kube-system";
|
||||
};
|
||||
data = {
|
||||
Corefile = ".:${toString ports.dns} {
|
||||
errors
|
||||
health :${toString ports.health}
|
||||
kubernetes ${cfg.clusterDomain} in-addr.arpa ip6.arpa {
|
||||
pods insecure
|
||||
fallthrough in-addr.arpa ip6.arpa
|
||||
}
|
||||
prometheus :${toString ports.metrics}
|
||||
forward . /etc/resolv.conf
|
||||
cache 30
|
||||
loop
|
||||
reload
|
||||
loadbalance
|
||||
}";
|
||||
Corefile = cfg.corefile;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -189,7 +189,7 @@ in
|
||||
# manually paste it in place. Just symlink.
|
||||
# otherwise, create the target file, ready for users to insert the token
|
||||
|
||||
mkdir -p $(dirname ${certmgrAPITokenPath})
|
||||
mkdir -p "$(dirname "${certmgrAPITokenPath}")"
|
||||
if [ -f "${cfsslAPITokenPath}" ]; then
|
||||
ln -fs "${cfsslAPITokenPath}" "${certmgrAPITokenPath}"
|
||||
else
|
||||
|
@ -4,7 +4,10 @@ with lib;
|
||||
|
||||
let
|
||||
|
||||
pkg = pkgs.sane-backends;
|
||||
pkg = pkgs.sane-backends.override {
|
||||
scanSnapDriversUnfree = config.hardware.sane.drivers.scanSnap.enable;
|
||||
scanSnapDriversPackage = config.hardware.sane.drivers.scanSnap.package;
|
||||
};
|
||||
|
||||
sanedConf = pkgs.writeTextFile {
|
||||
name = "saned.conf";
|
||||
@ -98,6 +101,28 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
hardware.sane.drivers.scanSnap.enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
example = true;
|
||||
description = ''
|
||||
Whether to enable drivers for the Fujitsu ScanSnap scanners.
|
||||
|
||||
The driver files are unfree and extracted from the Windows driver image.
|
||||
'';
|
||||
};
|
||||
|
||||
hardware.sane.drivers.scanSnap.package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.sane-drivers.epjitsu;
|
||||
description = ''
|
||||
Epjitsu driver package to use. Useful if you want to extract the driver files yourself.
|
||||
|
||||
The process is described in the <literal>/etc/sane.d/epjitsu.conf</literal> file in
|
||||
the <literal>sane-backends</literal> package.
|
||||
'';
|
||||
};
|
||||
|
||||
services.saned.enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
|
@ -523,19 +523,12 @@ in
|
||||
''}
|
||||
|
||||
# update all hooks' binary paths
|
||||
HOOKS=$(find ${cfg.repositoryRoot} -mindepth 4 -maxdepth 6 -type f -wholename "*git/hooks/*")
|
||||
if [ "$HOOKS" ]
|
||||
then
|
||||
sed -ri 's,/nix/store/[a-z0-9.-]+/bin/gitea,${gitea}/bin/gitea,g' $HOOKS
|
||||
sed -ri 's,/nix/store/[a-z0-9.-]+/bin/env,${pkgs.coreutils}/bin/env,g' $HOOKS
|
||||
sed -ri 's,/nix/store/[a-z0-9.-]+/bin/bash,${pkgs.bash}/bin/bash,g' $HOOKS
|
||||
sed -ri 's,/nix/store/[a-z0-9.-]+/bin/perl,${pkgs.perl}/bin/perl,g' $HOOKS
|
||||
fi
|
||||
${gitea}/bin/gitea admin regenerate hooks
|
||||
|
||||
# update command option in authorized_keys
|
||||
if [ -r ${cfg.stateDir}/.ssh/authorized_keys ]
|
||||
then
|
||||
sed -ri 's,/nix/store/[a-z0-9.-]+/bin/gitea,${gitea}/bin/gitea,g' ${cfg.stateDir}/.ssh/authorized_keys
|
||||
${gitea}/bin/gitea admin regenerate keys
|
||||
fi
|
||||
'';
|
||||
|
||||
|
66
nixos/modules/services/misc/libreddit.nix
Normal file
66
nixos/modules/services/misc/libreddit.nix
Normal file
@ -0,0 +1,66 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.libreddit;
|
||||
|
||||
args = concatStringsSep " " ([
|
||||
"--port ${toString cfg.port}"
|
||||
"--address ${cfg.address}"
|
||||
] ++ optional cfg.redirect "--redirect-https");
|
||||
|
||||
in
|
||||
{
|
||||
options = {
|
||||
services.libreddit = {
|
||||
enable = mkEnableOption "Private front-end for Reddit";
|
||||
|
||||
address = mkOption {
|
||||
default = "0.0.0.0";
|
||||
example = "127.0.0.1";
|
||||
type = types.str;
|
||||
description = "The address to listen on";
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
default = 8080;
|
||||
example = 8000;
|
||||
type = types.port;
|
||||
description = "The port to listen on";
|
||||
};
|
||||
|
||||
redirect = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Enable the redirecting to HTTPS";
|
||||
};
|
||||
|
||||
openFirewall = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Open ports in the firewall for the libreddit web interface";
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
systemd.services.libreddit = {
|
||||
description = "Private front-end for Reddit";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
serviceConfig = {
|
||||
DynamicUser = true;
|
||||
ExecStart = "${pkgs.libreddit}/bin/libreddit ${args}";
|
||||
AmbientCapabilities = lib.mkIf (cfg.port < 1024) [ "CAP_NET_BIND_SERVICE" ];
|
||||
Restart = "on-failure";
|
||||
RestartSec = "2s";
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall = mkIf cfg.openFirewall {
|
||||
allowedTCPPorts = [ cfg.port ];
|
||||
};
|
||||
};
|
||||
}
|
120
nixos/modules/services/misc/mx-puppet-discord.nix
Normal file
120
nixos/modules/services/misc/mx-puppet-discord.nix
Normal file
@ -0,0 +1,120 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
dataDir = "/var/lib/mx-puppet-discord";
|
||||
registrationFile = "${dataDir}/discord-registration.yaml";
|
||||
cfg = config.services.mx-puppet-discord;
|
||||
settingsFormat = pkgs.formats.json {};
|
||||
settingsFile = settingsFormat.generate "mx-puppet-discord-config.json" cfg.settings;
|
||||
|
||||
in {
|
||||
options = {
|
||||
services.mx-puppet-discord = {
|
||||
enable = mkEnableOption ''
|
||||
mx-puppet-discord is a discord puppeting bridge for matrix.
|
||||
It handles bridging private and group DMs, as well as Guilds (servers)
|
||||
'';
|
||||
|
||||
settings = mkOption rec {
|
||||
apply = recursiveUpdate default;
|
||||
inherit (settingsFormat) type;
|
||||
default = {
|
||||
bridge.port = 8434;
|
||||
presence = {
|
||||
enabled = true;
|
||||
interval = 500;
|
||||
};
|
||||
provisioning.whitelist = [ ];
|
||||
relay.whitelist = [ ];
|
||||
|
||||
# variables are preceded by a colon.
|
||||
namePatterns = {
|
||||
user = ":name";
|
||||
userOverride = ":displayname";
|
||||
room = ":name";
|
||||
group = ":name";
|
||||
};
|
||||
|
||||
#defaults to sqlite but can be configured to use postgresql with
|
||||
#connstring
|
||||
database.filename = "${dataDir}/mx-puppet-discord/database.db";
|
||||
logging = {
|
||||
console = "info";
|
||||
lineDateFormat = "MMM-D HH:mm:ss.SSS";
|
||||
};
|
||||
};
|
||||
example = literalExample ''
|
||||
{
|
||||
bridge = {
|
||||
bindAddress = "localhost";
|
||||
domain = "example.com";
|
||||
homeserverUrl = "https://example.com";
|
||||
};
|
||||
|
||||
provisioning.whitelist = [ "@admin:example.com" ];
|
||||
relay.whitelist = [ "@.*:example.com" ];
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
<filename>config.yaml</filename> configuration as a Nix attribute set.
|
||||
Configuration options should match those described in
|
||||
<link xlink:href="https://github.com/matrix-discord/mx-puppet-discord/blob/master/sample.config.yaml">
|
||||
sample.config.yaml</link>.
|
||||
'';
|
||||
};
|
||||
serviceDependencies = mkOption {
|
||||
type = with types; listOf str;
|
||||
default = optional config.services.matrix-synapse.enable "matrix-synapse.service";
|
||||
description = ''
|
||||
List of Systemd services to require and wait for when starting the application service.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
systemd.services.mx-puppet-discord = {
|
||||
description = ''
|
||||
mx-puppet-discord is a discord puppeting bridge for matrix.
|
||||
It handles bridging private and group DMs, as well as Guilds (servers).
|
||||
'';
|
||||
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
wants = [ "network-online.target" ] ++ cfg.serviceDependencies;
|
||||
after = [ "network-online.target" ] ++ cfg.serviceDependencies;
|
||||
|
||||
preStart = ''
|
||||
# generate the appservice's registration file if absent
|
||||
if [ ! -f '${registrationFile}' ]; then
|
||||
${pkgs.mx-puppet-discord}/bin/mx-puppet-discord -r -c ${settingsFile} \
|
||||
-f ${registrationFile}
|
||||
fi
|
||||
'';
|
||||
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
Restart = "always";
|
||||
|
||||
ProtectSystem = "strict";
|
||||
ProtectHome = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectControlGroups = true;
|
||||
|
||||
DynamicUser = true;
|
||||
PrivateTmp = true;
|
||||
WorkingDirectory = pkgs.mx-puppet-discord;
|
||||
StateDirectory = baseNameOf dataDir;
|
||||
UMask = 0027;
|
||||
|
||||
ExecStart = ''
|
||||
${pkgs.mx-puppet-discord}/bin/mx-puppet-discord -c ${settingsFile}
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
meta.maintainers = with maintainers; [ govanify ];
|
||||
}
|
@ -458,7 +458,7 @@ in
|
||||
description = "The flake reference to which <option>from></option> is to be rewritten.";
|
||||
};
|
||||
flake = mkOption {
|
||||
type = types.unspecified;
|
||||
type = types.nullOr types.attrs;
|
||||
default = null;
|
||||
example = literalExample "nixpkgs";
|
||||
description = ''
|
||||
|
@ -33,6 +33,7 @@ let
|
||||
"domain"
|
||||
"dovecot"
|
||||
"fritzbox"
|
||||
"influxdb"
|
||||
"json"
|
||||
"jitsi"
|
||||
"kea"
|
||||
|
@ -0,0 +1,34 @@
|
||||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.influxdb;
|
||||
in
|
||||
{
|
||||
port = 9122;
|
||||
extraOpts = {
|
||||
sampleExpiry = mkOption {
|
||||
type = types.str;
|
||||
default = "5m";
|
||||
example = "10m";
|
||||
description = "How long a sample is valid for";
|
||||
};
|
||||
udpBindAddress = mkOption {
|
||||
type = types.str;
|
||||
default = ":9122";
|
||||
example = "192.0.2.1:9122";
|
||||
description = "Address on which to listen for udp packets";
|
||||
};
|
||||
};
|
||||
serviceOpts = {
|
||||
serviceConfig = {
|
||||
RuntimeDirectory = "prometheus-influxdb-exporter";
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-influxdb-exporter}/bin/influxdb_exporter \
|
||||
--web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
|
||||
--influxdb.sample-expiry ${cfg.sampleExpiry} ${concatStringsSep " " cfg.extraFlags}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
@ -0,0 +1,100 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.litestream;
|
||||
settingsFormat = pkgs.formats.yaml {};
|
||||
in
|
||||
{
|
||||
options.services.litestream = {
|
||||
enable = mkEnableOption "litestream";
|
||||
|
||||
package = mkOption {
|
||||
description = "Package to use.";
|
||||
default = pkgs.litestream;
|
||||
defaultText = "pkgs.litestream";
|
||||
type = types.package;
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
description = ''
|
||||
See the <link xlink:href="https://litestream.io/reference/config/">documentation</link>.
|
||||
'';
|
||||
type = settingsFormat.type;
|
||||
example = {
|
||||
dbs = [
|
||||
{
|
||||
path = "/var/lib/db1";
|
||||
replicas = [
|
||||
{
|
||||
url = "s3://mybkt.litestream.io/db1";
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
environmentFile = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
default = null;
|
||||
example = "/run/secrets/litestream";
|
||||
description = ''
|
||||
Environment file as defined in <citerefentry>
|
||||
<refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum>
|
||||
</citerefentry>.
|
||||
|
||||
Secrets may be passed to the service without adding them to the
|
||||
world-readable Nix store, by specifying placeholder variables as
|
||||
the option value in Nix and setting these variables accordingly in the
|
||||
environment file.
|
||||
|
||||
By default, Litestream will perform environment variable expansion
|
||||
within the config file before reading it. Any references to ''$VAR or
|
||||
''${VAR} formatted variables will be replaced with their environment
|
||||
variable values. If no value is set then it will be replaced with an
|
||||
empty string.
|
||||
|
||||
<programlisting>
|
||||
# Content of the environment file
|
||||
LITESTREAM_ACCESS_KEY_ID=AKIAxxxxxxxxxxxxxxxx
|
||||
LITESTREAM_SECRET_ACCESS_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/xxxxxxxxx
|
||||
</programlisting>
|
||||
|
||||
Note that this file needs to be available on the host on which
|
||||
this exporter is running.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
environment.systemPackages = [ cfg.package ];
|
||||
environment.etc = {
|
||||
"litestream.yml" = {
|
||||
source = settingsFormat.generate "litestream-config.yaml" cfg.settings;
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.litestream = {
|
||||
description = "Litestream";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "networking.target" ];
|
||||
serviceConfig = {
|
||||
EnvironmentFile = mkIf (cfg.environmentFile != null) cfg.environmentFile;
|
||||
ExecStart = "${cfg.package}/bin/litestream replicate";
|
||||
Restart = "always";
|
||||
User = "litestream";
|
||||
Group = "litestream";
|
||||
};
|
||||
};
|
||||
|
||||
users.users.litestream = {
|
||||
description = "Litestream user";
|
||||
group = "litestream";
|
||||
isSystemUser = true;
|
||||
};
|
||||
users.groups.litestream = {};
|
||||
};
|
||||
meta.doc = ./litestream.xml;
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
<chapter xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
version="5.0"
|
||||
xml:id="module-services-litestream">
|
||||
<title>Litestream</title>
|
||||
<para>
|
||||
<link xlink:href="https://litestream.io/">Litestream</link> is a standalone streaming
|
||||
replication tool for SQLite.
|
||||
</para>
|
||||
|
||||
<section xml:id="module-services-litestream-configuration">
|
||||
<title>Configuration</title>
|
||||
|
||||
<para>
|
||||
Litestream service is managed by a dedicated user named <literal>litestream</literal>
|
||||
which needs permission to the database file. Here's an example config which gives
|
||||
required permissions to access <link linkend="opt-services.grafana.database.path">
|
||||
grafana database</link>:
|
||||
<programlisting>
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
users.users.litestream.extraGroups = [ "grafana" ];
|
||||
|
||||
systemd.services.grafana.serviceConfig.ExecStartPost = "+" + pkgs.writeShellScript "grant-grafana-permissions" ''
|
||||
timeout=10
|
||||
|
||||
while [ ! -f /var/lib/grafana/data/grafana.db ];
|
||||
do
|
||||
if [ "$timeout" == 0 ]; then
|
||||
echo "ERROR: Timeout while waiting for /var/lib/grafana/data/grafana.db."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
|
||||
((timeout--))
|
||||
done
|
||||
|
||||
find /var/lib/grafana -type d -exec chmod -v 775 {} \;
|
||||
find /var/lib/grafana -type f -exec chmod -v 660 {} \;
|
||||
'';
|
||||
|
||||
services.litestream = {
|
||||
enable = true;
|
||||
|
||||
environmentFile = "/run/secrets/litestream";
|
||||
|
||||
settings = {
|
||||
dbs = [
|
||||
{
|
||||
path = "/var/lib/grafana/data/grafana.db";
|
||||
replicas = [{
|
||||
url = "s3://mybkt.litestream.io/grafana";
|
||||
}];
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
</programlisting>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
</chapter>
|
@ -10,8 +10,8 @@ let
|
||||
birdBin = if variant == "bird6" then "bird6" else "bird";
|
||||
birdc = if variant == "bird6" then "birdc6" else "birdc";
|
||||
descr =
|
||||
{ bird = "1.9.x with IPv4 suport";
|
||||
bird6 = "1.9.x with IPv6 suport";
|
||||
{ bird = "1.6.x with IPv4 support";
|
||||
bird6 = "1.6.x with IPv6 support";
|
||||
bird2 = "2.x";
|
||||
}.${variant};
|
||||
in {
|
||||
|
@ -339,6 +339,8 @@ in
|
||||
description =
|
||||
''
|
||||
Whether to log rejected or dropped incoming connections.
|
||||
Note: The logs are found in the kernel logs, i.e. dmesg
|
||||
or journalctl -k.
|
||||
'';
|
||||
};
|
||||
|
||||
@ -350,6 +352,8 @@ in
|
||||
Whether to log all rejected or dropped incoming packets.
|
||||
This tends to give a lot of log messages, so it's mostly
|
||||
useful for debugging.
|
||||
Note: The logs are found in the kernel logs, i.e. dmesg
|
||||
or journalctl -k.
|
||||
'';
|
||||
};
|
||||
|
||||
|
@ -238,6 +238,10 @@ in
|
||||
KEA_PIDFILE_DIR = "/run/kea";
|
||||
};
|
||||
|
||||
restartTriggers = [
|
||||
ctrlAgentConfig
|
||||
];
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = "${package}/bin/kea-ctrl-agent -c /etc/kea/ctrl-agent.conf ${lib.escapeShellArgs cfg.dhcp4.extraArgs}";
|
||||
KillMode = "process";
|
||||
@ -269,6 +273,10 @@ in
|
||||
KEA_PIDFILE_DIR = "/run/kea";
|
||||
};
|
||||
|
||||
restartTriggers = [
|
||||
dhcp4Config
|
||||
];
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = "${package}/bin/kea-dhcp4 -c /etc/kea/dhcp4-server.conf ${lib.escapeShellArgs cfg.dhcp4.extraArgs}";
|
||||
# Kea does not request capabilities by itself
|
||||
@ -307,6 +315,10 @@ in
|
||||
KEA_PIDFILE_DIR = "/run/kea";
|
||||
};
|
||||
|
||||
restartTriggers = [
|
||||
dhcp6Config
|
||||
];
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = "${package}/bin/kea-dhcp6 -c /etc/kea/dhcp6-server.conf ${lib.escapeShellArgs cfg.dhcp6.extraArgs}";
|
||||
# Kea does not request capabilities by itself
|
||||
@ -343,6 +355,10 @@ in
|
||||
KEA_PIDFILE_DIR = "/run/kea";
|
||||
};
|
||||
|
||||
restartTriggers = [
|
||||
dhcpDdnsConfig
|
||||
];
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = "${package}/bin/kea-dhcp-ddns -c /etc/kea/dhcp-ddns.conf ${lib.escapeShellArgs cfg.dhcp-ddns.extraArgs}";
|
||||
AmbientCapabilites = [
|
||||
|
@ -6,7 +6,6 @@ let
|
||||
cfg = config.networking.networkmanager;
|
||||
|
||||
basePackages = with pkgs; [
|
||||
crda
|
||||
modemmanager
|
||||
networkmanager
|
||||
networkmanager-fortisslvpn
|
||||
@ -49,6 +48,7 @@ let
|
||||
rc-manager =
|
||||
if config.networking.resolvconf.enable then "resolvconf"
|
||||
else "unmanaged";
|
||||
firewall-backend = cfg.firewallBackend;
|
||||
})
|
||||
(mkSection "keyfile" {
|
||||
unmanaged-devices =
|
||||
@ -244,6 +244,15 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
firewallBackend = mkOption {
|
||||
type = types.enum [ "iptables" "nftables" "none" ];
|
||||
default = "iptables";
|
||||
description = ''
|
||||
Which firewall backend should be used for configuring masquerading with shared mode.
|
||||
If set to none, NetworkManager doesn't manage the configuration at all.
|
||||
'';
|
||||
};
|
||||
|
||||
logLevel = mkOption {
|
||||
type = types.enum [ "OFF" "ERR" "WARN" "INFO" "DEBUG" "TRACE" ];
|
||||
default = "WARN";
|
||||
@ -404,6 +413,8 @@ in {
|
||||
}
|
||||
];
|
||||
|
||||
hardware.wirelessRegulatoryDatabase = true;
|
||||
|
||||
environment.etc = with pkgs; {
|
||||
"NetworkManager/NetworkManager.conf".source = configFile;
|
||||
|
||||
|
@ -103,6 +103,7 @@ in
|
||||
}];
|
||||
boot.blacklistedKernelModules = [ "ip_tables" ];
|
||||
environment.systemPackages = [ pkgs.nftables ];
|
||||
networking.networkmanager.firewallBackend = mkDefault "nftables";
|
||||
systemd.services.nftables = {
|
||||
description = "nftables firewall";
|
||||
before = [ "network-pre.target" ];
|
||||
|
@ -5,15 +5,16 @@ with lib;
|
||||
let
|
||||
cfg = config.services.syncthing;
|
||||
defaultUser = "syncthing";
|
||||
defaultGroup = defaultUser;
|
||||
|
||||
devices = mapAttrsToList (name: device: {
|
||||
deviceID = device.id;
|
||||
inherit (device) name addresses introducer;
|
||||
}) cfg.declarative.devices;
|
||||
}) cfg.devices;
|
||||
|
||||
folders = mapAttrsToList ( _: folder: {
|
||||
inherit (folder) path id label type;
|
||||
devices = map (device: { deviceId = cfg.declarative.devices.${device}.id; }) folder.devices;
|
||||
devices = map (device: { deviceId = cfg.devices.${device}.id; }) folder.devices;
|
||||
rescanIntervalS = folder.rescanInterval;
|
||||
fsWatcherEnabled = folder.watch;
|
||||
fsWatcherDelayS = folder.watchDelay;
|
||||
@ -23,215 +24,218 @@ let
|
||||
}) (filterAttrs (
|
||||
_: folder:
|
||||
folder.enable
|
||||
) cfg.declarative.folders);
|
||||
|
||||
# get the api key by parsing the config.xml
|
||||
getApiKey = pkgs.writers.writeDash "getAPIKey" ''
|
||||
${pkgs.libxml2}/bin/xmllint \
|
||||
--xpath 'string(configuration/gui/apikey)'\
|
||||
${cfg.configDir}/config.xml
|
||||
'';
|
||||
) cfg.folders);
|
||||
|
||||
updateConfig = pkgs.writers.writeDash "merge-syncthing-config" ''
|
||||
set -efu
|
||||
# wait for syncthing port to open
|
||||
until ${pkgs.curl}/bin/curl -Ss ${cfg.guiAddress} -o /dev/null; do
|
||||
sleep 1
|
||||
done
|
||||
|
||||
API_KEY=$(${getApiKey})
|
||||
OLD_CFG=$(${pkgs.curl}/bin/curl -Ss \
|
||||
-H "X-API-Key: $API_KEY" \
|
||||
${cfg.guiAddress}/rest/system/config)
|
||||
# get the api key by parsing the config.xml
|
||||
while
|
||||
! api_key=$(${pkgs.libxml2}/bin/xmllint \
|
||||
--xpath 'string(configuration/gui/apikey)' \
|
||||
${cfg.configDir}/config.xml)
|
||||
do sleep 1; done
|
||||
|
||||
# generate the new config by merging with the nixos config options
|
||||
NEW_CFG=$(echo "$OLD_CFG" | ${pkgs.jq}/bin/jq -s '.[] as $in | $in * {
|
||||
"devices": (${builtins.toJSON devices}${optionalString (! cfg.declarative.overrideDevices) " + $in.devices"}),
|
||||
"folders": (${builtins.toJSON folders}${optionalString (! cfg.declarative.overrideFolders) " + $in.folders"})
|
||||
}')
|
||||
curl() {
|
||||
${pkgs.curl}/bin/curl -sS -H "X-API-Key: $api_key" \
|
||||
--retry 1000 --retry-delay 1 --retry-all-errors \
|
||||
"$@"
|
||||
}
|
||||
|
||||
# POST the new config to syncthing
|
||||
echo "$NEW_CFG" | ${pkgs.curl}/bin/curl -Ss \
|
||||
-H "X-API-Key: $API_KEY" \
|
||||
${cfg.guiAddress}/rest/system/config -d @-
|
||||
# query the old config
|
||||
old_cfg=$(curl ${cfg.guiAddress}/rest/config)
|
||||
|
||||
# restart syncthing after sending the new config
|
||||
${pkgs.curl}/bin/curl -Ss \
|
||||
-H "X-API-Key: $API_KEY" \
|
||||
-X POST \
|
||||
${cfg.guiAddress}/rest/system/restart
|
||||
# generate the new config by merging with the NixOS config options
|
||||
new_cfg=$(echo "$old_cfg" | ${pkgs.jq}/bin/jq -c '. * {
|
||||
"devices": (${builtins.toJSON devices}${optionalString (! cfg.overrideDevices) " + .devices"}),
|
||||
"folders": (${builtins.toJSON folders}${optionalString (! cfg.overrideFolders) " + .folders"})
|
||||
} * ${builtins.toJSON cfg.extraOptions}')
|
||||
|
||||
# send the new config
|
||||
curl -X PUT -d "$new_cfg" ${cfg.guiAddress}/rest/config
|
||||
|
||||
# restart Syncthing if required
|
||||
if curl ${cfg.guiAddress}/rest/config/restart-required |
|
||||
${pkgs.jq}/bin/jq -e .requiresRestart > /dev/null; then
|
||||
curl -X POST ${cfg.guiAddress}/rest/system/restart
|
||||
fi
|
||||
'';
|
||||
in {
|
||||
###### interface
|
||||
options = {
|
||||
services.syncthing = {
|
||||
|
||||
enable = mkEnableOption ''
|
||||
Syncthing - the self-hosted open-source alternative
|
||||
to Dropbox and Bittorrent Sync. Initial interface will be
|
||||
available on http://127.0.0.1:8384/.
|
||||
'';
|
||||
enable = mkEnableOption
|
||||
"Syncthing, a self-hosted open-source alternative to Dropbox and Bittorrent Sync";
|
||||
|
||||
declarative = {
|
||||
cert = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Path to users cert.pem file, will be copied into the syncthing's
|
||||
<literal>configDir</literal>
|
||||
'';
|
||||
};
|
||||
cert = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Path to the <literal>cert.pem</literal> file, which will be copied into Syncthing's
|
||||
<link linkend="opt-services.syncthing.configDir">configDir</link>.
|
||||
'';
|
||||
};
|
||||
|
||||
key = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Path to users key.pem file, will be copied into the syncthing's
|
||||
<literal>configDir</literal>
|
||||
'';
|
||||
};
|
||||
key = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Path to the <literal>key.pem</literal> file, which will be copied into Syncthing's
|
||||
<link linkend="opt-services.syncthing.configDir">configDir</link>.
|
||||
'';
|
||||
};
|
||||
|
||||
overrideDevices = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to delete the devices which are not configured via the
|
||||
<literal>declarative.devices</literal> option.
|
||||
If set to false, devices added via the webinterface will
|
||||
persist but will have to be deleted manually.
|
||||
'';
|
||||
};
|
||||
overrideDevices = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to delete the devices which are not configured via the
|
||||
<link linkend="opt-services.syncthing.devices">devices</link> option.
|
||||
If set to <literal>false</literal>, devices added via the web
|
||||
interface will persist and will have to be deleted manually.
|
||||
'';
|
||||
};
|
||||
|
||||
devices = mkOption {
|
||||
default = {};
|
||||
description = ''
|
||||
Peers/devices which syncthing should communicate with.
|
||||
'';
|
||||
example = {
|
||||
bigbox = {
|
||||
id = "7CFNTQM-IMTJBHJ-3UWRDIU-ZGQJFR6-VCXZ3NB-XUH3KZO-N52ITXR-LAIYUAU";
|
||||
addresses = [ "tcp://192.168.0.10:51820" ];
|
||||
};
|
||||
devices = mkOption {
|
||||
default = {};
|
||||
description = ''
|
||||
Peers/devices which Syncthing should communicate with.
|
||||
|
||||
Note that you can still add devices manually, but those changes
|
||||
will be reverted on restart if <link linkend="opt-services.syncthing.overrideDevices">overrideDevices</link>
|
||||
is enabled.
|
||||
'';
|
||||
example = {
|
||||
bigbox = {
|
||||
id = "7CFNTQM-IMTJBHJ-3UWRDIU-ZGQJFR6-VCXZ3NB-XUH3KZO-N52ITXR-LAIYUAU";
|
||||
addresses = [ "tcp://192.168.0.10:51820" ];
|
||||
};
|
||||
type = types.attrsOf (types.submodule ({ name, ... }: {
|
||||
options = {
|
||||
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
default = name;
|
||||
description = ''
|
||||
Name of the device
|
||||
'';
|
||||
};
|
||||
|
||||
addresses = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
description = ''
|
||||
The addresses used to connect to the device.
|
||||
If this is let empty, dynamic configuration is attempted
|
||||
'';
|
||||
};
|
||||
|
||||
id = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
The id of the other peer, this is mandatory. It's documented at
|
||||
https://docs.syncthing.net/dev/device-ids.html
|
||||
'';
|
||||
};
|
||||
|
||||
introducer = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
If the device should act as an introducer and be allowed
|
||||
to add folders on this computer.
|
||||
'';
|
||||
};
|
||||
};
|
||||
type = types.attrsOf (types.submodule ({ name, ... }: {
|
||||
options = {
|
||||
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
default = name;
|
||||
description = ''
|
||||
The name of the device.
|
||||
'';
|
||||
};
|
||||
}));
|
||||
};
|
||||
|
||||
overrideFolders = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to delete the folders which are not configured via the
|
||||
<literal>declarative.folders</literal> option.
|
||||
If set to false, folders added via the webinterface will persist
|
||||
but will have to be deleted manually.
|
||||
'';
|
||||
};
|
||||
addresses = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
description = ''
|
||||
The addresses used to connect to the device.
|
||||
If this is left empty, dynamic configuration is attempted.
|
||||
'';
|
||||
};
|
||||
|
||||
folders = mkOption {
|
||||
default = {};
|
||||
description = ''
|
||||
folders which should be shared by syncthing.
|
||||
'';
|
||||
example = literalExample ''
|
||||
{
|
||||
"/home/user/sync" = {
|
||||
id = "syncme";
|
||||
devices = [ "bigbox" ];
|
||||
};
|
||||
}
|
||||
'';
|
||||
type = types.attrsOf (types.submodule ({ name, ... }: {
|
||||
options = {
|
||||
id = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
The device ID. See <link xlink:href="https://docs.syncthing.net/dev/device-ids.html"/>.
|
||||
'';
|
||||
};
|
||||
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
share this folder.
|
||||
This option is useful when you want to define all folders
|
||||
in one place, but not every machine should share all folders.
|
||||
'';
|
||||
};
|
||||
introducer = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether the device should act as an introducer and be allowed
|
||||
to add folders on this computer.
|
||||
See <link xlink:href="https://docs.syncthing.net/users/introducer.html"/>.
|
||||
'';
|
||||
};
|
||||
|
||||
path = mkOption {
|
||||
type = types.str;
|
||||
default = name;
|
||||
description = ''
|
||||
The path to the folder which should be shared.
|
||||
'';
|
||||
};
|
||||
};
|
||||
}));
|
||||
};
|
||||
|
||||
id = mkOption {
|
||||
type = types.str;
|
||||
default = name;
|
||||
description = ''
|
||||
The id of the folder. Must be the same on all devices.
|
||||
'';
|
||||
};
|
||||
overrideFolders = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to delete the folders which are not configured via the
|
||||
<link linkend="opt-services.syncthing.folders">folders</link> option.
|
||||
If set to <literal>false</literal>, folders added via the web
|
||||
interface will persist and will have to be deleted manually.
|
||||
'';
|
||||
};
|
||||
|
||||
label = mkOption {
|
||||
type = types.str;
|
||||
default = name;
|
||||
description = ''
|
||||
The label of the folder.
|
||||
'';
|
||||
};
|
||||
folders = mkOption {
|
||||
default = {};
|
||||
description = ''
|
||||
Folders which should be shared by Syncthing.
|
||||
|
||||
devices = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
description = ''
|
||||
The devices this folder should be shared with. Must be defined
|
||||
in the <literal>declarative.devices</literal> attribute.
|
||||
'';
|
||||
};
|
||||
Note that you can still add devices manually, but those changes
|
||||
will be reverted on restart if <link linkend="opt-services.syncthing.overrideDevices">overrideDevices</link>
|
||||
is enabled.
|
||||
'';
|
||||
example = literalExample ''
|
||||
{
|
||||
"/home/user/sync" = {
|
||||
id = "syncme";
|
||||
devices = [ "bigbox" ];
|
||||
};
|
||||
}
|
||||
'';
|
||||
type = types.attrsOf (types.submodule ({ name, ... }: {
|
||||
options = {
|
||||
|
||||
versioning = mkOption {
|
||||
default = null;
|
||||
description = ''
|
||||
How to keep changed/deleted files with syncthing.
|
||||
There are 4 different types of versioning with different parameters.
|
||||
See https://docs.syncthing.net/users/versioning.html
|
||||
'';
|
||||
example = [
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to share this folder.
|
||||
This option is useful when you want to define all folders
|
||||
in one place, but not every machine should share all folders.
|
||||
'';
|
||||
};
|
||||
|
||||
path = mkOption {
|
||||
type = types.str;
|
||||
default = name;
|
||||
description = ''
|
||||
The path to the folder which should be shared.
|
||||
'';
|
||||
};
|
||||
|
||||
id = mkOption {
|
||||
type = types.str;
|
||||
default = name;
|
||||
description = ''
|
||||
The ID of the folder. Must be the same on all devices.
|
||||
'';
|
||||
};
|
||||
|
||||
label = mkOption {
|
||||
type = types.str;
|
||||
default = name;
|
||||
description = ''
|
||||
The label of the folder.
|
||||
'';
|
||||
};
|
||||
|
||||
devices = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
description = ''
|
||||
The devices this folder should be shared with. Each device must
|
||||
be defined in the <link linkend="opt-services.syncthing.devices">devices</link> option.
|
||||
'';
|
||||
};
|
||||
|
||||
versioning = mkOption {
|
||||
default = null;
|
||||
description = ''
|
||||
How to keep changed/deleted files with Syncthing.
|
||||
There are 4 different types of versioning with different parameters.
|
||||
See <link xlink:href="https://docs.syncthing.net/users/versioning.html"/>.
|
||||
'';
|
||||
example = literalExample ''
|
||||
[
|
||||
{
|
||||
versioning = {
|
||||
type = "simple";
|
||||
@ -257,87 +261,99 @@ in {
|
||||
{
|
||||
versioning = {
|
||||
type = "external";
|
||||
params.versionsPath = pkgs.writers.writeBash "backup" ''
|
||||
params.versionsPath = pkgs.writers.writeBash "backup" '''
|
||||
folderpath="$1"
|
||||
filepath="$2"
|
||||
rm -rf "$folderpath/$filepath"
|
||||
'';
|
||||
''';
|
||||
};
|
||||
}
|
||||
];
|
||||
type = with types; nullOr (submodule {
|
||||
options = {
|
||||
type = mkOption {
|
||||
type = enum [ "external" "simple" "staggered" "trashcan" ];
|
||||
description = ''
|
||||
Type of versioning.
|
||||
See https://docs.syncthing.net/users/versioning.html
|
||||
'';
|
||||
};
|
||||
params = mkOption {
|
||||
type = attrsOf (either str path);
|
||||
description = ''
|
||||
Parameters for versioning. Structure depends on versioning.type.
|
||||
See https://docs.syncthing.net/users/versioning.html
|
||||
'';
|
||||
};
|
||||
]
|
||||
'';
|
||||
type = with types; nullOr (submodule {
|
||||
options = {
|
||||
type = mkOption {
|
||||
type = enum [ "external" "simple" "staggered" "trashcan" ];
|
||||
description = ''
|
||||
The type of versioning.
|
||||
See <link xlink:href="https://docs.syncthing.net/users/versioning.html"/>.
|
||||
'';
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
rescanInterval = mkOption {
|
||||
type = types.int;
|
||||
default = 3600;
|
||||
description = ''
|
||||
How often the folders should be rescaned for changes.
|
||||
'';
|
||||
};
|
||||
|
||||
type = mkOption {
|
||||
type = types.enum [ "sendreceive" "sendonly" "receiveonly" ];
|
||||
default = "sendreceive";
|
||||
description = ''
|
||||
Whether to send only changes from this folder, only receive them
|
||||
or propagate both.
|
||||
'';
|
||||
};
|
||||
|
||||
watch = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether the folder should be watched for changes by inotify.
|
||||
'';
|
||||
};
|
||||
|
||||
watchDelay = mkOption {
|
||||
type = types.int;
|
||||
default = 10;
|
||||
description = ''
|
||||
The delay after an inotify event is triggered.
|
||||
'';
|
||||
};
|
||||
|
||||
ignorePerms = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to propagate permission changes.
|
||||
'';
|
||||
};
|
||||
|
||||
ignoreDelete = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to delete files in destination. See <link
|
||||
xlink:href="https://docs.syncthing.net/advanced/folder-ignoredelete.html">
|
||||
upstream's docs</link>.
|
||||
'';
|
||||
};
|
||||
|
||||
params = mkOption {
|
||||
type = attrsOf (either str path);
|
||||
description = ''
|
||||
The parameters for versioning. Structure depends on
|
||||
<link linkend="opt-services.syncthing.folders._name_.versioning.type">versioning.type</link>.
|
||||
See <link xlink:href="https://docs.syncthing.net/users/versioning.html"/>.
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
}));
|
||||
|
||||
rescanInterval = mkOption {
|
||||
type = types.int;
|
||||
default = 3600;
|
||||
description = ''
|
||||
How often the folder should be rescanned for changes.
|
||||
'';
|
||||
};
|
||||
|
||||
type = mkOption {
|
||||
type = types.enum [ "sendreceive" "sendonly" "receiveonly" ];
|
||||
default = "sendreceive";
|
||||
description = ''
|
||||
Whether to only send changes for this folder, only receive them
|
||||
or both.
|
||||
'';
|
||||
};
|
||||
|
||||
watch = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether the folder should be watched for changes by inotify.
|
||||
'';
|
||||
};
|
||||
|
||||
watchDelay = mkOption {
|
||||
type = types.int;
|
||||
default = 10;
|
||||
description = ''
|
||||
The delay after an inotify event is triggered.
|
||||
'';
|
||||
};
|
||||
|
||||
ignorePerms = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to ignore permission changes.
|
||||
'';
|
||||
};
|
||||
|
||||
ignoreDelete = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to skip deleting files that are deleted by peers.
|
||||
See <link xlink:href="https://docs.syncthing.net/advanced/folder-ignoredelete.html"/>.
|
||||
'';
|
||||
};
|
||||
};
|
||||
}));
|
||||
};
|
||||
|
||||
extraOptions = mkOption {
|
||||
type = types.addCheck (pkgs.formats.json {}).type isAttrs;
|
||||
default = {};
|
||||
description = ''
|
||||
Extra configuration options for Syncthing.
|
||||
See <link xlink:href="https://docs.syncthing.net/users/config.html"/>.
|
||||
'';
|
||||
example = {
|
||||
options.localAnnounceEnabled = false;
|
||||
gui.theme = "black";
|
||||
};
|
||||
};
|
||||
|
||||
@ -345,31 +361,35 @@ in {
|
||||
type = types.str;
|
||||
default = "127.0.0.1:8384";
|
||||
description = ''
|
||||
Address to serve the GUI.
|
||||
The address to serve the web interface at.
|
||||
'';
|
||||
};
|
||||
|
||||
systemService = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Auto launch Syncthing as a system service.";
|
||||
description = ''
|
||||
Whether to auto-launch Syncthing as a system service.
|
||||
'';
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
default = defaultUser;
|
||||
example = "yourUser";
|
||||
description = ''
|
||||
Syncthing will be run under this user (user will be created if it doesn't exist.
|
||||
This can be your user name).
|
||||
The user to run Syncthing as.
|
||||
By default, a user named <literal>${defaultUser}</literal> will be created.
|
||||
'';
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
default = defaultUser;
|
||||
default = defaultGroup;
|
||||
example = "yourGroup";
|
||||
description = ''
|
||||
Syncthing will be run under this group (group will not be created if it doesn't exist.
|
||||
This can be your user name).
|
||||
The group to run Syncthing under.
|
||||
By default, a group named <literal>${defaultGroup}</literal> will be created.
|
||||
'';
|
||||
};
|
||||
|
||||
@ -378,63 +398,67 @@ in {
|
||||
default = null;
|
||||
example = "socks5://address.com:1234";
|
||||
description = ''
|
||||
Overwrites all_proxy environment variable for the syncthing process to
|
||||
the given value. This is normaly used to let relay client connect
|
||||
through SOCKS5 proxy server.
|
||||
Overwrites the all_proxy environment variable for the Syncthing process to
|
||||
the given value. This is normally used to let Syncthing connect
|
||||
through a SOCKS5 proxy server.
|
||||
See <link xlink:href="https://docs.syncthing.net/users/proxying.html"/>.
|
||||
'';
|
||||
};
|
||||
|
||||
dataDir = mkOption {
|
||||
type = types.path;
|
||||
default = "/var/lib/syncthing";
|
||||
example = "/home/yourUser";
|
||||
description = ''
|
||||
Path where synced directories will exist.
|
||||
The path where synchronised directories will exist.
|
||||
'';
|
||||
};
|
||||
|
||||
configDir = mkOption {
|
||||
configDir = let
|
||||
cond = versionAtLeast config.system.stateVersion "19.03";
|
||||
in mkOption {
|
||||
type = types.path;
|
||||
description = ''
|
||||
Path where the settings and keys will exist.
|
||||
The path where the settings and keys will exist.
|
||||
'';
|
||||
default =
|
||||
let
|
||||
nixos = config.system.stateVersion;
|
||||
cond = versionAtLeast nixos "19.03";
|
||||
in cfg.dataDir + (optionalString cond "/.config/syncthing");
|
||||
default = cfg.dataDir + (optionalString cond "/.config/syncthing");
|
||||
defaultText = literalExample "dataDir${optionalString cond " + \"/.config/syncthing\""}";
|
||||
};
|
||||
|
||||
openDefaultPorts = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
example = literalExample "true";
|
||||
example = true;
|
||||
description = ''
|
||||
Open the default ports in the firewall:
|
||||
- TCP 22000 for transfers
|
||||
- UDP 21027 for discovery
|
||||
If multiple users are running syncthing on this machine, you will need to manually open a set of ports for each instance and leave this disabled.
|
||||
Alternatively, if are running only a single instance on this machine using the default ports, enable this.
|
||||
Whether to open the default ports in the firewall: TCP 22000 for transfers
|
||||
and UDP 21027 for discovery.
|
||||
|
||||
If multiple users are running Syncthing on this machine, you will need
|
||||
to manually open a set of ports for each instance and leave this disabled.
|
||||
Alternatively, if you are running only a single instance on this machine
|
||||
using the default ports, enable this.
|
||||
'';
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.syncthing;
|
||||
defaultText = "pkgs.syncthing";
|
||||
example = literalExample "pkgs.syncthing";
|
||||
defaultText = literalExample "pkgs.syncthing";
|
||||
description = ''
|
||||
Syncthing package to use.
|
||||
The Syncthing package to use.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
imports = [
|
||||
(mkRemovedOptionModule ["services" "syncthing" "useInotify"] ''
|
||||
This option was removed because syncthing now has the inotify functionality included under the name "fswatcher".
|
||||
It can be enabled on a per-folder basis through the webinterface.
|
||||
(mkRemovedOptionModule [ "services" "syncthing" "useInotify" ] ''
|
||||
This option was removed because Syncthing now has the inotify functionality included under the name "fswatcher".
|
||||
It can be enabled on a per-folder basis through the web interface.
|
||||
'')
|
||||
];
|
||||
] ++ map (o:
|
||||
mkRenamedOptionModule [ "services" "syncthing" "declarative" o ] [ "services" "syncthing" o ]
|
||||
) [ "cert" "key" "devices" "folders" "overrideDevices" "overrideFolders" "extraOptions"];
|
||||
|
||||
###### implementation
|
||||
|
||||
@ -457,8 +481,8 @@ in {
|
||||
};
|
||||
};
|
||||
|
||||
users.groups = mkIf (cfg.systemService && cfg.group == defaultUser) {
|
||||
${defaultUser}.gid =
|
||||
users.groups = mkIf (cfg.systemService && cfg.group == defaultGroup) {
|
||||
${defaultGroup}.gid =
|
||||
config.ids.gids.syncthing;
|
||||
};
|
||||
|
||||
@ -478,14 +502,14 @@ in {
|
||||
RestartForceExitStatus="3 4";
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
ExecStartPre = mkIf (cfg.declarative.cert != null || cfg.declarative.key != null)
|
||||
ExecStartPre = mkIf (cfg.cert != null || cfg.key != null)
|
||||
"+${pkgs.writers.writeBash "syncthing-copy-keys" ''
|
||||
install -dm700 -o ${cfg.user} -g ${cfg.group} ${cfg.configDir}
|
||||
${optionalString (cfg.declarative.cert != null) ''
|
||||
install -Dm400 -o ${cfg.user} -g ${cfg.group} ${toString cfg.declarative.cert} ${cfg.configDir}/cert.pem
|
||||
${optionalString (cfg.cert != null) ''
|
||||
install -Dm400 -o ${cfg.user} -g ${cfg.group} ${toString cfg.cert} ${cfg.configDir}/cert.pem
|
||||
''}
|
||||
${optionalString (cfg.declarative.key != null) ''
|
||||
install -Dm400 -o ${cfg.user} -g ${cfg.group} ${toString cfg.declarative.key} ${cfg.configDir}/key.pem
|
||||
${optionalString (cfg.key != null) ''
|
||||
install -Dm400 -o ${cfg.user} -g ${cfg.group} ${toString cfg.key} ${cfg.configDir}/key.pem
|
||||
''}
|
||||
''}"
|
||||
;
|
||||
@ -516,8 +540,10 @@ in {
|
||||
};
|
||||
};
|
||||
syncthing-init = mkIf (
|
||||
cfg.declarative.devices != {} || cfg.declarative.folders != {}
|
||||
cfg.devices != {} || cfg.folders != {} || cfg.extraOptions != {}
|
||||
) {
|
||||
description = "Syncthing configuration updater";
|
||||
requisite = [ "syncthing.service" ];
|
||||
after = [ "syncthing.service" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
|
@ -241,7 +241,8 @@ in {
|
||||
environment.systemPackages = [ package ];
|
||||
|
||||
services.dbus.packages = [ package ];
|
||||
services.udev.packages = [ pkgs.crda ];
|
||||
|
||||
hardware.wirelessRegulatoryDatabase = true;
|
||||
|
||||
# FIXME: start a separate wpa_supplicant instance per interface.
|
||||
systemd.services.wpa_supplicant = let
|
||||
|
@ -4,7 +4,7 @@ with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.uptimed;
|
||||
stateDir = "/var/spool/uptimed";
|
||||
stateDir = "/var/lib/uptimed";
|
||||
in
|
||||
{
|
||||
options = {
|
||||
@ -21,12 +21,16 @@ in
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
environment.systemPackages = [ pkgs.uptimed ];
|
||||
|
||||
users.users.uptimed = {
|
||||
description = "Uptimed daemon user";
|
||||
home = stateDir;
|
||||
createHome = true;
|
||||
uid = config.ids.uids.uptimed;
|
||||
group = "uptimed";
|
||||
};
|
||||
users.groups.uptimed = {};
|
||||
|
||||
systemd.services.uptimed = {
|
||||
unitConfig.Documentation = "man:uptimed(8) man:uprecords(1)";
|
||||
@ -41,7 +45,7 @@ in
|
||||
PrivateTmp = "yes";
|
||||
PrivateNetwork = "yes";
|
||||
NoNewPrivileges = "yes";
|
||||
ReadWriteDirectories = stateDir;
|
||||
StateDirectory = [ "uptimed" ];
|
||||
InaccessibleDirectories = "/home";
|
||||
ExecStart = "${pkgs.uptimed}/sbin/uptimed -f -p ${stateDir}/pid";
|
||||
};
|
||||
|
148
nixos/modules/services/web-apps/node-red.nix
Normal file
148
nixos/modules/services/web-apps/node-red.nix
Normal file
@ -0,0 +1,148 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.node-red;
|
||||
defaultUser = "node-red";
|
||||
finalPackage = if cfg.withNpmAndGcc then node-red_withNpmAndGcc else cfg.package;
|
||||
node-red_withNpmAndGcc = pkgs.runCommandNoCC "node-red" {
|
||||
nativeBuildInputs = [ pkgs.makeWrapper ];
|
||||
}
|
||||
''
|
||||
mkdir -p $out/bin
|
||||
makeWrapper ${pkgs.nodePackages.node-red}/bin/node-red $out/bin/node-red \
|
||||
--set PATH '${lib.makeBinPath [ pkgs.nodePackages.npm pkgs.gcc ]}:$PATH' \
|
||||
'';
|
||||
in
|
||||
{
|
||||
options.services.node-red = {
|
||||
enable = mkEnableOption "the Node-RED service";
|
||||
|
||||
package = mkOption {
|
||||
default = pkgs.nodePackages.node-red;
|
||||
defaultText = "pkgs.nodePackages.node-red";
|
||||
type = types.package;
|
||||
description = "Node-RED package to use.";
|
||||
};
|
||||
|
||||
openFirewall = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Open ports in the firewall for the server.
|
||||
'';
|
||||
};
|
||||
|
||||
withNpmAndGcc = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Give Node-RED access to NPM and GCC at runtime, so 'Nodes' can be
|
||||
downloaded and managed imperatively via the 'Palette Manager'.
|
||||
'';
|
||||
};
|
||||
|
||||
configFile = mkOption {
|
||||
type = types.path;
|
||||
default = "${cfg.package}/lib/node_modules/node-red/settings.js";
|
||||
defaultText = "\${cfg.package}/lib/node_modules/node-red/settings.js";
|
||||
description = ''
|
||||
Path to the JavaScript configuration file.
|
||||
See <link
|
||||
xlink:href="https://github.com/node-red/node-red/blob/master/packages/node_modules/node-red/settings.js"/>
|
||||
for a configuration example.
|
||||
'';
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
default = 1880;
|
||||
description = "Listening port.";
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
default = defaultUser;
|
||||
description = ''
|
||||
User under which Node-RED runs.If left as the default value this user
|
||||
will automatically be created on system activation, otherwise the
|
||||
sysadmin is responsible for ensuring the user exists.
|
||||
'';
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
default = defaultUser;
|
||||
description = ''
|
||||
Group under which Node-RED runs.If left as the default value this group
|
||||
will automatically be created on system activation, otherwise the
|
||||
sysadmin is responsible for ensuring the group exists.
|
||||
'';
|
||||
};
|
||||
|
||||
userDir = mkOption {
|
||||
type = types.path;
|
||||
default = "/var/lib/node-red";
|
||||
description = ''
|
||||
The directory to store all user data, such as flow and credential files and all library data. If left
|
||||
as the default value this directory will automatically be created before the node-red service starts,
|
||||
otherwise the sysadmin is responsible for ensuring the directory exists with appropriate ownership
|
||||
and permissions.
|
||||
'';
|
||||
};
|
||||
|
||||
safe = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Whether to launch Node-RED in --safe mode.";
|
||||
};
|
||||
|
||||
define = mkOption {
|
||||
type = types.attrs;
|
||||
default = {};
|
||||
description = "List of settings.js overrides to pass via -D to Node-RED.";
|
||||
example = literalExample ''
|
||||
{
|
||||
"logging.console.level" = "trace";
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
users.users = optionalAttrs (cfg.user == defaultUser) {
|
||||
${defaultUser} = {
|
||||
isSystemUser = true;
|
||||
};
|
||||
};
|
||||
|
||||
users.groups = optionalAttrs (cfg.group == defaultUser) {
|
||||
${defaultUser} = { };
|
||||
};
|
||||
|
||||
networking.firewall = mkIf cfg.openFirewall {
|
||||
allowedTCPPorts = [ cfg.port ];
|
||||
};
|
||||
|
||||
systemd.services.node-red = {
|
||||
description = "Node-RED Service";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "networking.target" ];
|
||||
environment = {
|
||||
HOME = cfg.userDir;
|
||||
};
|
||||
serviceConfig = mkMerge [
|
||||
{
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
ExecStart = "${finalPackage}/bin/node-red ${pkgs.lib.optionalString cfg.safe "--safe"} --settings ${cfg.configFile} --port ${toString cfg.port} --userDir ${cfg.userDir} ${concatStringsSep " " (mapAttrsToList (name: value: "-D ${name}=${value}") cfg.define)}";
|
||||
PrivateTmp = true;
|
||||
Restart = "always";
|
||||
WorkingDirectory = cfg.userDir;
|
||||
}
|
||||
(mkIf (cfg.userDir == "/var/lib/node-red") { StateDirectory = "node-red"; })
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
@ -19,82 +19,84 @@ let
|
||||
mysqlLocal = cfg.database.createLocally && cfg.database.type == "mysql";
|
||||
pgsqlLocal = cfg.database.createLocally && cfg.database.type == "pgsql";
|
||||
|
||||
tt-rss-config = pkgs.writeText "config.php" ''
|
||||
tt-rss-config = let
|
||||
password =
|
||||
if (cfg.database.password != null) then
|
||||
"${(escape ["'" "\\"] cfg.database.password)}"
|
||||
else if (cfg.database.passwordFile != null) then
|
||||
"file_get_contents('${cfg.database.passwordFile}'"
|
||||
else
|
||||
""
|
||||
;
|
||||
in pkgs.writeText "config.php" ''
|
||||
<?php
|
||||
putenv('TTRSS_PHP_EXECUTABLE=${pkgs.php}/bin/php');
|
||||
|
||||
define('PHP_EXECUTABLE', '${pkgs.php}/bin/php');
|
||||
putenv('TTRSS_LOCK_DIRECTORY=${lockDir}');
|
||||
putenv('TTRSS_CACHE_DIR=${cacheDir}');
|
||||
putenv('TTRSS_ICONS_DIR=${feedIconsDir}');
|
||||
putenv('TTRSS_ICONS_URL=${feedIconsDir}');
|
||||
putenv('TTRSS_SELF_URL_PATH=${cfg.selfUrlPath}');
|
||||
|
||||
define('LOCK_DIRECTORY', '${lockDir}');
|
||||
define('CACHE_DIR', '${cacheDir}');
|
||||
define('ICONS_DIR', '${feedIconsDir}');
|
||||
define('ICONS_URL', '${feedIconsDir}');
|
||||
define('SELF_URL_PATH', '${cfg.selfUrlPath}');
|
||||
putenv('TTRSS_MYSQL_CHARSET=UTF8');
|
||||
|
||||
define('MYSQL_CHARSET', 'UTF8');
|
||||
putenv('TTRSS_DB_TYPE=${cfg.database.type}');
|
||||
putenv('TTRSS_DB_HOST=${optionalString (cfg.database.host != null) cfg.database.host}');
|
||||
putenv('TTRSS_DB_USER=${cfg.database.user}');
|
||||
putenv('TTRSS_DB_NAME=${cfg.database.name}');
|
||||
putenv('TTRSS_DB_PASS=${password}');
|
||||
putenv('TTRSS_DB_PORT=${toString dbPort}');
|
||||
|
||||
define('DB_TYPE', '${cfg.database.type}');
|
||||
define('DB_HOST', '${optionalString (cfg.database.host != null) cfg.database.host}');
|
||||
define('DB_USER', '${cfg.database.user}');
|
||||
define('DB_NAME', '${cfg.database.name}');
|
||||
define('DB_PASS', ${
|
||||
if (cfg.database.password != null) then
|
||||
"'${(escape ["'" "\\"] cfg.database.password)}'"
|
||||
else if (cfg.database.passwordFile != null) then
|
||||
"file_get_contents('${cfg.database.passwordFile}')"
|
||||
else
|
||||
"''"
|
||||
});
|
||||
define('DB_PORT', '${toString dbPort}');
|
||||
putenv('TTRSS_AUTH_AUTO_CREATE=${boolToString cfg.auth.autoCreate}');
|
||||
putenv('TTRSS_AUTH_AUTO_LOGIN=${boolToString cfg.auth.autoLogin}');
|
||||
|
||||
define('AUTH_AUTO_CREATE', ${boolToString cfg.auth.autoCreate});
|
||||
define('AUTH_AUTO_LOGIN', ${boolToString cfg.auth.autoLogin});
|
||||
|
||||
define('FEED_CRYPT_KEY', '${escape ["'" "\\"] cfg.feedCryptKey}');
|
||||
putenv('TTRSS_FEED_CRYPT_KEY=${escape ["'" "\\"] cfg.feedCryptKey}');
|
||||
|
||||
|
||||
define('SINGLE_USER_MODE', ${boolToString cfg.singleUserMode});
|
||||
putenv('TTRSS_SINGLE_USER_MODE=${boolToString cfg.singleUserMode}');
|
||||
|
||||
define('SIMPLE_UPDATE_MODE', ${boolToString cfg.simpleUpdateMode});
|
||||
putenv('TTRSS_SIMPLE_UPDATE_MODE=${boolToString cfg.simpleUpdateMode}');
|
||||
|
||||
// Never check for updates - the running version of the code should be
|
||||
// controlled entirely by the version of TT-RSS active in the current Nix
|
||||
// profile. If TT-RSS updates itself to a version requiring a database
|
||||
// schema upgrade, and then the SystemD tt-rss.service is restarted, the
|
||||
// old code copied from the Nix store will overwrite the updated version,
|
||||
// causing the code to detect the need for a schema "upgrade" (since the
|
||||
// schema version in the database is different than in the code), but the
|
||||
// update schema operation in TT-RSS will do nothing because the schema
|
||||
// version in the database is newer than that in the code.
|
||||
define('CHECK_FOR_UPDATES', false);
|
||||
# Never check for updates - the running version of the code should
|
||||
# be controlled entirely by the version of TT-RSS active in the
|
||||
# current Nix profile. If TT-RSS updates itself to a version
|
||||
# requiring a database schema upgrade, and then the SystemD
|
||||
# tt-rss.service is restarted, the old code copied from the Nix
|
||||
# store will overwrite the updated version, causing the code to
|
||||
# detect the need for a schema "upgrade" (since the schema version
|
||||
# in the database is different than in the code), but the update
|
||||
# schema operation in TT-RSS will do nothing because the schema
|
||||
# version in the database is newer than that in the code.
|
||||
putenv('TTRSS_CHECK_FOR_UPDATES=false');
|
||||
|
||||
define('FORCE_ARTICLE_PURGE', ${toString cfg.forceArticlePurge});
|
||||
define('SESSION_COOKIE_LIFETIME', ${toString cfg.sessionCookieLifetime});
|
||||
define('ENABLE_GZIP_OUTPUT', ${boolToString cfg.enableGZipOutput});
|
||||
putenv('TTRSS_FORCE_ARTICLE_PURGE=${toString cfg.forceArticlePurge}');
|
||||
putenv('TTRSS_SESSION_COOKIE_LIFETIME=${toString cfg.sessionCookieLifetime}');
|
||||
putenv('TTRSS_ENABLE_GZIP_OUTPUT=${boolToString cfg.enableGZipOutput}');
|
||||
|
||||
define('PLUGINS', '${builtins.concatStringsSep "," cfg.plugins}');
|
||||
putenv('TTRSS_PLUGINS=${builtins.concatStringsSep "," cfg.plugins}');
|
||||
|
||||
define('LOG_DESTINATION', '${cfg.logDestination}');
|
||||
define('CONFIG_VERSION', ${toString configVersion});
|
||||
putenv('TTRSS_LOG_DESTINATION=${cfg.logDestination}');
|
||||
putenv('TTRSS_CONFIG_VERSION=${toString configVersion}');
|
||||
|
||||
|
||||
define('PUBSUBHUBBUB_ENABLED', ${boolToString cfg.pubSubHubbub.enable});
|
||||
define('PUBSUBHUBBUB_HUB', '${cfg.pubSubHubbub.hub}');
|
||||
putenv('TTRSS_PUBSUBHUBBUB_ENABLED=${boolToString cfg.pubSubHubbub.enable}');
|
||||
putenv('TTRSS_PUBSUBHUBBUB_HUB=${cfg.pubSubHubbub.hub}');
|
||||
|
||||
define('SPHINX_SERVER', '${cfg.sphinx.server}');
|
||||
define('SPHINX_INDEX', '${builtins.concatStringsSep "," cfg.sphinx.index}');
|
||||
putenv('TTRSS_SPHINX_SERVER=${cfg.sphinx.server}');
|
||||
putenv('TTRSS_SPHINX_INDEX=${builtins.concatStringsSep "," cfg.sphinx.index}');
|
||||
|
||||
define('ENABLE_REGISTRATION', ${boolToString cfg.registration.enable});
|
||||
define('REG_NOTIFY_ADDRESS', '${cfg.registration.notifyAddress}');
|
||||
define('REG_MAX_USERS', ${toString cfg.registration.maxUsers});
|
||||
putenv('TTRSS_ENABLE_REGISTRATION=${boolToString cfg.registration.enable}');
|
||||
putenv('TTRSS_REG_NOTIFY_ADDRESS=${cfg.registration.notifyAddress}');
|
||||
putenv('TTRSS_REG_MAX_USERS=${toString cfg.registration.maxUsers}');
|
||||
|
||||
define('SMTP_SERVER', '${cfg.email.server}');
|
||||
define('SMTP_LOGIN', '${cfg.email.login}');
|
||||
define('SMTP_PASSWORD', '${escape ["'" "\\"] cfg.email.password}');
|
||||
define('SMTP_SECURE', '${cfg.email.security}');
|
||||
putenv('TTRSS_SMTP_SERVER=${cfg.email.server}');
|
||||
putenv('TTRSS_SMTP_LOGIN=${cfg.email.login}');
|
||||
putenv('TTRSS_SMTP_PASSWORD=${escape ["'" "\\"] cfg.email.password}');
|
||||
putenv('TTRSS_SMTP_SECURE=${cfg.email.security}');
|
||||
|
||||
define('SMTP_FROM_NAME', '${escape ["'" "\\"] cfg.email.fromName}');
|
||||
define('SMTP_FROM_ADDRESS', '${escape ["'" "\\"] cfg.email.fromAddress}');
|
||||
define('DIGEST_SUBJECT', '${escape ["'" "\\"] cfg.email.digestSubject}');
|
||||
putenv('TTRSS_SMTP_FROM_NAME=${escape ["'" "\\"] cfg.email.fromName}');
|
||||
putenv('TTRSS_SMTP_FROM_ADDRESS=${escape ["'" "\\"] cfg.email.fromAddress}');
|
||||
putenv('TTRSS_DIGEST_SUBJECT=${escape ["'" "\\"] cfg.email.digestSubject}');
|
||||
|
||||
${cfg.extraConfig}
|
||||
'';
|
||||
@ -564,9 +566,12 @@ let
|
||||
"Z '${cfg.root}' 0755 ${cfg.user} tt_rss - -"
|
||||
];
|
||||
|
||||
systemd.services.tt-rss =
|
||||
{
|
||||
systemd.services = {
|
||||
phpfpm-tt-rss = mkIf (cfg.pool == "${poolName}") {
|
||||
restartTriggers = [ tt-rss-config pkgs.tt-rss ];
|
||||
};
|
||||
|
||||
tt-rss = {
|
||||
description = "Tiny Tiny RSS feeds update daemon";
|
||||
|
||||
preStart = let
|
||||
@ -604,6 +609,9 @@ let
|
||||
''}
|
||||
ln -sf "${tt-rss-config}" "${cfg.root}/config.php"
|
||||
chmod -R 755 "${cfg.root}"
|
||||
chmod -R ug+rwX "${cfg.root}/${lockDir}"
|
||||
chmod -R ug+rwX "${cfg.root}/${cacheDir}"
|
||||
chmod -R ug+rwX "${cfg.root}/${feedIconsDir}"
|
||||
''
|
||||
|
||||
+ (optionalString (cfg.database.type == "pgsql") ''
|
||||
@ -640,6 +648,7 @@ let
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
requires = optional mysqlLocal "mysql.service" ++ optional pgsqlLocal "postgresql.service";
|
||||
after = [ "network.target" ] ++ optional mysqlLocal "mysql.service" ++ optional pgsqlLocal "postgresql.service";
|
||||
};
|
||||
};
|
||||
|
||||
services.mysql = mkIf mysqlLocal {
|
||||
|
@ -72,11 +72,14 @@ def main():
|
||||
f"Setting session name: {session}, as we found the existing wayland-session: {session_file}"
|
||||
)
|
||||
user.set_session(session)
|
||||
user.set_session_type("wayland")
|
||||
elif is_session_xsession(session_file):
|
||||
logging.debug(
|
||||
f"Setting session name: {session}, as we found the existing xsession: {session_file}"
|
||||
)
|
||||
user.set_x_session(session)
|
||||
user.set_session(session)
|
||||
user.set_session_type("x11")
|
||||
else:
|
||||
logging.error(f"Couldn't figure out session type for {session_file}")
|
||||
sys.exit(1)
|
||||
|
@ -1044,7 +1044,7 @@ in
|
||||
done
|
||||
'' + concatMapStrings (name: optionalString (hasPrefix "tmpfiles.d/" name) ''
|
||||
rm -f $out/${removePrefix "tmpfiles.d/" name}
|
||||
'') config.system.build.etc.targets;
|
||||
'') config.system.build.etc.passthru.targets;
|
||||
}) + "/*";
|
||||
|
||||
"systemd/system-generators" = { source = hooks "generators" cfg.generators; };
|
||||
@ -1053,6 +1053,7 @@ in
|
||||
|
||||
services.dbus.enable = true;
|
||||
|
||||
users.users.systemd-coredump.uid = config.ids.uids.systemd-coredump;
|
||||
users.users.systemd-network.uid = config.ids.uids.systemd-network;
|
||||
users.groups.systemd-network.gid = config.ids.gids.systemd-network;
|
||||
users.users.systemd-resolve.uid = config.ids.uids.systemd-resolve;
|
||||
|
@ -8,21 +8,61 @@ let
|
||||
|
||||
etc' = filter (f: f.enable) (attrValues config.environment.etc);
|
||||
|
||||
etc = pkgs.stdenvNoCC.mkDerivation {
|
||||
name = "etc";
|
||||
|
||||
builder = ./make-etc.sh;
|
||||
|
||||
etc = pkgs.runCommand "etc" {
|
||||
preferLocalBuild = true;
|
||||
allowSubstitutes = false;
|
||||
|
||||
/* !!! Use toXML. */
|
||||
sources = map (x: x.source) etc';
|
||||
targets = map (x: x.target) etc';
|
||||
modes = map (x: x.mode) etc';
|
||||
users = map (x: x.user) etc';
|
||||
groups = map (x: x.group) etc';
|
||||
};
|
||||
# This is needed for the systemd module
|
||||
passthru.targets = map (x: x.target) etc';
|
||||
} /* sh */ ''
|
||||
set -euo pipefail
|
||||
|
||||
makeEtcEntry() {
|
||||
src="$1"
|
||||
target="$2"
|
||||
mode="$3"
|
||||
user="$4"
|
||||
group="$5"
|
||||
|
||||
if [[ "$src" = *'*'* ]]; then
|
||||
# If the source name contains '*', perform globbing.
|
||||
mkdir -p "$out/etc/$target"
|
||||
for fn in $src; do
|
||||
ln -s "$fn" "$out/etc/$target/"
|
||||
done
|
||||
else
|
||||
|
||||
mkdir -p "$out/etc/$(dirname "$target")"
|
||||
if ! [ -e "$out/etc/$target" ]; then
|
||||
ln -s "$src" "$out/etc/$target"
|
||||
else
|
||||
echo "duplicate entry $target -> $src"
|
||||
if [ "$(readlink "$out/etc/$target")" != "$src" ]; then
|
||||
echo "mismatched duplicate entry $(readlink "$out/etc/$target") <-> $src"
|
||||
ret=1
|
||||
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$mode" != symlink ]; then
|
||||
echo "$mode" > "$out/etc/$target.mode"
|
||||
echo "$user" > "$out/etc/$target.uid"
|
||||
echo "$group" > "$out/etc/$target.gid"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
mkdir -p "$out/etc"
|
||||
${concatMapStringsSep "\n" (etcEntry: escapeShellArgs [
|
||||
"makeEtcEntry"
|
||||
etcEntry.source
|
||||
etcEntry.target
|
||||
etcEntry.mode
|
||||
etcEntry.user
|
||||
etcEntry.group
|
||||
]) etc'}
|
||||
'';
|
||||
|
||||
in
|
||||
|
||||
|
@ -1,45 +0,0 @@
|
||||
source $stdenv/setup
|
||||
|
||||
mkdir -p $out/etc
|
||||
|
||||
set -f
|
||||
sources_=($sources)
|
||||
targets_=($targets)
|
||||
modes_=($modes)
|
||||
users_=($users)
|
||||
groups_=($groups)
|
||||
set +f
|
||||
|
||||
for ((i = 0; i < ${#targets_[@]}; i++)); do
|
||||
source="${sources_[$i]}"
|
||||
target="${targets_[$i]}"
|
||||
|
||||
if [[ "$source" =~ '*' ]]; then
|
||||
|
||||
# If the source name contains '*', perform globbing.
|
||||
mkdir -p $out/etc/$target
|
||||
for fn in $source; do
|
||||
ln -s "$fn" $out/etc/$target/
|
||||
done
|
||||
|
||||
else
|
||||
|
||||
mkdir -p $out/etc/$(dirname $target)
|
||||
if ! [ -e $out/etc/$target ]; then
|
||||
ln -s $source $out/etc/$target
|
||||
else
|
||||
echo "duplicate entry $target -> $source"
|
||||
if test "$(readlink $out/etc/$target)" != "$source"; then
|
||||
echo "mismatched duplicate entry $(readlink $out/etc/$target) <-> $source"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "${modes_[$i]}" != symlink; then
|
||||
echo "${modes_[$i]}" > $out/etc/$target.mode
|
||||
echo "${users_[$i]}" > $out/etc/$target.uid
|
||||
echo "${groups_[$i]}" > $out/etc/$target.gid
|
||||
fi
|
||||
|
||||
fi
|
||||
done
|
@ -18,6 +18,13 @@ in {
|
||||
The size of the VirtualBox base image in MiB.
|
||||
'';
|
||||
};
|
||||
baseImageFreeSpace = mkOption {
|
||||
type = with types; int;
|
||||
default = 30 * 1024;
|
||||
description = ''
|
||||
Free space in the VirtualBox base image in MiB.
|
||||
'';
|
||||
};
|
||||
memorySize = mkOption {
|
||||
type = types.int;
|
||||
default = 1536;
|
||||
@ -129,6 +136,7 @@ in {
|
||||
inherit pkgs lib config;
|
||||
partitionTableType = "legacy";
|
||||
diskSize = cfg.baseImageSize;
|
||||
additionalSpace = "${toString cfg.baseImageFreeSpace}M";
|
||||
|
||||
postVM =
|
||||
''
|
||||
|
@ -204,6 +204,7 @@ in
|
||||
k3s = handleTest ./k3s.nix {};
|
||||
kafka = handleTest ./kafka.nix {};
|
||||
kbd-setfont-decompress = handleTest ./kbd-setfont-decompress.nix {};
|
||||
kbd-update-search-paths-patch = handleTest ./kbd-update-search-paths-patch.nix {};
|
||||
kea = handleTest ./kea.nix {};
|
||||
keepalived = handleTest ./keepalived.nix {};
|
||||
keepassxc = handleTest ./keepassxc.nix {};
|
||||
@ -222,10 +223,12 @@ in
|
||||
latestKernel.hardened = handleTest ./hardened.nix { latestKernel = true; };
|
||||
latestKernel.login = handleTest ./login.nix { latestKernel = true; };
|
||||
leaps = handleTest ./leaps.nix {};
|
||||
libreddit = handleTest ./libreddit.nix {};
|
||||
lidarr = handleTest ./lidarr.nix {};
|
||||
libreswan = handleTest ./libreswan.nix {};
|
||||
lightdm = handleTest ./lightdm.nix {};
|
||||
limesurvey = handleTest ./limesurvey.nix {};
|
||||
litestream = handleTest ./litestream.nix {};
|
||||
locate = handleTest ./locate.nix {};
|
||||
login = handleTest ./login.nix {};
|
||||
loki = handleTest ./loki.nix {};
|
||||
@ -258,6 +261,7 @@ in
|
||||
morty = handleTest ./morty.nix {};
|
||||
mosquitto = handleTest ./mosquitto.nix {};
|
||||
mpd = handleTest ./mpd.nix {};
|
||||
mpv = handleTest ./mpv.nix {};
|
||||
mumble = handleTest ./mumble.nix {};
|
||||
musescore = handleTest ./musescore.nix {};
|
||||
munin = handleTest ./munin.nix {};
|
||||
@ -300,6 +304,7 @@ in
|
||||
nix-serve = handleTest ./nix-ssh-serve.nix {};
|
||||
nix-ssh-serve = handleTest ./nix-ssh-serve.nix {};
|
||||
nixos-generate-config = handleTest ./nixos-generate-config.nix {};
|
||||
node-red = handleTest ./node-red.nix {};
|
||||
nomad = handleTest ./nomad.nix {};
|
||||
novacomd = handleTestOn ["x86_64-linux"] ./novacomd.nix {};
|
||||
nsd = handleTest ./nsd.nix {};
|
||||
|
18
nixos/tests/kbd-update-search-paths-patch.nix
Normal file
18
nixos/tests/kbd-update-search-paths-patch.nix
Normal file
@ -0,0 +1,18 @@
|
||||
import ./make-test-python.nix ({ pkgs, ... }: {
|
||||
name = "kbd-update-search-paths-patch";
|
||||
|
||||
machine = { pkgs, options, ... }: {
|
||||
console = {
|
||||
packages = options.console.packages.default ++ [ pkgs.terminus_font ];
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
command = "${pkgs.kbd}/bin/setfont ter-112n 2>&1"
|
||||
(status, out) = machine.execute(command)
|
||||
pattern = re.compile(r".*Unable to find file:.*")
|
||||
match = pattern.match(out)
|
||||
if match:
|
||||
raise Exception("command `{}` failed".format(command))
|
||||
'';
|
||||
})
|
19
nixos/tests/libreddit.nix
Normal file
19
nixos/tests/libreddit.nix
Normal file
@ -0,0 +1,19 @@
|
||||
import ./make-test-python.nix ({ lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
name = "libreddit";
|
||||
meta.maintainers = with maintainers; [ fab ];
|
||||
|
||||
nodes.machine =
|
||||
{ pkgs, ... }:
|
||||
{ services.libreddit.enable = true; };
|
||||
|
||||
testScript = ''
|
||||
machine.wait_for_unit("libreddit.service")
|
||||
machine.wait_for_open_port("8080")
|
||||
# The service wants to get data from https://www.reddit.com
|
||||
machine.succeed("curl http://localhost:8080/")
|
||||
'';
|
||||
})
|
93
nixos/tests/litestream.nix
Normal file
93
nixos/tests/litestream.nix
Normal file
@ -0,0 +1,93 @@
|
||||
import ./make-test-python.nix ({ pkgs, ...} : {
|
||||
name = "litestream";
|
||||
meta = with pkgs.lib.maintainers; {
|
||||
maintainers = [ jwygoda ];
|
||||
};
|
||||
|
||||
machine =
|
||||
{ pkgs, ... }:
|
||||
{ services.litestream = {
|
||||
enable = true;
|
||||
settings = {
|
||||
dbs = [
|
||||
{
|
||||
path = "/var/lib/grafana/data/grafana.db";
|
||||
replicas = [{
|
||||
url = "sftp://foo:bar@127.0.0.1:22/home/foo/grafana";
|
||||
}];
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
systemd.services.grafana.serviceConfig.ExecStartPost = "+" + pkgs.writeShellScript "grant-grafana-permissions" ''
|
||||
timeout=10
|
||||
|
||||
while [ ! -f /var/lib/grafana/data/grafana.db ];
|
||||
do
|
||||
if [ "$timeout" == 0 ]; then
|
||||
echo "ERROR: Timeout while waiting for /var/lib/grafana/data/grafana.db."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
|
||||
((timeout--))
|
||||
done
|
||||
|
||||
find /var/lib/grafana -type d -exec chmod -v 775 {} \;
|
||||
find /var/lib/grafana -type f -exec chmod -v 660 {} \;
|
||||
'';
|
||||
services.openssh = {
|
||||
enable = true;
|
||||
allowSFTP = true;
|
||||
listenAddresses = [ { addr = "127.0.0.1"; port = 22; } ];
|
||||
};
|
||||
services.grafana = {
|
||||
enable = true;
|
||||
security = {
|
||||
adminUser = "admin";
|
||||
adminPassword = "admin";
|
||||
};
|
||||
addr = "localhost";
|
||||
port = 3000;
|
||||
extraOptions = {
|
||||
DATABASE_URL = "sqlite3:///var/lib/grafana/data/grafana.db?cache=private&mode=rwc&_journal_mode=WAL";
|
||||
};
|
||||
};
|
||||
users.users.foo = {
|
||||
isNormalUser = true;
|
||||
password = "bar";
|
||||
};
|
||||
users.users.litestream.extraGroups = [ "grafana" ];
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
start_all()
|
||||
machine.wait_until_succeeds("test -d /home/foo/grafana")
|
||||
machine.wait_for_open_port(3000)
|
||||
machine.succeed("""
|
||||
curl -sSfN -X PUT -H "Content-Type: application/json" -d '{
|
||||
"oldPassword": "admin",
|
||||
"newPassword": "newpass",
|
||||
"confirmNew": "newpass"
|
||||
}' http://admin:admin@127.0.0.1:3000/api/user/password
|
||||
""")
|
||||
# https://litestream.io/guides/systemd/#simulating-a-disaster
|
||||
machine.systemctl("stop litestream.service")
|
||||
machine.succeed(
|
||||
"rm -f /var/lib/grafana/data/grafana.db "
|
||||
"/var/lib/grafana/data/grafana.db-shm "
|
||||
"/var/lib/grafana/data/grafana.db-wal"
|
||||
)
|
||||
machine.succeed(
|
||||
"litestream restore /var/lib/grafana/data/grafana.db "
|
||||
"&& chown grafana:grafana /var/lib/grafana/data/grafana.db "
|
||||
"&& chmod 660 /var/lib/grafana/data/grafana.db"
|
||||
)
|
||||
machine.systemctl("restart grafana.service")
|
||||
machine.wait_for_open_port(3000)
|
||||
machine.succeed(
|
||||
"curl -sSfN -u admin:newpass http://127.0.0.1:3000/api/org/users | grep admin\@localhost"
|
||||
)
|
||||
'';
|
||||
})
|
28
nixos/tests/mpv.nix
Normal file
28
nixos/tests/mpv.nix
Normal file
@ -0,0 +1,28 @@
|
||||
import ./make-test-python.nix ({ lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
port = toString 4321;
|
||||
in
|
||||
{
|
||||
name = "mpv";
|
||||
meta.maintainers = with maintainers; [ zopieux ];
|
||||
|
||||
nodes.machine =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
environment.systemPackages = [
|
||||
pkgs.curl
|
||||
(pkgs.mpv-with-scripts.override {
|
||||
scripts = [ pkgs.mpvScripts.simple-mpv-webui ];
|
||||
})
|
||||
];
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
machine.execute("set -m; mpv --script-opts=webui-port=${port} --idle=yes &")
|
||||
machine.wait_for_open_port(${port})
|
||||
assert "<title>simple-mpv-webui" in machine.succeed("curl -s localhost:${port}")
|
||||
'';
|
||||
})
|
31
nixos/tests/node-red.nix
Normal file
31
nixos/tests/node-red.nix
Normal file
@ -0,0 +1,31 @@
|
||||
import ./make-test-python.nix ({ pkgs, ... }: {
|
||||
name = "nodered";
|
||||
meta = with pkgs.lib.maintainers; {
|
||||
maintainers = [ matthewcroughan ];
|
||||
};
|
||||
|
||||
nodes = {
|
||||
client = { config, pkgs, ... }: {
|
||||
environment.systemPackages = [ pkgs.curl ];
|
||||
};
|
||||
nodered = { config, pkgs, ... }: {
|
||||
services.node-red = {
|
||||
enable = true;
|
||||
openFirewall = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
start_all()
|
||||
nodered.wait_for_unit("node-red.service")
|
||||
nodered.wait_for_open_port("1880")
|
||||
|
||||
client.wait_for_unit("multi-user.target")
|
||||
|
||||
with subtest("Check that the Node-RED webserver can be reached."):
|
||||
assert "<title>Node-RED</title>" in client.succeed(
|
||||
"curl -sSf http:/nodered:1880/ | grep title"
|
||||
)
|
||||
'';
|
||||
})
|
@ -273,6 +273,26 @@ let
|
||||
'';
|
||||
};
|
||||
|
||||
influxdb = {
|
||||
exporterConfig = {
|
||||
enable = true;
|
||||
sampleExpiry = "3s";
|
||||
};
|
||||
exporterTest = ''
|
||||
wait_for_unit("prometheus-influxdb-exporter.service")
|
||||
succeed(
|
||||
"curl -XPOST http://localhost:9122/write --data-binary 'influxdb_exporter,distro=nixos,added_in=21.09 value=1'"
|
||||
)
|
||||
succeed(
|
||||
"curl -sSf http://localhost:9122/metrics | grep 'nixos'"
|
||||
)
|
||||
execute("sleep 5")
|
||||
fail(
|
||||
"curl -sSf http://localhost:9122/metrics | grep 'nixos'"
|
||||
)
|
||||
'';
|
||||
};
|
||||
|
||||
jitsi = {
|
||||
exporterConfig = {
|
||||
enable = true;
|
||||
|
24
nixos/tests/soapui.nix
Normal file
24
nixos/tests/soapui.nix
Normal file
@ -0,0 +1,24 @@
|
||||
import ./make-test-python.nix ({ pkgs, ... }: {
|
||||
name = "soapui";
|
||||
meta = with pkgs.lib.maintainers; {
|
||||
maintainers = [ asbachb ];
|
||||
};
|
||||
|
||||
machine = { config, pkgs, ... }: {
|
||||
imports = [
|
||||
./common/x11.nix
|
||||
];
|
||||
|
||||
services.xserver.enable = true;
|
||||
|
||||
environment.systemPackages = [ pkgs.soapui ];
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
machine.wait_for_x()
|
||||
machine.succeed("soapui &")
|
||||
machine.wait_for_window(r"SoapUI \d+\.\d+\.\d+")
|
||||
machine.sleep(1)
|
||||
machine.screenshot("soapui")
|
||||
'';
|
||||
})
|
@ -9,15 +9,14 @@ in {
|
||||
machine = {
|
||||
services.syncthing = {
|
||||
enable = true;
|
||||
declarative = {
|
||||
devices.testDevice = {
|
||||
id = testId;
|
||||
};
|
||||
folders.testFolder = {
|
||||
path = "/tmp/test";
|
||||
devices = [ "testDevice" ];
|
||||
};
|
||||
devices.testDevice = {
|
||||
id = testId;
|
||||
};
|
||||
folders.testFolder = {
|
||||
path = "/tmp/test";
|
||||
devices = [ "testDevice" ];
|
||||
};
|
||||
extraOptions.gui.user = "guiUser";
|
||||
};
|
||||
};
|
||||
|
||||
@ -27,5 +26,6 @@ in {
|
||||
|
||||
assert "testFolder" in config
|
||||
assert "${testId}" in config
|
||||
assert "guiUser" in config
|
||||
'';
|
||||
})
|
||||
|
@ -25,7 +25,7 @@ import ./make-test-python.nix ({ lib, pkgs, ... }: {
|
||||
"xmllint --xpath 'string(configuration/gui/apikey)' %s/config.xml" % confdir
|
||||
).strip()
|
||||
oldConf = host.succeed(
|
||||
"curl -Ssf -H 'X-API-Key: %s' 127.0.0.1:8384/rest/system/config" % APIKey
|
||||
"curl -Ssf -H 'X-API-Key: %s' 127.0.0.1:8384/rest/config" % APIKey
|
||||
)
|
||||
conf = json.loads(oldConf)
|
||||
conf["devices"].append({"deviceID": deviceID, "id": name})
|
||||
@ -39,7 +39,7 @@ import ./make-test-python.nix ({ lib, pkgs, ... }: {
|
||||
)
|
||||
newConf = json.dumps(conf)
|
||||
host.succeed(
|
||||
"curl -Ssf -H 'X-API-Key: %s' 127.0.0.1:8384/rest/system/config -d %s"
|
||||
"curl -Ssf -H 'X-API-Key: %s' 127.0.0.1:8384/rest/config -X PUT -d %s"
|
||||
% (APIKey, shlex.quote(newConf))
|
||||
)
|
||||
|
||||
|
@ -1,19 +1,19 @@
|
||||
{ stdenv, lib, fetchurl, pkg-config, systemd ? null, libobjc, IOKit, fetchpatch }:
|
||||
{ stdenv, lib, fetchurl, pkg-config, systemd, libobjc, IOKit, fetchpatch }:
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
name = "libusb-1.0.19";
|
||||
pname = "libusb";
|
||||
version = "1.0.19";
|
||||
|
||||
src = fetchurl {
|
||||
url = "mirror://sourceforge/libusb/${name}.tar.bz2";
|
||||
url = "mirror://sourceforge/libusb/libusb-${version}.tar.bz2";
|
||||
sha256 = "0h38p9rxfpg9vkrbyb120i1diq57qcln82h5fr7hvy82c20jql3c";
|
||||
};
|
||||
|
||||
outputs = [ "out" "dev" ]; # get rid of propagating systemd closure
|
||||
|
||||
buildInputs = [ pkg-config ];
|
||||
propagatedBuildInputs =
|
||||
lib.optional stdenv.isLinux systemd ++
|
||||
lib.optionals stdenv.isDarwin [ libobjc IOKit ];
|
||||
propagatedBuildInputs = lib.optional stdenv.isLinux systemd
|
||||
++ lib.optionals stdenv.isDarwin [ libobjc IOKit ];
|
||||
|
||||
patches = [
|
||||
(fetchpatch {
|
||||
@ -32,6 +32,7 @@ stdenv.mkDerivation rec {
|
||||
meta = with lib; {
|
||||
homepage = "http://www.libusb.info";
|
||||
description = "User-space USB library";
|
||||
maintainers = with maintainers; [ ];
|
||||
platforms = platforms.unix;
|
||||
license = licenses.lgpl21;
|
||||
};
|
||||
|
@ -47,8 +47,6 @@ in mkDerivation rec {
|
||||
substituteInPlace dfasma.pro --replace "CONFIG += file_sdif" "";
|
||||
'';
|
||||
|
||||
enableParallelBuilding = true;
|
||||
|
||||
meta = with lib; {
|
||||
description = "Analyse and compare audio files in time and frequency";
|
||||
longDescription = ''
|
||||
|
@ -32,13 +32,13 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "easyeffects";
|
||||
version = "6.0.0";
|
||||
version = "6.0.3";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "wwmm";
|
||||
repo = "easyeffects";
|
||||
rev = "v${version}";
|
||||
hash = "sha256:1m3jamnhgpx3z51nfc8xg7adhf5x7dirvw0wf129hzxx4fjl7rch";
|
||||
sha256 = "sha256-GzqPC/m/HMthLMamhJ4EXX6fxZYscdX1QmXgqHOPEcg=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
|
@ -38,8 +38,6 @@ mkDerivation rec {
|
||||
PREFIXSHORTCUT=$out"
|
||||
'';
|
||||
|
||||
enableParallelBuilding = true;
|
||||
|
||||
meta = {
|
||||
description = "Free Musical Instrument Tuner";
|
||||
longDescription = ''
|
||||
|
@ -38,7 +38,7 @@ in py.buildPythonApplication rec {
|
||||
|
||||
meta = with lib; {
|
||||
description = "A real-time audio analyzer";
|
||||
homepage = "http://friture.org/";
|
||||
homepage = "https://friture.org/";
|
||||
license = licenses.gpl3;
|
||||
platforms = platforms.linux; # fails on Darwin
|
||||
maintainers = [ maintainers.laikq ];
|
||||
|
@ -29,8 +29,14 @@ python3Packages.buildPythonApplication rec {
|
||||
glibcLocales
|
||||
];
|
||||
|
||||
# as of 2021-07, the gobject-introspection setup hook does not
|
||||
# work with `strictDeps` enabled, thus for proper `wrapGAppsHook`
|
||||
# it needs to be disabled explicitly. https://github.com/NixOS/nixpkgs/issues/56943
|
||||
strictDeps = false;
|
||||
|
||||
buildInputs = [
|
||||
python3
|
||||
gtk3
|
||||
gobject-introspection
|
||||
gnome.adwaita-icon-theme
|
||||
];
|
||||
@ -49,7 +55,6 @@ python3Packages.buildPythonApplication rec {
|
||||
eyeD3
|
||||
podcastparser
|
||||
html5lib
|
||||
gtk3
|
||||
];
|
||||
|
||||
makeFlags = [
|
||||
|
@ -19,8 +19,6 @@ mkDerivation rec {
|
||||
|
||||
installFlags = [ "INSTALL_ROOT=$(out)" ];
|
||||
|
||||
enableParallelBuilding = true;
|
||||
|
||||
meta = with lib; {
|
||||
description = "Graphical open-source sequencer";
|
||||
homepage = "https://www.iannix.org/";
|
||||
|
@ -1,6 +1,6 @@
|
||||
{ fetchurl, lib, pythonPackages, libmms }:
|
||||
{ fetchurl, lib, python2Packages, libmms }:
|
||||
|
||||
pythonPackages.buildPythonApplication rec {
|
||||
python2Packages.buildPythonApplication rec {
|
||||
pname = "mimms";
|
||||
version = "3.2";
|
||||
|
||||
|
@ -111,8 +111,6 @@ mkDerivation rec {
|
||||
wavpack
|
||||
];
|
||||
|
||||
enableParallelBuilding = true;
|
||||
|
||||
qtWrapperArgs = [
|
||||
"--set LOCALE_ARCHIVE ${glibcLocales}/lib/locale/locale-archive"
|
||||
];
|
||||
|
@ -14,16 +14,16 @@ let
|
||||
in
|
||||
rustPlatform.buildRustPackage rec {
|
||||
pname = "ncspot";
|
||||
version = "0.7.3";
|
||||
version = "0.8.1";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "hrkfdn";
|
||||
repo = "ncspot";
|
||||
rev = "v${version}";
|
||||
sha256 = "0lfly3d8pag78pabmna4i6xjwzi65dx1mwfmsk7nx64brq3iypbq";
|
||||
sha256 = "0sgnd6n8j8lygmb9qvv6i2ir28fdsrpmzlviz7d0gbx684qj0zkc";
|
||||
};
|
||||
|
||||
cargoSha256 = "0a6d41ll90fza6k3lixjqzwxim98q6zbkqa3zvxvs7q5ydzg8nsp";
|
||||
cargoSha256 = "0piipqf5y5bczbwkaplv6niqh3rp2di1gn7wwpd0gaa2cw7ylbb1";
|
||||
|
||||
cargoBuildFlags = [ "--no-default-features" "--features" "${lib.concatStringsSep "," features}" ];
|
||||
|
||||
|
@ -1,22 +1,40 @@
|
||||
{ lib, stdenv, fetchurl, cmake, makedepend, perl, pkg-config, qttools, wrapQtAppsHook
|
||||
, dssi, fftwSinglePrec, ladspaH, ladspaPlugins, libjack2, alsa-lib
|
||||
, liblo, libsamplerate, libsndfile, lirc ? null, lrdf, qtbase }:
|
||||
{ lib
|
||||
, stdenv
|
||||
, fetchurl
|
||||
, cmake
|
||||
, makedepend
|
||||
, perl
|
||||
, pkg-config
|
||||
, qttools
|
||||
, wrapQtAppsHook
|
||||
, dssi
|
||||
, fftwSinglePrec
|
||||
, ladspaH
|
||||
, ladspaPlugins
|
||||
, libjack2
|
||||
, alsa-lib
|
||||
, liblo
|
||||
, libsamplerate
|
||||
, libsndfile
|
||||
, lirc
|
||||
, lrdf
|
||||
, qtbase
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation (rec {
|
||||
version = "20.12";
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "rosegarden";
|
||||
version = "20.12";
|
||||
|
||||
src = fetchurl {
|
||||
url = "mirror://sourceforge/rosegarden/${pname}-${version}.tar.bz2";
|
||||
sha256 = "sha256-iGaEr8WFipV4I00fhFGI2xMBFPf784IIxNXs2hUTHFs=";
|
||||
};
|
||||
|
||||
patchPhase = ''
|
||||
postPhase = ''
|
||||
substituteInPlace src/CMakeLists.txt --replace svnheader svnversion
|
||||
'';
|
||||
|
||||
nativeBuildInputs =
|
||||
[ cmake makedepend perl pkg-config qttools wrapQtAppsHook ];
|
||||
nativeBuildInputs = [ cmake makedepend perl pkg-config qttools wrapQtAppsHook ];
|
||||
|
||||
buildInputs = [
|
||||
dssi
|
||||
@ -49,4 +67,4 @@ stdenv.mkDerivation (rec {
|
||||
license = licenses.lgpl2Plus;
|
||||
platforms = platforms.linux;
|
||||
};
|
||||
})
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ stdenv.mkDerivation rec {
|
||||
pname = "spectmorph";
|
||||
version = "0.5.2";
|
||||
src = fetchurl {
|
||||
url = "http://spectmorph.org/files/releases/${pname}-${version}.tar.bz2";
|
||||
url = "https://spectmorph.org/files/releases/${pname}-${version}.tar.bz2";
|
||||
sha256 = "0yrq7mknhk096wfsx0q3b6wwa2w5la0rxa113di26rrrw136xl1f";
|
||||
};
|
||||
|
||||
|
@ -45,8 +45,6 @@ stdenv.mkDerivation rec {
|
||||
tagparser
|
||||
];
|
||||
|
||||
enableParallelBuilding = true;
|
||||
|
||||
meta = with pkgs.lib; {
|
||||
homepage = "https://github.com/Martchus/tageditor";
|
||||
description = "A tag editor with Qt GUI and command-line interface supporting MP4/M4A/AAC (iTunes), ID3, Vorbis, Opus, FLAC and Matroska";
|
||||
|
@ -1,12 +1,28 @@
|
||||
{ lib, stdenv, mkDerivation, fetchFromGitHub, pkg-config, cmake, openssl, db53, boost
|
||||
, zlib, miniupnpc, qtbase ? null , qttools ? null, util-linux, protobuf, qrencode, libevent
|
||||
, withGui, python3, jemalloc, zeromq4 }:
|
||||
|
||||
with lib;
|
||||
{ lib
|
||||
, stdenv
|
||||
, mkDerivation
|
||||
, fetchFromGitHub
|
||||
, pkg-config
|
||||
, cmake
|
||||
, openssl
|
||||
, db53
|
||||
, boost
|
||||
, zlib
|
||||
, miniupnpc
|
||||
, qtbase ? null
|
||||
, qttools ? null
|
||||
, util-linux
|
||||
, protobuf
|
||||
, qrencode
|
||||
, libevent
|
||||
, withGui
|
||||
, python3
|
||||
, jemalloc
|
||||
, zeromq4
|
||||
}:
|
||||
|
||||
mkDerivation rec {
|
||||
|
||||
name = "bitcoin" + (toString (optional (!withGui) "d")) + "-abc-" + version;
|
||||
pname = "bitcoin" + lib.optionalString (!withGui) "d" + "-abc";
|
||||
version = "0.21.13";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
@ -19,11 +35,21 @@ mkDerivation rec {
|
||||
patches = [ ./fix-bitcoin-qt-build.patch ];
|
||||
|
||||
nativeBuildInputs = [ pkg-config cmake ];
|
||||
buildInputs = [ openssl db53 boost zlib python3 jemalloc zeromq4
|
||||
miniupnpc util-linux protobuf libevent ]
|
||||
++ optionals withGui [ qtbase qttools qrencode ];
|
||||
buildInputs = [
|
||||
openssl
|
||||
db53
|
||||
boost
|
||||
zlib
|
||||
python3
|
||||
jemalloc
|
||||
zeromq4
|
||||
miniupnpc
|
||||
util-linux
|
||||
protobuf
|
||||
libevent
|
||||
] ++ lib.optionals withGui [ qtbase qttools qrencode ];
|
||||
|
||||
cmakeFlags = optionals (!withGui) [
|
||||
cmakeFlags = lib.optionals (!withGui) [
|
||||
"-DBUILD_BITCOIN_QT=OFF"
|
||||
];
|
||||
|
||||
@ -32,9 +58,9 @@ mkDerivation rec {
|
||||
find ./. -type f -iname "*.sh" -exec chmod +x {} \;
|
||||
'';
|
||||
|
||||
meta = {
|
||||
meta = with lib; {
|
||||
description = "Peer-to-peer electronic cash system (Cash client)";
|
||||
longDescription= ''
|
||||
longDescription = ''
|
||||
Bitcoin ABC is the name of open source software which enables the use of Bitcoin.
|
||||
It is designed to facilite a hard fork to increase Bitcoin's block size limit.
|
||||
"ABC" stands for "Adjustable Blocksize Cap".
|
@ -1,12 +1,24 @@
|
||||
{ lib, stdenv, fetchFromGitHub, pkg-config, autoreconfHook, openssl, db48, boost
|
||||
, zlib, miniupnpc, qtbase ? null, qttools ? null, util-linux, protobuf, qrencode, libevent
|
||||
, withGui }:
|
||||
|
||||
with lib;
|
||||
{ lib
|
||||
, stdenv
|
||||
, fetchFromGitHub
|
||||
, pkg-config
|
||||
, autoreconfHook
|
||||
, openssl
|
||||
, db48
|
||||
, boost
|
||||
, zlib
|
||||
, miniupnpc
|
||||
, qtbase ? null
|
||||
, qttools ? null
|
||||
, util-linux
|
||||
, protobuf
|
||||
, qrencode
|
||||
, libevent
|
||||
, withGui
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
|
||||
name = "bitcoin" + (toString (optional (!withGui) "d")) + "-classic-" + version;
|
||||
pname = "bitcoin" + lib.optionalString (!withGui) "d" + "-classic";
|
||||
version = "1.3.8uahf";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
@ -17,22 +29,30 @@ stdenv.mkDerivation rec {
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ pkg-config autoreconfHook ];
|
||||
buildInputs = [ openssl db48 boost zlib
|
||||
miniupnpc util-linux protobuf libevent ]
|
||||
++ optionals withGui [ qtbase qttools qrencode ];
|
||||
buildInputs = [
|
||||
openssl
|
||||
db48
|
||||
boost
|
||||
zlib
|
||||
miniupnpc
|
||||
util-linux
|
||||
protobuf
|
||||
libevent
|
||||
] ++ lib.optionals withGui [ qtbase qttools qrencode ];
|
||||
|
||||
configureFlags = [ "--with-boost-libdir=${boost.out}/lib" ]
|
||||
++ optionals withGui [ "--with-gui=qt5"
|
||||
"--with-qt-bindir=${qtbase.dev}/bin:${qttools.dev}/bin"
|
||||
];
|
||||
++ lib.optionals withGui [
|
||||
"--with-gui=qt5"
|
||||
"--with-qt-bindir=${qtbase.dev}/bin:${qttools.dev}/bin"
|
||||
];
|
||||
|
||||
enableParallelBuilding = true;
|
||||
|
||||
dontWrapQtApps = true;
|
||||
|
||||
meta = {
|
||||
meta = with lib; {
|
||||
description = "Peer-to-peer electronic cash system (Classic client)";
|
||||
longDescription= ''
|
||||
longDescription = ''
|
||||
Bitcoin is a free open source peer-to-peer electronic cash system that is
|
||||
completely decentralized, without the need for a central server or trusted
|
||||
parties. Users hold the crypto keys to their own money and transact directly
|
65
pkgs/applications/blockchains/chia-plotter/default.nix
Normal file
65
pkgs/applications/blockchains/chia-plotter/default.nix
Normal file
@ -0,0 +1,65 @@
|
||||
{ lib
|
||||
, fetchFromGitHub
|
||||
, stdenv
|
||||
, libsodium
|
||||
, cmake
|
||||
, substituteAll
|
||||
, pythonPackages
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation {
|
||||
pname = "chia-plotter";
|
||||
version = "unstable-2021-07-12";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "madMAx43v3r";
|
||||
repo = "chia-plotter";
|
||||
rev = "974d6e5f1440f68c48492122ca33828a98864dfc";
|
||||
sha256 = "0dliswvqmi3wq9w8jp0sb0z74n5k37608sig6r60z206g2bwhjja";
|
||||
fetchSubmodules = true;
|
||||
};
|
||||
|
||||
patches = [
|
||||
# prevent CMake from trying to get libraries on the Internet
|
||||
(substituteAll {
|
||||
src = ./dont_fetch_dependencies.patch;
|
||||
pybind11_src = pythonPackages.pybind11.src;
|
||||
relic_src = fetchFromGitHub {
|
||||
owner = "relic-toolkit";
|
||||
repo = "relic";
|
||||
rev = "1885ae3b681c423c72b65ce1fe70910142cf941c";
|
||||
hash = "sha256-tsSZTcssl8t7Nqdex4BesgQ+ACPgTdtHnJFvS9josN0=";
|
||||
};
|
||||
})
|
||||
];
|
||||
|
||||
nativeBuildInputs = [ cmake ];
|
||||
|
||||
buildInputs = [ libsodium ];
|
||||
|
||||
# These flags come from the upstream build script:
|
||||
# https://github.com/madMAx43v3r/chia-plotter/blob/974d6e5f1440f68c48492122ca33828a98864dfc/make_devel.sh#L7
|
||||
CXXFLAGS = "-O3 -fmax-errors=1";
|
||||
cmakeFlags = [
|
||||
"-DARITH=easy"
|
||||
"-DBUILD_BLS_PYTHON_BINDINGS=false"
|
||||
"-DBUILD_BLS_TESTS=false"
|
||||
"-DBUILD_BLS_BENCHMARKS=false"
|
||||
];
|
||||
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
|
||||
install -D -m 755 chia_plot $out/bin/chia_plot
|
||||
|
||||
runHook postInstall
|
||||
'';
|
||||
|
||||
meta = with lib; {
|
||||
homepage = "https://github.com/madMAx43v3r/chia-plotter";
|
||||
description = "New implementation of a chia plotter which is designed as a processing pipeline";
|
||||
license = licenses.gpl3Only;
|
||||
platforms = platforms.linux;
|
||||
maintainers = with maintainers; [ ilyakooo0 ];
|
||||
};
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
diff --git a/lib/bls-signatures/python-bindings/CMakeLists.txt b/lib/bls-signatures/python-bindings/CMakeLists.txt
|
||||
index 255e3bb..5f99c3a 100644
|
||||
--- a/lib/bls-signatures/python-bindings/CMakeLists.txt
|
||||
+++ b/lib/bls-signatures/python-bindings/CMakeLists.txt
|
||||
@@ -6,8 +6,7 @@ include(FetchContent)
|
||||
|
||||
FetchContent_Declare(
|
||||
pybind11
|
||||
- GIT_REPOSITORY https://github.com/pybind/pybind11.git
|
||||
- GIT_TAG v2.6.2
|
||||
+ SOURCE_DIR @pybind11_src@
|
||||
)
|
||||
FetchContent_MakeAvailable(pybind11 relic)
|
||||
|
||||
diff --git a/lib/bls-signatures/src/CMakeLists.txt b/lib/bls-signatures/src/CMakeLists.txt
|
||||
index b762b5d..e06073b 100644
|
||||
--- a/lib/bls-signatures/src/CMakeLists.txt
|
||||
+++ b/lib/bls-signatures/src/CMakeLists.txt
|
||||
@@ -4,18 +4,11 @@ set (CMAKE_CXX_STANDARD 17)
|
||||
# CMake 3.14+
|
||||
include(FetchContent)
|
||||
|
||||
-if (DEFINED ENV{RELIC_MAIN})
|
||||
- set(RELIC_GIT_TAG "origin/main")
|
||||
-else ()
|
||||
- set(RELIC_GIT_TAG "1885ae3b681c423c72b65ce1fe70910142cf941c")
|
||||
-endif ()
|
||||
-
|
||||
message(STATUS "Relic will be built from: ${RELIC_GIT_TAG}")
|
||||
|
||||
FetchContent_Declare(
|
||||
relic
|
||||
- GIT_REPOSITORY https://github.com/relic-toolkit/relic.git
|
||||
- GIT_TAG ${RELIC_GIT_TAG}
|
||||
+ SOURCE_DIR @relic_src@
|
||||
)
|
||||
FetchContent_MakeAvailable(relic)
|
||||
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index 970ec74..948441a 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -38,6 +38,7 @@ include_directories(
|
||||
${BLAKE3_PATH}
|
||||
${CMAKE_BINARY_DIR}/_deps/relic-src/include
|
||||
${CMAKE_BINARY_DIR}/_deps/relic-build/include
|
||||
+ @relic_src@/include
|
||||
)
|
||||
|
||||
IF (WIN32)
|
@ -72,6 +72,7 @@ python3Packages.buildPythonApplication rec {
|
||||
--replace "click==7.1.2" "click>=7.1.2" \
|
||||
--replace "clvm_rs==0.1.8" "clvm_rs>=0.1.8" \
|
||||
--replace "clvm==0.9.7" "clvm>=0.9.7" \
|
||||
--replace "bitstring==3.1.7" "bitstring>=3.1.9" \
|
||||
'';
|
||||
|
||||
preCheck = ''
|
||||
|
@ -2,12 +2,12 @@
|
||||
|
||||
let
|
||||
pname = "ledger-live-desktop";
|
||||
version = "2.30.0";
|
||||
version = "2.31.1";
|
||||
name = "${pname}-${version}";
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://github.com/LedgerHQ/${pname}/releases/download/v${version}/${pname}-${version}-linux-x86_64.AppImage";
|
||||
sha256 = "0xh28m3slzg6bp0fm183m62ydzqkvj384j4dwsfalgz4ndwvy595";
|
||||
sha256 = "0cxf4i58l0kg9c13j7mf0w5ijrkkf9z1375vn6xghd0r8g5hvws5";
|
||||
};
|
||||
|
||||
appimageContents = appimageTools.extractType2 {
|
||||
@ -30,7 +30,7 @@ in appimageTools.wrapType2 rec {
|
||||
description = "Wallet app for Ledger Nano S and Ledger Blue";
|
||||
homepage = "https://www.ledger.com/live";
|
||||
license = licenses.mit;
|
||||
maintainers = with maintainers; [ thedavidmeister nyanloutre RaghavSood th0rgal ];
|
||||
maintainers = with maintainers; [ andresilva thedavidmeister nyanloutre RaghavSood th0rgal ];
|
||||
platforms = [ "x86_64-linux" ];
|
||||
};
|
||||
}
|
||||
|
@ -2,13 +2,13 @@
|
||||
|
||||
python3Packages.buildPythonApplication rec {
|
||||
pname = "lndmanage";
|
||||
version = "0.11.0";
|
||||
version = "0.12.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "bitromortac";
|
||||
repo = pname;
|
||||
rev = "v${version}";
|
||||
sha256 = "19sqf7cjslwpfzcdbyq182dx7gnn9hii77sahbnh88v69qxgwzvb";
|
||||
sha256 = "1p73wdxv3fca2ga4nqpjk5lig7bj2v230lh8niw490p5y7hhnggl";
|
||||
};
|
||||
|
||||
propagatedBuildInputs = with python3Packages; [
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user