Merge master into haskell-updates
This commit is contained in:
commit
fc9b80e7a3
@ -378,7 +378,7 @@ The staging workflow exists to batch Hydra builds of many packages together.
|
|||||||
It works by directing commits that cause [mass rebuilds][mass-rebuild] to a separate `staging` branch that isn't directly built by Hydra.
|
It works by directing commits that cause [mass rebuilds][mass-rebuild] to a separate `staging` branch that isn't directly built by Hydra.
|
||||||
Regularly, the `staging` branch is _manually_ merged into a `staging-next` branch to be built by Hydra using the [`nixpkgs:staging-next` jobset](https://hydra.nixos.org/jobset/nixpkgs/staging-next).
|
Regularly, the `staging` branch is _manually_ merged into a `staging-next` branch to be built by Hydra using the [`nixpkgs:staging-next` jobset](https://hydra.nixos.org/jobset/nixpkgs/staging-next).
|
||||||
The `staging-next` branch should then only receive direct commits in order to fix Hydra builds.
|
The `staging-next` branch should then only receive direct commits in order to fix Hydra builds.
|
||||||
Once it is verified that there are no major regressions, it is merged into `master` using [a pull requests](https://github.com/NixOS/nixpkgs/pulls?q=head%3Astaging-next).
|
Once it is verified that there are no major regressions, it is merged into `master` using [a pull request](https://github.com/NixOS/nixpkgs/pulls?q=head%3Astaging-next).
|
||||||
This is done manually in order to ensure it's a good use of Hydra's computing resources.
|
This is done manually in order to ensure it's a good use of Hydra's computing resources.
|
||||||
By keeping the `staging-next` branch separate from `staging`, this batching does not block developers from merging changes into `staging`.
|
By keeping the `staging-next` branch separate from `staging`, this batching does not block developers from merging changes into `staging`.
|
||||||
|
|
||||||
|
@ -80,6 +80,8 @@ Do _not_ use `dart run <package_name>`, as this will attempt to download depende
|
|||||||
|
|
||||||
### Usage with nix-shell {#ssec-dart-applications-nix-shell}
|
### Usage with nix-shell {#ssec-dart-applications-nix-shell}
|
||||||
|
|
||||||
|
#### Using dependencies from the Nix store {#ssec-dart-applications-nix-shell-deps}
|
||||||
|
|
||||||
As `buildDartApplication` provides dependencies instead of `pub get`, Dart needs to be explicitly told where to find them.
|
As `buildDartApplication` provides dependencies instead of `pub get`, Dart needs to be explicitly told where to find them.
|
||||||
|
|
||||||
Run the following commands in the source directory to configure Dart appropriately.
|
Run the following commands in the source directory to configure Dart appropriately.
|
||||||
@ -103,6 +105,9 @@ flutter.buildFlutterApplication {
|
|||||||
pname = "firmware-updater";
|
pname = "firmware-updater";
|
||||||
version = "unstable-2023-04-30";
|
version = "unstable-2023-04-30";
|
||||||
|
|
||||||
|
# To build for the Web, use the targetFlutterPlatform argument.
|
||||||
|
# targetFlutterPlatform = "web";
|
||||||
|
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "canonical";
|
owner = "canonical";
|
||||||
repo = "firmware-updater";
|
repo = "firmware-updater";
|
||||||
@ -117,4 +122,15 @@ flutter.buildFlutterApplication {
|
|||||||
|
|
||||||
### Usage with nix-shell {#ssec-dart-flutter-nix-shell}
|
### Usage with nix-shell {#ssec-dart-flutter-nix-shell}
|
||||||
|
|
||||||
See the [Dart documentation](#ssec-dart-applications-nix-shell) for nix-shell instructions.
|
Flutter-specific `nix-shell` usage notes are included here. See the [Dart documentation](#ssec-dart-applications-nix-shell) for general `nix-shell` instructions.
|
||||||
|
|
||||||
|
#### Entering the shell {#ssec-dart-flutter-nix-shell-enter}
|
||||||
|
|
||||||
|
By default, dependencies for only the `targetFlutterPlatform` are available in the
|
||||||
|
build environment. This is useful for keeping closures small, but be problematic
|
||||||
|
during development. It's common, for example, to build Web apps for Linux during
|
||||||
|
development to take advantage of native features such as stateful hot reload.
|
||||||
|
|
||||||
|
To enter a shell with all the usual target platforms available, use the `multiShell` attribute.
|
||||||
|
|
||||||
|
e.g. `nix-shell '<nixpkgs>' -A fluffychat-web.multiShell`.
|
||||||
|
@ -2553,6 +2553,12 @@
|
|||||||
githubId = 52386117;
|
githubId = 52386117;
|
||||||
name = "Blusk";
|
name = "Blusk";
|
||||||
};
|
};
|
||||||
|
bmanuel = {
|
||||||
|
name = "Benjamin Manuel";
|
||||||
|
email = "ben@benmanuel.com";
|
||||||
|
github = "bmanuel";
|
||||||
|
githubId = 3662307;
|
||||||
|
};
|
||||||
bmilanov = {
|
bmilanov = {
|
||||||
name = "Biser Milanov";
|
name = "Biser Milanov";
|
||||||
email = "bmilanov11+nixpkgs@gmail.com";
|
email = "bmilanov11+nixpkgs@gmail.com";
|
||||||
@ -15504,6 +15510,16 @@
|
|||||||
githubId = 1891350;
|
githubId = 1891350;
|
||||||
name = "Michael Raskin";
|
name = "Michael Raskin";
|
||||||
};
|
};
|
||||||
|
ratcornu = {
|
||||||
|
email = "ratcornu@skaven.org";
|
||||||
|
github = "RatCornu";
|
||||||
|
githubId = 98173832;
|
||||||
|
name = "Balthazar Patiachvili";
|
||||||
|
matrix = "@ratcornu:skweel.skaven.org";
|
||||||
|
keys = [{
|
||||||
|
fingerprint = "1B91 F087 3D06 1319 D3D0 7F91 FA47 BDA2 6048 9ADA";
|
||||||
|
}];
|
||||||
|
};
|
||||||
ratsclub = {
|
ratsclub = {
|
||||||
email = "victor@freire.dev.br";
|
email = "victor@freire.dev.br";
|
||||||
github = "ratsclub";
|
github = "ratsclub";
|
||||||
|
@ -37,6 +37,8 @@ In addition to numerous new and upgraded packages, this release has the followin
|
|||||||
- [Anki Sync Server](https://docs.ankiweb.net/sync-server.html), the official sync server built into recent versions of Anki. Available as [services.anki-sync-server](#opt-services.anki-sync-server.enable).
|
- [Anki Sync Server](https://docs.ankiweb.net/sync-server.html), the official sync server built into recent versions of Anki. Available as [services.anki-sync-server](#opt-services.anki-sync-server.enable).
|
||||||
The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been marked deprecated and will be dropped after 24.05 due to lack of maintenance of the anki-sync-server softwares.
|
The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been marked deprecated and will be dropped after 24.05 due to lack of maintenance of the anki-sync-server softwares.
|
||||||
|
|
||||||
|
- [Suwayomi Server](https://github.com/Suwayomi/Suwayomi-Server), a free and open source manga reader server that runs extensions built for [Tachiyomi](https://tachiyomi.org). Available as [services.suwayomi-server](#opt-services.suwayomi-server.enable).
|
||||||
|
|
||||||
- [ping_exporter](https://github.com/czerwonk/ping_exporter), a Prometheus exporter for ICMP echo requests. Available as [services.prometheus.exporters.ping](#opt-services.prometheus.exporters.ping.enable).
|
- [ping_exporter](https://github.com/czerwonk/ping_exporter), a Prometheus exporter for ICMP echo requests. Available as [services.prometheus.exporters.ping](#opt-services.prometheus.exporters.ping.enable).
|
||||||
|
|
||||||
- [Clevis](https://github.com/latchset/clevis), a pluggable framework for automated decryption, used to unlock encrypted devices in initrd. Available as [boot.initrd.clevis.enable](#opt-boot.initrd.clevis.enable).
|
- [Clevis](https://github.com/latchset/clevis), a pluggable framework for automated decryption, used to unlock encrypted devices in initrd. Available as [boot.initrd.clevis.enable](#opt-boot.initrd.clevis.enable).
|
||||||
@ -112,6 +114,13 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m
|
|||||||
- `services.avahi.nssmdns` got split into `services.avahi.nssmdns4` and `services.avahi.nssmdns6` which enable the mDNS NSS switch for IPv4 and IPv6 respectively.
|
- `services.avahi.nssmdns` got split into `services.avahi.nssmdns4` and `services.avahi.nssmdns6` which enable the mDNS NSS switch for IPv4 and IPv6 respectively.
|
||||||
Since most mDNS responders only register IPv4 addresses, most users want to keep the IPv6 support disabled to avoid long timeouts.
|
Since most mDNS responders only register IPv4 addresses, most users want to keep the IPv6 support disabled to avoid long timeouts.
|
||||||
|
|
||||||
|
- `multi-user.target` no longer depends on `network-online.target`.
|
||||||
|
This will potentially break services that assumed this was the case in the past.
|
||||||
|
This was changed for consistency with other distributions as well as improved boot times.
|
||||||
|
|
||||||
|
We have added a warning for services that are
|
||||||
|
`after = [ "network-online.target" ]` but do not depend on it (e.g. using `wants`).
|
||||||
|
|
||||||
- `networking.iproute2.enable` now does not set `environment.etc."iproute2/rt_tables".text`.
|
- `networking.iproute2.enable` now does not set `environment.etc."iproute2/rt_tables".text`.
|
||||||
|
|
||||||
Setting `environment.etc."iproute2/{CONFIG_FILE_NAME}".text` will override the whole configuration file instead of appending it to the upstream configuration file.
|
Setting `environment.etc."iproute2/{CONFIG_FILE_NAME}".text` will override the whole configuration file instead of appending it to the upstream configuration file.
|
||||||
|
@ -110,6 +110,7 @@ let
|
|||||||
withExtraAttrs = configuration: configuration // {
|
withExtraAttrs = configuration: configuration // {
|
||||||
inherit extraArgs;
|
inherit extraArgs;
|
||||||
inherit (configuration._module.args) pkgs;
|
inherit (configuration._module.args) pkgs;
|
||||||
|
inherit lib;
|
||||||
extendModules = args: withExtraAttrs (configuration.extendModules args);
|
extendModules = args: withExtraAttrs (configuration.extendModules args);
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
|
@ -10,6 +10,8 @@
|
|||||||
, systemd
|
, systemd
|
||||||
, fakeroot
|
, fakeroot
|
||||||
, util-linux
|
, util-linux
|
||||||
|
|
||||||
|
# filesystem tools
|
||||||
, dosfstools
|
, dosfstools
|
||||||
, mtools
|
, mtools
|
||||||
, e2fsprogs
|
, e2fsprogs
|
||||||
@ -18,8 +20,13 @@
|
|||||||
, btrfs-progs
|
, btrfs-progs
|
||||||
, xfsprogs
|
, xfsprogs
|
||||||
|
|
||||||
|
# compression tools
|
||||||
|
, zstd
|
||||||
|
, xz
|
||||||
|
|
||||||
# arguments
|
# arguments
|
||||||
, name
|
, imageFileBasename
|
||||||
|
, compression
|
||||||
, fileSystems
|
, fileSystems
|
||||||
, partitions
|
, partitions
|
||||||
, split
|
, split
|
||||||
@ -52,14 +59,25 @@ let
|
|||||||
};
|
};
|
||||||
|
|
||||||
fileSystemTools = builtins.concatMap (f: fileSystemToolMapping."${f}") fileSystems;
|
fileSystemTools = builtins.concatMap (f: fileSystemToolMapping."${f}") fileSystems;
|
||||||
|
|
||||||
|
compressionPkg = {
|
||||||
|
"zstd" = zstd;
|
||||||
|
"xz" = xz;
|
||||||
|
}."${compression.algorithm}";
|
||||||
|
|
||||||
|
compressionCommand = {
|
||||||
|
"zstd" = "zstd --no-progress --threads=0 -${toString compression.level}";
|
||||||
|
"xz" = "xz --keep --verbose --threads=0 -${toString compression.level}";
|
||||||
|
}."${compression.algorithm}";
|
||||||
in
|
in
|
||||||
|
|
||||||
runCommand name
|
runCommand imageFileBasename
|
||||||
{
|
{
|
||||||
nativeBuildInputs = [
|
nativeBuildInputs = [
|
||||||
systemd
|
systemd
|
||||||
fakeroot
|
fakeroot
|
||||||
util-linux
|
util-linux
|
||||||
|
compressionPkg
|
||||||
] ++ fileSystemTools;
|
] ++ fileSystemTools;
|
||||||
} ''
|
} ''
|
||||||
amendedRepartDefinitions=$(${amendRepartDefinitions} ${partitions} ${definitionsDirectory})
|
amendedRepartDefinitions=$(${amendRepartDefinitions} ${partitions} ${definitionsDirectory})
|
||||||
@ -67,6 +85,7 @@ runCommand name
|
|||||||
mkdir -p $out
|
mkdir -p $out
|
||||||
cd $out
|
cd $out
|
||||||
|
|
||||||
|
echo "Building image with systemd-repart..."
|
||||||
unshare --map-root-user fakeroot systemd-repart \
|
unshare --map-root-user fakeroot systemd-repart \
|
||||||
--dry-run=no \
|
--dry-run=no \
|
||||||
--empty=create \
|
--empty=create \
|
||||||
@ -75,6 +94,17 @@ runCommand name
|
|||||||
--definitions="$amendedRepartDefinitions" \
|
--definitions="$amendedRepartDefinitions" \
|
||||||
--split="${lib.boolToString split}" \
|
--split="${lib.boolToString split}" \
|
||||||
--json=pretty \
|
--json=pretty \
|
||||||
image.raw \
|
${imageFileBasename}.raw \
|
||||||
| tee repart-output.json
|
| tee repart-output.json
|
||||||
|
|
||||||
|
# Compression is implemented in the same derivation as opposed to in a
|
||||||
|
# separate derivation to allow users to save disk space. Disk images are
|
||||||
|
# already very space intensive so we want to allow users to mitigate this.
|
||||||
|
if ${lib.boolToString compression.enable}; then
|
||||||
|
for f in ${imageFileBasename}*; do
|
||||||
|
echo "Compressing $f with ${compression.algorithm}..."
|
||||||
|
# Keep the original file when compressing and only delete it afterwards
|
||||||
|
${compressionCommand} $f && rm $f
|
||||||
|
done
|
||||||
|
fi
|
||||||
''
|
''
|
||||||
|
@ -66,7 +66,53 @@ in
|
|||||||
|
|
||||||
name = lib.mkOption {
|
name = lib.mkOption {
|
||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
description = lib.mdDoc "The name of the image.";
|
description = lib.mdDoc ''
|
||||||
|
Name of the image.
|
||||||
|
|
||||||
|
If this option is unset but config.system.image.id is set,
|
||||||
|
config.system.image.id is used as the default value.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
version = lib.mkOption {
|
||||||
|
type = lib.types.nullOr lib.types.str;
|
||||||
|
default = config.system.image.version;
|
||||||
|
defaultText = lib.literalExpression "config.system.image.version";
|
||||||
|
description = lib.mdDoc "Version of the image";
|
||||||
|
};
|
||||||
|
|
||||||
|
imageFileBasename = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
readOnly = true;
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Basename of the image filename without any extension (e.g. `image_1`).
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
imageFile = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
readOnly = true;
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Filename of the image including all extensions (e.g `image_1.raw` or
|
||||||
|
`image_1.raw.zst`).
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
compression = {
|
||||||
|
enable = lib.mkEnableOption (lib.mdDoc "Image compression");
|
||||||
|
|
||||||
|
algorithm = lib.mkOption {
|
||||||
|
type = lib.types.enum [ "zstd" "xz" ];
|
||||||
|
default = "zstd";
|
||||||
|
description = lib.mdDoc "Compression algorithm";
|
||||||
|
};
|
||||||
|
|
||||||
|
level = lib.mkOption {
|
||||||
|
type = lib.types.int;
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Compression level. The available range depends on the used algorithm.
|
||||||
|
'';
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
seed = lib.mkOption {
|
seed = lib.mkOption {
|
||||||
@ -131,6 +177,32 @@ in
|
|||||||
|
|
||||||
config = {
|
config = {
|
||||||
|
|
||||||
|
image.repart =
|
||||||
|
let
|
||||||
|
version = config.image.repart.version;
|
||||||
|
versionInfix = if version != null then "_${version}" else "";
|
||||||
|
compressionSuffix = lib.optionalString cfg.compression.enable
|
||||||
|
{
|
||||||
|
"zstd" = ".zst";
|
||||||
|
"xz" = ".xz";
|
||||||
|
}."${cfg.compression.algorithm}";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
name = lib.mkIf (config.system.image.id != null) (lib.mkOptionDefault config.system.image.id);
|
||||||
|
imageFileBasename = cfg.name + versionInfix;
|
||||||
|
imageFile = cfg.imageFileBasename + ".raw" + compressionSuffix;
|
||||||
|
|
||||||
|
compression = {
|
||||||
|
# Generally default to slightly faster than default compression
|
||||||
|
# levels under the assumption that most of the building will be done
|
||||||
|
# for development and release builds will be customized.
|
||||||
|
level = lib.mkOptionDefault {
|
||||||
|
"zstd" = 3;
|
||||||
|
"xz" = 3;
|
||||||
|
}."${cfg.compression.algorithm}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
system.build.image =
|
system.build.image =
|
||||||
let
|
let
|
||||||
fileSystems = lib.filter
|
fileSystems = lib.filter
|
||||||
@ -160,7 +232,7 @@ in
|
|||||||
in
|
in
|
||||||
pkgs.callPackage ./repart-image.nix {
|
pkgs.callPackage ./repart-image.nix {
|
||||||
systemd = cfg.package;
|
systemd = cfg.package;
|
||||||
inherit (cfg) name split seed;
|
inherit (cfg) imageFileBasename compression split seed;
|
||||||
inherit fileSystems definitionsDirectory partitions;
|
inherit fileSystems definitionsDirectory partitions;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -28,6 +28,8 @@ let
|
|||||||
DOCUMENTATION_URL = lib.optionalString (cfg.distroId == "nixos") "https://nixos.org/learn.html";
|
DOCUMENTATION_URL = lib.optionalString (cfg.distroId == "nixos") "https://nixos.org/learn.html";
|
||||||
SUPPORT_URL = lib.optionalString (cfg.distroId == "nixos") "https://nixos.org/community.html";
|
SUPPORT_URL = lib.optionalString (cfg.distroId == "nixos") "https://nixos.org/community.html";
|
||||||
BUG_REPORT_URL = lib.optionalString (cfg.distroId == "nixos") "https://github.com/NixOS/nixpkgs/issues";
|
BUG_REPORT_URL = lib.optionalString (cfg.distroId == "nixos") "https://github.com/NixOS/nixpkgs/issues";
|
||||||
|
IMAGE_ID = lib.optionalString (config.system.image.id != null) config.system.image.id;
|
||||||
|
IMAGE_VERSION = lib.optionalString (config.system.image.version != null) config.system.image.version;
|
||||||
} // lib.optionalAttrs (cfg.variant_id != null) {
|
} // lib.optionalAttrs (cfg.variant_id != null) {
|
||||||
VARIANT_ID = cfg.variant_id;
|
VARIANT_ID = cfg.variant_id;
|
||||||
};
|
};
|
||||||
@ -110,6 +112,38 @@ in
|
|||||||
example = "installer";
|
example = "installer";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
image = {
|
||||||
|
|
||||||
|
id = lib.mkOption {
|
||||||
|
type = types.nullOr (types.strMatching "^[a-z0-9._-]+$");
|
||||||
|
default = null;
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Image identifier.
|
||||||
|
|
||||||
|
This corresponds to the IMAGE_ID field in os-release. See the
|
||||||
|
upstream docs for more details on valid characters for this field:
|
||||||
|
https://www.freedesktop.org/software/systemd/man/latest/os-release.html#IMAGE_ID=
|
||||||
|
|
||||||
|
You would only want to set this option if you're build NixOS appliance images.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
version = lib.mkOption {
|
||||||
|
type = types.nullOr (types.strMatching "^[a-z0-9._-]+$");
|
||||||
|
default = null;
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Image version.
|
||||||
|
|
||||||
|
This corresponds to the IMAGE_VERSION field in os-release. See the
|
||||||
|
upstream docs for more details on valid characters for this field:
|
||||||
|
https://www.freedesktop.org/software/systemd/man/latest/os-release.html#IMAGE_VERSION=
|
||||||
|
|
||||||
|
You would only want to set this option if you're build NixOS appliance images.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
stateVersion = mkOption {
|
stateVersion = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
# TODO Remove this and drop the default of the option so people are forced to set it.
|
# TODO Remove this and drop the default of the option so people are forced to set it.
|
||||||
|
@ -1339,6 +1339,7 @@
|
|||||||
./services/web-apps/restya-board.nix
|
./services/web-apps/restya-board.nix
|
||||||
./services/web-apps/rimgo.nix
|
./services/web-apps/rimgo.nix
|
||||||
./services/web-apps/sftpgo.nix
|
./services/web-apps/sftpgo.nix
|
||||||
|
./services/web-apps/suwayomi-server.nix
|
||||||
./services/web-apps/rss-bridge.nix
|
./services/web-apps/rss-bridge.nix
|
||||||
./services/web-apps/selfoss.nix
|
./services/web-apps/selfoss.nix
|
||||||
./services/web-apps/shiori.nix
|
./services/web-apps/shiori.nix
|
||||||
|
@ -64,6 +64,7 @@ in
|
|||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
systemd = {
|
systemd = {
|
||||||
services.gmediarender = {
|
services.gmediarender = {
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network-online.target" ];
|
after = [ "network-online.target" ];
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
description = "gmediarender server daemon";
|
description = "gmediarender server daemon";
|
||||||
|
@ -26,6 +26,7 @@ in
|
|||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
systemd.services.jmusicbot = {
|
systemd.services.jmusicbot = {
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network-online.target" ];
|
after = [ "network-online.target" ];
|
||||||
description = "Discord music bot that's easy to set up and run yourself!";
|
description = "Discord music bot that's easy to set up and run yourself!";
|
||||||
serviceConfig = mkMerge [{
|
serviceConfig = mkMerge [{
|
||||||
|
@ -50,6 +50,7 @@ in
|
|||||||
|
|
||||||
systemd.services.spotifyd = {
|
systemd.services.spotifyd = {
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network-online.target" "sound.target" ];
|
after = [ "network-online.target" "sound.target" ];
|
||||||
description = "spotifyd, a Spotify playing daemon";
|
description = "spotifyd, a Spotify playing daemon";
|
||||||
environment.SHELL = "/bin/sh";
|
environment.SHELL = "/bin/sh";
|
||||||
|
@ -50,6 +50,7 @@ in {
|
|||||||
description = "Standalone MPD Web GUI written in C";
|
description = "Standalone MPD Web GUI written in C";
|
||||||
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network-online.target" ];
|
after = [ "network-online.target" ];
|
||||||
|
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
|
@ -268,6 +268,7 @@ in {
|
|||||||
systemd.services.buildbot-master = {
|
systemd.services.buildbot-master = {
|
||||||
description = "Buildbot Continuous Integration Server.";
|
description = "Buildbot Continuous Integration Server.";
|
||||||
after = [ "network-online.target" ];
|
after = [ "network-online.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
path = cfg.packages ++ cfg.pythonPackages python.pkgs;
|
path = cfg.packages ++ cfg.pythonPackages python.pkgs;
|
||||||
environment.PYTHONPATH = "${python.withPackages (self: cfg.pythonPackages self ++ [ package ])}/${python.sitePackages}";
|
environment.PYTHONPATH = "${python.withPackages (self: cfg.pythonPackages self ++ [ package ])}/${python.sitePackages}";
|
||||||
|
@ -188,6 +188,7 @@ in
|
|||||||
nameValuePair "gitea-runner-${escapeSystemdPath name}" {
|
nameValuePair "gitea-runner-${escapeSystemdPath name}" {
|
||||||
inherit (instance) enable;
|
inherit (instance) enable;
|
||||||
description = "Gitea Actions Runner";
|
description = "Gitea Actions Runner";
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [
|
after = [
|
||||||
"network-online.target"
|
"network-online.target"
|
||||||
] ++ optionals (wantsDocker) [
|
] ++ optionals (wantsDocker) [
|
||||||
|
@ -393,6 +393,7 @@ in
|
|||||||
systemd.services.hydra-evaluator =
|
systemd.services.hydra-evaluator =
|
||||||
{ wantedBy = [ "multi-user.target" ];
|
{ wantedBy = [ "multi-user.target" ];
|
||||||
requires = [ "hydra-init.service" ];
|
requires = [ "hydra-init.service" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "hydra-init.service" "network.target" "network-online.target" ];
|
after = [ "hydra-init.service" "network.target" "network-online.target" ];
|
||||||
path = with pkgs; [ hydra-package nettools jq ];
|
path = with pkgs; [ hydra-package nettools jq ];
|
||||||
restartTriggers = [ hydraConf ];
|
restartTriggers = [ hydraConf ];
|
||||||
|
@ -143,7 +143,7 @@ in
|
|||||||
# ConnectionTimeout = 180
|
# ConnectionTimeout = 180
|
||||||
|
|
||||||
#RemoteServiceName = gds_db
|
#RemoteServiceName = gds_db
|
||||||
RemoteServicePort = ${cfg.port}
|
RemoteServicePort = ${toString cfg.port}
|
||||||
|
|
||||||
# randomly choose port for server Event Notification
|
# randomly choose port for server Event Notification
|
||||||
#RemoteAuxPort = 0
|
#RemoteAuxPort = 0
|
||||||
|
@ -104,6 +104,7 @@ in
|
|||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
systemd.services.lldap = {
|
systemd.services.lldap = {
|
||||||
description = "Lightweight LDAP server (lldap)";
|
description = "Lightweight LDAP server (lldap)";
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network-online.target" ];
|
after = [ "network-online.target" ];
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
|
@ -294,6 +294,7 @@ in {
|
|||||||
"man:slapd-mdb"
|
"man:slapd-mdb"
|
||||||
];
|
];
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network-online.target" ];
|
after = [ "network-online.target" ];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
User = cfg.user;
|
User = cfg.user;
|
||||||
|
@ -200,6 +200,7 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
systemd.services.geoclue = {
|
systemd.services.geoclue = {
|
||||||
|
wants = lib.optionals cfg.enableWifi [ "network-online.target" ];
|
||||||
after = lib.optionals cfg.enableWifi [ "network-online.target" ];
|
after = lib.optionals cfg.enableWifi [ "network-online.target" ];
|
||||||
# restart geoclue service when the configuration changes
|
# restart geoclue service when the configuration changes
|
||||||
restartTriggers = [
|
restartTriggers = [
|
||||||
@ -217,6 +218,7 @@ in
|
|||||||
# we can't be part of a system service, and the agent should
|
# we can't be part of a system service, and the agent should
|
||||||
# be okay with the main service coming and going
|
# be okay with the main service coming and going
|
||||||
wantedBy = [ "default.target" ];
|
wantedBy = [ "default.target" ];
|
||||||
|
wants = lib.optionals cfg.enableWifi [ "network-online.target" ];
|
||||||
after = lib.optionals cfg.enableWifi [ "network-online.target" ];
|
after = lib.optionals cfg.enableWifi [ "network-online.target" ];
|
||||||
unitConfig.ConditionUser = "!@system";
|
unitConfig.ConditionUser = "!@system";
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
|
@ -41,6 +41,7 @@ in
|
|||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
systemd.services.evcc = {
|
systemd.services.evcc = {
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [
|
after = [
|
||||||
"network-online.target"
|
"network-online.target"
|
||||||
"mosquitto.target"
|
"mosquitto.target"
|
||||||
|
@ -435,6 +435,7 @@ in {
|
|||||||
|
|
||||||
systemd.services.home-assistant = {
|
systemd.services.home-assistant = {
|
||||||
description = "Home Assistant";
|
description = "Home Assistant";
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [
|
after = [
|
||||||
"network-online.target"
|
"network-online.target"
|
||||||
|
|
||||||
|
@ -84,6 +84,7 @@ in {
|
|||||||
systemd.services.journaldriver = {
|
systemd.services.journaldriver = {
|
||||||
description = "Stackdriver Logging journal forwarder";
|
description = "Stackdriver Logging journal forwarder";
|
||||||
script = "${pkgs.journaldriver}/bin/journaldriver";
|
script = "${pkgs.journaldriver}/bin/journaldriver";
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network-online.target" ];
|
after = [ "network-online.target" ];
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
|
||||||
|
@ -250,6 +250,7 @@ in
|
|||||||
path = [ config.services.postgresql.package ];
|
path = [ config.services.postgresql.package ];
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network-online.target" ];
|
after = [ "network-online.target" ];
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
script = let
|
script = let
|
||||||
|
@ -435,7 +435,7 @@ in
|
|||||||
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
after = [ "network-online.target" ];
|
after = [ "network-online.target" ];
|
||||||
wants = sympaSubServices;
|
wants = sympaSubServices ++ [ "network-online.target" ];
|
||||||
before = sympaSubServices;
|
before = sympaSubServices;
|
||||||
serviceConfig = sympaServiceConfig "sympa_msg";
|
serviceConfig = sympaServiceConfig "sympa_msg";
|
||||||
|
|
||||||
|
@ -1056,6 +1056,7 @@ in {
|
|||||||
|
|
||||||
systemd.targets.matrix-synapse = lib.mkIf hasWorkers {
|
systemd.targets.matrix-synapse = lib.mkIf hasWorkers {
|
||||||
description = "Synapse Matrix parent target";
|
description = "Synapse Matrix parent target";
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network-online.target" ] ++ optional hasLocalPostgresDB "postgresql.service";
|
after = [ "network-online.target" ] ++ optional hasLocalPostgresDB "postgresql.service";
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
};
|
};
|
||||||
@ -1071,6 +1072,7 @@ in {
|
|||||||
requires = optional hasLocalPostgresDB "postgresql.service";
|
requires = optional hasLocalPostgresDB "postgresql.service";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network-online.target" ] ++ optional hasLocalPostgresDB "postgresql.service";
|
after = [ "network-online.target" ] ++ optional hasLocalPostgresDB "postgresql.service";
|
||||||
requires = optional hasLocalPostgresDB "postgresql.service";
|
requires = optional hasLocalPostgresDB "postgresql.service";
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
@ -41,6 +41,7 @@ in {
|
|||||||
# See https://github.com/aws/amazon-ssm-agent/blob/mainline/packaging/linux/amazon-ssm-agent.service
|
# See https://github.com/aws/amazon-ssm-agent/blob/mainline/packaging/linux/amazon-ssm-agent.service
|
||||||
systemd.services.amazon-ssm-agent = {
|
systemd.services.amazon-ssm-agent = {
|
||||||
inherit (cfg.package.meta) description;
|
inherit (cfg.package.meta) description;
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network-online.target" ];
|
after = [ "network-online.target" ];
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
|
||||||
|
@ -154,7 +154,7 @@ in
|
|||||||
in {
|
in {
|
||||||
description = "BigClown Gateway";
|
description = "BigClown Gateway";
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
wants = mkIf config.services.mosquitto.enable [ "mosquitto.service" ];
|
wants = [ "network-online.target" ] ++ lib.optional config.services.mosquitto.enable "mosquitto.service";
|
||||||
after = [ "network-online.target" ];
|
after = [ "network-online.target" ];
|
||||||
preStart = ''
|
preStart = ''
|
||||||
umask 077
|
umask 077
|
||||||
|
@ -35,6 +35,7 @@ in {
|
|||||||
systemd.services."domoticz" = {
|
systemd.services."domoticz" = {
|
||||||
description = pkgDesc;
|
description = pkgDesc;
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network-online.target" ];
|
after = [ "network-online.target" ];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
DynamicUser = true;
|
DynamicUser = true;
|
||||||
|
@ -59,6 +59,7 @@ in
|
|||||||
|
|
||||||
systemd.services.etesync-dav = {
|
systemd.services.etesync-dav = {
|
||||||
description = "etesync-dav - A CalDAV and CardDAV adapter for EteSync";
|
description = "etesync-dav - A CalDAV and CardDAV adapter for EteSync";
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network-online.target" ];
|
after = [ "network-online.target" ];
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
path = [ pkgs.etesync-dav ];
|
path = [ pkgs.etesync-dav ];
|
||||||
|
@ -357,6 +357,7 @@ in {
|
|||||||
description = "${cfg.serverName} media Server";
|
description = "${cfg.serverName} media Server";
|
||||||
# Gerbera might fail if the network interface is not available on startup
|
# Gerbera might fail if the network interface is not available on startup
|
||||||
# https://github.com/gerbera/gerbera/issues/1324
|
# https://github.com/gerbera/gerbera/issues/1324
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network.target" "network-online.target" ];
|
after = [ "network.target" "network-online.target" ];
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
serviceConfig.ExecStart = "${binaryCommand} --port ${toString cfg.port} ${interfaceFlag} ${configFlag} --home ${cfg.dataDir}";
|
serviceConfig.ExecStart = "${binaryCommand} --port ${toString cfg.port} ${interfaceFlag} ${configFlag} --home ${cfg.dataDir}";
|
||||||
|
@ -77,6 +77,7 @@ in {
|
|||||||
systemd.services.metabase = {
|
systemd.services.metabase = {
|
||||||
description = "Metabase server";
|
description = "Metabase server";
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network-online.target" ];
|
after = [ "network-online.target" ];
|
||||||
environment = {
|
environment = {
|
||||||
MB_PLUGINS_DIR = "${dataDir}/plugins";
|
MB_PLUGINS_DIR = "${dataDir}/plugins";
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{ config, lib, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
let cfg = config.nix.sshServe;
|
let cfg = config.nix.sshServe;
|
||||||
@ -46,7 +46,7 @@ in {
|
|||||||
description = "Nix SSH store user";
|
description = "Nix SSH store user";
|
||||||
isSystemUser = true;
|
isSystemUser = true;
|
||||||
group = "nix-ssh";
|
group = "nix-ssh";
|
||||||
useDefaultShell = true;
|
shell = pkgs.bashInteractive;
|
||||||
};
|
};
|
||||||
users.groups.nix-ssh = {};
|
users.groups.nix-ssh = {};
|
||||||
|
|
||||||
|
@ -297,6 +297,7 @@ in
|
|||||||
wantedBy = [ "paperless-scheduler.service" ];
|
wantedBy = [ "paperless-scheduler.service" ];
|
||||||
before = [ "paperless-scheduler.service" ];
|
before = [ "paperless-scheduler.service" ];
|
||||||
after = [ "network-online.target" ];
|
after = [ "network-online.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
serviceConfig = defaultServiceConfig // {
|
serviceConfig = defaultServiceConfig // {
|
||||||
User = cfg.user;
|
User = cfg.user;
|
||||||
Type = "oneshot";
|
Type = "oneshot";
|
||||||
|
@ -84,6 +84,7 @@ in {
|
|||||||
# upstream service file in https://git.io/JUt4Q
|
# upstream service file in https://git.io/JUt4Q
|
||||||
systemd.services.mackerel-agent = {
|
systemd.services.mackerel-agent = {
|
||||||
description = "mackerel.io agent";
|
description = "mackerel.io agent";
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network-online.target" "nss-lookup.target" ];
|
after = [ "network-online.target" "nss-lookup.target" ];
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
environment = {
|
environment = {
|
||||||
|
@ -174,6 +174,7 @@ in {
|
|||||||
|
|
||||||
systemd.services.alertmanager = {
|
systemd.services.alertmanager = {
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network-online.target" ];
|
after = [ "network-online.target" ];
|
||||||
preStart = ''
|
preStart = ''
|
||||||
${lib.getBin pkgs.envsubst}/bin/envsubst -o "/tmp/alert-manager-substituted.yaml" \
|
${lib.getBin pkgs.envsubst}/bin/envsubst -o "/tmp/alert-manager-substituted.yaml" \
|
||||||
|
@ -30,6 +30,7 @@ in
|
|||||||
description = "TeamViewer remote control daemon";
|
description = "TeamViewer remote control daemon";
|
||||||
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network-online.target" "network.target" "dbus.service" ];
|
after = [ "network-online.target" "network.target" "dbus.service" ];
|
||||||
requires = [ "dbus.service" ];
|
requires = [ "dbus.service" ];
|
||||||
preStart = "mkdir -pv /var/lib/teamviewer /var/log/teamviewer";
|
preStart = "mkdir -pv /var/lib/teamviewer /var/log/teamviewer";
|
||||||
|
@ -59,6 +59,7 @@ in {
|
|||||||
in {
|
in {
|
||||||
description = "Telegraf Agent";
|
description = "Telegraf Agent";
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network-online.target" ];
|
after = [ "network-online.target" ];
|
||||||
path = lib.optional (config.services.telegraf.extraConfig.inputs ? procstat) pkgs.procps;
|
path = lib.optional (config.services.telegraf.extraConfig.inputs ? procstat) pkgs.procps;
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
|
@ -215,6 +215,7 @@ in
|
|||||||
systemd.services.afsd = {
|
systemd.services.afsd = {
|
||||||
description = "AFS client";
|
description = "AFS client";
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
wants = lib.optional (!cfg.startDisconnected) "network-online.target";
|
||||||
after = singleton (if cfg.startDisconnected then "network.target" else "network-online.target");
|
after = singleton (if cfg.startDisconnected then "network.target" else "network-online.target");
|
||||||
serviceConfig = { RemainAfterExit = true; };
|
serviceConfig = { RemainAfterExit = true; };
|
||||||
restartIfChanged = false;
|
restartIfChanged = false;
|
||||||
|
@ -154,7 +154,7 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
securityType = mkOption {
|
securityType = mkOption {
|
||||||
type = types.str;
|
type = types.enum [ "auto" "user" "domain" "ads" ];
|
||||||
default = "user";
|
default = "user";
|
||||||
description = lib.mdDoc "Samba security type";
|
description = lib.mdDoc "Samba security type";
|
||||||
};
|
};
|
||||||
|
@ -198,6 +198,7 @@ in
|
|||||||
'';
|
'';
|
||||||
in {
|
in {
|
||||||
description = "Bitcoin daemon";
|
description = "Bitcoin daemon";
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network-online.target" ];
|
after = [ "network-online.target" ];
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
|
@ -47,6 +47,7 @@ in
|
|||||||
|
|
||||||
systemd.services.dante = {
|
systemd.services.dante = {
|
||||||
description = "Dante SOCKS v4 and v5 compatible proxy server";
|
description = "Dante SOCKS v4 and v5 compatible proxy server";
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network-online.target" ];
|
after = [ "network-online.target" ];
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
|
||||||
|
@ -114,6 +114,7 @@ in {
|
|||||||
systemd.services.ergo = {
|
systemd.services.ergo = {
|
||||||
description = "ergo server";
|
description = "ergo server";
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network-online.target" ];
|
after = [ "network-online.target" ];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
User = cfg.user;
|
User = cfg.user;
|
||||||
|
@ -21,6 +21,7 @@ with lib;
|
|||||||
RestartSec = 5;
|
RestartSec = 5;
|
||||||
};
|
};
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network.target" "network-online.target" ];
|
after = [ "network.target" "network-online.target" ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -460,6 +460,7 @@ in {
|
|||||||
|
|
||||||
systemd.services.headscale = {
|
systemd.services.headscale = {
|
||||||
description = "headscale coordination server for Tailscale";
|
description = "headscale coordination server for Tailscale";
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = ["network-online.target"];
|
after = ["network-online.target"];
|
||||||
wantedBy = ["multi-user.target"];
|
wantedBy = ["multi-user.target"];
|
||||||
restartTriggers = [configFile];
|
restartTriggers = [configFile];
|
||||||
|
@ -125,7 +125,8 @@ in
|
|||||||
|
|
||||||
systemd.services.ircd-hybrid = {
|
systemd.services.ircd-hybrid = {
|
||||||
description = "IRCD Hybrid server";
|
description = "IRCD Hybrid server";
|
||||||
after = [ "started networking" ];
|
wants = [ "network-online.target" ];
|
||||||
|
after = [ "network-online.target" ];
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
script = "${ircdService}/bin/control start";
|
script = "${ircdService}/bin/control start";
|
||||||
};
|
};
|
||||||
|
@ -27,7 +27,7 @@ with lib;
|
|||||||
systemd.services.ivpn-service = {
|
systemd.services.ivpn-service = {
|
||||||
description = "iVPN daemon";
|
description = "iVPN daemon";
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
wants = [ "network.target" ];
|
wants = [ "network.target" "network-online.target" ];
|
||||||
after = [
|
after = [
|
||||||
"network-online.target"
|
"network-online.target"
|
||||||
"NetworkManager.service"
|
"NetworkManager.service"
|
||||||
|
@ -325,6 +325,9 @@ in
|
|||||||
"network-online.target"
|
"network-online.target"
|
||||||
"time-sync.target"
|
"time-sync.target"
|
||||||
];
|
];
|
||||||
|
wants = [
|
||||||
|
"network-online.target"
|
||||||
|
];
|
||||||
wantedBy = [
|
wantedBy = [
|
||||||
"multi-user.target"
|
"multi-user.target"
|
||||||
];
|
];
|
||||||
@ -372,6 +375,9 @@ in
|
|||||||
"network-online.target"
|
"network-online.target"
|
||||||
"time-sync.target"
|
"time-sync.target"
|
||||||
];
|
];
|
||||||
|
wants = [
|
||||||
|
"network-online.target"
|
||||||
|
];
|
||||||
wantedBy = [
|
wantedBy = [
|
||||||
"multi-user.target"
|
"multi-user.target"
|
||||||
];
|
];
|
||||||
@ -413,6 +419,7 @@ in
|
|||||||
"https://kea.readthedocs.io/en/kea-${package.version}/arm/ddns.html"
|
"https://kea.readthedocs.io/en/kea-${package.version}/arm/ddns.html"
|
||||||
];
|
];
|
||||||
|
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [
|
after = [
|
||||||
"network-online.target"
|
"network-online.target"
|
||||||
"time-sync.target"
|
"time-sync.target"
|
||||||
|
@ -596,6 +596,7 @@ in
|
|||||||
systemd.services.mosquitto = {
|
systemd.services.mosquitto = {
|
||||||
description = "Mosquitto MQTT Broker Daemon";
|
description = "Mosquitto MQTT Broker Daemon";
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network-online.target" ];
|
after = [ "network-online.target" ];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Type = "notify";
|
Type = "notify";
|
||||||
|
@ -53,7 +53,7 @@ with lib;
|
|||||||
systemd.services.mullvad-daemon = {
|
systemd.services.mullvad-daemon = {
|
||||||
description = "Mullvad VPN daemon";
|
description = "Mullvad VPN daemon";
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
wants = [ "network.target" ];
|
wants = [ "network.target" "network-online.target" ];
|
||||||
after = [
|
after = [
|
||||||
"network-online.target"
|
"network-online.target"
|
||||||
"NetworkManager.service"
|
"NetworkManager.service"
|
||||||
|
@ -117,6 +117,7 @@ in
|
|||||||
boot.kernelModules = [ "nbd" ];
|
boot.kernelModules = [ "nbd" ];
|
||||||
|
|
||||||
systemd.services.nbd-server = {
|
systemd.services.nbd-server = {
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network-online.target" ];
|
after = [ "network-online.target" ];
|
||||||
before = [ "multi-user.target" ];
|
before = [ "multi-user.target" ];
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
@ -85,6 +85,7 @@ in
|
|||||||
systemd.services.ocserv = {
|
systemd.services.ocserv = {
|
||||||
description = "OpenConnect SSL VPN server";
|
description = "OpenConnect SSL VPN server";
|
||||||
documentation = [ "man:ocserv(8)" ];
|
documentation = [ "man:ocserv(8)" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "dbus.service" "network-online.target" ];
|
after = [ "dbus.service" "network-online.target" ];
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
|
||||||
|
@ -92,6 +92,7 @@ in {
|
|||||||
|
|
||||||
systemd.services.pleroma = {
|
systemd.services.pleroma = {
|
||||||
description = "Pleroma social network";
|
description = "Pleroma social network";
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network-online.target" "postgresql.service" ];
|
after = [ "network-online.target" "postgresql.service" ];
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
restartTriggers = [ config.environment.etc."/pleroma/config.exs".source ];
|
restartTriggers = [ config.environment.etc."/pleroma/config.exs".source ];
|
||||||
|
@ -208,6 +208,7 @@ in
|
|||||||
in
|
in
|
||||||
rec {
|
rec {
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network-online.target" ];
|
after = [ "network-online.target" ];
|
||||||
path = [ cfg.package pkgs.wireguard-tools ];
|
path = [ cfg.package pkgs.wireguard-tools ];
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ in {
|
|||||||
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
after = [ "systemd-modules-load.service" "network-online.target" ];
|
after = [ "systemd-modules-load.service" "network-online.target" ];
|
||||||
wants = [ "network-pre.target" ];
|
wants = [ "network-pre.target" "network-online.target" ];
|
||||||
|
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Type = "oneshot";
|
Type = "oneshot";
|
||||||
|
@ -110,6 +110,7 @@ in
|
|||||||
systemd.services.soju = {
|
systemd.services.soju = {
|
||||||
description = "soju IRC bouncer";
|
description = "soju IRC bouncer";
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network-online.target" ];
|
after = [ "network-online.target" ];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
DynamicUser = true;
|
DynamicUser = true;
|
||||||
|
@ -55,6 +55,7 @@ in {
|
|||||||
systemd.services.strongswan-swanctl = {
|
systemd.services.strongswan-swanctl = {
|
||||||
description = "strongSwan IPsec IKEv1/IKEv2 daemon using swanctl";
|
description = "strongSwan IPsec IKEv1/IKEv2 daemon using swanctl";
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network-online.target" ];
|
after = [ "network-online.target" ];
|
||||||
path = with pkgs; [ kmod iproute2 iptables util-linux ];
|
path = with pkgs; [ kmod iproute2 iptables util-linux ];
|
||||||
environment = {
|
environment = {
|
||||||
|
@ -153,6 +153,7 @@ in
|
|||||||
description = "strongSwan IPSec Service";
|
description = "strongSwan IPSec Service";
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
path = with pkgs; [ kmod iproute2 iptables util-linux ]; # XXX Linux
|
path = with pkgs; [ kmod iproute2 iptables util-linux ]; # XXX Linux
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network-online.target" ];
|
after = [ "network-online.target" ];
|
||||||
environment = {
|
environment = {
|
||||||
STRONGSWAN_CONF = strongswanConf { inherit setup connections ca secretsFile managePlugins enabledPlugins; };
|
STRONGSWAN_CONF = strongswanConf { inherit setup connections ca secretsFile managePlugins enabledPlugins; };
|
||||||
|
@ -107,6 +107,7 @@ in
|
|||||||
systemd.services.syncplay = {
|
systemd.services.syncplay = {
|
||||||
description = "Syncplay Service";
|
description = "Syncplay Service";
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network-online.target" ];
|
after = [ "network-online.target" ];
|
||||||
|
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
|
@ -119,6 +119,7 @@ in {
|
|||||||
systemd.services.wasabibackend = {
|
systemd.services.wasabibackend = {
|
||||||
description = "wasabibackend server";
|
description = "wasabibackend server";
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network-online.target" ];
|
after = [ "network-online.target" ];
|
||||||
environment = {
|
environment = {
|
||||||
DOTNET_PRINT_TELEMETRY_MESSAGE = "false";
|
DOTNET_PRINT_TELEMETRY_MESSAGE = "false";
|
||||||
|
@ -243,6 +243,7 @@ in
|
|||||||
systemd.services.znc = {
|
systemd.services.znc = {
|
||||||
description = "ZNC Server";
|
description = "ZNC Server";
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network-online.target" ];
|
after = [ "network-online.target" ];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
User = cfg.user;
|
User = cfg.user;
|
||||||
|
@ -182,6 +182,7 @@ in
|
|||||||
systemd.services.certmgr = {
|
systemd.services.certmgr = {
|
||||||
description = "certmgr";
|
description = "certmgr";
|
||||||
path = mkIf (cfg.svcManager == "command") [ pkgs.bash ];
|
path = mkIf (cfg.svcManager == "command") [ pkgs.bash ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network-online.target" ];
|
after = [ "network-online.target" ];
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
inherit preStart;
|
inherit preStart;
|
||||||
|
@ -572,6 +572,7 @@ in
|
|||||||
description = "OAuth2 Proxy";
|
description = "OAuth2 Proxy";
|
||||||
path = [ cfg.package ];
|
path = [ cfg.package ];
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network-online.target" ];
|
after = [ "network-online.target" ];
|
||||||
|
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
|
@ -49,6 +49,7 @@ in {
|
|||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
systemd.services.cachix-agent = {
|
systemd.services.cachix-agent = {
|
||||||
description = "Cachix Deploy Agent";
|
description = "Cachix Deploy Agent";
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = ["network-online.target"];
|
after = ["network-online.target"];
|
||||||
path = [ config.nix.package ];
|
path = [ config.nix.package ];
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
@ -61,6 +61,7 @@ in
|
|||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
systemd.services.cachix-watch-store-agent = {
|
systemd.services.cachix-watch-store-agent = {
|
||||||
description = "Cachix watch store Agent";
|
description = "Cachix watch store Agent";
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network-online.target" ];
|
after = [ "network-online.target" ];
|
||||||
path = [ config.nix.package ];
|
path = [ config.nix.package ];
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
@ -94,6 +94,7 @@ in
|
|||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
systemd.services.go2rtc = {
|
systemd.services.go2rtc = {
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [
|
after = [
|
||||||
"network-online.target"
|
"network-online.target"
|
||||||
];
|
];
|
||||||
|
@ -974,7 +974,7 @@ in {
|
|||||||
# This service depends on network-online.target and is sequenced after
|
# This service depends on network-online.target and is sequenced after
|
||||||
# it because it requires access to the Internet to function properly.
|
# it because it requires access to the Internet to function properly.
|
||||||
bindsTo = [ "akkoma-config.service" ];
|
bindsTo = [ "akkoma-config.service" ];
|
||||||
wants = [ "network-online.service" ];
|
wants = [ "network-online.target" ];
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
after = [
|
after = [
|
||||||
"akkoma-config.target"
|
"akkoma-config.target"
|
||||||
|
@ -94,6 +94,7 @@ in {
|
|||||||
description = "alps is a simple and extensible webmail.";
|
description = "alps is a simple and extensible webmail.";
|
||||||
documentation = [ "https://git.sr.ht/~migadu/alps" ];
|
documentation = [ "https://git.sr.ht/~migadu/alps" ];
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network.target" "network-online.target" ];
|
after = [ "network.target" "network-online.target" ];
|
||||||
|
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
|
@ -80,6 +80,7 @@ in {
|
|||||||
description = "c2FmZQ-server";
|
description = "c2FmZQ-server";
|
||||||
documentation = [ "https://github.com/c2FmZQ/c2FmZQ/blob/main/README.md" ];
|
documentation = [ "https://github.com/c2FmZQ/c2FmZQ/blob/main/README.md" ];
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network.target" "network-online.target" ];
|
after = [ "network.target" "network-online.target" ];
|
||||||
|
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
|
@ -205,6 +205,7 @@ in {
|
|||||||
systemd.services.code-server = {
|
systemd.services.code-server = {
|
||||||
description = "Code server";
|
description = "Code server";
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network-online.target" ];
|
after = [ "network-online.target" ];
|
||||||
path = cfg.extraPackages;
|
path = cfg.extraPackages;
|
||||||
environment = {
|
environment = {
|
||||||
|
@ -176,6 +176,7 @@ in
|
|||||||
systemd.targets.healthchecks = {
|
systemd.targets.healthchecks = {
|
||||||
description = "Target for all Healthchecks services";
|
description = "Target for all Healthchecks services";
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network.target" "network-online.target" ];
|
after = [ "network.target" "network-online.target" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -267,6 +267,7 @@ in {
|
|||||||
systemd.targets.netbox = {
|
systemd.targets.netbox = {
|
||||||
description = "Target for all NetBox services";
|
description = "Target for all NetBox services";
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network-online.target" "redis-netbox.service" ];
|
after = [ "network-online.target" "redis-netbox.service" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -159,6 +159,7 @@ in
|
|||||||
systemd.services.openvscode-server = {
|
systemd.services.openvscode-server = {
|
||||||
description = "OpenVSCode server";
|
description = "OpenVSCode server";
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network-online.target" ];
|
after = [ "network-online.target" ];
|
||||||
path = cfg.extraPackages;
|
path = cfg.extraPackages;
|
||||||
environment = cfg.extraEnvironment;
|
environment = cfg.extraEnvironment;
|
||||||
|
@ -196,6 +196,7 @@ in {
|
|||||||
systemd.targets.peering-manager = {
|
systemd.targets.peering-manager = {
|
||||||
description = "Target for all Peering Manager services";
|
description = "Target for all Peering Manager services";
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network-online.target" "redis-peering-manager.service" ];
|
after = [ "network-online.target" "redis-peering-manager.service" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
108
nixos/modules/services/web-apps/suwayomi-server.md
Normal file
108
nixos/modules/services/web-apps/suwayomi-server.md
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
# Suwayomi-Server {#module-services-suwayomi-server}
|
||||||
|
|
||||||
|
A free and open source manga reader server that runs extensions built for Tachiyomi.
|
||||||
|
|
||||||
|
## Basic usage {#module-services-suwayomi-server-basic-usage}
|
||||||
|
|
||||||
|
By default, the module will execute Suwayomi-Server backend and web UI:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{ ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
services.suwayomi-server = {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
It runs in the systemd service named `suwayomi-server` in the data directory `/var/lib/suwayomi-server`.
|
||||||
|
|
||||||
|
You can change the default parameters with some other parameters:
|
||||||
|
```nix
|
||||||
|
{ ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
services.suwayomi-server = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
dataDir = "/var/lib/suwayomi"; # Default is "/var/lib/suwayomi-server"
|
||||||
|
openFirewall = true;
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
server.port = 4567;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
If you want to create a desktop icon, you can activate the system tray option:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{ ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
services.suwayomi-server = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
dataDir = "/var/lib/suwayomi"; # Default is "/var/lib/suwayomi-server"
|
||||||
|
openFirewall = true;
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
server.port = 4567;
|
||||||
|
server.enableSystemTray = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Basic authentication {#module-services-suwayomi-server-basic-auth}
|
||||||
|
|
||||||
|
You can configure a basic authentication to the web interface with:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{ ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
services.suwayomi-server = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
openFirewall = true;
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
server.port = 4567;
|
||||||
|
server = {
|
||||||
|
basicAuthEnabled = true;
|
||||||
|
basicAuthUsername = "username";
|
||||||
|
|
||||||
|
# NOTE: this is not a real upstream option
|
||||||
|
basicAuthPasswordFile = ./path/to/the/password/file;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Extra configuration {#module-services-suwayomi-server-extra-config}
|
||||||
|
|
||||||
|
Not all the configuration options are available directly in this module, but you can add the other options of suwayomi-server with:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{ ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
services.suwayomi-server = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
openFirewall = true;
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
server = {
|
||||||
|
port = 4567;
|
||||||
|
autoDownloadNewChapters = false;
|
||||||
|
maxSourcesInParallel" = 6;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
260
nixos/modules/services/web-apps/suwayomi-server.nix
Normal file
260
nixos/modules/services/web-apps/suwayomi-server.nix
Normal file
@ -0,0 +1,260 @@
|
|||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.suwayomi-server;
|
||||||
|
inherit (lib) mkOption mdDoc mkEnableOption mkIf types;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
services.suwayomi-server = {
|
||||||
|
enable = mkEnableOption (mdDoc "Suwayomi, a free and open source manga reader server that runs extensions built for Tachiyomi.");
|
||||||
|
|
||||||
|
package = lib.mkPackageOptionMD pkgs "suwayomi-server" { };
|
||||||
|
|
||||||
|
dataDir = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
default = "/var/lib/suwayomi-server";
|
||||||
|
example = "/var/data/mangas";
|
||||||
|
description = mdDoc ''
|
||||||
|
The path to the data directory in which Suwayomi-Server will download scans.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
user = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "suwayomi";
|
||||||
|
example = "root";
|
||||||
|
description = mdDoc ''
|
||||||
|
User account under which Suwayomi-Server runs.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
group = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "suwayomi";
|
||||||
|
example = "medias";
|
||||||
|
description = mdDoc ''
|
||||||
|
Group under which Suwayomi-Server runs.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
openFirewall = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = mdDoc ''
|
||||||
|
Whether to open the firewall for the port in {option}`services.suwayomi-server.settings.server.port`.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
settings = mkOption {
|
||||||
|
type = types.submodule {
|
||||||
|
freeformType =
|
||||||
|
let
|
||||||
|
recursiveAttrsType = with types; attrsOf (nullOr (oneOf [
|
||||||
|
str
|
||||||
|
path
|
||||||
|
int
|
||||||
|
float
|
||||||
|
bool
|
||||||
|
(listOf str)
|
||||||
|
(recursiveAttrsType // { description = "instances of this type recursively"; })
|
||||||
|
]));
|
||||||
|
in
|
||||||
|
recursiveAttrsType;
|
||||||
|
options = {
|
||||||
|
server = {
|
||||||
|
ip = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "0.0.0.0";
|
||||||
|
example = "127.0.0.1";
|
||||||
|
description = mdDoc ''
|
||||||
|
The ip that Suwayomi will bind to.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
port = mkOption {
|
||||||
|
type = types.port;
|
||||||
|
default = 8080;
|
||||||
|
example = 4567;
|
||||||
|
description = mdDoc ''
|
||||||
|
The port that Suwayomi will listen to.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
basicAuthEnabled = mkEnableOption (mdDoc ''
|
||||||
|
Add basic access authentication to Suwayomi-Server.
|
||||||
|
Enabling this option is useful when hosting on a public network/the Internet
|
||||||
|
'');
|
||||||
|
|
||||||
|
basicAuthUsername = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
description = mdDoc ''
|
||||||
|
The username value that you have to provide when authenticating.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
# NOTE: this is not a real upstream option
|
||||||
|
basicAuthPasswordFile = mkOption {
|
||||||
|
type = types.nullOr types.path;
|
||||||
|
default = null;
|
||||||
|
example = "/var/secrets/suwayomi-server-password";
|
||||||
|
description = mdDoc ''
|
||||||
|
The password file containing the value that you have to provide when authenticating.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
downloadAsCbz = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = mdDoc ''
|
||||||
|
Download chapters as `.cbz` files.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
localSourcePath = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
default = cfg.dataDir;
|
||||||
|
defaultText = lib.literalExpression "suwayomi-server.dataDir";
|
||||||
|
example = "/var/data/local_mangas";
|
||||||
|
description = mdDoc ''
|
||||||
|
Path to the local source folder.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
systemTrayEnabled = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = mdDoc ''
|
||||||
|
Whether to enable a system tray icon, if possible.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
description = mdDoc ''
|
||||||
|
Configuration to write to {file}`server.conf`.
|
||||||
|
See <https://github.com/Suwayomi/Suwayomi-Server/wiki/Configuring-Suwayomi-Server> for more information.
|
||||||
|
'';
|
||||||
|
default = { };
|
||||||
|
example = {
|
||||||
|
server.socksProxyEnabled = true;
|
||||||
|
server.socksProxyHost = "yourproxyhost.com";
|
||||||
|
server.socksProxyPort = "8080";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
|
||||||
|
assertions = [{
|
||||||
|
assertion = with cfg.settings.server; basicAuthEnabled -> (basicAuthUsername != null && basicAuthPasswordFile != null);
|
||||||
|
message = ''
|
||||||
|
[suwayomi-server]: the username and the password file cannot be null when the basic auth is enabled
|
||||||
|
'';
|
||||||
|
}];
|
||||||
|
|
||||||
|
networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ cfg.settings.server.port ];
|
||||||
|
|
||||||
|
users.groups = mkIf (cfg.group == "suwayomi") {
|
||||||
|
suwayomi = { };
|
||||||
|
};
|
||||||
|
|
||||||
|
users.users = mkIf (cfg.user == "suwayomi") {
|
||||||
|
suwayomi = {
|
||||||
|
group = cfg.group;
|
||||||
|
# Need to set the user home because the package writes to ~/.local/Tachidesk
|
||||||
|
home = cfg.dataDir;
|
||||||
|
description = "Suwayomi Daemon user";
|
||||||
|
isSystemUser = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.tmpfiles.settings."10-suwayomi-server" = {
|
||||||
|
"${cfg.dataDir}/.local/share/Tachidesk".d = {
|
||||||
|
mode = "0700";
|
||||||
|
inherit (cfg) user group;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.suwayomi-server =
|
||||||
|
let
|
||||||
|
flattenConfig = prefix: config:
|
||||||
|
lib.foldl'
|
||||||
|
lib.mergeAttrs
|
||||||
|
{ }
|
||||||
|
(lib.attrValues
|
||||||
|
(lib.mapAttrs
|
||||||
|
(k: v:
|
||||||
|
if !(lib.isAttrs v)
|
||||||
|
then { "${prefix}${k}" = v; }
|
||||||
|
else flattenConfig "${prefix}${k}." v
|
||||||
|
)
|
||||||
|
config
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
# HOCON is a JSON superset that suwayomi-server use for configuration
|
||||||
|
toHOCON = attr:
|
||||||
|
let
|
||||||
|
attrType = builtins.typeOf attr;
|
||||||
|
in
|
||||||
|
if builtins.elem attrType [ "string" "path" "int" "float" ]
|
||||||
|
then ''"${toString attr}"''
|
||||||
|
else if attrType == "bool"
|
||||||
|
then lib.boolToString attr
|
||||||
|
else if attrType == "list"
|
||||||
|
then "[\n${lib.concatMapStringsSep ",\n" toHOCON attr}\n]"
|
||||||
|
else # attrs, lambda, null
|
||||||
|
throw ''
|
||||||
|
[suwayomi-server]: invalid config value type '${attrType}'.
|
||||||
|
'';
|
||||||
|
|
||||||
|
configFile = pkgs.writeText "server.conf" (lib.pipe cfg.settings [
|
||||||
|
(settings: lib.recursiveUpdate settings {
|
||||||
|
server.basicAuthPasswordFile = null;
|
||||||
|
server.basicAuthPassword =
|
||||||
|
if settings.server.basicAuthEnabled
|
||||||
|
then "$TACHIDESK_SERVER_BASIC_AUTH_PASSWORD"
|
||||||
|
else null;
|
||||||
|
})
|
||||||
|
(flattenConfig "")
|
||||||
|
(lib.filterAttrs (_: x: x != null))
|
||||||
|
(lib.mapAttrsToList (name: value: ''${name} = ${toHOCON value}''))
|
||||||
|
lib.concatLines
|
||||||
|
]);
|
||||||
|
|
||||||
|
in
|
||||||
|
{
|
||||||
|
description = "A free and open source manga reader server that runs extensions built for Tachiyomi.";
|
||||||
|
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
|
after = [ "network-online.target" ];
|
||||||
|
|
||||||
|
script = ''
|
||||||
|
${lib.optionalString cfg.settings.server.basicAuthEnabled ''
|
||||||
|
export TACHIDESK_SERVER_BASIC_AUTH_PASSWORD="$(<${cfg.settings.server.basicAuthPasswordFile})"
|
||||||
|
''}
|
||||||
|
${lib.getExe pkgs.envsubst} -i ${configFile} -o ${cfg.dataDir}/.local/share/Tachidesk/server.conf
|
||||||
|
${lib.getExe cfg.package} -Dsuwayomi.tachidesk.config.server.rootDir=${cfg.dataDir}
|
||||||
|
'';
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
User = cfg.user;
|
||||||
|
Group = cfg.group;
|
||||||
|
|
||||||
|
Type = "simple";
|
||||||
|
Restart = "on-failure";
|
||||||
|
|
||||||
|
StateDirectory = mkIf (cfg.dataDir == "/var/lib/suwayomi-server") "suwayomi-server";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
maintainers = with lib.maintainers; [ ratcornu ];
|
||||||
|
doc = ./suwayomi-server.md;
|
||||||
|
};
|
||||||
|
}
|
@ -174,22 +174,22 @@ let
|
|||||||
List of path(s) to respective language(s) which are copied from the 'languages' directory.
|
List of path(s) to respective language(s) which are copied from the 'languages' directory.
|
||||||
'';
|
'';
|
||||||
example = literalExpression ''
|
example = literalExpression ''
|
||||||
[(
|
[
|
||||||
# Let's package the German language.
|
# Let's package the German language.
|
||||||
# For other languages try to replace language and country code in the download URL with your desired one.
|
# For other languages try to replace language and country code in the download URL with your desired one.
|
||||||
# Reference https://translate.wordpress.org for available translations and
|
# Reference https://translate.wordpress.org for available translations and
|
||||||
# codes.
|
# codes.
|
||||||
language-de = pkgs.stdenv.mkDerivation {
|
(pkgs.stdenv.mkDerivation {
|
||||||
name = "language-de";
|
name = "language-de";
|
||||||
src = pkgs.fetchurl {
|
src = pkgs.fetchurl {
|
||||||
url = "https://de.wordpress.org/wordpress-''${pkgs.wordpress.version}-de_DE.tar.gz";
|
url = "https://de.wordpress.org/wordpress-''${pkgs.wordpress.version}-de_DE.tar.gz";
|
||||||
# Name is required to invalidate the hash when wordpress is updated
|
# Name is required to invalidate the hash when wordpress is updated
|
||||||
name = "wordpress-''${pkgs.wordpress.version}-language-de"
|
name = "wordpress-''${pkgs.wordpress.version}-language-de";
|
||||||
sha256 = "sha256-dlas0rXTSV4JAl8f/UyMbig57yURRYRhTMtJwF9g8h0=";
|
sha256 = "sha256-dlas0rXTSV4JAl8f/UyMbig57yURRYRhTMtJwF9g8h0=";
|
||||||
};
|
};
|
||||||
installPhase = "mkdir -p $out; cp -r ./wp-content/languages/* $out/";
|
installPhase = "mkdir -p $out; cp -r ./wp-content/languages/* $out/";
|
||||||
};
|
})
|
||||||
)];
|
];
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -71,6 +71,7 @@ in
|
|||||||
systemd.services.agate = {
|
systemd.services.agate = {
|
||||||
description = "Agate";
|
description = "Agate";
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network.target" "network-online.target" ];
|
after = [ "network.target" "network-online.target" ];
|
||||||
|
|
||||||
script =
|
script =
|
||||||
|
@ -101,6 +101,7 @@ in {
|
|||||||
];
|
];
|
||||||
systemd.services.mighttpd2 = {
|
systemd.services.mighttpd2 = {
|
||||||
description = "Mighttpd2 web server";
|
description = "Mighttpd2 web server";
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network-online.target" ];
|
after = [ "network-online.target" ];
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
|
@ -98,6 +98,7 @@ in
|
|||||||
|
|
||||||
services.minio = {
|
services.minio = {
|
||||||
description = "Minio Object Storage";
|
description = "Minio Object Storage";
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network-online.target" ];
|
after = [ "network-online.target" ];
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
|
@ -144,6 +144,7 @@ in {
|
|||||||
|
|
||||||
systemd.services.traefik = {
|
systemd.services.traefik = {
|
||||||
description = "Traefik web server";
|
description = "Traefik web server";
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network-online.target" ];
|
after = [ "network-online.target" ];
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
startLimitIntervalSec = 86400;
|
startLimitIntervalSec = 86400;
|
||||||
|
@ -15,6 +15,19 @@ import json
|
|||||||
from typing import NamedTuple, Dict, List
|
from typing import NamedTuple, Dict, List
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
# These values will be replaced with actual values during the package build
|
||||||
|
EFI_SYS_MOUNT_POINT = "@efiSysMountPoint@"
|
||||||
|
TIMEOUT = "@timeout@"
|
||||||
|
EDITOR = bool("@editor@")
|
||||||
|
CONSOLE_MODE = "@consoleMode@"
|
||||||
|
BOOTSPEC_TOOLS = "@bootspecTools@"
|
||||||
|
DISTRO_NAME = "@distroName@"
|
||||||
|
NIX = "@nix@"
|
||||||
|
SYSTEMD = "@systemd@"
|
||||||
|
CONFIGURATION_LIMIT = int("@configurationLimit@")
|
||||||
|
CAN_TOUCH_EFI_VARIABLES = "@canTouchEfiVariables@"
|
||||||
|
GRACEFUL = "@graceful@"
|
||||||
|
COPY_EXTRA_FILES = "@copyExtraFiles@"
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class BootSpec:
|
class BootSpec:
|
||||||
@ -29,7 +42,6 @@ class BootSpec:
|
|||||||
initrdSecrets: str | None = None
|
initrdSecrets: str | None = None
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
libc = ctypes.CDLL("libc.so.6")
|
libc = ctypes.CDLL("libc.so.6")
|
||||||
|
|
||||||
class SystemIdentifier(NamedTuple):
|
class SystemIdentifier(NamedTuple):
|
||||||
@ -75,16 +87,16 @@ def generation_conf_filename(profile: str | None, generation: int, specialisatio
|
|||||||
|
|
||||||
|
|
||||||
def write_loader_conf(profile: str | None, generation: int, specialisation: str | None) -> None:
|
def write_loader_conf(profile: str | None, generation: int, specialisation: str | None) -> None:
|
||||||
with open("@efiSysMountPoint@/loader/loader.conf.tmp", 'w') as f:
|
with open(f"{EFI_SYS_MOUNT_POINT}/loader/loader.conf.tmp", 'w') as f:
|
||||||
if "@timeout@" != "":
|
if TIMEOUT != "":
|
||||||
f.write("timeout @timeout@\n")
|
f.write(f"timeout {TIMEOUT}\n")
|
||||||
f.write("default %s\n" % generation_conf_filename(profile, generation, specialisation))
|
f.write("default %s\n" % generation_conf_filename(profile, generation, specialisation))
|
||||||
if not @editor@:
|
if not EDITOR:
|
||||||
f.write("editor 0\n")
|
f.write("editor 0\n")
|
||||||
f.write("console-mode @consoleMode@\n")
|
f.write(f"console-mode {CONSOLE_MODE}\n")
|
||||||
f.flush()
|
f.flush()
|
||||||
os.fsync(f.fileno())
|
os.fsync(f.fileno())
|
||||||
os.rename("@efiSysMountPoint@/loader/loader.conf.tmp", "@efiSysMountPoint@/loader/loader.conf")
|
os.rename(f"{EFI_SYS_MOUNT_POINT}/loader/loader.conf.tmp", f"{EFI_SYS_MOUNT_POINT}/loader/loader.conf")
|
||||||
|
|
||||||
|
|
||||||
def get_bootspec(profile: str | None, generation: int) -> BootSpec:
|
def get_bootspec(profile: str | None, generation: int) -> BootSpec:
|
||||||
@ -95,7 +107,7 @@ def get_bootspec(profile: str | None, generation: int) -> BootSpec:
|
|||||||
bootspec_json = json.load(boot_json_f)
|
bootspec_json = json.load(boot_json_f)
|
||||||
else:
|
else:
|
||||||
boot_json_str = subprocess.check_output([
|
boot_json_str = subprocess.check_output([
|
||||||
"@bootspecTools@/bin/synthesize",
|
f"{BOOTSPEC_TOOLS}/bin/synthesize",
|
||||||
"--version",
|
"--version",
|
||||||
"1",
|
"1",
|
||||||
system_directory,
|
system_directory,
|
||||||
@ -116,7 +128,7 @@ def copy_from_file(file: str, dry_run: bool = False) -> str:
|
|||||||
store_dir = os.path.basename(os.path.dirname(store_file_path))
|
store_dir = os.path.basename(os.path.dirname(store_file_path))
|
||||||
efi_file_path = "/efi/nixos/%s-%s.efi" % (store_dir, suffix)
|
efi_file_path = "/efi/nixos/%s-%s.efi" % (store_dir, suffix)
|
||||||
if not dry_run:
|
if not dry_run:
|
||||||
copy_if_not_exists(store_file_path, "@efiSysMountPoint@%s" % (efi_file_path))
|
copy_if_not_exists(store_file_path, f"{EFI_SYS_MOUNT_POINT}%s" % (efi_file_path))
|
||||||
return efi_file_path
|
return efi_file_path
|
||||||
|
|
||||||
def write_entry(profile: str | None, generation: int, specialisation: str | None,
|
def write_entry(profile: str | None, generation: int, specialisation: str | None,
|
||||||
@ -126,13 +138,14 @@ def write_entry(profile: str | None, generation: int, specialisation: str | None
|
|||||||
kernel = copy_from_file(bootspec.kernel)
|
kernel = copy_from_file(bootspec.kernel)
|
||||||
initrd = copy_from_file(bootspec.initrd)
|
initrd = copy_from_file(bootspec.initrd)
|
||||||
|
|
||||||
title = "@distroName@{profile}{specialisation}".format(
|
title = "{name}{profile}{specialisation}".format(
|
||||||
|
name=DISTRO_NAME,
|
||||||
profile=" [" + profile + "]" if profile else "",
|
profile=" [" + profile + "]" if profile else "",
|
||||||
specialisation=" (%s)" % specialisation if specialisation else "")
|
specialisation=" (%s)" % specialisation if specialisation else "")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if bootspec.initrdSecrets is not None:
|
if bootspec.initrdSecrets is not None:
|
||||||
subprocess.check_call([bootspec.initrdSecrets, "@efiSysMountPoint@%s" % (initrd)])
|
subprocess.check_call([bootspec.initrdSecrets, f"{EFI_SYS_MOUNT_POINT}%s" % (initrd)])
|
||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
if current:
|
if current:
|
||||||
print("failed to create initrd secrets!", file=sys.stderr)
|
print("failed to create initrd secrets!", file=sys.stderr)
|
||||||
@ -142,7 +155,7 @@ def write_entry(profile: str | None, generation: int, specialisation: str | None
|
|||||||
f'for "{title} - Configuration {generation}", an older generation', file=sys.stderr)
|
f'for "{title} - Configuration {generation}", an older generation', file=sys.stderr)
|
||||||
print("note: this is normal after having removed "
|
print("note: this is normal after having removed "
|
||||||
"or renamed a file in `boot.initrd.secrets`", file=sys.stderr)
|
"or renamed a file in `boot.initrd.secrets`", file=sys.stderr)
|
||||||
entry_file = "@efiSysMountPoint@/loader/entries/%s" % (
|
entry_file = f"{EFI_SYS_MOUNT_POINT}/loader/entries/%s" % (
|
||||||
generation_conf_filename(profile, generation, specialisation))
|
generation_conf_filename(profile, generation, specialisation))
|
||||||
tmp_path = "%s.tmp" % (entry_file)
|
tmp_path = "%s.tmp" % (entry_file)
|
||||||
kernel_params = "init=%s " % bootspec.init
|
kernel_params = "init=%s " % bootspec.init
|
||||||
@ -167,7 +180,7 @@ def write_entry(profile: str | None, generation: int, specialisation: str | None
|
|||||||
|
|
||||||
def get_generations(profile: str | None = None) -> list[SystemIdentifier]:
|
def get_generations(profile: str | None = None) -> list[SystemIdentifier]:
|
||||||
gen_list = subprocess.check_output([
|
gen_list = subprocess.check_output([
|
||||||
"@nix@/bin/nix-env",
|
f"{NIX}/bin/nix-env",
|
||||||
"--list-generations",
|
"--list-generations",
|
||||||
"-p",
|
"-p",
|
||||||
"/nix/var/nix/profiles/%s" % ("system-profiles/" + profile if profile else "system"),
|
"/nix/var/nix/profiles/%s" % ("system-profiles/" + profile if profile else "system"),
|
||||||
@ -176,7 +189,7 @@ def get_generations(profile: str | None = None) -> list[SystemIdentifier]:
|
|||||||
gen_lines = gen_list.split('\n')
|
gen_lines = gen_list.split('\n')
|
||||||
gen_lines.pop()
|
gen_lines.pop()
|
||||||
|
|
||||||
configurationLimit = @configurationLimit@
|
configurationLimit = CONFIGURATION_LIMIT
|
||||||
configurations = [
|
configurations = [
|
||||||
SystemIdentifier(
|
SystemIdentifier(
|
||||||
profile=profile,
|
profile=profile,
|
||||||
@ -189,14 +202,14 @@ def get_generations(profile: str | None = None) -> list[SystemIdentifier]:
|
|||||||
|
|
||||||
|
|
||||||
def remove_old_entries(gens: list[SystemIdentifier]) -> None:
|
def remove_old_entries(gens: list[SystemIdentifier]) -> None:
|
||||||
rex_profile = re.compile(r"^@efiSysMountPoint@/loader/entries/nixos-(.*)-generation-.*\.conf$")
|
rex_profile = re.compile(r"^" + re.escape(EFI_SYS_MOUNT_POINT) + "/loader/entries/nixos-(.*)-generation-.*\.conf$")
|
||||||
rex_generation = re.compile(r"^@efiSysMountPoint@/loader/entries/nixos.*-generation-([0-9]+)(-specialisation-.*)?\.conf$")
|
rex_generation = re.compile(r"^" + re.escape(EFI_SYS_MOUNT_POINT) + "/loader/entries/nixos.*-generation-([0-9]+)(-specialisation-.*)?\.conf$")
|
||||||
known_paths = []
|
known_paths = []
|
||||||
for gen in gens:
|
for gen in gens:
|
||||||
bootspec = get_bootspec(gen.profile, gen.generation)
|
bootspec = get_bootspec(gen.profile, gen.generation)
|
||||||
known_paths.append(copy_from_file(bootspec.kernel, True))
|
known_paths.append(copy_from_file(bootspec.kernel, True))
|
||||||
known_paths.append(copy_from_file(bootspec.initrd, True))
|
known_paths.append(copy_from_file(bootspec.initrd, True))
|
||||||
for path in glob.iglob("@efiSysMountPoint@/loader/entries/nixos*-generation-[1-9]*.conf"):
|
for path in glob.iglob(f"{EFI_SYS_MOUNT_POINT}/loader/entries/nixos*-generation-[1-9]*.conf"):
|
||||||
if rex_profile.match(path):
|
if rex_profile.match(path):
|
||||||
prof = rex_profile.sub(r"\1", path)
|
prof = rex_profile.sub(r"\1", path)
|
||||||
else:
|
else:
|
||||||
@ -207,7 +220,7 @@ def remove_old_entries(gens: list[SystemIdentifier]) -> None:
|
|||||||
continue
|
continue
|
||||||
if not (prof, gen_number, None) in gens:
|
if not (prof, gen_number, None) in gens:
|
||||||
os.unlink(path)
|
os.unlink(path)
|
||||||
for path in glob.iglob("@efiSysMountPoint@/efi/nixos/*"):
|
for path in glob.iglob(f"{EFI_SYS_MOUNT_POINT}/efi/nixos/*"):
|
||||||
if not path in known_paths and not os.path.isdir(path):
|
if not path in known_paths and not os.path.isdir(path):
|
||||||
os.unlink(path)
|
os.unlink(path)
|
||||||
|
|
||||||
@ -230,7 +243,7 @@ def install_bootloader(args: argparse.Namespace) -> None:
|
|||||||
# Since systemd version 232 a machine ID is required and it might not
|
# Since systemd version 232 a machine ID is required and it might not
|
||||||
# be there on newly installed systems, so let's generate one so that
|
# be there on newly installed systems, so let's generate one so that
|
||||||
# bootctl can find it and we can also pass it to write_entry() later.
|
# bootctl can find it and we can also pass it to write_entry() later.
|
||||||
cmd = ["@systemd@/bin/systemd-machine-id-setup", "--print"]
|
cmd = [f"{SYSTEMD}/bin/systemd-machine-id-setup", "--print"]
|
||||||
machine_id = subprocess.run(
|
machine_id = subprocess.run(
|
||||||
cmd, text=True, check=True, stdout=subprocess.PIPE
|
cmd, text=True, check=True, stdout=subprocess.PIPE
|
||||||
).stdout.rstrip()
|
).stdout.rstrip()
|
||||||
@ -242,22 +255,22 @@ def install_bootloader(args: argparse.Namespace) -> None:
|
|||||||
# flags to pass to bootctl install/update
|
# flags to pass to bootctl install/update
|
||||||
bootctl_flags = []
|
bootctl_flags = []
|
||||||
|
|
||||||
if "@canTouchEfiVariables@" != "1":
|
if CAN_TOUCH_EFI_VARIABLES != "1":
|
||||||
bootctl_flags.append("--no-variables")
|
bootctl_flags.append("--no-variables")
|
||||||
|
|
||||||
if "@graceful@" == "1":
|
if GRACEFUL == "1":
|
||||||
bootctl_flags.append("--graceful")
|
bootctl_flags.append("--graceful")
|
||||||
|
|
||||||
if os.getenv("NIXOS_INSTALL_BOOTLOADER") == "1":
|
if os.getenv("NIXOS_INSTALL_BOOTLOADER") == "1":
|
||||||
# bootctl uses fopen() with modes "wxe" and fails if the file exists.
|
# bootctl uses fopen() with modes "wxe" and fails if the file exists.
|
||||||
if os.path.exists("@efiSysMountPoint@/loader/loader.conf"):
|
if os.path.exists(f"{EFI_SYS_MOUNT_POINT}/loader/loader.conf"):
|
||||||
os.unlink("@efiSysMountPoint@/loader/loader.conf")
|
os.unlink(f"{EFI_SYS_MOUNT_POINT}/loader/loader.conf")
|
||||||
|
|
||||||
subprocess.check_call(["@systemd@/bin/bootctl", "--esp-path=@efiSysMountPoint@"] + bootctl_flags + ["install"])
|
subprocess.check_call([f"{SYSTEMD}/bin/bootctl", f"--esp-path={EFI_SYS_MOUNT_POINT}"] + bootctl_flags + ["install"])
|
||||||
else:
|
else:
|
||||||
# Update bootloader to latest if needed
|
# Update bootloader to latest if needed
|
||||||
available_out = subprocess.check_output(["@systemd@/bin/bootctl", "--version"], universal_newlines=True).split()[2]
|
available_out = subprocess.check_output([f"{SYSTEMD}/bin/bootctl", "--version"], universal_newlines=True).split()[2]
|
||||||
installed_out = subprocess.check_output(["@systemd@/bin/bootctl", "--esp-path=@efiSysMountPoint@", "status"], universal_newlines=True)
|
installed_out = subprocess.check_output([f"{SYSTEMD}/bin/bootctl", f"--esp-path={EFI_SYS_MOUNT_POINT}", "status"], universal_newlines=True)
|
||||||
|
|
||||||
# See status_binaries() in systemd bootctl.c for code which generates this
|
# See status_binaries() in systemd bootctl.c for code which generates this
|
||||||
installed_match = re.search(r"^\W+File:.*/EFI/(?:BOOT|systemd)/.*\.efi \(systemd-boot ([\d.]+[^)]*)\)$",
|
installed_match = re.search(r"^\W+File:.*/EFI/(?:BOOT|systemd)/.*\.efi \(systemd-boot ([\d.]+[^)]*)\)$",
|
||||||
@ -276,10 +289,10 @@ def install_bootloader(args: argparse.Namespace) -> None:
|
|||||||
|
|
||||||
if installed_version < available_version:
|
if installed_version < available_version:
|
||||||
print("updating systemd-boot from %s to %s" % (installed_version, available_version))
|
print("updating systemd-boot from %s to %s" % (installed_version, available_version))
|
||||||
subprocess.check_call(["@systemd@/bin/bootctl", "--esp-path=@efiSysMountPoint@"] + bootctl_flags + ["update"])
|
subprocess.check_call([f"{SYSTEMD}/bin/bootctl", f"--esp-path={EFI_SYS_MOUNT_POINT}"] + bootctl_flags + ["update"])
|
||||||
|
|
||||||
os.makedirs("@efiSysMountPoint@/efi/nixos", exist_ok=True)
|
os.makedirs(f"{EFI_SYS_MOUNT_POINT}/efi/nixos", exist_ok=True)
|
||||||
os.makedirs("@efiSysMountPoint@/loader/entries", exist_ok=True)
|
os.makedirs(f"{EFI_SYS_MOUNT_POINT}/loader/entries", exist_ok=True)
|
||||||
|
|
||||||
gens = get_generations()
|
gens = get_generations()
|
||||||
for profile in get_profiles():
|
for profile in get_profiles():
|
||||||
@ -302,9 +315,9 @@ def install_bootloader(args: argparse.Namespace) -> None:
|
|||||||
else:
|
else:
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
for root, _, files in os.walk('@efiSysMountPoint@/efi/nixos/.extra-files', topdown=False):
|
for root, _, files in os.walk(f"{EFI_SYS_MOUNT_POINT}/efi/nixos/.extra-files", topdown=False):
|
||||||
relative_root = root.removeprefix("@efiSysMountPoint@/efi/nixos/.extra-files").removeprefix("/")
|
relative_root = root.removeprefix(f"{EFI_SYS_MOUNT_POINT}/efi/nixos/.extra-files").removeprefix("/")
|
||||||
actual_root = os.path.join("@efiSysMountPoint@", relative_root)
|
actual_root = os.path.join(f"{EFI_SYS_MOUNT_POINT}", relative_root)
|
||||||
|
|
||||||
for file in files:
|
for file in files:
|
||||||
actual_file = os.path.join(actual_root, file)
|
actual_file = os.path.join(actual_root, file)
|
||||||
@ -317,14 +330,14 @@ def install_bootloader(args: argparse.Namespace) -> None:
|
|||||||
os.rmdir(actual_root)
|
os.rmdir(actual_root)
|
||||||
os.rmdir(root)
|
os.rmdir(root)
|
||||||
|
|
||||||
os.makedirs("@efiSysMountPoint@/efi/nixos/.extra-files", exist_ok=True)
|
os.makedirs(f"{EFI_SYS_MOUNT_POINT}/efi/nixos/.extra-files", exist_ok=True)
|
||||||
|
|
||||||
subprocess.check_call("@copyExtraFiles@")
|
subprocess.check_call(COPY_EXTRA_FILES)
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
def main() -> None:
|
||||||
parser = argparse.ArgumentParser(description='Update @distroName@-related systemd-boot files')
|
parser = argparse.ArgumentParser(description=f"Update {DISTRO_NAME}-related systemd-boot files")
|
||||||
parser.add_argument('default_config', metavar='DEFAULT-CONFIG', help='The default @distroName@ config to boot')
|
parser.add_argument('default_config', metavar='DEFAULT-CONFIG', help=f"The default {DISTRO_NAME} config to boot")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -334,9 +347,9 @@ def main() -> None:
|
|||||||
# it can leave the system in an unbootable state, when a crash/outage
|
# it can leave the system in an unbootable state, when a crash/outage
|
||||||
# happens shortly after an update. To decrease the likelihood of this
|
# happens shortly after an update. To decrease the likelihood of this
|
||||||
# event sync the efi filesystem after each update.
|
# event sync the efi filesystem after each update.
|
||||||
rc = libc.syncfs(os.open("@efiSysMountPoint@", os.O_RDONLY))
|
rc = libc.syncfs(os.open(f"{EFI_SYS_MOUNT_POINT}", os.O_RDONLY))
|
||||||
if rc != 0:
|
if rc != 0:
|
||||||
print("could not sync @efiSysMountPoint@: {}".format(os.strerror(rc)), file=sys.stderr)
|
print(f"could not sync {EFI_SYS_MOUNT_POINT}: {os.strerror(rc)}", file=sys.stderr)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
@ -81,7 +81,11 @@ in {
|
|||||||
|
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
|
|
||||||
description = lib.mdDoc "Whether to enable the systemd-boot (formerly gummiboot) EFI boot manager";
|
description = lib.mdDoc ''
|
||||||
|
Whether to enable the systemd-boot (formerly gummiboot) EFI boot manager.
|
||||||
|
For more information about systemd-boot:
|
||||||
|
https://www.freedesktop.org/wiki/Software/systemd/systemd-boot/
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
editor = mkOption {
|
editor = mkOption {
|
||||||
|
@ -451,20 +451,37 @@ in
|
|||||||
cfg.services
|
cfg.services
|
||||||
);
|
);
|
||||||
|
|
||||||
assertions = concatLists (
|
assertions = let
|
||||||
mapAttrsToList
|
mkOneAssert = typeStr: name: def: {
|
||||||
(name: service:
|
assertion = lib.elem "network-online.target" def.after -> lib.elem "network-online.target" (def.wants ++ def.requires ++ def.bindsTo);
|
||||||
map (message: {
|
message = "${name}.${typeStr} is ordered after 'network-online.target' but doesn't depend on it";
|
||||||
assertion = false;
|
};
|
||||||
inherit message;
|
mkAsserts = typeStr: lib.mapAttrsToList (mkOneAssert typeStr);
|
||||||
}) (concatLists [
|
mkMountAsserts = typeStr: map (m: mkOneAssert typeStr m.what m);
|
||||||
(optional ((builtins.elem "network-interfaces.target" service.after) || (builtins.elem "network-interfaces.target" service.wants))
|
in mkMerge [
|
||||||
"Service '${name}.service' is using the deprecated target network-interfaces.target, which no longer exists. Using network.target is recommended instead."
|
(concatLists (
|
||||||
)
|
mapAttrsToList
|
||||||
])
|
(name: service:
|
||||||
)
|
map (message: {
|
||||||
cfg.services
|
assertion = false;
|
||||||
);
|
inherit message;
|
||||||
|
}) (concatLists [
|
||||||
|
(optional ((builtins.elem "network-interfaces.target" service.after) || (builtins.elem "network-interfaces.target" service.wants))
|
||||||
|
"Service '${name}.service' is using the deprecated target network-interfaces.target, which no longer exists. Using network.target is recommended instead."
|
||||||
|
)
|
||||||
|
])
|
||||||
|
)
|
||||||
|
cfg.services
|
||||||
|
))
|
||||||
|
(mkAsserts "target" cfg.targets)
|
||||||
|
(mkAsserts "service" cfg.services)
|
||||||
|
(mkAsserts "socket" cfg.sockets)
|
||||||
|
(mkAsserts "timer" cfg.timers)
|
||||||
|
(mkAsserts "path" cfg.paths)
|
||||||
|
(mkMountAsserts "mount" cfg.mounts)
|
||||||
|
(mkMountAsserts "automount" cfg.automounts)
|
||||||
|
(mkAsserts "slice" cfg.slices)
|
||||||
|
];
|
||||||
|
|
||||||
system.build.units = cfg.units;
|
system.build.units = cfg.units;
|
||||||
|
|
||||||
@ -641,7 +658,6 @@ in
|
|||||||
systemd.services.systemd-udev-settle.restartIfChanged = false; # Causes long delays in nixos-rebuild
|
systemd.services.systemd-udev-settle.restartIfChanged = false; # Causes long delays in nixos-rebuild
|
||||||
systemd.targets.local-fs.unitConfig.X-StopOnReconfiguration = true;
|
systemd.targets.local-fs.unitConfig.X-StopOnReconfiguration = true;
|
||||||
systemd.targets.remote-fs.unitConfig.X-StopOnReconfiguration = true;
|
systemd.targets.remote-fs.unitConfig.X-StopOnReconfiguration = true;
|
||||||
systemd.targets.network-online.wantedBy = [ "multi-user.target" ];
|
|
||||||
systemd.services.systemd-importd.environment = proxy_env;
|
systemd.services.systemd-importd.environment = proxy_env;
|
||||||
systemd.services.systemd-pstore.wantedBy = [ "sysinit.target" ]; # see #81138
|
systemd.services.systemd-pstore.wantedBy = [ "sysinit.target" ]; # see #81138
|
||||||
|
|
||||||
|
@ -71,6 +71,7 @@ in
|
|||||||
|
|
||||||
systemd.services.fetch-ec2-metadata = {
|
systemd.services.fetch-ec2-metadata = {
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
after = ["network-online.target"];
|
after = ["network-online.target"];
|
||||||
path = [ pkgs.curl ];
|
path = [ pkgs.curl ];
|
||||||
script = builtins.readFile ./ec2-metadata-fetcher.sh;
|
script = builtins.readFile ./ec2-metadata-fetcher.sh;
|
||||||
|
@ -267,6 +267,7 @@ let
|
|||||||
};
|
};
|
||||||
in {
|
in {
|
||||||
wantedBy = [] ++ optional (container.autoStart) "multi-user.target";
|
wantedBy = [] ++ optional (container.autoStart) "multi-user.target";
|
||||||
|
wants = lib.optional (container.imageFile == null) "network-online.target";
|
||||||
after = lib.optionals (cfg.backend == "docker") [ "docker.service" "docker.socket" ]
|
after = lib.optionals (cfg.backend == "docker") [ "docker.service" "docker.socket" ]
|
||||||
# if imageFile is not set, the service needs the network to download the image from the registry
|
# if imageFile is not set, the service needs the network to download the image from the registry
|
||||||
++ lib.optionals (container.imageFile == null) [ "network-online.target" ]
|
++ lib.optionals (container.imageFile == null) [ "network-online.target" ]
|
||||||
|
@ -150,26 +150,33 @@ in
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable
|
config =
|
||||||
{
|
let
|
||||||
|
networkConfig = ({
|
||||||
|
dns_enabled = false;
|
||||||
|
driver = "bridge";
|
||||||
|
id = "0000000000000000000000000000000000000000000000000000000000000000";
|
||||||
|
internal = false;
|
||||||
|
ipam_options = { driver = "host-local"; };
|
||||||
|
ipv6_enabled = false;
|
||||||
|
name = "podman";
|
||||||
|
network_interface = "podman0";
|
||||||
|
subnets = [{ gateway = "10.88.0.1"; subnet = "10.88.0.0/16"; }];
|
||||||
|
} // cfg.defaultNetwork.settings);
|
||||||
|
inherit (networkConfig) dns_enabled network_interface;
|
||||||
|
in
|
||||||
|
lib.mkIf cfg.enable {
|
||||||
environment.systemPackages = [ cfg.package ]
|
environment.systemPackages = [ cfg.package ]
|
||||||
++ lib.optional cfg.dockerCompat dockerCompat;
|
++ lib.optional cfg.dockerCompat dockerCompat;
|
||||||
|
|
||||||
# https://github.com/containers/podman/blob/097cc6eb6dd8e598c0e8676d21267b4edb11e144/docs/tutorials/basic_networking.md#default-network
|
# https://github.com/containers/podman/blob/097cc6eb6dd8e598c0e8676d21267b4edb11e144/docs/tutorials/basic_networking.md#default-network
|
||||||
environment.etc."containers/networks/podman.json" = lib.mkIf (cfg.defaultNetwork.settings != { }) {
|
environment.etc."containers/networks/podman.json" = lib.mkIf (cfg.defaultNetwork.settings != { }) {
|
||||||
source = json.generate "podman.json" ({
|
source = json.generate "podman.json" networkConfig;
|
||||||
dns_enabled = false;
|
|
||||||
driver = "bridge";
|
|
||||||
id = "0000000000000000000000000000000000000000000000000000000000000000";
|
|
||||||
internal = false;
|
|
||||||
ipam_options = { driver = "host-local"; };
|
|
||||||
ipv6_enabled = false;
|
|
||||||
name = "podman";
|
|
||||||
network_interface = "podman0";
|
|
||||||
subnets = [{ gateway = "10.88.0.1"; subnet = "10.88.0.0/16"; }];
|
|
||||||
} // cfg.defaultNetwork.settings);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# containers cannot reach aardvark-dns otherwise
|
||||||
|
networking.firewall.interfaces.${network_interface}.allowedUDPPorts = lib.mkIf dns_enabled [ 53 ];
|
||||||
|
|
||||||
virtualisation.containers = {
|
virtualisation.containers = {
|
||||||
enable = true; # Enable common /etc/containers configuration
|
enable = true; # Enable common /etc/containers configuration
|
||||||
containersConf.settings = {
|
containersConf.settings = {
|
||||||
|
@ -134,6 +134,7 @@
|
|||||||
testScript = ''
|
testScript = ''
|
||||||
start_all()
|
start_all()
|
||||||
|
|
||||||
|
peer0.systemctl("start network-online.target")
|
||||||
peer0.wait_for_unit("network-online.target")
|
peer0.wait_for_unit("network-online.target")
|
||||||
|
|
||||||
peer1.wait_for_unit("3proxy.service")
|
peer1.wait_for_unit("3proxy.service")
|
||||||
|
@ -522,6 +522,7 @@ in {
|
|||||||
'curl --data \'{"host": "${caDomain}", "addresses": ["${nodes.acme.networking.primaryIPAddress}"]}\' http://${dnsServerIP nodes}:8055/add-a'
|
'curl --data \'{"host": "${caDomain}", "addresses": ["${nodes.acme.networking.primaryIPAddress}"]}\' http://${dnsServerIP nodes}:8055/add-a'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
acme.systemctl("start network-online.target")
|
||||||
acme.wait_for_unit("network-online.target")
|
acme.wait_for_unit("network-online.target")
|
||||||
acme.wait_for_unit("pebble.service")
|
acme.wait_for_unit("pebble.service")
|
||||||
|
|
||||||
|
@ -126,6 +126,7 @@
|
|||||||
|
|
||||||
with subtest("Testing successful DHCP start"):
|
with subtest("Testing successful DHCP start"):
|
||||||
dhcpConf.wait_for_unit("adguardhome.service")
|
dhcpConf.wait_for_unit("adguardhome.service")
|
||||||
|
client.systemctl("start network-online.target")
|
||||||
client.wait_for_unit("network-online.target")
|
client.wait_for_unit("network-online.target")
|
||||||
# Test IP assignment via DHCP
|
# Test IP assignment via DHCP
|
||||||
dhcpConf.wait_until_succeeds("ping -c 5 10.0.10.100")
|
dhcpConf.wait_until_succeeds("ping -c 5 10.0.10.100")
|
||||||
|
@ -587,6 +587,7 @@ in {
|
|||||||
nginx-globalredirect = handleTest ./nginx-globalredirect.nix {};
|
nginx-globalredirect = handleTest ./nginx-globalredirect.nix {};
|
||||||
nginx-http3 = handleTest ./nginx-http3.nix {};
|
nginx-http3 = handleTest ./nginx-http3.nix {};
|
||||||
nginx-modsecurity = handleTest ./nginx-modsecurity.nix {};
|
nginx-modsecurity = handleTest ./nginx-modsecurity.nix {};
|
||||||
|
nginx-moreheaders = handleTest ./nginx-moreheaders.nix {};
|
||||||
nginx-njs = handleTest ./nginx-njs.nix {};
|
nginx-njs = handleTest ./nginx-njs.nix {};
|
||||||
nginx-proxyprotocol = handleTest ./nginx-proxyprotocol {};
|
nginx-proxyprotocol = handleTest ./nginx-proxyprotocol {};
|
||||||
nginx-pubhtml = handleTest ./nginx-pubhtml.nix {};
|
nginx-pubhtml = handleTest ./nginx-pubhtml.nix {};
|
||||||
@ -808,6 +809,7 @@ in {
|
|||||||
stunnel = handleTest ./stunnel.nix {};
|
stunnel = handleTest ./stunnel.nix {};
|
||||||
sudo = handleTest ./sudo.nix {};
|
sudo = handleTest ./sudo.nix {};
|
||||||
sudo-rs = handleTest ./sudo-rs.nix {};
|
sudo-rs = handleTest ./sudo-rs.nix {};
|
||||||
|
suwayomi-server = handleTest ./suwayomi-server.nix {};
|
||||||
swap-file-btrfs = handleTest ./swap-file-btrfs.nix {};
|
swap-file-btrfs = handleTest ./swap-file-btrfs.nix {};
|
||||||
swap-partition = handleTest ./swap-partition.nix {};
|
swap-partition = handleTest ./swap-partition.nix {};
|
||||||
swap-random-encryption = handleTest ./swap-random-encryption.nix {};
|
swap-random-encryption = handleTest ./swap-random-encryption.nix {};
|
||||||
|
@ -8,6 +8,9 @@
|
|||||||
let
|
let
|
||||||
rootPartitionLabel = "root";
|
rootPartitionLabel = "root";
|
||||||
|
|
||||||
|
imageId = "nixos-appliance";
|
||||||
|
imageVersion = "1-rc1";
|
||||||
|
|
||||||
bootLoaderConfigPath = "/loader/entries/nixos.conf";
|
bootLoaderConfigPath = "/loader/entries/nixos.conf";
|
||||||
kernelPath = "/EFI/nixos/kernel.efi";
|
kernelPath = "/EFI/nixos/kernel.efi";
|
||||||
initrdPath = "/EFI/nixos/initrd.efi";
|
initrdPath = "/EFI/nixos/initrd.efi";
|
||||||
@ -29,6 +32,9 @@ in
|
|||||||
# TODO(raitobezarius): revisit this when #244907 lands
|
# TODO(raitobezarius): revisit this when #244907 lands
|
||||||
boot.loader.grub.enable = false;
|
boot.loader.grub.enable = false;
|
||||||
|
|
||||||
|
system.image.id = imageId;
|
||||||
|
system.image.version = imageVersion;
|
||||||
|
|
||||||
virtualisation.fileSystems = lib.mkForce {
|
virtualisation.fileSystems = lib.mkForce {
|
||||||
"/" = {
|
"/" = {
|
||||||
device = "/dev/disk/by-partlabel/${rootPartitionLabel}";
|
device = "/dev/disk/by-partlabel/${rootPartitionLabel}";
|
||||||
@ -99,7 +105,7 @@ in
|
|||||||
"-f",
|
"-f",
|
||||||
"qcow2",
|
"qcow2",
|
||||||
"-b",
|
"-b",
|
||||||
"${nodes.machine.system.build.image}/image.raw",
|
"${nodes.machine.system.build.image}/${nodes.machine.image.repart.imageFile}",
|
||||||
"-F",
|
"-F",
|
||||||
"raw",
|
"raw",
|
||||||
tmp_disk_image.name,
|
tmp_disk_image.name,
|
||||||
@ -108,6 +114,10 @@ in
|
|||||||
# Set NIX_DISK_IMAGE so that the qemu script finds the right disk image.
|
# Set NIX_DISK_IMAGE so that the qemu script finds the right disk image.
|
||||||
os.environ['NIX_DISK_IMAGE'] = tmp_disk_image.name
|
os.environ['NIX_DISK_IMAGE'] = tmp_disk_image.name
|
||||||
|
|
||||||
|
os_release = machine.succeed("cat /etc/os-release")
|
||||||
|
assert 'IMAGE_ID="${imageId}"' in os_release
|
||||||
|
assert 'IMAGE_VERSION="${imageVersion}"' in os_release
|
||||||
|
|
||||||
bootctl_status = machine.succeed("bootctl status")
|
bootctl_status = machine.succeed("bootctl status")
|
||||||
assert "${bootLoaderConfigPath}" in bootctl_status
|
assert "${bootLoaderConfigPath}" in bootctl_status
|
||||||
assert "${kernelPath}" in bootctl_status
|
assert "${kernelPath}" in bootctl_status
|
||||||
|
@ -4,7 +4,7 @@ in {
|
|||||||
name = "ayatana-indicators";
|
name = "ayatana-indicators";
|
||||||
|
|
||||||
meta = {
|
meta = {
|
||||||
maintainers = with lib.maintainers; [ OPNA2608 ];
|
maintainers = lib.teams.lomiri.members;
|
||||||
};
|
};
|
||||||
|
|
||||||
nodes.machine = { config, ... }: {
|
nodes.machine = { config, ... }: {
|
||||||
@ -28,16 +28,34 @@ in {
|
|||||||
enable = true;
|
enable = true;
|
||||||
packages = with pkgs; [
|
packages = with pkgs; [
|
||||||
ayatana-indicator-messages
|
ayatana-indicator-messages
|
||||||
];
|
] ++ (with pkgs.lomiri; [
|
||||||
|
lomiri-indicator-network
|
||||||
|
]);
|
||||||
};
|
};
|
||||||
|
|
||||||
# Services needed by some indicators
|
# Setup needed by some indicators
|
||||||
|
|
||||||
services.accounts-daemon.enable = true; # messages
|
services.accounts-daemon.enable = true; # messages
|
||||||
|
|
||||||
|
# Lomiri-ish setup for Lomiri indicators
|
||||||
|
# TODO move into a Lomiri module, once the package set is far enough for the DE to start
|
||||||
|
|
||||||
|
networking.networkmanager.enable = true; # lomiri-network-indicator
|
||||||
|
# TODO potentially urfkill for lomiri-network-indicator?
|
||||||
};
|
};
|
||||||
|
|
||||||
# TODO session indicator starts up in a semi-broken state, but works fine after a restart. maybe being started before graphical session is truly up & ready?
|
# TODO session indicator starts up in a semi-broken state, but works fine after a restart. maybe being started before graphical session is truly up & ready?
|
||||||
testScript = { nodes, ... }: let
|
testScript = { nodes, ... }: let
|
||||||
runCommandPerIndicatorService = command: lib.strings.concatMapStringsSep "\n" command nodes.machine.systemd.user.targets."ayatana-indicators".wants;
|
runCommandOverServiceList = list: command:
|
||||||
|
lib.strings.concatMapStringsSep "\n" command list;
|
||||||
|
|
||||||
|
runCommandOverAyatanaIndicators = runCommandOverServiceList
|
||||||
|
(builtins.filter
|
||||||
|
(service: !(lib.strings.hasPrefix "lomiri" service || lib.strings.hasPrefix "telephony-service" service))
|
||||||
|
nodes.machine.systemd.user.targets."ayatana-indicators".wants);
|
||||||
|
|
||||||
|
runCommandOverAllIndicators = runCommandOverServiceList
|
||||||
|
nodes.machine.systemd.user.targets."ayatana-indicators".wants;
|
||||||
in ''
|
in ''
|
||||||
start_all()
|
start_all()
|
||||||
machine.wait_for_x()
|
machine.wait_for_x()
|
||||||
@ -50,7 +68,7 @@ in {
|
|||||||
machine.sleep(10)
|
machine.sleep(10)
|
||||||
|
|
||||||
# Now check if all indicators were brought up successfully, and kill them for later
|
# Now check if all indicators were brought up successfully, and kill them for later
|
||||||
'' + (runCommandPerIndicatorService (service: let serviceExec = builtins.replaceStrings [ "." ] [ "-" ] service; in ''
|
'' + (runCommandOverAyatanaIndicators (service: let serviceExec = builtins.replaceStrings [ "." ] [ "-" ] service; in ''
|
||||||
machine.succeed("pgrep -f ${serviceExec}")
|
machine.succeed("pgrep -f ${serviceExec}")
|
||||||
machine.succeed("pkill -f ${serviceExec}")
|
machine.succeed("pkill -f ${serviceExec}")
|
||||||
'')) + ''
|
'')) + ''
|
||||||
@ -65,7 +83,7 @@ in {
|
|||||||
machine.sleep(10)
|
machine.sleep(10)
|
||||||
|
|
||||||
# Now check if all indicator services were brought up successfully
|
# Now check if all indicator services were brought up successfully
|
||||||
'' + runCommandPerIndicatorService (service: ''
|
'' + runCommandOverAllIndicators (service: ''
|
||||||
machine.wait_for_unit("${service}", "${user}")
|
machine.wait_for_unit("${service}", "${user}")
|
||||||
'');
|
'');
|
||||||
})
|
})
|
||||||
|
@ -120,10 +120,6 @@ import ./make-test-python.nix ({ pkgs, lib, ...} : {
|
|||||||
''
|
''
|
||||||
start_all()
|
start_all()
|
||||||
|
|
||||||
client.wait_for_unit("network-online.target")
|
|
||||||
local_router.wait_for_unit("network-online.target")
|
|
||||||
remote_router.wait_for_unit("network-online.target")
|
|
||||||
|
|
||||||
local_router.wait_for_unit("babeld.service")
|
local_router.wait_for_unit("babeld.service")
|
||||||
remote_router.wait_for_unit("babeld.service")
|
remote_router.wait_for_unit("babeld.service")
|
||||||
|
|
||||||
|
@ -115,6 +115,7 @@ in
|
|||||||
start_all()
|
start_all()
|
||||||
|
|
||||||
# Wait for network and miniupnpd.
|
# Wait for network and miniupnpd.
|
||||||
|
router.systemctl("start network-online.target")
|
||||||
router.wait_for_unit("network-online.target")
|
router.wait_for_unit("network-online.target")
|
||||||
router.wait_for_unit("miniupnpd")
|
router.wait_for_unit("miniupnpd")
|
||||||
|
|
||||||
@ -129,6 +130,7 @@ in
|
|||||||
tracker.succeed("chmod 644 /tmp/test.torrent")
|
tracker.succeed("chmod 644 /tmp/test.torrent")
|
||||||
|
|
||||||
# Start the tracker. !!! use a less crappy tracker
|
# Start the tracker. !!! use a less crappy tracker
|
||||||
|
tracker.systemctl("start network-online.target")
|
||||||
tracker.wait_for_unit("network-online.target")
|
tracker.wait_for_unit("network-online.target")
|
||||||
tracker.wait_for_unit("opentracker.service")
|
tracker.wait_for_unit("opentracker.service")
|
||||||
tracker.wait_for_open_port(6969)
|
tracker.wait_for_open_port(6969)
|
||||||
@ -140,6 +142,7 @@ in
|
|||||||
|
|
||||||
# Now we should be able to download from the client behind the NAT.
|
# Now we should be able to download from the client behind the NAT.
|
||||||
tracker.wait_for_unit("httpd")
|
tracker.wait_for_unit("httpd")
|
||||||
|
client1.systemctl("start network-online.target")
|
||||||
client1.wait_for_unit("network-online.target")
|
client1.wait_for_unit("network-online.target")
|
||||||
client1.succeed("transmission-remote --add http://${externalTrackerAddress}/test.torrent >&2 &")
|
client1.succeed("transmission-remote --add http://${externalTrackerAddress}/test.torrent >&2 &")
|
||||||
client1.wait_for_file("${download-dir}/test.tar.bz2")
|
client1.wait_for_file("${download-dir}/test.tar.bz2")
|
||||||
@ -152,6 +155,7 @@ in
|
|||||||
|
|
||||||
# Now download from the second client. This can only succeed if
|
# Now download from the second client. This can only succeed if
|
||||||
# the first client created a NAT hole in the router.
|
# the first client created a NAT hole in the router.
|
||||||
|
client2.systemctl("start network-online.target")
|
||||||
client2.wait_for_unit("network-online.target")
|
client2.wait_for_unit("network-online.target")
|
||||||
client2.succeed(
|
client2.succeed(
|
||||||
"transmission-remote --add http://${externalTrackerAddress}/test.torrent --no-portmap --no-dht >&2 &"
|
"transmission-remote --add http://${externalTrackerAddress}/test.torrent --no-portmap --no-dht >&2 &"
|
||||||
|
@ -71,6 +71,7 @@ import ./make-test-python.nix ({ pkgs, ... }: {
|
|||||||
gitrepo.wait_for_unit("multi-user.target")
|
gitrepo.wait_for_unit("multi-user.target")
|
||||||
|
|
||||||
with subtest("Repo is accessible via git daemon"):
|
with subtest("Repo is accessible via git daemon"):
|
||||||
|
bbmaster.systemctl("start network-online.target")
|
||||||
bbmaster.wait_for_unit("network-online.target")
|
bbmaster.wait_for_unit("network-online.target")
|
||||||
bbmaster.succeed("rm -rfv /tmp/fakerepo")
|
bbmaster.succeed("rm -rfv /tmp/fakerepo")
|
||||||
bbmaster.succeed("git clone git://gitrepo/fakerepo /tmp/fakerepo")
|
bbmaster.succeed("git clone git://gitrepo/fakerepo /tmp/fakerepo")
|
||||||
@ -78,6 +79,7 @@ import ./make-test-python.nix ({ pkgs, ... }: {
|
|||||||
with subtest("Master service and worker successfully connect"):
|
with subtest("Master service and worker successfully connect"):
|
||||||
bbmaster.wait_for_unit("buildbot-master.service")
|
bbmaster.wait_for_unit("buildbot-master.service")
|
||||||
bbmaster.wait_until_succeeds("curl --fail -s --head http://bbmaster:8010")
|
bbmaster.wait_until_succeeds("curl --fail -s --head http://bbmaster:8010")
|
||||||
|
bbworker.systemctl("start network-online.target")
|
||||||
bbworker.wait_for_unit("network-online.target")
|
bbworker.wait_for_unit("network-online.target")
|
||||||
bbworker.succeed("nc -z bbmaster 8010")
|
bbworker.succeed("nc -z bbmaster 8010")
|
||||||
bbworker.succeed("nc -z bbmaster 9989")
|
bbworker.succeed("nc -z bbmaster 9989")
|
||||||
|
@ -56,6 +56,8 @@ import ./make-test-python.nix (
|
|||||||
|
|
||||||
with subtest("Wait for CoreRAD and network ready"):
|
with subtest("Wait for CoreRAD and network ready"):
|
||||||
# Ensure networking is online and CoreRAD is ready.
|
# Ensure networking is online and CoreRAD is ready.
|
||||||
|
router.systemctl("start network-online.target")
|
||||||
|
client.systemctl("start network-online.target")
|
||||||
router.wait_for_unit("network-online.target")
|
router.wait_for_unit("network-online.target")
|
||||||
client.wait_for_unit("network-online.target")
|
client.wait_for_unit("network-online.target")
|
||||||
router.wait_for_unit("corerad.service")
|
router.wait_for_unit("corerad.service")
|
||||||
|
@ -144,6 +144,8 @@ in {
|
|||||||
start_all()
|
start_all()
|
||||||
|
|
||||||
with subtest("Wait for network"):
|
with subtest("Wait for network"):
|
||||||
|
web.systemctl("start network-online.target")
|
||||||
|
curl.systemctl("start network-online.target")
|
||||||
web.wait_for_unit("network-online.target")
|
web.wait_for_unit("network-online.target")
|
||||||
curl.wait_for_unit("network-online.target")
|
curl.wait_for_unit("network-online.target")
|
||||||
|
|
||||||
|
@ -55,6 +55,8 @@ import ./make-test-python.nix ({ pkgs, ...} : {
|
|||||||
''
|
''
|
||||||
start_all()
|
start_all()
|
||||||
|
|
||||||
|
client.systemctl("start network-online.target")
|
||||||
|
server.systemctl("start network-online.target")
|
||||||
client.wait_for_unit("network-online.target")
|
client.wait_for_unit("network-online.target")
|
||||||
server.wait_for_unit("network-online.target")
|
server.wait_for_unit("network-online.target")
|
||||||
server.wait_for_unit("ferm.service")
|
server.wait_for_unit("ferm.service")
|
||||||
|
@ -59,6 +59,9 @@ in {
|
|||||||
with subtest("git daemon starts"):
|
with subtest("git daemon starts"):
|
||||||
server.wait_for_unit("git-daemon.service")
|
server.wait_for_unit("git-daemon.service")
|
||||||
|
|
||||||
|
|
||||||
|
server.systemctl("start network-online.target")
|
||||||
|
client.systemctl("start network-online.target")
|
||||||
server.wait_for_unit("network-online.target")
|
server.wait_for_unit("network-online.target")
|
||||||
client.wait_for_unit("network-online.target")
|
client.wait_for_unit("network-online.target")
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user