mirror of
https://github.com/NixOS/nixpkgs.git
synced 2024-11-21 22:43:01 +00:00
Merge branch master into haskell-updates
Conflicts from #341407 resolved.
This commit is contained in:
commit
b341506a8d
@ -171,3 +171,6 @@ cffc27daf06c77c0d76bc35d24b929cb9d68c3c9
|
||||
|
||||
# nixos/kanidm: inherit lib, nixfmt
|
||||
8f18393d380079904d072007fb19dc64baef0a3a
|
||||
|
||||
# fetchurl: nixfmt-rfc-style
|
||||
ce21e97a1f20dee15da85c084f9d1148d84f853b
|
||||
|
3
.github/CODEOWNERS
vendored
3
.github/CODEOWNERS
vendored
@ -120,7 +120,8 @@ nixos/modules/installer/tools/nix-fallback-paths.nix @NixOS/nix-team @raitobeza
|
||||
/nixos/modules/system/boot/loader/systemd-boot @JulienMalka
|
||||
|
||||
# Images and installer media
|
||||
/nixos/modules/installer/cd-dvd/
|
||||
/nixos/modules/profiles/installation-device.nix @ElvishJerricco
|
||||
/nixos/modules/installer/cd-dvd/ @ElvishJerricco
|
||||
/nixos/modules/installer/sd-card/
|
||||
|
||||
# Updaters
|
||||
|
11
.github/labeler.yml
vendored
11
.github/labeler.yml
vendored
@ -380,6 +380,17 @@
|
||||
- any-glob-to-any-file:
|
||||
- pkgs/applications/editors/vscode/**/*
|
||||
|
||||
"6.topic: xen":
|
||||
- any:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- nixos/modules/virtualisation/xen*
|
||||
- pkgs/applications/virtualization/xen/**
|
||||
- pkgs/by-name/xe/xen-guest-agent/*
|
||||
- pkgs/by-name/xt/xtf/*
|
||||
- pkgs/development/ocaml-modules/xen*/*
|
||||
- pkgs/development/ocaml-modules/vchan/*
|
||||
|
||||
"6.topic: xfce":
|
||||
- any:
|
||||
- changed-files:
|
||||
|
@ -453,7 +453,7 @@ See [](#ex-dockerTools-streamLayeredImage-exploringlayers) to understand how the
|
||||
`streamLayeredImage` allows scripts to be run when creating the additional layer with symlinks, allowing custom behaviour to affect the final results of the image (see the documentation of the `extraCommands` and `fakeRootCommands` attributes).
|
||||
|
||||
The resulting repository tarball will list a single image as specified by the `name` and `tag` attributes.
|
||||
By default, that image will use a static creation date (see documentation for the `created` attribute).
|
||||
By default, that image will use a static creation date (see documentation for the `created` and `mtime` attributes).
|
||||
This allows the function to produce reproducible images.
|
||||
|
||||
### Inputs {#ssec-pkgs-dockerTools-streamLayeredImage-inputs}
|
||||
@ -516,6 +516,7 @@ This allows the function to produce reproducible images.
|
||||
`created` (String; _optional_)
|
||||
|
||||
: Specifies the time of creation of the generated image.
|
||||
This date will be used for the image metadata.
|
||||
This should be either a date and time formatted according to [ISO-8601](https://en.wikipedia.org/wiki/ISO_8601) or `"now"`, in which case the current date will be used.
|
||||
|
||||
:::{.caution}
|
||||
@ -524,6 +525,18 @@ This allows the function to produce reproducible images.
|
||||
|
||||
_Default value:_ `"1970-01-01T00:00:01Z"`.
|
||||
|
||||
`mtime` (String; _optional_)
|
||||
|
||||
: Specifies the time used for the modification timestamp of files within the layers of the generated image.
|
||||
This should be either a date and time formatted according to [ISO-8601](https://en.wikipedia.org/wiki/ISO_8601) or `"now"`, in which case the current date will be used.
|
||||
|
||||
:::{.caution}
|
||||
Using a non-constant date will cause built layers to have a different hash each time, preventing deduplication.
|
||||
Using `"now"` also means that the generated image will not be reproducible anymore (because the date will always change whenever it's built).
|
||||
:::
|
||||
|
||||
_Default value:_ `"1970-01-01T00:00:01Z"`.
|
||||
|
||||
`uid` (Number; _optional_) []{#dockerTools-buildLayeredImage-arg-uid}
|
||||
`gid` (Number; _optional_) []{#dockerTools-buildLayeredImage-arg-gid}
|
||||
`uname` (String; _optional_) []{#dockerTools-buildLayeredImage-arg-uname}
|
||||
|
@ -501,7 +501,7 @@ writeTextFile {
|
||||
text = ''
|
||||
Contents of File
|
||||
'';
|
||||
destination = "share/my-file";
|
||||
destination = "/share/my-file";
|
||||
}
|
||||
```
|
||||
|
||||
@ -586,7 +586,7 @@ writeTextFile {
|
||||
echo "hi"
|
||||
'';
|
||||
executable = true;
|
||||
destination = "bin/my-script";
|
||||
destination = "/bin/my-script";
|
||||
}
|
||||
```
|
||||
|
||||
@ -674,7 +674,7 @@ writeTextFile {
|
||||
echo "hi"
|
||||
'';
|
||||
executable = true;
|
||||
destination = "bin/my-script";
|
||||
destination = "/bin/my-script";
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -47,7 +47,7 @@
|
||||
checks = forAllSystems (system: {
|
||||
tarball = jobs.${system}.tarball;
|
||||
# Exclude power64 due to "libressl is not available on the requested hostPlatform" with hostPlatform being power64
|
||||
} // lib.optionalAttrs (self.legacyPackages.${system}.stdenv.isLinux && !self.legacyPackages.${system}.targetPlatform.isPower64) {
|
||||
} // lib.optionalAttrs (self.legacyPackages.${system}.stdenv.hostPlatform.isLinux && !self.legacyPackages.${system}.targetPlatform.isPower64) {
|
||||
# Test that ensures that the nixosSystem function can accept a lib argument
|
||||
# Note: prefer not to extend or modify `lib`, especially if you want to share reusable modules
|
||||
# alternatives include: `import` a file, or put a custom library in an option or in `_module.args.<libname>`
|
||||
|
@ -33,7 +33,7 @@ pkgs.runCommand "nixpkgs-lib-tests-nix-${nix.version}" {
|
||||
nativeBuildInputs = [
|
||||
nix
|
||||
pkgs.gitMinimal
|
||||
] ++ lib.optional pkgs.stdenv.isLinux pkgs.inotify-tools;
|
||||
] ++ lib.optional pkgs.stdenv.hostPlatform.isLinux pkgs.inotify-tools;
|
||||
strictDeps = true;
|
||||
} ''
|
||||
datadir="${nix}/share"
|
||||
|
@ -1028,12 +1028,6 @@
|
||||
githubId = 30437811;
|
||||
name = "Alex Andrews";
|
||||
};
|
||||
alibabzo = {
|
||||
email = "alistair.bill@gmail.com";
|
||||
github = "alistairbill";
|
||||
githubId = 2822871;
|
||||
name = "Alistair Bill";
|
||||
};
|
||||
alirezameskin = {
|
||||
email = "alireza.meskin@gmail.com";
|
||||
github = "alirezameskin";
|
||||
@ -3339,6 +3333,12 @@
|
||||
githubId = 141733;
|
||||
name = "Andrew Bruce";
|
||||
};
|
||||
camerondugan = {
|
||||
email = "cameron.dugan@protonmail.com";
|
||||
github = "camerondugan";
|
||||
githubId = 54632731;
|
||||
name = "Cameron Dugan";
|
||||
};
|
||||
cameronfyfe = {
|
||||
email = "cameron.j.fyfe@gmail.com";
|
||||
github = "cameronfyfe";
|
||||
@ -9168,6 +9168,12 @@
|
||||
githubId = 1817528;
|
||||
name = "Igor Polyakov";
|
||||
};
|
||||
iosmanthus = {
|
||||
email = "myosmanthustree@gmail.com";
|
||||
github = "iosmanthus";
|
||||
githubId = 16307070;
|
||||
name = "iosmanthus";
|
||||
};
|
||||
iquerejeta = {
|
||||
github = "iquerejeta";
|
||||
githubId = 31273774;
|
||||
@ -9905,6 +9911,11 @@
|
||||
githubId = 1061229;
|
||||
name = "Jiehong Ma";
|
||||
};
|
||||
jigglycrumb = {
|
||||
github = "jigglycrumb";
|
||||
githubId = 1476865;
|
||||
name = "jigglycrumb";
|
||||
};
|
||||
jirkamarsik = {
|
||||
email = "jiri.marsik89@gmail.com";
|
||||
github = "jirkamarsik";
|
||||
@ -18205,12 +18216,6 @@
|
||||
github = "rosehobgoblin";
|
||||
githubId = 84164410;
|
||||
};
|
||||
roshaen = {
|
||||
name = "Roshan Kumar";
|
||||
email = "roshaen09@gmail.com";
|
||||
github = "roshaen";
|
||||
githubId = 58213083;
|
||||
};
|
||||
RossComputerGuy = {
|
||||
name = "Tristan Ross";
|
||||
email = "tristan.ross@midstall.com";
|
||||
@ -19339,6 +19344,12 @@
|
||||
github = "kf5grd";
|
||||
githubId = 18297490;
|
||||
};
|
||||
shogo = {
|
||||
email = "shouryagoel10000@gmail.com";
|
||||
github = "Sh0g0-1758";
|
||||
githubId = 114918019;
|
||||
name = "Shourya Goel";
|
||||
};
|
||||
shortcord = {
|
||||
name = "Short Cord";
|
||||
email = "short@shortcord.com";
|
||||
@ -23289,6 +23300,12 @@
|
||||
github = "YoshiRulz";
|
||||
githubId = 13409956;
|
||||
};
|
||||
youhaveme9 = {
|
||||
name = "Roshan Kumar";
|
||||
email = "roshaen09@gmail.com";
|
||||
github = "youhaveme9";
|
||||
githubId = 58213083;
|
||||
};
|
||||
yrashk = {
|
||||
email = "yrashk@gmail.com";
|
||||
github = "yrashk";
|
||||
|
@ -13,5 +13,5 @@ mkShell {
|
||||
clippy
|
||||
rustfmt
|
||||
]
|
||||
++ lib.optional stdenv.isDarwin pkgs.libiconv;
|
||||
++ lib.optional stdenv.hostPlatform.isDarwin pkgs.libiconv;
|
||||
}
|
||||
|
@ -114,6 +114,7 @@ middleclass,,,,,,
|
||||
mimetypes,,,,,,
|
||||
mpack,,,,,,
|
||||
moonscript,https://raw.githubusercontent.com/leafo/moonscript/master/moonscript-dev-1.rockspec,,,,,arobyn
|
||||
neorg,,,,,,GaetanLepage
|
||||
neotest,,,,,,mrcjkb
|
||||
nlua,,,,,,teto
|
||||
nui.nvim,,,,,,mrcjkb
|
||||
|
|
@ -565,6 +565,7 @@ with lib.maintainers;
|
||||
linux-kernel = {
|
||||
members = [
|
||||
TredwellGit
|
||||
k900
|
||||
ma27
|
||||
nequissimus
|
||||
qyliss
|
||||
|
@ -80,6 +80,7 @@ Reviewing process:
|
||||
|
||||
- Ensure that all file paths [fit the guidelines](../CONTRIBUTING.md#file-naming-and-organisation).
|
||||
- Ensure that the module tests, if any, are succeeding.
|
||||
- Ensure that new module tests are added to the package `passthru.tests`.
|
||||
- Ensure that the introduced options are correct.
|
||||
- Type should be appropriate (string related types differs in their merging capabilities, `loaOf` and `string` types are deprecated).
|
||||
- Description, default and example should be provided.
|
||||
@ -95,7 +96,8 @@ Sample template for a new module review is provided below.
|
||||
##### Reviewed points
|
||||
|
||||
- [ ] module path fits the guidelines
|
||||
- [ ] module tests succeed on ARCHITECTURE
|
||||
- [ ] module tests, if any, succeed on ARCHITECTURE
|
||||
- [ ] module tests, if any, are added to package `passthru.tests`
|
||||
- [ ] options have appropriate types
|
||||
- [ ] options have default
|
||||
- [ ] options have example
|
||||
|
@ -133,20 +133,3 @@ This section was moved to the [Nixpkgs manual](https://nixos.org/nixpkgs/manual#
|
||||
It's a common issue that the latest stable version of ZFS doesn't support the latest
|
||||
available Linux kernel. It is recommended to use the latest available LTS that's compatible
|
||||
with ZFS. Usually this is the default kernel provided by nixpkgs (i.e. `pkgs.linuxPackages`).
|
||||
|
||||
Alternatively, it's possible to pin the system to the latest available kernel
|
||||
version _that is supported by ZFS_ like this:
|
||||
|
||||
```nix
|
||||
{
|
||||
boot.kernelPackages = pkgs.zfs.latestCompatibleLinuxPackages;
|
||||
}
|
||||
```
|
||||
|
||||
Please note that the version this attribute points to isn't monotonic because the latest kernel
|
||||
version only refers to kernel versions supported by the Linux developers. In other words,
|
||||
the latest kernel version that ZFS is compatible with may decrease over time.
|
||||
|
||||
An example: the latest version ZFS is compatible with is 5.19 which is a non-longterm version. When 5.19
|
||||
is out of maintenance, the latest supported kernel version is 5.15 because it's longterm and the versions
|
||||
5.16, 5.17 and 5.18 are already out of maintenance because they're non-longterm.
|
||||
|
@ -61,7 +61,7 @@
|
||||
|
||||
## New Modules {#sec-release-24.11-new-modules}
|
||||
|
||||
- [TaskChampion Sync-Server](https://github.com/GothenburgBitFactory/taskchampion-sync-server), a [Taskwariror 3](https://taskwarrior.org/docs/upgrade-3/) sync server, replacing Taskwarrior 2's sync server named [`taskserver`](https://github.com/GothenburgBitFactory/taskserver).
|
||||
- [TaskChampion Sync-Server](https://github.com/GothenburgBitFactory/taskchampion-sync-server), a [Taskwarrior 3](https://taskwarrior.org/docs/upgrade-3/) sync server, replacing Taskwarrior 2's sync server named [`taskserver`](https://github.com/GothenburgBitFactory/taskserver).
|
||||
|
||||
- [FlareSolverr](https://github.com/FlareSolverr/FlareSolverr), proxy server to bypass Cloudflare protection. Available as [services.flaresolverr](#opt-services.flaresolverr.enable) service.
|
||||
|
||||
@ -108,6 +108,8 @@
|
||||
|
||||
- [zeronsd](https://github.com/zerotier/zeronsd), a DNS server for ZeroTier users. Available with [services.zeronsd.servedNetworks](#opt-services.zeronsd.servedNetworks).
|
||||
|
||||
- [Collabora Online](https://www.collaboraonline.com/), a collaborative online office suite based on LibreOffice technology. Available as [services.collabora-online](options.html#opt-services.collabora-online.enable).
|
||||
|
||||
- [wg-access-server](https://github.com/freifunkMUC/wg-access-server/), an all-in-one WireGuard VPN solution with a web ui for connecting devices. Available at [services.wg-access-server](#opt-services.wg-access-server.enable).
|
||||
|
||||
- [Pingvin Share](https://github.com/stonith404/pingvin-share), a self-hosted file sharing platform and an alternative for WeTransfer. Available as [services.pingvin-share](#opt-services.pingvin-share.enable).
|
||||
@ -151,8 +153,18 @@
|
||||
|
||||
- [Dependency Track](https://dependencytrack.org/), an intelligent Component Analysis platform that allows organizations to identify and reduce risk in the software supply chain. Available as [services.dependency-track](option.html#opt-services.dependency-track).
|
||||
|
||||
- [Immich](https://github.com/immich-app/immich), a self-hosted photo and video backup solution. Available as [services.immich](#opt-services.immich.enable).
|
||||
|
||||
## Backward Incompatibilities {#sec-release-24.11-incompatibilities}
|
||||
|
||||
- The `sound` options have been removed or renamed, as they had a lot of unintended side effects. See [below](#sec-release-24.11-migration-sound) for details.
|
||||
|
||||
- The nvidia driver no longer defaults to the proprietary driver starting with version 560. You will need to manually set `hardware.nvidia.open` to select the proprietary or open driver.
|
||||
|
||||
- All Cinnamon and XApp packages have been moved to top-level (i.e., `cinnamon.nemo` is now `nemo`).
|
||||
|
||||
- All GNOME packages have been moved to top-level (i.e., `gnome.nautilus` is now `nautilus`).
|
||||
|
||||
- `transmission` package has been aliased with a `trace` warning to `transmission_3`. Since [Transmission 4 has been released last year](https://github.com/transmission/transmission/releases/tag/4.0.0), and Transmission 3 will eventually go away, it was decided perform this warning alias to make people aware of the new version. The `services.transmission.package` defaults to `transmission_3` as well because the upgrade can cause data loss in certain specific usage patterns (examples: [#5153](https://github.com/transmission/transmission/issues/5153), [#6796](https://github.com/transmission/transmission/issues/6796)). Please make sure to back up to your data directory per your usage:
|
||||
- `transmission-gtk`: `~/.config/transmission`
|
||||
- `transmission-daemon` using NixOS module: `${config.services.transmission.home}/.config/transmission-daemon` (defaults to `/var/lib/transmission/.config/transmission-daemon`)
|
||||
@ -214,8 +226,6 @@
|
||||
- The `mautrix-signal` module was adapted to incorporate the configuration rearrangement that resulted from the update to the mautrix bridgev2 architecture. Pre-0.7.0 configurations should continue to work.
|
||||
In case you want to update your configuration make sure to check the NixOS manual.
|
||||
|
||||
- The nvidia driver no longer defaults to the proprietary driver starting with version 560. You will need to manually set `hardware.nvidia.open` to select the proprietary or open driver.
|
||||
|
||||
- `singularity-tools` have the `storeDir` argument removed from its override interface and use `builtins.storeDir` instead.
|
||||
|
||||
- Two build helpers in `singularity-tools`, i.e., `mkLayer` and `shellScript`, are deprecated, as they are no longer involved in image-building. Maintainers will remove them in future releases.
|
||||
@ -229,10 +239,6 @@
|
||||
- The method to safely handle secrets in the `networking.wireless` module has been changed to benefit from a [new feature](https://w1.fi/cgit/hostap/commit/?id=e680a51e94a33591f61edb210926bcb71217a21a) of wpa_supplicant.
|
||||
The syntax to refer to secrets has changed slightly and the option `networking.wireless.environmentFile` has been replaced by `networking.wireless.secretsFile`; see the description of the latter for how to upgrade.
|
||||
|
||||
- All Cinnamon and XApp packages have been moved to top-level (i.e., `cinnamon.nemo` is now `nemo`).
|
||||
|
||||
- All GNOME packages have been moved to top-level (i.e., `gnome.nautilus` is now `nautilus`).
|
||||
|
||||
- `services.cgit` now runs as the cgit user by default instead of root.
|
||||
This change requires granting access to the repositories to this user or
|
||||
setting the appropriate one through `services.cgit.some-instance.user`.
|
||||
@ -430,8 +436,6 @@
|
||||
|
||||
- `services.roundcube.maxAttachmentSize` will multiply the value set with `1.37` to offset overhead introduced by the base64 encoding applied to attachments.
|
||||
|
||||
- The `sound` options have been removed or renamed, as they had a lot of unintended side effects. See [below](#sec-release-24.11-migration-sound) for details.
|
||||
|
||||
- The `services.mxisd` module has been removed as both [mxisd](https://github.com/kamax-matrix/mxisd) and [ma1sd](https://github.com/ma1uta/ma1sd) are not maintained any longer.
|
||||
Consequently the package `pkgs.ma1sd` has also been removed.
|
||||
|
||||
@ -485,6 +489,8 @@
|
||||
place. The GUI components related to the project are non-free and not
|
||||
packaged.
|
||||
|
||||
- Compatible string matching for `hardware.deviceTree.overlays` has been changed to a more correct behavior. See [below](#sec-release-24.11-migration-dto-compatible) for details.
|
||||
|
||||
## Other Notable Changes {#sec-release-24.11-notable-changes}
|
||||
|
||||
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
|
||||
@ -512,6 +518,9 @@
|
||||
|
||||
- `lib.misc.mapAttrsFlatten` is now formally deprecated and will be removed in future releases; use the identical [`lib.attrsets.mapAttrsToList`](https://nixos.org/manual/nixpkgs/unstable#function-library-lib.attrsets.mapAttrsToList) instead.
|
||||
|
||||
- Tailscale's `authKeyFile` can now have its corresponding parameters set through `config.services.tailscale.authKeyParameters`, allowing for non-ephemeral unsupervised deployment and more.
|
||||
See [Registering new nodes using OAuth credentials](https://tailscale.com/kb/1215/oauth-clients#registering-new-nodes-using-oauth-credentials) for the supported options.
|
||||
|
||||
- `nixosTests` now provide a working IPv6 setup for VLAN 1 by default.
|
||||
|
||||
- Kanidm can now be provisioned using the new [`services.kanidm.provision`] option, but requires using a patched version available via `pkgs.kanidm.withSecretProvisioning`.
|
||||
@ -609,3 +618,22 @@ in {
|
||||
];
|
||||
};
|
||||
```
|
||||
|
||||
### `hardware.deviceTree.overlays` compatible string matching {#sec-release-24.11-migration-dto-compatible}
|
||||
|
||||
The original compatible string implementation in older NixOS versions relied on substring matching,
|
||||
which is incorrect for overlays with multiple compatible strings and other cases.
|
||||
|
||||
The new behavior is consistent with what other tools already do - the overlay is considered applicable if,
|
||||
and only if, _any_ of the compatible strings in the overlay match _any_ of the compatible strings in the DT.
|
||||
|
||||
To provide some examples:
|
||||
|
||||
| Overlay `compatible` | DT `compatible` | Pre-24.11 behavior | Correct behavior | Notes |
|
||||
|----------------------|-----------------|--------------------|------------------|--------------------------------------------|
|
||||
| `"foo"` | `"foo", "bar"` | match | match | Most common use case does not change |
|
||||
| `"foo"` | `"foobar"` | match | no match | Substrings should not be matched |
|
||||
| `"foo bar"` | `"foo", "bar"` | match | no match | Separators should not be matched to spaces |
|
||||
| `"foo", "bar"` | `"baz", "bar"` | no match | match | One compatible string matching is enough |
|
||||
|
||||
Note that this also allows writing overlays that explicitly apply to multiple boards.
|
||||
|
@ -52,7 +52,7 @@ let
|
||||
${lib.optionalString (pkgs.stdenv.hostPlatform == pkgs.stdenv.buildPlatform) ''
|
||||
<!-- Pre-generated font caches -->
|
||||
<cachedir>${cache}</cachedir>
|
||||
${lib.optionalString (pkgs.stdenv.isx86_64 && cfg.cache32Bit) ''
|
||||
${lib.optionalString (pkgs.stdenv.hostPlatform.isx86_64 && cfg.cache32Bit) ''
|
||||
<cachedir>${cache32}</cachedir>
|
||||
''}
|
||||
''}
|
||||
|
@ -32,7 +32,7 @@ in {
|
||||
|
||||
config = {
|
||||
assertions = [
|
||||
{ assertion = isNull config.environment.ldso32 || pkgs.stdenv.isx86_64;
|
||||
{ assertion = isNull config.environment.ldso32 || pkgs.stdenv.hostPlatform.isx86_64;
|
||||
message = "Option environment.ldso32 currently only works on x86_64.";
|
||||
}
|
||||
];
|
||||
@ -44,7 +44,7 @@ in {
|
||||
"d /${libDir} 0755 root root - -"
|
||||
"L+ /${libDir}/${ldsoBasename} - - - - ${config.environment.ldso}"
|
||||
]
|
||||
) ++ optionals pkgs.stdenv.isx86_64 (
|
||||
) ++ optionals pkgs.stdenv.hostPlatform.isx86_64 (
|
||||
if isNull config.environment.ldso32 then [
|
||||
"r /${libDir32}/${ldsoBasename32} - - - - -"
|
||||
] else [
|
||||
|
@ -12,7 +12,7 @@ let
|
||||
|
||||
# Forces 32bit pulseaudio and alsa-plugins to be built/supported for apps
|
||||
# using 32bit alsa on 64bit linux.
|
||||
enable32BitAlsaPlugins = cfg.support32Bit && pkgs.stdenv.isx86_64 && (pkgs.pkgsi686Linux.alsa-lib != null && pkgs.pkgsi686Linux.libpulseaudio != null);
|
||||
enable32BitAlsaPlugins = cfg.support32Bit && pkgs.stdenv.hostPlatform.isx86_64 && (pkgs.pkgsi686Linux.alsa-lib != null && pkgs.pkgsi686Linux.libpulseaudio != null);
|
||||
|
||||
|
||||
myConfigFile =
|
||||
|
@ -49,7 +49,7 @@ in {
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
environment.ldso = mkDefault stub-ld;
|
||||
environment.ldso32 = mkIf pkgs.stdenv.isx86_64 (mkDefault stub-ld32);
|
||||
environment.ldso32 = mkIf pkgs.stdenv.hostPlatform.isx86_64 (mkDefault stub-ld32);
|
||||
};
|
||||
|
||||
meta.maintainers = with lib.maintainers; [ tejing ];
|
||||
|
@ -14,7 +14,7 @@ let
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
(lib.mkRenamedOptionModule [ "services" "xserver" "vaapiDrivers" ] [ "hardware" "opengl" "extraPackages" ])
|
||||
(lib.mkRenamedOptionModule [ "services" "xserver" "vaapiDrivers" ] [ "hardware" "graphics" "extraPackages" ])
|
||||
(lib.mkRemovedOptionModule [ "hardware" "opengl" "s3tcSupport" ] "S3TC support is now always enabled in Mesa.")
|
||||
(lib.mkRemovedOptionModule [ "hardware" "opengl" "driSupport"] "The setting can be removed.")
|
||||
|
||||
@ -100,7 +100,7 @@ in
|
||||
config = lib.mkIf cfg.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion = cfg.enable32Bit -> pkgs.stdenv.isx86_64;
|
||||
assertion = cfg.enable32Bit -> pkgs.stdenv.hostPlatform.isx86_64;
|
||||
message = "`hardware.graphics.enable32Bit` only makes sense on a 64-bit system.";
|
||||
}
|
||||
{
|
||||
@ -112,7 +112,7 @@ in
|
||||
systemd.tmpfiles.settings.graphics-driver = {
|
||||
"/run/opengl-driver"."L+".argument = toString driversEnv;
|
||||
"/run/opengl-driver-32" =
|
||||
if pkgs.stdenv.isi686 then
|
||||
if pkgs.stdenv.hostPlatform.isi686 then
|
||||
{ "L+".argument = "opengl-driver"; }
|
||||
else if cfg.enable32Bit then
|
||||
{ "L+".argument = toString driversEnv32; }
|
||||
|
@ -772,9 +772,10 @@ in
|
||||
# here and it causes a cyclic dependency.
|
||||
boot.loader.grub.enable = false;
|
||||
|
||||
environment.systemPackages = [ grubPkgs.grub2 grubPkgs.grub2_efi ]
|
||||
environment.systemPackages = [ grubPkgs.grub2 ]
|
||||
++ lib.optional (config.isoImage.makeBiosBootable) pkgs.syslinux
|
||||
;
|
||||
system.extraDependencies = [ grubPkgs.grub2_efi ];
|
||||
|
||||
# In stage 1 of the boot, mount the CD as the root FS by label so
|
||||
# that we don't need to know its device. We pass the label of the
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
x86_64-linux = "/nix/store/mczjdfprd67mdn90488854bf6b3nkp8j-nix-2.18.7";
|
||||
i686-linux = "/nix/store/qqll8zrx7ibdx34ry1ijanqdpdpnibbc-nix-2.18.7";
|
||||
aarch64-linux = "/nix/store/lwysvjn745fwsz8nv13zzsfq0dhiyxlp-nix-2.18.7";
|
||||
x86_64-darwin = "/nix/store/frzvlvzzj7hwvg8p0y0ivl27430nxhfy-nix-2.18.7";
|
||||
aarch64-darwin = "/nix/store/43dp3pl3k95gszp1hl9sjm22gly65sxi-nix-2.18.7";
|
||||
x86_64-linux = "/nix/store/vhv7ckr0winivvwfqxd54d6pgq2hx1is-nix-2.18.8";
|
||||
i686-linux = "/nix/store/8x7rmgi225r5kygpf17swvk3vll0c61y-nix-2.18.8";
|
||||
aarch64-linux = "/nix/store/sbyj0rb1wd314zfxpf834d0clvxrxmv3-nix-2.18.8";
|
||||
x86_64-darwin = "/nix/store/vsy1wl865md71qv177nchj0aj5p26pkl-nix-2.18.8";
|
||||
aarch64-darwin = "/nix/store/54kqc2da3fjyjgzab4vaszxjmdvii6yk-nix-2.18.8";
|
||||
}
|
||||
|
@ -216,7 +216,7 @@ in
|
||||
imports = let
|
||||
mkToolModule = { name, package ? pkgs.${name} }: { config, ... }: {
|
||||
options.system.tools.${name}.enable = lib.mkEnableOption "${name} script" // {
|
||||
default = true;
|
||||
default = config.nix.enable;
|
||||
internal = true;
|
||||
};
|
||||
|
||||
|
@ -1192,6 +1192,7 @@
|
||||
./services/networking/scion/scion-daemon.nix
|
||||
./services/networking/scion/scion-dispatcher.nix
|
||||
./services/networking/scion/scion-router.nix
|
||||
./services/networking/scion/scion-ip-gateway.nix
|
||||
./services/networking/seafile.nix
|
||||
./services/networking/searx.nix
|
||||
./services/networking/shadowsocks.nix
|
||||
@ -1391,6 +1392,7 @@
|
||||
./services/web-apps/chatgpt-retrieval-plugin.nix
|
||||
./services/web-apps/cloudlog.nix
|
||||
./services/web-apps/code-server.nix
|
||||
./services/web-apps/collabora-online.nix
|
||||
./services/web-apps/commafeed.nix
|
||||
./services/web-apps/convos.nix
|
||||
./services/web-apps/crabfit.nix
|
||||
@ -1430,6 +1432,7 @@
|
||||
./services/web-apps/icingaweb2/icingaweb2.nix
|
||||
./services/web-apps/icingaweb2/module-monitoring.nix
|
||||
./services/web-apps/ifm.nix
|
||||
./services/web-apps/immich.nix
|
||||
./services/web-apps/invidious.nix
|
||||
./services/web-apps/invoiceplane.nix
|
||||
./services/web-apps/isso.nix
|
||||
@ -1639,6 +1642,7 @@
|
||||
./system/boot/systemd/sysupdate.nix
|
||||
./system/boot/systemd/sysusers.nix
|
||||
./system/boot/systemd/tmpfiles.nix
|
||||
./system/boot/systemd/tpm2.nix
|
||||
./system/boot/systemd/user.nix
|
||||
./system/boot/systemd/userdbd.nix
|
||||
./system/boot/systemd/homed.nix
|
||||
|
@ -52,7 +52,7 @@ in
|
||||
# VMware support.
|
||||
"mptspi" "vmxnet3" "vsock"
|
||||
] ++ lib.optional platform.isx86 "vmw_balloon"
|
||||
++ lib.optionals (pkgs.stdenv.isi686 || pkgs.stdenv.isx86_64) [
|
||||
++ lib.optionals (pkgs.stdenv.hostPlatform.isi686 || pkgs.stdenv.hostPlatform.isx86_64) [
|
||||
"vmw_vmci" "vmwgfx" "vmw_vsock_vmci_transport"
|
||||
|
||||
# Hyper-V support.
|
||||
@ -68,7 +68,7 @@ in
|
||||
|
||||
# Broadcom
|
||||
"vc4"
|
||||
] ++ lib.optionals pkgs.stdenv.isAarch64 [
|
||||
] ++ lib.optionals pkgs.stdenv.hostPlatform.isAarch64 [
|
||||
# Most of the following falls into two categories:
|
||||
# - early KMS / early display
|
||||
# - early storage (e.g. USB) support
|
||||
|
@ -19,13 +19,7 @@
|
||||
pkgs.cryptsetup # needed for dm-crypt volumes
|
||||
|
||||
# Some text editors.
|
||||
(pkgs.vim.customize {
|
||||
name = "vim";
|
||||
vimrcConfig.packages.default = {
|
||||
start = [ pkgs.vimPlugins.vim-nix ];
|
||||
};
|
||||
vimrcConfig.customRC = "syntax on";
|
||||
})
|
||||
pkgs.vim
|
||||
|
||||
# Some networking tools.
|
||||
pkgs.fuse
|
||||
|
@ -1,4 +1,9 @@
|
||||
{ pkgs, config, lib, ... }:
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
cfg = config.programs.firefox;
|
||||
@ -78,7 +83,7 @@ in
|
||||
|
||||
wrapperConfig = lib.mkOption {
|
||||
type = lib.types.attrs;
|
||||
default = {};
|
||||
default = { };
|
||||
description = "Arguments to pass to Firefox wrapper";
|
||||
};
|
||||
|
||||
@ -99,7 +104,13 @@ in
|
||||
};
|
||||
|
||||
preferences = lib.mkOption {
|
||||
type = with lib.types; attrsOf (oneOf [ bool int str ]);
|
||||
type =
|
||||
with lib.types;
|
||||
attrsOf (oneOf [
|
||||
bool
|
||||
int
|
||||
str
|
||||
]);
|
||||
default = { };
|
||||
description = ''
|
||||
Preferences to set from `about:config`.
|
||||
@ -112,7 +123,12 @@ in
|
||||
};
|
||||
|
||||
preferencesStatus = lib.mkOption {
|
||||
type = lib.types.enum [ "default" "locked" "user" "clear" ];
|
||||
type = lib.types.enum [
|
||||
"default"
|
||||
"locked"
|
||||
"user"
|
||||
"clear"
|
||||
];
|
||||
default = "locked";
|
||||
description = ''
|
||||
The status of `firefox.preferences`.
|
||||
@ -127,111 +143,113 @@ in
|
||||
|
||||
languagePacks = lib.mkOption {
|
||||
# Available languages can be found in https://releases.mozilla.org/pub/firefox/releases/${cfg.package.version}/linux-x86_64/xpi/
|
||||
type = lib.types.listOf (lib.types.enum ([
|
||||
"ach"
|
||||
"af"
|
||||
"an"
|
||||
"ar"
|
||||
"ast"
|
||||
"az"
|
||||
"be"
|
||||
"bg"
|
||||
"bn"
|
||||
"br"
|
||||
"bs"
|
||||
"ca-valencia"
|
||||
"ca"
|
||||
"cak"
|
||||
"cs"
|
||||
"cy"
|
||||
"da"
|
||||
"de"
|
||||
"dsb"
|
||||
"el"
|
||||
"en-CA"
|
||||
"en-GB"
|
||||
"en-US"
|
||||
"eo"
|
||||
"es-AR"
|
||||
"es-CL"
|
||||
"es-ES"
|
||||
"es-MX"
|
||||
"et"
|
||||
"eu"
|
||||
"fa"
|
||||
"ff"
|
||||
"fi"
|
||||
"fr"
|
||||
"fur"
|
||||
"fy-NL"
|
||||
"ga-IE"
|
||||
"gd"
|
||||
"gl"
|
||||
"gn"
|
||||
"gu-IN"
|
||||
"he"
|
||||
"hi-IN"
|
||||
"hr"
|
||||
"hsb"
|
||||
"hu"
|
||||
"hy-AM"
|
||||
"ia"
|
||||
"id"
|
||||
"is"
|
||||
"it"
|
||||
"ja"
|
||||
"ka"
|
||||
"kab"
|
||||
"kk"
|
||||
"km"
|
||||
"kn"
|
||||
"ko"
|
||||
"lij"
|
||||
"lt"
|
||||
"lv"
|
||||
"mk"
|
||||
"mr"
|
||||
"ms"
|
||||
"my"
|
||||
"nb-NO"
|
||||
"ne-NP"
|
||||
"nl"
|
||||
"nn-NO"
|
||||
"oc"
|
||||
"pa-IN"
|
||||
"pl"
|
||||
"pt-BR"
|
||||
"pt-PT"
|
||||
"rm"
|
||||
"ro"
|
||||
"ru"
|
||||
"sat"
|
||||
"sc"
|
||||
"sco"
|
||||
"si"
|
||||
"sk"
|
||||
"skr"
|
||||
"sl"
|
||||
"son"
|
||||
"sq"
|
||||
"sr"
|
||||
"sv-SE"
|
||||
"szl"
|
||||
"ta"
|
||||
"te"
|
||||
"tg"
|
||||
"th"
|
||||
"tl"
|
||||
"tr"
|
||||
"trs"
|
||||
"uk"
|
||||
"ur"
|
||||
"uz"
|
||||
"vi"
|
||||
"xh"
|
||||
"zh-CN"
|
||||
"zh-TW"
|
||||
]));
|
||||
type = lib.types.listOf (
|
||||
lib.types.enum ([
|
||||
"ach"
|
||||
"af"
|
||||
"an"
|
||||
"ar"
|
||||
"ast"
|
||||
"az"
|
||||
"be"
|
||||
"bg"
|
||||
"bn"
|
||||
"br"
|
||||
"bs"
|
||||
"ca-valencia"
|
||||
"ca"
|
||||
"cak"
|
||||
"cs"
|
||||
"cy"
|
||||
"da"
|
||||
"de"
|
||||
"dsb"
|
||||
"el"
|
||||
"en-CA"
|
||||
"en-GB"
|
||||
"en-US"
|
||||
"eo"
|
||||
"es-AR"
|
||||
"es-CL"
|
||||
"es-ES"
|
||||
"es-MX"
|
||||
"et"
|
||||
"eu"
|
||||
"fa"
|
||||
"ff"
|
||||
"fi"
|
||||
"fr"
|
||||
"fur"
|
||||
"fy-NL"
|
||||
"ga-IE"
|
||||
"gd"
|
||||
"gl"
|
||||
"gn"
|
||||
"gu-IN"
|
||||
"he"
|
||||
"hi-IN"
|
||||
"hr"
|
||||
"hsb"
|
||||
"hu"
|
||||
"hy-AM"
|
||||
"ia"
|
||||
"id"
|
||||
"is"
|
||||
"it"
|
||||
"ja"
|
||||
"ka"
|
||||
"kab"
|
||||
"kk"
|
||||
"km"
|
||||
"kn"
|
||||
"ko"
|
||||
"lij"
|
||||
"lt"
|
||||
"lv"
|
||||
"mk"
|
||||
"mr"
|
||||
"ms"
|
||||
"my"
|
||||
"nb-NO"
|
||||
"ne-NP"
|
||||
"nl"
|
||||
"nn-NO"
|
||||
"oc"
|
||||
"pa-IN"
|
||||
"pl"
|
||||
"pt-BR"
|
||||
"pt-PT"
|
||||
"rm"
|
||||
"ro"
|
||||
"ru"
|
||||
"sat"
|
||||
"sc"
|
||||
"sco"
|
||||
"si"
|
||||
"sk"
|
||||
"skr"
|
||||
"sl"
|
||||
"son"
|
||||
"sq"
|
||||
"sr"
|
||||
"sv-SE"
|
||||
"szl"
|
||||
"ta"
|
||||
"te"
|
||||
"tg"
|
||||
"th"
|
||||
"tl"
|
||||
"tr"
|
||||
"trs"
|
||||
"uk"
|
||||
"ur"
|
||||
"uz"
|
||||
"vi"
|
||||
"xh"
|
||||
"zh-CN"
|
||||
"zh-TW"
|
||||
])
|
||||
);
|
||||
default = [ ];
|
||||
description = ''
|
||||
The language packs to install.
|
||||
@ -249,10 +267,23 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
autoConfigFiles = lib.mkOption {
|
||||
type = with lib.types; listOf path;
|
||||
default = [ ];
|
||||
description = ''
|
||||
AutoConfig files can be used to set and lock preferences that are not covered
|
||||
by the policies.json for Mac and Linux. This method can be used to automatically
|
||||
change user preferences or prevent the end user from modifiying specific
|
||||
preferences by locking them. More info can be found in https://support.mozilla.org/en-US/kb/customizing-firefox-using-autoconfig.
|
||||
|
||||
Files are concated and autoConfig is appended.
|
||||
'';
|
||||
};
|
||||
|
||||
nativeMessagingHosts = ({
|
||||
packages = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.package;
|
||||
default = [];
|
||||
default = [ ];
|
||||
description = ''
|
||||
Additional packages containing native messaging hosts that should be made available to Firefox extensions.
|
||||
'';
|
||||
@ -260,48 +291,64 @@ in
|
||||
}) // (builtins.mapAttrs (k: v: lib.mkEnableOption "${v.name} support") nmhOptions);
|
||||
};
|
||||
|
||||
config = let
|
||||
forEachEnabledNmh = fn: lib.flatten (lib.mapAttrsToList (k: v: lib.optional cfg.nativeMessagingHosts.${k} (fn k v)) nmhOptions);
|
||||
in lib.mkIf cfg.enable {
|
||||
warnings = forEachEnabledNmh (k: v:
|
||||
"The `programs.firefox.nativeMessagingHosts.${k}` option is deprecated, " +
|
||||
"please add `${v.package.pname}` to `programs.firefox.nativeMessagingHosts.packages` instead."
|
||||
);
|
||||
programs.firefox.nativeMessagingHosts.packages = forEachEnabledNmh (_: v: v.package);
|
||||
config =
|
||||
let
|
||||
forEachEnabledNmh =
|
||||
fn:
|
||||
lib.flatten (
|
||||
lib.mapAttrsToList (k: v: lib.optional cfg.nativeMessagingHosts.${k} (fn k v)) nmhOptions
|
||||
);
|
||||
in
|
||||
lib.mkIf cfg.enable {
|
||||
warnings = forEachEnabledNmh (
|
||||
k: v:
|
||||
"The `programs.firefox.nativeMessagingHosts.${k}` option is deprecated, "
|
||||
+ "please add `${v.package.pname}` to `programs.firefox.nativeMessagingHosts.packages` instead."
|
||||
);
|
||||
programs.firefox.nativeMessagingHosts.packages = forEachEnabledNmh (_: v: v.package);
|
||||
|
||||
environment.systemPackages = [
|
||||
(cfg.package.override (old: {
|
||||
extraPrefsFiles = old.extraPrefsFiles or [] ++ [(pkgs.writeText "firefox-autoconfig.js" cfg.autoConfig)];
|
||||
nativeMessagingHosts = old.nativeMessagingHosts or [] ++ cfg.nativeMessagingHosts.packages;
|
||||
cfg = (old.cfg or {}) // cfg.wrapperConfig;
|
||||
}))
|
||||
];
|
||||
environment.systemPackages = [
|
||||
(cfg.package.override (old: {
|
||||
extraPrefsFiles =
|
||||
old.extraPrefsFiles or [ ]
|
||||
++ cfg.autoConfigFiles
|
||||
++ [ (pkgs.writeText "firefox-autoconfig.js" cfg.autoConfig) ];
|
||||
nativeMessagingHosts = old.nativeMessagingHosts or [ ] ++ cfg.nativeMessagingHosts.packages;
|
||||
cfg = (old.cfg or { }) // cfg.wrapperConfig;
|
||||
}))
|
||||
];
|
||||
|
||||
environment.etc =
|
||||
let
|
||||
policiesJSON = policyFormat.generate "firefox-policies.json" { inherit (cfg) policies; };
|
||||
in
|
||||
lib.mkIf (cfg.policies != { }) {
|
||||
"firefox/policies/policies.json".source = "${policiesJSON}";
|
||||
environment.etc =
|
||||
let
|
||||
policiesJSON = policyFormat.generate "firefox-policies.json" { inherit (cfg) policies; };
|
||||
in
|
||||
lib.mkIf (cfg.policies != { }) {
|
||||
"firefox/policies/policies.json".source = "${policiesJSON}";
|
||||
};
|
||||
|
||||
# Preferences are converted into a policy
|
||||
programs.firefox.policies = {
|
||||
DisableAppUpdate = true;
|
||||
Preferences = (
|
||||
builtins.mapAttrs (_: value: {
|
||||
Value = value;
|
||||
Status = cfg.preferencesStatus;
|
||||
}) cfg.preferences
|
||||
);
|
||||
ExtensionSettings = builtins.listToAttrs (
|
||||
builtins.map (
|
||||
lang:
|
||||
lib.attrsets.nameValuePair "langpack-${lang}@firefox.mozilla.org" {
|
||||
installation_mode = "normal_installed";
|
||||
install_url = "https://releases.mozilla.org/pub/firefox/releases/${cfg.package.version}/linux-x86_64/xpi/${lang}.xpi";
|
||||
}
|
||||
) cfg.languagePacks
|
||||
);
|
||||
};
|
||||
|
||||
# Preferences are converted into a policy
|
||||
programs.firefox.policies = {
|
||||
DisableAppUpdate = true;
|
||||
Preferences = (builtins.mapAttrs
|
||||
(_: value: { Value = value; Status = cfg.preferencesStatus; })
|
||||
cfg.preferences);
|
||||
ExtensionSettings = builtins.listToAttrs (builtins.map
|
||||
(lang: lib.attrsets.nameValuePair
|
||||
"langpack-${lang}@firefox.mozilla.org"
|
||||
{
|
||||
installation_mode = "normal_installed";
|
||||
install_url = "https://releases.mozilla.org/pub/firefox/releases/${cfg.package.version}/linux-x86_64/xpi/${lang}.xpi";
|
||||
}
|
||||
)
|
||||
cfg.languagePacks);
|
||||
};
|
||||
};
|
||||
|
||||
meta.maintainers = with lib.maintainers; [ danth ];
|
||||
meta.maintainers = with lib.maintainers; [
|
||||
danth
|
||||
linsui
|
||||
];
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ let
|
||||
pcmPlugin = cfg.jackd.enable && cfg.alsa.enable;
|
||||
loopback = cfg.jackd.enable && cfg.loopback.enable;
|
||||
|
||||
enable32BitAlsaPlugins = cfg.alsa.support32Bit && pkgs.stdenv.isx86_64 && pkgs.pkgsi686Linux.alsa-lib != null;
|
||||
enable32BitAlsaPlugins = cfg.alsa.support32Bit && pkgs.stdenv.hostPlatform.isx86_64 && pkgs.pkgsi686Linux.alsa-lib != null;
|
||||
|
||||
umaskNeeded = versionOlder cfg.jackd.package.version "1.9.12";
|
||||
bridgeNeeded = versionAtLeast cfg.jackd.package.version "1.9.12";
|
||||
|
@ -30,12 +30,12 @@ let
|
||||
lib.optionalString (val != null) "${val}";
|
||||
os' = prefix: val:
|
||||
lib.optionalString (val != null) (prefix + "${val}");
|
||||
flatten = key: value:
|
||||
toQueryString = key: value:
|
||||
"&${key}=${value}";
|
||||
in
|
||||
"--stream.stream=\"${opt.type}://" + os opt.location + "?" + os' "name=" name
|
||||
+ os' "&sampleformat=" opt.sampleFormat + os' "&codec=" opt.codec
|
||||
+ lib.concatStrings (lib.mapAttrsToList lib.flatten opt.query) + "\"";
|
||||
+ lib.concatStrings (lib.mapAttrsToList toQueryString opt.query) + "\"";
|
||||
|
||||
optionalNull = val: ret:
|
||||
lib.optional (val != null) ret;
|
||||
|
@ -67,16 +67,16 @@ let
|
||||
inherit (cfg.provision) organizations users;
|
||||
});
|
||||
|
||||
provisioningScript = pkgs.writeShellScript "post-start-provision" ''
|
||||
set -euo pipefail
|
||||
export INFLUX_HOST="http://"${escapeShellArg (
|
||||
influxHost = "http://${escapeShellArg (
|
||||
if ! hasAttr "http-bind-address" cfg.settings
|
||||
|| hasInfix "0.0.0.0" cfg.settings.http-bind-address
|
||||
then "localhost:8086"
|
||||
else cfg.settings.http-bind-address
|
||||
)}
|
||||
)}";
|
||||
|
||||
# Wait for the influxdb server to come online
|
||||
waitUntilServiceIsReady = pkgs.writeShellScript "wait-until-service-is-ready" ''
|
||||
set -euo pipefail
|
||||
export INFLUX_HOST=${influxHost}
|
||||
count=0
|
||||
while ! influx ping &>/dev/null; do
|
||||
if [ "$count" -eq 300 ]; then
|
||||
@ -92,6 +92,11 @@ let
|
||||
sleep 0.1
|
||||
count=$((count++))
|
||||
done
|
||||
'';
|
||||
|
||||
provisioningScript = pkgs.writeShellScript "post-start-provision" ''
|
||||
set -euo pipefail
|
||||
export INFLUX_HOST=${influxHost}
|
||||
|
||||
# Do the initial database setup. Pass /dev/null as configs-path to
|
||||
# avoid saving the token as the active config.
|
||||
@ -433,6 +438,7 @@ in
|
||||
ZONEINFO = "${pkgs.tzdata}/share/zoneinfo";
|
||||
};
|
||||
serviceConfig = {
|
||||
Type = "exec"; # When credentials are used with systemd before v257 this is necessary to make the service start reliably (see systemd/systemd#33953)
|
||||
ExecStart = "${cfg.package}/bin/influxd --bolt-path \${STATE_DIRECTORY}/influxd.bolt --engine-path \${STATE_DIRECTORY}/engine";
|
||||
StateDirectory = "influxdb2";
|
||||
User = "influxdb2";
|
||||
@ -447,11 +453,13 @@ in
|
||||
"admin-token:${cfg.provision.initialSetup.tokenFile}"
|
||||
];
|
||||
|
||||
ExecStartPost = mkIf cfg.provision.enable (
|
||||
ExecStartPost = [
|
||||
waitUntilServiceIsReady
|
||||
] ++ (lib.optionals cfg.provision.enable (
|
||||
[provisioningScript] ++
|
||||
# Only the restarter runs with elevated privileges
|
||||
optional anyAuthDefined "+${restarterScript}"
|
||||
);
|
||||
));
|
||||
};
|
||||
|
||||
path = [
|
||||
|
@ -35,3 +35,10 @@ Note that the TigerBeetle module won't open any firewall ports automatically, so
|
||||
|
||||
A complete list of options for TigerBeetle can be found [here](#opt-services.tigerbeetle.enable).
|
||||
|
||||
## Upgrading {#module-services-tigerbeetle-upgrading}
|
||||
|
||||
Usually, TigerBeetle's [upgrade process](https://docs.tigerbeetle.com/operating/upgrading) only requires replacing the binary used for the servers.
|
||||
This is not directly possible with NixOS since the new binary will be located at a different place in the Nix store.
|
||||
|
||||
However, since TigerBeetle is managed through systemd on NixOS, the only action you need to take when upgrading is to make sure the version of TigerBeetle you're upgrading to supports upgrades from the version you're currently running.
|
||||
This information will be on the [release notes](https://github.com/tigerbeetle/tigerbeetle/releases) for the version you're upgrading to.
|
||||
|
@ -42,8 +42,8 @@ in
|
||||
};
|
||||
|
||||
cacheGridSize = mkOption {
|
||||
type = types.strMatching "[0-9]+(K|M|G)B";
|
||||
default = "1GB";
|
||||
type = types.strMatching "[0-9]+(K|M|G)iB";
|
||||
default = "1GiB";
|
||||
description = ''
|
||||
The grid cache size.
|
||||
The grid cache acts like a page cache for TigerBeetle.
|
||||
@ -97,16 +97,26 @@ in
|
||||
'';
|
||||
|
||||
serviceConfig = {
|
||||
Type = "exec";
|
||||
|
||||
DynamicUser = true;
|
||||
ProtectHome = true;
|
||||
DevicePolicy = "closed";
|
||||
|
||||
DynamicUser = true;
|
||||
ExecStart = "${lib.getExe cfg.package} start --cache-grid=${cfg.cacheGridSize} --addresses=${lib.escapeShellArg (builtins.concatStringsSep "," cfg.addresses)} ${replicaDataPath}";
|
||||
LockPersonality = true;
|
||||
ProtectClock = true;
|
||||
ProtectControlGroups = true;
|
||||
ProtectHome = true;
|
||||
ProtectHostname = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectProc = "noaccess";
|
||||
ProtectSystem = "strict";
|
||||
RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ];
|
||||
RestrictNamespaces = true;
|
||||
RestrictRealtime = true;
|
||||
RestrictSUIDSGID = true;
|
||||
StateDirectory = "tigerbeetle";
|
||||
StateDirectoryMode = 700;
|
||||
|
||||
ExecStart = "${lib.getExe cfg.package} start --cache-grid=${cfg.cacheGridSize} --addresses=${lib.escapeShellArg (builtins.concatStringsSep "," cfg.addresses)} ${replicaDataPath}";
|
||||
Type = "exec";
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -143,10 +143,12 @@ in {
|
||||
kate
|
||||
khelpcenter
|
||||
dolphin
|
||||
baloo-widgets # baloo information in Dolphin
|
||||
dolphin-plugins
|
||||
spectacle
|
||||
ffmpegthumbs
|
||||
krdp
|
||||
xwaylandvideobridge # exposes Wayland windows to X11 screen capture
|
||||
] ++ lib.optionals config.services.flatpak.enable [
|
||||
# Since PackageKit Nix support is not there yet,
|
||||
# only install discover if flatpak is enabled.
|
||||
@ -245,7 +247,10 @@ in {
|
||||
xdg.icons.enable = true;
|
||||
|
||||
xdg.portal.enable = true;
|
||||
xdg.portal.extraPortals = [kdePackages.xdg-desktop-portal-kde];
|
||||
xdg.portal.extraPortals = [
|
||||
kdePackages.xdg-desktop-portal-kde
|
||||
pkgs.xdg-desktop-portal-gtk
|
||||
];
|
||||
xdg.portal.configPackages = mkDefault [kdePackages.xdg-desktop-portal-kde];
|
||||
services.pipewire.enable = mkDefault true;
|
||||
|
||||
|
@ -19,7 +19,7 @@ let
|
||||
'';
|
||||
cfg = config.services.pipewire;
|
||||
enable32BitAlsaPlugins = cfg.alsa.support32Bit
|
||||
&& pkgs.stdenv.isx86_64
|
||||
&& pkgs.stdenv.hostPlatform.isx86_64
|
||||
&& pkgs.pkgsi686Linux.pipewire != null;
|
||||
|
||||
# The package doesn't output to $out/lib/pipewire directly so that the
|
||||
|
@ -18,15 +18,15 @@ in {
|
||||
type = lib.types.submodule {
|
||||
freeformType = format.type;
|
||||
options = {
|
||||
Touch = {
|
||||
Touchscreen = {
|
||||
DisableOnPalm = lib.mkOption {
|
||||
default = false;
|
||||
description = "Ignore all touch inputs if a palm was registered on the display.";
|
||||
description = "Ignore all touchscreen inputs if a palm was registered on the display.";
|
||||
type = lib.types.bool;
|
||||
};
|
||||
DisableOnStylus = lib.mkOption {
|
||||
default = false;
|
||||
description = "Ignore all touch inputs if a stylus is in proximity.";
|
||||
description = "Ignore all touchscreen inputs if a stylus is in proximity.";
|
||||
type = lib.types.bool;
|
||||
};
|
||||
};
|
||||
@ -43,6 +43,10 @@ in {
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
warnings = lib.optional (lib.hasAttr "Touch" cfg.config) ''
|
||||
The option `services.iptsd.config.Touch` has been renamed to `services.iptsd.config.Touchscreen`.
|
||||
'';
|
||||
|
||||
systemd.packages = [ pkgs.iptsd ];
|
||||
environment.etc."iptsd.conf".source = configFile;
|
||||
systemd.services."iptsd@".restartTriggers = [ configFile ];
|
||||
|
@ -80,7 +80,7 @@ in {
|
||||
PrivateUsers = true;
|
||||
|
||||
SupplementaryGroups = lib.optional (allowSystemdJournal) "systemd-journal";
|
||||
} // (optionalAttrs (!pkgs.stdenv.isAarch64) { # FIXME: figure out why this breaks on aarch64
|
||||
} // (optionalAttrs (!pkgs.stdenv.hostPlatform.isAarch64) { # FIXME: figure out why this breaks on aarch64
|
||||
SystemCallFilter = "@system-service";
|
||||
});
|
||||
};
|
||||
|
@ -30,6 +30,10 @@ let
|
||||
ENGINE = "haystack.backends.whoosh_backend.WhooshEngine";
|
||||
PATH = "/var/lib/mailman-web/fulltext-index";
|
||||
};
|
||||
} // lib.optionalAttrs cfg.enablePostfix {
|
||||
EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend";
|
||||
EMAIL_HOST = "127.0.0.1";
|
||||
EMAIL_PORT = 25;
|
||||
} // cfg.webSettings;
|
||||
|
||||
webSettingsJSON = pkgs.writeText "settings.json" (builtins.toJSON webSettings);
|
||||
|
@ -1,7 +1,7 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
let
|
||||
cfg = config.services.mame;
|
||||
mame = "mame${lib.optionalString pkgs.stdenv.is64bit "64"}";
|
||||
mame = "mame${lib.optionalString pkgs.stdenv.hostPlatform.is64bit "64"}";
|
||||
in
|
||||
{
|
||||
options = {
|
||||
|
@ -35,6 +35,14 @@ let
|
||||
descriptionClass = "conjunction";
|
||||
};
|
||||
|
||||
intOrNumberOrRange = lib.types.either lib.types.ints.unsigned (
|
||||
lib.types.strMatching "[[:digit:]]+(\-[[:digit:]]+)?"
|
||||
// {
|
||||
description = "string containing either a number or a range";
|
||||
descriptionClass = "conjunction";
|
||||
}
|
||||
);
|
||||
|
||||
configOptions = {
|
||||
SUBVOLUME = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
@ -93,7 +101,7 @@ let
|
||||
};
|
||||
|
||||
TIMELINE_LIMIT_HOURLY = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
type = intOrNumberOrRange;
|
||||
default = 10;
|
||||
description = ''
|
||||
Limits for timeline cleanup.
|
||||
@ -101,7 +109,7 @@ let
|
||||
};
|
||||
|
||||
TIMELINE_LIMIT_DAILY = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
type = intOrNumberOrRange;
|
||||
default = 10;
|
||||
description = ''
|
||||
Limits for timeline cleanup.
|
||||
@ -109,7 +117,7 @@ let
|
||||
};
|
||||
|
||||
TIMELINE_LIMIT_WEEKLY = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
type = intOrNumberOrRange;
|
||||
default = 0;
|
||||
description = ''
|
||||
Limits for timeline cleanup.
|
||||
@ -117,7 +125,7 @@ let
|
||||
};
|
||||
|
||||
TIMELINE_LIMIT_MONTHLY = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
type = intOrNumberOrRange;
|
||||
default = 10;
|
||||
description = ''
|
||||
Limits for timeline cleanup.
|
||||
@ -125,7 +133,7 @@ let
|
||||
};
|
||||
|
||||
TIMELINE_LIMIT_QUARTERLY = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
type = intOrNumberOrRange;
|
||||
default = 0;
|
||||
description = ''
|
||||
Limits for timeline cleanup.
|
||||
@ -133,7 +141,7 @@ let
|
||||
};
|
||||
|
||||
TIMELINE_LIMIT_YEARLY = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
type = intOrNumberOrRange;
|
||||
default = 10;
|
||||
description = ''
|
||||
Limits for timeline cleanup.
|
||||
|
@ -71,7 +71,7 @@ in
|
||||
|
||||
- nixpkgs.config.cudaSupport
|
||||
- nixpkgs.config.rocmSupport
|
||||
- if stdenv.isDarwin && stdenv.isAarch64
|
||||
- if stdenv.hostPlatform.isDarwin && stdenv.hostPlatform.isAarch64
|
||||
|
||||
IFF multiple acceleration methods are found to be enabled or if you
|
||||
haven't set either `cudaSupport or rocmSupport` you will have to
|
||||
|
@ -274,7 +274,7 @@ in
|
||||
CapabilityBoundingSet = "CAP_NET_ADMIN CAP_NET_RAW CAP_SETUID";
|
||||
ProtectSystem = true;
|
||||
# Doesn't work on i686, causing service to fail
|
||||
MemoryDenyWriteExecute = !pkgs.stdenv.isi686;
|
||||
MemoryDenyWriteExecute = !pkgs.stdenv.hostPlatform.isi686;
|
||||
ProtectHome = true;
|
||||
PrivateTmp = true;
|
||||
};
|
||||
|
@ -603,8 +603,8 @@ in
|
||||
|
||||
reuseport = mkOption {
|
||||
type = types.bool;
|
||||
default = pkgs.stdenv.isLinux;
|
||||
defaultText = literalExpression "pkgs.stdenv.isLinux";
|
||||
default = pkgs.stdenv.hostPlatform.isLinux;
|
||||
defaultText = literalExpression "pkgs.stdenv.hostPlatform.isLinux";
|
||||
description = ''
|
||||
Whether to enable SO_REUSEPORT on all used sockets. This lets multiple
|
||||
processes bind to the same port. This speeds up operation especially
|
||||
|
92
nixos/modules/services/networking/scion/scion-ip-gateway.nix
Normal file
92
nixos/modules/services/networking/scion/scion-ip-gateway.nix
Normal file
@ -0,0 +1,92 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
globalCfg = config.services.scion;
|
||||
cfg = config.services.scion.scion-ip-gateway;
|
||||
toml = pkgs.formats.toml { };
|
||||
json = pkgs.formats.json { };
|
||||
connectionDir = if globalCfg.stateless then "/run" else "/var/lib";
|
||||
defaultConfig = {
|
||||
tunnel = { };
|
||||
gateway = {
|
||||
traffic_policy_file = "${trafficConfigFile}";
|
||||
};
|
||||
};
|
||||
defaultTrafficConfig = {
|
||||
ASes = { };
|
||||
ConfigVersion = 9001;
|
||||
};
|
||||
configFile = toml.generate "scion-ip-gateway.toml" (recursiveUpdate defaultConfig cfg.config);
|
||||
trafficConfigFile = json.generate "scion-ip-gateway-traffic.json" (
|
||||
recursiveUpdate defaultTrafficConfig cfg.trafficConfig
|
||||
);
|
||||
in
|
||||
{
|
||||
options.services.scion.scion-ip-gateway = {
|
||||
enable = mkEnableOption "the scion-ip-gateway service";
|
||||
config = mkOption {
|
||||
default = { };
|
||||
type = toml.type;
|
||||
example = literalExpression ''
|
||||
{
|
||||
tunnel = {
|
||||
src_ipv4 = "172.16.100.1";
|
||||
};
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
scion-ip-gateway daemon configuration
|
||||
'';
|
||||
};
|
||||
trafficConfig = mkOption {
|
||||
default = { };
|
||||
type = json.type;
|
||||
example = literalExpression ''
|
||||
{
|
||||
ASes = {
|
||||
"2-ffaa:0:b" = {
|
||||
Nets = [
|
||||
"172.16.1.0/24"
|
||||
];
|
||||
};
|
||||
};
|
||||
ConfigVersion = 9001;
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
scion-ip-gateway traffic configuration
|
||||
'';
|
||||
};
|
||||
};
|
||||
config = mkIf cfg.enable {
|
||||
systemd.services.scion-ip-gateway = {
|
||||
description = "SCION IP Gateway Service";
|
||||
after = [
|
||||
"network-online.target"
|
||||
"scion-dispatcher.service"
|
||||
];
|
||||
wants = [
|
||||
"network-online.target"
|
||||
"scion-dispatcher.service"
|
||||
];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
Group = if (config.services.scion.scion-dispatcher.enable == true) then "scion" else null;
|
||||
ExecStart = "${globalCfg.package}/bin/scion-ip-gateway --config ${configFile}";
|
||||
DynamicUser = true;
|
||||
AmbientCapabilities = [ "CAP_NET_ADMIN" ];
|
||||
Restart = "on-failure";
|
||||
KillMode = "control-group";
|
||||
RemainAfterExit = false;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
@ -42,6 +42,7 @@ in
|
||||
scion-daemon.enable = true;
|
||||
scion-router.enable = true;
|
||||
scion-control.enable = true;
|
||||
scion-ip-gateway.enable = true;
|
||||
};
|
||||
assertions = [
|
||||
{ assertion = cfg.bypassBootstrapWarning == true;
|
||||
|
@ -60,6 +60,33 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
authKeyParameters = mkOption {
|
||||
type = types.submodule {
|
||||
options = {
|
||||
ephemeral = mkOption {
|
||||
type = types.nullOr types.bool;
|
||||
default = null;
|
||||
description = "Whether to register as an ephemeral node.";
|
||||
};
|
||||
preauthorized = mkOption {
|
||||
type = types.nullOr types.bool;
|
||||
default = null;
|
||||
description = "Whether to skip manual device approval.";
|
||||
};
|
||||
baseURL = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "Base URL for the Tailscale API.";
|
||||
};
|
||||
};
|
||||
};
|
||||
default = { };
|
||||
description = ''
|
||||
Extra parameters to pass after the auth key.
|
||||
See https://tailscale.com/kb/1215/oauth-clients#registering-new-nodes-using-oauth-credentials
|
||||
'';
|
||||
};
|
||||
|
||||
extraUpFlags = mkOption {
|
||||
description = ''
|
||||
Extra flags to pass to {command}`tailscale up`. Only applied if `authKeyFile` is specified.";
|
||||
@ -124,13 +151,22 @@ in {
|
||||
# https://github.com/tailscale/tailscale/blob/v1.72.1/ipn/backend.go#L24-L32
|
||||
script = let
|
||||
statusCommand = "${lib.getExe cfg.package} status --json --peers=false | ${lib.getExe pkgs.jq} -r '.BackendState'";
|
||||
paramToString = v:
|
||||
if (builtins.isBool v) then (lib.boolToString v)
|
||||
else (toString v);
|
||||
params = lib.pipe cfg.authKeyParameters [
|
||||
(lib.filterAttrs (_: v: v != null))
|
||||
(lib.mapAttrsToList (k: v: "${k}=${paramToString v}"))
|
||||
(builtins.concatStringsSep "&")
|
||||
(params: if params != "" then "?${params}" else "")
|
||||
];
|
||||
in ''
|
||||
while [[ "$(${statusCommand})" == "NoState" ]]; do
|
||||
sleep 0.5
|
||||
done
|
||||
status=$(${statusCommand})
|
||||
if [[ "$status" == "NeedsLogin" || "$status" == "NeedsMachineAuth" ]]; then
|
||||
${lib.getExe cfg.package} up --auth-key 'file:${cfg.authKeyFile}' ${escapeShellArgs cfg.extraUpFlags}
|
||||
${lib.getExe cfg.package} up --auth-key "$(cat ${cfg.authKeyFile})${params}" ${escapeShellArgs cfg.extraUpFlags}
|
||||
fi
|
||||
'';
|
||||
};
|
||||
|
@ -9,7 +9,6 @@ let
|
||||
cfg = config.services.printing;
|
||||
cups = cfg.package;
|
||||
|
||||
avahiEnabled = config.services.avahi.enable;
|
||||
polkitEnabled = config.security.polkit.enable;
|
||||
|
||||
additionalBackends = pkgs.runCommand "additional-cups-backends" {
|
||||
@ -99,7 +98,7 @@ let
|
||||
cupsdFile
|
||||
(writeConf "client.conf" cfg.clientConf)
|
||||
(writeConf "snmp.conf" cfg.snmpConf)
|
||||
] ++ optional avahiEnabled browsedFile
|
||||
] ++ optional cfg.browsed.enable browsedFile
|
||||
++ cfg.drivers;
|
||||
pathsToLink = [ "/etc/cups" ];
|
||||
ignoreCollisions = true;
|
||||
@ -270,6 +269,15 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
browsed.enable = mkOption {
|
||||
type = types.bool;
|
||||
default = config.services.avahi.enable;
|
||||
defaultText = literalExpression "config.services.avahi.enable";
|
||||
description = ''
|
||||
Whether to enable the CUPS Remote Printer Discovery (browsed) daemon.
|
||||
'';
|
||||
};
|
||||
|
||||
browsedConf = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
@ -339,7 +347,7 @@ in
|
||||
services.dbus.packages = [ cups.out ] ++ optional polkitEnabled cups-pk-helper;
|
||||
services.udev.packages = cfg.drivers;
|
||||
|
||||
# Allow asswordless printer admin for members of wheel group
|
||||
# Allow passwordless printer admin for members of wheel group
|
||||
security.polkit.extraConfig = mkIf polkitEnabled ''
|
||||
polkit.addRule(function(action, subject) {
|
||||
if (action.id == "org.opensuse.cupspkhelper.mechanism.all-edit" &&
|
||||
@ -419,7 +427,7 @@ in
|
||||
serviceConfig.PrivateTmp = true;
|
||||
};
|
||||
|
||||
systemd.services.cups-browsed = mkIf avahiEnabled
|
||||
systemd.services.cups-browsed = mkIf cfg.browsed.enable
|
||||
{ description = "CUPS Remote Printer Discovery";
|
||||
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
@ -518,7 +518,7 @@ in
|
||||
libva-utils
|
||||
procps
|
||||
radeontop
|
||||
] ++ lib.optionals (!stdenv.isAarch64) [
|
||||
] ++ lib.optionals (!stdenv.hostPlatform.isAarch64) [
|
||||
# not available on aarch64-linux
|
||||
intel-gpu-tools
|
||||
];
|
||||
|
200
nixos/modules/services/web-apps/collabora-online.nix
Normal file
200
nixos/modules/services/web-apps/collabora-online.nix
Normal file
@ -0,0 +1,200 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
utils,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
cfg = config.services.collabora-online;
|
||||
|
||||
freeformType = lib.types.attrsOf ((pkgs.formats.json { }).type) // {
|
||||
description = ''
|
||||
`coolwsd.xml` configuration type, used to override values in the default configuration.
|
||||
|
||||
Attribute names correspond to XML tags unless prefixed with `@`. Nested attribute sets
|
||||
correspond to nested XML tags. Attribute prefixed with `@` correspond to XML attributes. E.g.,
|
||||
`{ storage.wopi."@allow" = true; }` in Nix corresponds to
|
||||
`<storage><wopi allow="true"/></storage>` in `coolwsd.xml`, or `--o:storage.wopi[@allow]=true`
|
||||
in the command line.
|
||||
|
||||
Arrays correspond to multiple elements with the same tag name. E.g.
|
||||
`{ host = [ '''127\.0\.0\.1''' "::1" ]; }` in Nix corresponds to
|
||||
```xml
|
||||
<net><post_allow>
|
||||
<host>127\.0\.0\.1</host>
|
||||
<host>::1</host>
|
||||
</post_allow></net>
|
||||
```
|
||||
in `coolwsd.xml`, or
|
||||
`--o:net.post_allow.host[0]='127\.0\.0\.1 --o:net.post_allow.host[1]=::1` in the command line.
|
||||
|
||||
Null values could be used to remove an element from the default configuration.
|
||||
'';
|
||||
};
|
||||
|
||||
configFile =
|
||||
pkgs.runCommandLocal "coolwsd.xml"
|
||||
{
|
||||
nativeBuildInputs = [
|
||||
pkgs.jq
|
||||
pkgs.yq-go
|
||||
];
|
||||
userConfig = builtins.toJSON { config = cfg.settings; };
|
||||
passAsFile = [ "userConfig" ];
|
||||
}
|
||||
# Merge the cfg.settings into the default coolwsd.xml.
|
||||
# See https://github.com/CollaboraOnline/online/issues/10049.
|
||||
''
|
||||
yq --input-format=xml \
|
||||
--xml-attribute-prefix=@ \
|
||||
--output-format=json \
|
||||
${cfg.package}/etc/coolwsd/coolwsd.xml \
|
||||
> ./default_coolwsd.json
|
||||
|
||||
jq '.[0] * .[1] | del(..|nulls)' \
|
||||
--slurp \
|
||||
./default_coolwsd.json \
|
||||
$userConfigPath \
|
||||
> ./merged.json
|
||||
|
||||
yq --output-format=xml \
|
||||
--xml-attribute-prefix=@ \
|
||||
./merged.json \
|
||||
> $out
|
||||
'';
|
||||
in
|
||||
{
|
||||
options.services.collabora-online = {
|
||||
enable = lib.mkEnableOption "collabora-online";
|
||||
|
||||
package = lib.mkPackageOption pkgs "Collabora Online" { default = "collabora-online"; };
|
||||
|
||||
port = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 9980;
|
||||
description = "Listening port";
|
||||
};
|
||||
|
||||
settings = lib.mkOption {
|
||||
type = freeformType;
|
||||
default = { };
|
||||
description = ''
|
||||
Configuration for Collabora Online WebSocket Daemon, see
|
||||
<https://sdk.collaboraonline.com/docs/installation/Configuration.html>, or
|
||||
<https://github.com/CollaboraOnline/online/blob/master/coolwsd.xml.in> for the default
|
||||
configuration.
|
||||
'';
|
||||
};
|
||||
|
||||
aliasGroups = lib.mkOption {
|
||||
type = lib.types.listOf (
|
||||
lib.types.submodule {
|
||||
options = {
|
||||
host = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
example = "scheme://hostname:port";
|
||||
description = "Hostname to allow or deny.";
|
||||
};
|
||||
|
||||
aliases = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
example = [
|
||||
"scheme://aliasname1:port"
|
||||
"scheme://aliasname2:port"
|
||||
];
|
||||
description = "A list of regex pattern of aliasname.";
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
default = [ ];
|
||||
description = "Alias groups to use.";
|
||||
};
|
||||
|
||||
extraArgs = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
description = "Extra arguments to pass to the service.";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
services.collabora-online.settings = {
|
||||
child_root_path = lib.mkDefault "/var/lib/cool/child-roots";
|
||||
sys_template_path = lib.mkDefault "/var/lib/cool/systemplate";
|
||||
|
||||
file_server_root_path = lib.mkDefault "${config.services.collabora-online.package}/share/coolwsd";
|
||||
|
||||
# Use mount namespaces instead of setcap'd coolmount/coolforkit.
|
||||
mount_namespaces = lib.mkDefault true;
|
||||
|
||||
# By default, use dummy self-signed certificates provided for testing.
|
||||
ssl.ca_file_path = lib.mkDefault "${config.services.collabora-online.package}/etc/coolwsd/ca-chain.cert.pem";
|
||||
ssl.cert_file_path = lib.mkDefault "${config.services.collabora-online.package}/etc/coolwsd/cert.pem";
|
||||
ssl.key_file_path = lib.mkDefault "${config.services.collabora-online.package}/etc/coolwsd/key.pem";
|
||||
};
|
||||
|
||||
users.users.cool = {
|
||||
isSystemUser = true;
|
||||
group = "cool";
|
||||
};
|
||||
users.groups.cool = { };
|
||||
|
||||
systemd.services.coolwsd-systemplate-setup = {
|
||||
description = "Collabora Online WebSocket Daemon Setup";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
ExecStart = utils.escapeSystemdExecArgs [
|
||||
"${cfg.package}/bin/coolwsd-systemplate-setup"
|
||||
"/var/lib/cool/systemplate"
|
||||
"${cfg.package.libreoffice}/lib/collaboraoffice"
|
||||
];
|
||||
RemainAfterExit = true;
|
||||
StateDirectory = "cool";
|
||||
Type = "oneshot";
|
||||
User = "cool";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.coolwsd = {
|
||||
description = "Collabora Online WebSocket Daemon";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [
|
||||
"network.target"
|
||||
"coolwsd-systemplate-setup.service"
|
||||
];
|
||||
|
||||
environment = builtins.listToAttrs (
|
||||
lib.imap1 (n: ag: {
|
||||
name = "aliasgroup${toString n}";
|
||||
value = lib.concatStringsSep "," ([ ag.host ] ++ ag.aliases);
|
||||
}) cfg.aliasGroups
|
||||
);
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = utils.escapeSystemdExecArgs (
|
||||
[
|
||||
"${cfg.package}/bin/coolwsd"
|
||||
"--config-file=${configFile}"
|
||||
"--port=${toString cfg.port}"
|
||||
"--use-env-vars"
|
||||
"--version"
|
||||
]
|
||||
++ cfg.extraArgs
|
||||
);
|
||||
KillMode = "mixed";
|
||||
KillSignal = "SIGINT";
|
||||
LimitNOFILE = "infinity:infinity";
|
||||
Restart = "always";
|
||||
StateDirectory = "cool";
|
||||
TimeoutStopSec = 120;
|
||||
User = "cool";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
meta.maintainers = [ lib.maintainers.xzfc ];
|
||||
}
|
311
nixos/modules/services/web-apps/immich.nix
Normal file
311
nixos/modules/services/web-apps/immich.nix
Normal file
@ -0,0 +1,311 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.services.immich;
|
||||
isPostgresUnixSocket = lib.hasPrefix "/" cfg.database.host;
|
||||
isRedisUnixSocket = lib.hasPrefix "/" cfg.redis.host;
|
||||
|
||||
commonServiceConfig = {
|
||||
Type = "simple";
|
||||
Restart = "on-failure";
|
||||
RestartSec = 3;
|
||||
|
||||
# Hardening
|
||||
CapabilityBoundingSet = "";
|
||||
NoNewPrivileges = true;
|
||||
PrivateUsers = true;
|
||||
PrivateTmp = true;
|
||||
PrivateDevices = true;
|
||||
PrivateMounts = true;
|
||||
ProtectClock = true;
|
||||
ProtectControlGroups = true;
|
||||
ProtectHome = true;
|
||||
ProtectHostname = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
RestrictAddressFamilies = [
|
||||
"AF_INET"
|
||||
"AF_INET6"
|
||||
"AF_UNIX"
|
||||
];
|
||||
RestrictNamespaces = true;
|
||||
RestrictRealtime = true;
|
||||
RestrictSUIDSGID = true;
|
||||
};
|
||||
inherit (lib)
|
||||
types
|
||||
mkIf
|
||||
mkOption
|
||||
mkEnableOption
|
||||
;
|
||||
in
|
||||
{
|
||||
options.services.immich = {
|
||||
enable = mkEnableOption "Immich";
|
||||
package = lib.mkPackageOption pkgs "immich" { };
|
||||
|
||||
mediaLocation = mkOption {
|
||||
type = types.path;
|
||||
default = "/var/lib/immich";
|
||||
description = "Directory used to store media files. If it is not the default, the directory has to be created manually such that the immich user is able to read and write to it.";
|
||||
};
|
||||
environment = mkOption {
|
||||
type = types.submodule { freeformType = types.attrsOf types.str; };
|
||||
default = { };
|
||||
example = {
|
||||
IMMICH_LOG_LEVEL = "verbose";
|
||||
};
|
||||
description = ''
|
||||
Extra configuration environment variables. Refer to the [documentation](https://immich.app/docs/install/environment-variables) for options tagged with 'server', 'api' or 'microservices'.
|
||||
'';
|
||||
};
|
||||
secretsFile = mkOption {
|
||||
type = types.nullOr (
|
||||
types.str
|
||||
// {
|
||||
# We don't want users to be able to pass a path literal here but
|
||||
# it should look like a path.
|
||||
check = it: lib.isString it && lib.types.path.check it;
|
||||
}
|
||||
);
|
||||
default = null;
|
||||
example = "/run/secrets/immich";
|
||||
description = ''
|
||||
Path of a file with extra environment variables to be loaded from disk. This file is not added to the nix store, so it can be used to pass secrets to immich. Refer to the [documentation](https://immich.app/docs/install/environment-variables) for options.
|
||||
|
||||
To set a database password set this to a file containing:
|
||||
```
|
||||
DB_PASSWORD=<pass>
|
||||
```
|
||||
'';
|
||||
};
|
||||
host = mkOption {
|
||||
type = types.str;
|
||||
default = "localhost";
|
||||
description = "The host that immich will listen on.";
|
||||
};
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
default = 3001;
|
||||
description = "The port that immich will listen on.";
|
||||
};
|
||||
openFirewall = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Whether to open the immich port in the firewall";
|
||||
};
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
default = "immich";
|
||||
description = "The user immich should run as.";
|
||||
};
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
default = "immich";
|
||||
description = "The group immich should run as.";
|
||||
};
|
||||
|
||||
machine-learning = {
|
||||
enable =
|
||||
mkEnableOption "immich's machine-learning functionality to detect faces and search for objects"
|
||||
// {
|
||||
default = true;
|
||||
};
|
||||
environment = mkOption {
|
||||
type = types.submodule { freeformType = types.attrsOf types.str; };
|
||||
default = { };
|
||||
example = {
|
||||
MACHINE_LEARNING_MODEL_TTL = "600";
|
||||
};
|
||||
description = ''
|
||||
Extra configuration environment variables. Refer to the [documentation](https://immich.app/docs/install/environment-variables) for options tagged with 'machine-learning'.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
database = {
|
||||
enable =
|
||||
mkEnableOption "the postgresql database for use with immich. See {option}`services.postgresql`"
|
||||
// {
|
||||
default = true;
|
||||
};
|
||||
createDB = mkEnableOption "the automatic creation of the database for immich." // {
|
||||
default = true;
|
||||
};
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
default = "immich";
|
||||
description = "The name of the immich database.";
|
||||
};
|
||||
host = mkOption {
|
||||
type = types.str;
|
||||
default = "/run/postgresql";
|
||||
example = "127.0.0.1";
|
||||
description = "Hostname or address of the postgresql server. If an absolute path is given here, it will be interpreted as a unix socket path.";
|
||||
};
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
default = "immich";
|
||||
description = "The database user for immich.";
|
||||
};
|
||||
};
|
||||
redis = {
|
||||
enable = mkEnableOption "a redis cache for use with immich" // {
|
||||
default = true;
|
||||
};
|
||||
host = mkOption {
|
||||
type = types.str;
|
||||
default = config.services.redis.servers.immich.unixSocket;
|
||||
defaultText = lib.literalExpression "config.services.redis.servers.immich.unixSocket";
|
||||
description = "The host that redis will listen on.";
|
||||
};
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
default = 0;
|
||||
description = "The port that redis will listen on. Set to zero to disable TCP.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion = !isPostgresUnixSocket -> cfg.secretsFile != null;
|
||||
message = "A secrets file containing at least the database password must be provided when unix sockets are not used.";
|
||||
}
|
||||
];
|
||||
|
||||
services.postgresql = mkIf cfg.database.enable {
|
||||
enable = true;
|
||||
ensureDatabases = mkIf cfg.database.createDB [ cfg.database.name ];
|
||||
ensureUsers = mkIf cfg.database.createDB [
|
||||
{
|
||||
name = cfg.database.user;
|
||||
ensureDBOwnership = true;
|
||||
ensureClauses.login = true;
|
||||
}
|
||||
];
|
||||
extraPlugins = ps: with ps; [ pgvecto-rs ];
|
||||
settings = {
|
||||
shared_preload_libraries = [ "vectors.so" ];
|
||||
search_path = "\"$user\", public, vectors";
|
||||
};
|
||||
};
|
||||
systemd.services.postgresql.serviceConfig.ExecStartPost =
|
||||
let
|
||||
sqlFile = pkgs.writeText "immich-pgvectors-setup.sql" ''
|
||||
CREATE EXTENSION IF NOT EXISTS unaccent;
|
||||
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
||||
CREATE EXTENSION IF NOT EXISTS vectors;
|
||||
CREATE EXTENSION IF NOT EXISTS cube;
|
||||
CREATE EXTENSION IF NOT EXISTS earthdistance;
|
||||
CREATE EXTENSION IF NOT EXISTS pg_trgm;
|
||||
|
||||
ALTER SCHEMA public OWNER TO ${cfg.database.user};
|
||||
ALTER SCHEMA vectors OWNER TO ${cfg.database.user};
|
||||
GRANT SELECT ON TABLE pg_vector_index_stat TO ${cfg.database.user};
|
||||
|
||||
ALTER EXTENSION vectors UPDATE;
|
||||
'';
|
||||
in
|
||||
[
|
||||
''
|
||||
${lib.getExe' config.services.postgresql.package "psql"} -d "${cfg.database.name}" -f "${sqlFile}"
|
||||
''
|
||||
];
|
||||
|
||||
services.redis.servers = mkIf cfg.redis.enable {
|
||||
immich = {
|
||||
enable = true;
|
||||
user = cfg.user;
|
||||
port = cfg.redis.port;
|
||||
bind = mkIf (!isRedisUnixSocket) cfg.redis.host;
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ cfg.port ];
|
||||
|
||||
services.immich.environment =
|
||||
let
|
||||
postgresEnv =
|
||||
if isPostgresUnixSocket then
|
||||
{ DB_URL = "socket://${cfg.database.host}?dbname=${cfg.database.name}"; }
|
||||
else
|
||||
{
|
||||
DB_HOSTNAME = cfg.database.host;
|
||||
DB_PORT = toString cfg.database.port;
|
||||
DB_DATABASE_NAME = cfg.database.name;
|
||||
DB_USERNAME = cfg.database.user;
|
||||
};
|
||||
redisEnv =
|
||||
if isRedisUnixSocket then
|
||||
{ REDIS_SOCKET = cfg.redis.host; }
|
||||
else
|
||||
{
|
||||
REDIS_PORT = toString cfg.redis.port;
|
||||
REDIS_HOSTNAME = cfg.redis.host;
|
||||
};
|
||||
in
|
||||
postgresEnv
|
||||
// redisEnv
|
||||
// {
|
||||
HOST = cfg.host;
|
||||
IMMICH_PORT = toString cfg.port;
|
||||
IMMICH_MEDIA_LOCATION = cfg.mediaLocation;
|
||||
IMMICH_MACHINE_LEARNING_URL = "http://localhost:3003";
|
||||
};
|
||||
|
||||
services.immich.machine-learning.environment = {
|
||||
MACHINE_LEARNING_WORKERS = "1";
|
||||
MACHINE_LEARNING_WORKER_TIMEOUT = "120";
|
||||
MACHINE_LEARNING_CACHE_FOLDER = "/var/cache/immich";
|
||||
IMMICH_HOST = "localhost";
|
||||
IMMICH_PORT = "3003";
|
||||
};
|
||||
|
||||
systemd.services.immich-server = {
|
||||
description = "Immich backend server (Self-hosted photo and video backup solution)";
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
inherit (cfg) environment;
|
||||
|
||||
serviceConfig = commonServiceConfig // {
|
||||
ExecStart = lib.getExe cfg.package;
|
||||
EnvironmentFile = mkIf (cfg.secretsFile != null) cfg.secretsFile;
|
||||
StateDirectory = "immich";
|
||||
RuntimeDirectory = "immich";
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.immich-machine-learning = mkIf cfg.machine-learning.enable {
|
||||
description = "immich machine learning";
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
inherit (cfg.machine-learning) environment;
|
||||
serviceConfig = commonServiceConfig // {
|
||||
ExecStart = lib.getExe (cfg.package.machine-learning.override { immich = cfg.package; });
|
||||
CacheDirectory = "immich";
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
};
|
||||
};
|
||||
|
||||
users.users = mkIf (cfg.user == "immich") {
|
||||
immich = {
|
||||
name = "immich";
|
||||
group = cfg.group;
|
||||
isSystemUser = true;
|
||||
};
|
||||
};
|
||||
users.groups = mkIf (cfg.group == "immich") { immich = { }; };
|
||||
|
||||
meta.maintainers = with lib.maintainers; [ jvanbruegge ];
|
||||
};
|
||||
}
|
@ -294,6 +294,15 @@ in
|
||||
'')
|
||||
];
|
||||
|
||||
services.logrotate.settings.pretalx = {
|
||||
files = "${cfg.settings.filesystem.logs}/*.log";
|
||||
su = "${cfg.user} ${cfg.group}";
|
||||
frequency = "weekly";
|
||||
rotate = "12";
|
||||
copytruncate = true;
|
||||
compress = true;
|
||||
};
|
||||
|
||||
services = {
|
||||
nginx = lib.mkIf cfg.nginx.enable {
|
||||
enable = true;
|
||||
|
@ -403,6 +403,15 @@ in
|
||||
'')
|
||||
];
|
||||
|
||||
services.logrotate.settings.pretix = {
|
||||
files = "${cfg.settings.pretix.logdir}/*.log";
|
||||
su = "${cfg.user} ${cfg.group}";
|
||||
frequency = "weekly";
|
||||
rotate = "12";
|
||||
copytruncate = true;
|
||||
compress = true;
|
||||
};
|
||||
|
||||
services = {
|
||||
nginx = mkIf cfg.nginx.enable {
|
||||
enable = true;
|
||||
|
@ -59,6 +59,7 @@ in
|
||||
pngquant
|
||||
tesseract
|
||||
python3Packages.weasyprint
|
||||
ghostscript_headless
|
||||
]
|
||||
++ lib.optional (cfg.environment.INSTALL_BOOK_AND_ADVANCED_HTML_OPS or "false" == "true") calibre;
|
||||
|
||||
|
@ -129,12 +129,9 @@ let
|
||||
''));
|
||||
|
||||
commonHttpConfig = ''
|
||||
# Load mime types.
|
||||
# Load mime types and configure maximum size of the types hash tables.
|
||||
include ${cfg.defaultMimeTypes};
|
||||
# When recommendedOptimisation is disabled nginx fails to start because the mailmap mime.types database
|
||||
# contains 1026 entries and the default is only 1024. Setting to a higher number to remove the need to
|
||||
# overwrite it because nginx does not allow duplicated settings.
|
||||
types_hash_max_size 4096;
|
||||
types_hash_max_size ${toString cfg.typesHashMaxSize};
|
||||
|
||||
include ${cfg.package}/conf/fastcgi.conf;
|
||||
include ${cfg.package}/conf/uwsgi_params;
|
||||
@ -896,6 +893,19 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
typesHashMaxSize = mkOption {
|
||||
type = types.ints.positive;
|
||||
default = if cfg.defaultMimeTypes == "${pkgs.mailcap}/etc/nginx/mime.types" then 2688 else 1024;
|
||||
defaultText = literalExpression ''if cfg.defaultMimeTypes == "''${pkgs.mailcap}/etc/nginx/mime.types" then 2688 else 1024'';
|
||||
description = ''
|
||||
Sets the maximum size of the types hash tables (`types_hash_max_size`).
|
||||
It is recommended that the minimum size possible size is used.
|
||||
If {option}`recommendedOptimisation` is disabled, nginx would otherwise
|
||||
fail to start since the mailmap `mime.types` database has more entries
|
||||
than the nginx default value 1024.
|
||||
'';
|
||||
};
|
||||
|
||||
proxyCachePath = mkOption {
|
||||
type = types.attrsOf (types.submodule ({ ... }: {
|
||||
options = {
|
||||
|
@ -68,9 +68,19 @@ let
|
||||
else showWarnings config.warnings baseSystem;
|
||||
|
||||
# Replace runtime dependencies
|
||||
system = foldr ({ oldDependency, newDependency }: drv:
|
||||
pkgs.replaceDependency { inherit oldDependency newDependency drv; }
|
||||
) baseSystemAssertWarn config.system.replaceRuntimeDependencies;
|
||||
system = let inherit (config.system.replaceDependencies) replacements cutoffPackages; in
|
||||
if replacements == [] then
|
||||
# Avoid IFD if possible, by sidestepping replaceDependencies if no replacements are specified.
|
||||
baseSystemAssertWarn
|
||||
else
|
||||
(pkgs.replaceDependencies.override {
|
||||
replaceDirectDependencies = pkgs.replaceDirectDependencies.override {
|
||||
nix = config.nix.package;
|
||||
};
|
||||
}) {
|
||||
drv = baseSystemAssertWarn;
|
||||
inherit replacements cutoffPackages;
|
||||
};
|
||||
|
||||
systemWithBuildDeps = system.overrideAttrs (o: {
|
||||
systemBuildClosure = pkgs.closureInfo { rootPaths = [ system.drvPath ]; };
|
||||
@ -87,6 +97,7 @@ in
|
||||
(mkRemovedOptionModule [ "nesting" "clone" ] "Use `specialisation.«name» = { inheritParentConfig = true; configuration = { ... }; }` instead.")
|
||||
(mkRemovedOptionModule [ "nesting" "children" ] "Use `specialisation.«name».configuration = { ... }` instead.")
|
||||
(mkRenamedOptionModule [ "system" "forbiddenDependenciesRegex" ] [ "system" "forbiddenDependenciesRegexes" ])
|
||||
(mkRenamedOptionModule [ "system" "replaceRuntimeDependencies" ] [ "system" "replaceDependencies" "replacements" ])
|
||||
];
|
||||
|
||||
options = {
|
||||
@ -205,31 +216,47 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
system.replaceRuntimeDependencies = mkOption {
|
||||
default = [];
|
||||
example = lib.literalExpression "[ ({ original = pkgs.openssl; replacement = pkgs.callPackage /path/to/openssl { }; }) ]";
|
||||
type = types.listOf (types.submodule (
|
||||
{ ... }: {
|
||||
options.original = mkOption {
|
||||
type = types.package;
|
||||
description = "The original package to override.";
|
||||
};
|
||||
system.replaceDependencies = {
|
||||
replacements = mkOption {
|
||||
default = [];
|
||||
example = lib.literalExpression "[ ({ oldDependency = pkgs.openssl; newDependency = pkgs.callPackage /path/to/openssl { }; }) ]";
|
||||
type = types.listOf (types.submodule (
|
||||
{ ... }: {
|
||||
imports = [
|
||||
(mkRenamedOptionModule [ "original" ] [ "oldDependency" ])
|
||||
(mkRenamedOptionModule [ "replacement" ] [ "newDependency" ])
|
||||
];
|
||||
|
||||
options.replacement = mkOption {
|
||||
type = types.package;
|
||||
description = "The replacement package.";
|
||||
};
|
||||
})
|
||||
);
|
||||
apply = map ({ original, replacement, ... }: {
|
||||
oldDependency = original;
|
||||
newDependency = replacement;
|
||||
});
|
||||
description = ''
|
||||
List of packages to override without doing a full rebuild.
|
||||
The original derivation and replacement derivation must have the same
|
||||
name length, and ideally should have close-to-identical directory layout.
|
||||
'';
|
||||
options.oldDependency = mkOption {
|
||||
type = types.package;
|
||||
description = "The original package to override.";
|
||||
};
|
||||
|
||||
options.newDependency = mkOption {
|
||||
type = types.package;
|
||||
description = "The replacement package.";
|
||||
};
|
||||
})
|
||||
);
|
||||
apply = map ({ oldDependency, newDependency, ... }: {
|
||||
inherit oldDependency newDependency;
|
||||
});
|
||||
description = ''
|
||||
List of packages to override without doing a full rebuild.
|
||||
The original derivation and replacement derivation must have the same
|
||||
name length, and ideally should have close-to-identical directory layout.
|
||||
'';
|
||||
};
|
||||
|
||||
cutoffPackages = mkOption {
|
||||
default = [ config.system.build.initialRamdisk ];
|
||||
defaultText = literalExpression "[ config.system.build.initialRamdisk ]";
|
||||
type = types.listOf types.package;
|
||||
description = ''
|
||||
Packages to which no replacements should be applied.
|
||||
The initrd is matched by default, because its structure renders the replacement process ineffective and prone to breakage.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
system.name = mkOption {
|
||||
|
@ -1088,6 +1088,8 @@ in
|
||||
storePaths = [
|
||||
"${config.boot.initrd.systemd.package}/bin/systemd-cryptsetup"
|
||||
"${config.boot.initrd.systemd.package}/lib/systemd/system-generators/systemd-cryptsetup-generator"
|
||||
] ++ lib.optionals config.boot.initrd.systemd.tpm2.enable [
|
||||
"${config.boot.initrd.systemd.package}/lib/cryptsetup/libcryptsetup-token-systemd-tpm2.so"
|
||||
];
|
||||
|
||||
};
|
||||
|
@ -327,7 +327,7 @@ let
|
||||
|
||||
setHostId = optionalString (config.networking.hostId != null) ''
|
||||
hi="${config.networking.hostId}"
|
||||
${if pkgs.stdenv.isBigEndian then ''
|
||||
${if pkgs.stdenv.hostPlatform.isBigEndian then ''
|
||||
echo -ne "\x''${hi:0:2}\x''${hi:2:2}\x''${hi:4:2}\x''${hi:6:2}" > /etc/hostid
|
||||
'' else ''
|
||||
echo -ne "\x''${hi:6:2}\x''${hi:4:2}\x''${hi:2:2}\x''${hi:0:2}" > /etc/hostid
|
||||
|
@ -37,8 +37,6 @@ let
|
||||
"cryptsetup.target"
|
||||
"cryptsetup-pre.target"
|
||||
"remote-cryptsetup.target"
|
||||
] ++ optionals cfg.package.withTpm2Tss [
|
||||
"tpm2.target"
|
||||
] ++ [
|
||||
"sigpwr.target"
|
||||
"timers.target"
|
||||
@ -679,7 +677,7 @@ in
|
||||
|
||||
# Increase numeric PID range (set directly instead of copying a one-line file from systemd)
|
||||
# https://github.com/systemd/systemd/pull/12226
|
||||
boot.kernel.sysctl."kernel.pid_max" = mkIf pkgs.stdenv.is64bit (lib.mkDefault 4194304);
|
||||
boot.kernel.sysctl."kernel.pid_max" = mkIf pkgs.stdenv.hostPlatform.is64bit (lib.mkDefault 4194304);
|
||||
|
||||
services.logrotate.settings = {
|
||||
"/var/log/btmp" = mapAttrs (_: mkDefault) {
|
||||
|
@ -38,6 +38,7 @@ let
|
||||
"kmod-static-nodes.service"
|
||||
"local-fs-pre.target"
|
||||
"local-fs.target"
|
||||
"modprobe@.service"
|
||||
"multi-user.target"
|
||||
"paths.target"
|
||||
"poweroff.target"
|
||||
@ -68,7 +69,6 @@ let
|
||||
"systemd-reboot.service"
|
||||
"systemd-sysctl.service"
|
||||
"timers.target"
|
||||
"tpm2.target"
|
||||
"umount.target"
|
||||
"systemd-bsod.service"
|
||||
] ++ cfg.additionalUpstreamUnits;
|
||||
@ -349,15 +349,6 @@ in {
|
||||
visible = "shallow";
|
||||
description = "Definition of slice configurations.";
|
||||
};
|
||||
|
||||
enableTpm2 = mkOption {
|
||||
default = cfg.package.withTpm2Tss;
|
||||
defaultText = "boot.initrd.systemd.package.withTpm2Tss";
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Whether to enable TPM2 support in the initrd.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf (config.boot.initrd.enable && cfg.enable) {
|
||||
@ -394,9 +385,7 @@ in {
|
||||
# systemd needs this for some features
|
||||
"autofs"
|
||||
# systemd-cryptenroll
|
||||
] ++ lib.optional cfg.enableTpm2 "tpm-tis"
|
||||
++ lib.optional (cfg.enableTpm2 && !(pkgs.stdenv.hostPlatform.isRiscV64 || pkgs.stdenv.hostPlatform.isArmv7)) "tpm-crb"
|
||||
++ lib.optional cfg.package.withEfi "efivarfs";
|
||||
] ++ lib.optional cfg.package.withEfi "efivarfs";
|
||||
|
||||
boot.kernelParams = [
|
||||
"root=${config.boot.initrd.systemd.root}"
|
||||
@ -495,10 +484,6 @@ in {
|
||||
|
||||
# so NSS can look up usernames
|
||||
"${pkgs.glibc}/lib/libnss_files.so.2"
|
||||
] ++ optionals (cfg.package.withCryptsetup && cfg.enableTpm2) [
|
||||
# tpm2 support
|
||||
"${cfg.package}/lib/cryptsetup/libcryptsetup-token-systemd-tpm2.so"
|
||||
pkgs.tpm2-tss
|
||||
] ++ optionals cfg.package.withCryptsetup [
|
||||
# fido2 support
|
||||
"${cfg.package}/lib/cryptsetup/libcryptsetup-token-systemd-fido2.so"
|
||||
|
80
nixos/modules/system/boot/systemd/tpm2.nix
Normal file
80
nixos/modules/system/boot/systemd/tpm2.nix
Normal file
@ -0,0 +1,80 @@
|
||||
{
|
||||
lib,
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
{
|
||||
meta.maintainers = [ lib.maintainers.elvishjerricco ];
|
||||
|
||||
imports = [
|
||||
(lib.mkRenamedOptionModule
|
||||
[
|
||||
"boot"
|
||||
"initrd"
|
||||
"systemd"
|
||||
"enableTpm2"
|
||||
]
|
||||
[
|
||||
"boot"
|
||||
"initrd"
|
||||
"systemd"
|
||||
"tpm2"
|
||||
"enable"
|
||||
]
|
||||
)
|
||||
];
|
||||
|
||||
options = {
|
||||
systemd.tpm2.enable = lib.mkEnableOption "systemd TPM2 support" // {
|
||||
default = config.systemd.package.withTpm2Tss;
|
||||
defaultText = "systemd.package.withTpm2Tss";
|
||||
};
|
||||
|
||||
boot.initrd.systemd.tpm2.enable = lib.mkEnableOption "systemd initrd TPM2 support" // {
|
||||
default = config.boot.initrd.systemd.package.withTpm2Tss;
|
||||
defaultText = "boot.initrd.systemd.package.withTpm2Tss";
|
||||
};
|
||||
};
|
||||
|
||||
# TODO: pcrphase, pcrextend, pcrfs, pcrmachine
|
||||
config = lib.mkMerge [
|
||||
# Stage 2
|
||||
(
|
||||
let
|
||||
cfg = config.systemd;
|
||||
in
|
||||
lib.mkIf cfg.tpm2.enable {
|
||||
systemd.additionalUpstreamSystemUnits = [
|
||||
"tpm2.target"
|
||||
"systemd-tpm2-setup-early.service"
|
||||
"systemd-tpm2-setup.service"
|
||||
];
|
||||
}
|
||||
)
|
||||
|
||||
# Stage 1
|
||||
(
|
||||
let
|
||||
cfg = config.boot.initrd.systemd;
|
||||
in
|
||||
lib.mkIf cfg.tpm2.enable {
|
||||
boot.initrd.systemd.additionalUpstreamUnits = [
|
||||
"tpm2.target"
|
||||
"systemd-tpm2-setup-early.service"
|
||||
];
|
||||
|
||||
boot.initrd.availableKernelModules =
|
||||
[ "tpm-tis" ]
|
||||
++ lib.optional (
|
||||
!(pkgs.stdenv.hostPlatform.isRiscV64 || pkgs.stdenv.hostPlatform.isArmv7)
|
||||
) "tpm-crb";
|
||||
boot.initrd.systemd.storePaths = [
|
||||
pkgs.tpm2-tss
|
||||
"${cfg.package}/lib/systemd/systemd-tpm2-setup"
|
||||
"${cfg.package}/lib/systemd/system-generators/systemd-tpm2-generator"
|
||||
];
|
||||
}
|
||||
)
|
||||
];
|
||||
}
|
@ -168,7 +168,7 @@ in {
|
||||
assertions = [{
|
||||
assertion = !((cfg.channel != null) && (cfg.flake != null));
|
||||
message = ''
|
||||
The options 'system.autoUpgrade.channels' and 'system.autoUpgrade.flake' cannot both be set.
|
||||
The options 'system.autoUpgrade.channel' and 'system.autoUpgrade.flake' cannot both be set.
|
||||
'';
|
||||
}];
|
||||
|
||||
|
@ -16,7 +16,7 @@ let
|
||||
lib.optionalAttrs (cfg.server.nproc != null) {
|
||||
nfsd.threads = cfg.server.nproc;
|
||||
} // lib.optionalAttrs (cfg.server.hostName != null) {
|
||||
nfsd.host= cfg.hostName;
|
||||
nfsd.host = cfg.server.hostName;
|
||||
} // lib.optionalAttrs (cfg.server.mountdPort != null) {
|
||||
mountd.port = cfg.server.mountdPort;
|
||||
} // lib.optionalAttrs (cfg.server.statdPort != null) {
|
||||
|
@ -438,7 +438,7 @@ let
|
||||
|
||||
hostidFile = pkgs.runCommand "gen-hostid" { preferLocalBuild = true; } ''
|
||||
hi="${cfg.hostId}"
|
||||
${if pkgs.stdenv.isBigEndian then ''
|
||||
${if pkgs.stdenv.hostPlatform.isBigEndian then ''
|
||||
echo -ne "\x''${hi:0:2}\x''${hi:2:2}\x''${hi:4:2}\x''${hi:6:2}" > $out
|
||||
'' else ''
|
||||
echo -ne "\x''${hi:6:2}\x''${hi:4:2}\x''${hi:2:2}\x''${hi:0:2}" > $out
|
||||
|
@ -244,7 +244,7 @@ in
|
||||
};
|
||||
|
||||
assertions = [
|
||||
{ assertion = cfg.enableNvidia && pkgs.stdenv.isx86_64 -> config.hardware.graphics.enable32Bit or false;
|
||||
{ assertion = cfg.enableNvidia && pkgs.stdenv.hostPlatform.isx86_64 -> config.hardware.graphics.enable32Bit or false;
|
||||
message = "Option enableNvidia on x86_64 requires 32-bit support libraries";
|
||||
}];
|
||||
|
||||
|
@ -85,8 +85,13 @@ let
|
||||
|
||||
startScript = cfg:
|
||||
''
|
||||
mkdir -p -m 0755 "$root/etc" "$root/var/lib"
|
||||
mkdir -p -m 0700 "$root/var/lib/private" "$root/root" /run/nixos-containers
|
||||
# Declare root explicitly to avoid shellcheck warnings, it comes from the env
|
||||
declare root
|
||||
|
||||
mkdir -p "$root/etc" "$root/var/lib"
|
||||
chmod 0755 "$root/etc" "$root/var/lib"
|
||||
mkdir -p "$root/var/lib/private" "$root/root" /run/nixos-containers
|
||||
chmod 0700 "$root/var/lib/private" "$root/root" /run/nixos-containers
|
||||
if ! [ -e "$root/etc/os-release" ]; then
|
||||
touch "$root/etc/os-release"
|
||||
fi
|
||||
@ -95,7 +100,10 @@ let
|
||||
touch "$root/etc/machine-id"
|
||||
fi
|
||||
|
||||
mkdir -p -m 0755 \
|
||||
mkdir -p \
|
||||
"/nix/var/nix/profiles/per-container/$INSTANCE" \
|
||||
"/nix/var/nix/gcroots/per-container/$INSTANCE"
|
||||
chmod 0755 \
|
||||
"/nix/var/nix/profiles/per-container/$INSTANCE" \
|
||||
"/nix/var/nix/gcroots/per-container/$INSTANCE"
|
||||
|
||||
@ -137,7 +145,7 @@ let
|
||||
# If the host is 64-bit and the container is 32-bit, add a
|
||||
# --personality flag.
|
||||
${optionalString (pkgs.stdenv.hostPlatform.system == "x86_64-linux") ''
|
||||
if [ "$(< ''${SYSTEM_PATH:-/nix/var/nix/profiles/per-container/$INSTANCE/system}/system)" = i686-linux ]; then
|
||||
if [ "$(< "''${SYSTEM_PATH:-/nix/var/nix/profiles/per-container/$INSTANCE/system}/system")" = i686-linux ]; then
|
||||
extraFlags+=" --personality=x86"
|
||||
fi
|
||||
''}
|
||||
@ -203,33 +211,33 @@ let
|
||||
if cfg.${attribute} == null then
|
||||
''
|
||||
if [ -n "${variable}" ]; then
|
||||
${ipcmd} add ${variable} dev $ifaceHost
|
||||
${ipcmd} add "${variable}" dev "$ifaceHost"
|
||||
fi
|
||||
''
|
||||
else
|
||||
"${ipcmd} add ${cfg.${attribute}} dev $ifaceHost";
|
||||
''${ipcmd} add ${cfg.${attribute}} dev "$ifaceHost"'';
|
||||
renderExtraVeth = name: cfg:
|
||||
if cfg.hostBridge != null then
|
||||
''
|
||||
# Add ${name} to bridge ${cfg.hostBridge}
|
||||
ip link set dev ${name} master ${cfg.hostBridge} up
|
||||
ip link set dev "${name}" master "${cfg.hostBridge}" up
|
||||
''
|
||||
else
|
||||
''
|
||||
echo "Bring ${name} up"
|
||||
ip link set dev ${name} up
|
||||
ip link set dev "${name}" up
|
||||
# Set IPs and routes for ${name}
|
||||
${optionalString (cfg.hostAddress != null) ''
|
||||
ip addr add ${cfg.hostAddress} dev ${name}
|
||||
ip addr add ${cfg.hostAddress} dev "${name}"
|
||||
''}
|
||||
${optionalString (cfg.hostAddress6 != null) ''
|
||||
ip -6 addr add ${cfg.hostAddress6} dev ${name}
|
||||
ip -6 addr add ${cfg.hostAddress6} dev "${name}"
|
||||
''}
|
||||
${optionalString (cfg.localAddress != null) ''
|
||||
ip route add ${cfg.localAddress} dev ${name}
|
||||
ip route add ${cfg.localAddress} dev "${name}"
|
||||
''}
|
||||
${optionalString (cfg.localAddress6 != null) ''
|
||||
ip -6 route add ${cfg.localAddress6} dev ${name}
|
||||
ip -6 route add ${cfg.localAddress6} dev "${name}"
|
||||
''}
|
||||
'';
|
||||
in
|
||||
@ -238,7 +246,7 @@ let
|
||||
[ -n "$HOST_ADDRESS6" ] || [ -n "$LOCAL_ADDRESS6" ]; then
|
||||
if [ -z "$HOST_BRIDGE" ]; then
|
||||
ifaceHost=ve-$INSTANCE
|
||||
ip link set dev $ifaceHost up
|
||||
ip link set dev "$ifaceHost" up
|
||||
|
||||
${ipcall cfg "ip addr" "$HOST_ADDRESS" "hostAddress"}
|
||||
${ipcall cfg "ip -6 addr" "$HOST_ADDRESS6" "hostAddress6"}
|
||||
|
@ -1169,7 +1169,7 @@ in
|
||||
value.fsType = "9p";
|
||||
value.neededForBoot = true;
|
||||
value.options =
|
||||
[ "trans=virtio" "version=9p2000.L" "msize=${toString cfg.msize}" ]
|
||||
[ "trans=virtio" "version=9p2000.L" "msize=${toString cfg.msize}" "x-systemd.requires=modprobe@9pnet_virtio.service" ]
|
||||
++ lib.optional (tag == "nix-store") "cache=loose";
|
||||
};
|
||||
in lib.mkMerge [
|
||||
|
@ -605,7 +605,7 @@ in
|
||||
config = lib.modules.mkIf cfg.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion = pkgs.stdenv.isx86_64;
|
||||
assertion = pkgs.stdenv.hostPlatform.isx86_64;
|
||||
message = "Xen is currently not supported on ${pkgs.stdenv.hostPlatform.system}.";
|
||||
}
|
||||
{
|
||||
|
@ -455,6 +455,7 @@ in {
|
||||
icingaweb2 = handleTest ./icingaweb2.nix {};
|
||||
ifm = handleTest ./ifm.nix {};
|
||||
iftop = handleTest ./iftop.nix {};
|
||||
immich = handleTest ./web-apps/immich.nix {};
|
||||
incron = handleTest ./incron.nix {};
|
||||
incus = pkgs.recurseIntoAttrs (handleTest ./incus { inherit handleTestOn; inherit (pkgs) incus; });
|
||||
incus-lts = pkgs.recurseIntoAttrs (handleTest ./incus { inherit handleTestOn; });
|
||||
@ -669,6 +670,7 @@ in {
|
||||
nginx-etag-compression = handleTest ./nginx-etag-compression.nix {};
|
||||
nginx-globalredirect = handleTest ./nginx-globalredirect.nix {};
|
||||
nginx-http3 = handleTest ./nginx-http3.nix {};
|
||||
nginx-mime = handleTest ./nginx-mime.nix {};
|
||||
nginx-modsecurity = handleTest ./nginx-modsecurity.nix {};
|
||||
nginx-moreheaders = handleTest ./nginx-moreheaders.nix {};
|
||||
nginx-njs = handleTest ./nginx-njs.nix {};
|
||||
@ -856,6 +858,7 @@ in {
|
||||
redlib = handleTest ./redlib.nix {};
|
||||
redmine = handleTest ./redmine.nix {};
|
||||
renovate = handleTest ./renovate.nix {};
|
||||
replace-dependencies = handleTest ./replace-dependencies {};
|
||||
restartByActivationScript = handleTest ./restart-by-activation-script.nix {};
|
||||
restic-rest-server = handleTest ./restic-rest-server.nix {};
|
||||
restic = handleTest ./restic.nix {};
|
||||
|
@ -2,7 +2,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: {
|
||||
name = "filesender";
|
||||
meta = {
|
||||
maintainers = with lib.maintainers; [ nhnn ];
|
||||
broken = pkgs.stdenv.isAarch64; # selenium.common.exceptions.WebDriverException: Message: Unsupported platform/architecture combination: linux/aarch64
|
||||
broken = pkgs.stdenv.hostPlatform.isAarch64; # selenium.common.exceptions.WebDriverException: Message: Unsupported platform/architecture combination: linux/aarch64
|
||||
};
|
||||
|
||||
nodes.filesender = { ... }: let
|
||||
|
@ -24,7 +24,7 @@ let
|
||||
nodes = { "${name}" = machine; };
|
||||
meta.maintainers = with pkgs.lib.maintainers; [ kirillrdy ];
|
||||
# time-out on ofborg
|
||||
meta.broken = pkgs.stdenv.isAarch64;
|
||||
meta.broken = pkgs.stdenv.hostPlatform.isAarch64;
|
||||
enableOCR = true;
|
||||
|
||||
testScript = ''
|
||||
|
@ -6,7 +6,7 @@ makeInstalledTest {
|
||||
testConfig = {
|
||||
# Tests allocate a lot of memory trying to exploit a CVE
|
||||
# but qemu-system-i386 has a 2047M memory limit
|
||||
virtualisation.memorySize = if pkgs.stdenv.isi686 then 2047 else 4096;
|
||||
virtualisation.memorySize = if pkgs.stdenv.hostPlatform.isi686 then 2047 else 4096;
|
||||
};
|
||||
|
||||
testRunnerFlags = [ "--timeout" "1800" ];
|
||||
|
@ -189,7 +189,7 @@ import ../make-test-python.nix (
|
||||
m.start()
|
||||
m.wait_for_unit("k3s")
|
||||
|
||||
is_aarch64 = "${toString pkgs.stdenv.isAarch64}" == "1"
|
||||
is_aarch64 = "${toString pkgs.stdenv.hostPlatform.isAarch64}" == "1"
|
||||
|
||||
# wait for the agent to show up
|
||||
server.wait_until_succeeds("k3s kubectl get node agent")
|
||||
|
@ -30,7 +30,7 @@ import ./make-test-python.nix ({ pkgs, ... }: {
|
||||
|
||||
testScript = let
|
||||
nixosInstallISO = (import ../release.nix {}).iso_minimal.${pkgs.stdenv.hostPlatform.system};
|
||||
virshShutdownCmd = if pkgs.stdenv.isx86_64 then "shutdown" else "destroy";
|
||||
virshShutdownCmd = if pkgs.stdenv.hostPlatform.isx86_64 then "shutdown" else "destroy";
|
||||
in ''
|
||||
start_all()
|
||||
|
||||
|
26
nixos/tests/nginx-mime.nix
Normal file
26
nixos/tests/nginx-mime.nix
Normal file
@ -0,0 +1,26 @@
|
||||
import ./make-test-python.nix (
|
||||
{ lib, pkgs, ... }:
|
||||
{
|
||||
name = "nginx-mime";
|
||||
meta.maintainers = with pkgs.lib.maintainers; [ izorkin ];
|
||||
|
||||
nodes = {
|
||||
server =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
virtualHosts."localhost" = { };
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
server.start()
|
||||
server.wait_for_unit("nginx")
|
||||
# Check optimal size of types_hash
|
||||
server.fail("journalctl --unit nginx --grep 'could not build optimal types_hash'")
|
||||
server.shutdown()
|
||||
'';
|
||||
}
|
||||
)
|
@ -40,7 +40,7 @@ let
|
||||
};
|
||||
|
||||
environment.systemPackages = [ testers.testPlay pkgs.pavucontrol ]
|
||||
++ lib.optional pkgs.stdenv.isx86_64 testers.testPlay32;
|
||||
++ lib.optional pkgs.stdenv.hostPlatform.isx86_64 testers.testPlay32;
|
||||
} // lib.optionalAttrs systemWide {
|
||||
users.users.alice.extraGroups = [ "pulse-access" ];
|
||||
systemd.services.pulseaudio.wantedBy = [ "multi-user.target" ];
|
||||
@ -54,7 +54,7 @@ let
|
||||
|
||||
machine.send_chars("testPlay \n")
|
||||
machine.wait_for_file("/tmp/testPlay_success")
|
||||
${lib.optionalString pkgs.stdenv.isx86_64 ''
|
||||
${lib.optionalString pkgs.stdenv.hostPlatform.isx86_64 ''
|
||||
machine.send_chars("testPlay32 \n")
|
||||
machine.wait_for_file("/tmp/testPlay32_success")
|
||||
''}
|
||||
|
19
nixos/tests/replace-dependencies/default.nix
Normal file
19
nixos/tests/replace-dependencies/default.nix
Normal file
@ -0,0 +1,19 @@
|
||||
import ../make-test-python.nix (
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
name = "replace-dependencies";
|
||||
meta.maintainers = with pkgs.lib.maintainers; [ alois31 ];
|
||||
|
||||
nodes.machine =
|
||||
{ ... }:
|
||||
{
|
||||
nix.settings.experimental-features = [ "ca-derivations" ];
|
||||
system.extraDependencies = [ pkgs.stdenvNoCC ];
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
start_all()
|
||||
machine.succeed("nix-build --option substitute false ${pkgs.path}/nixos/tests/replace-dependencies/guest.nix")
|
||||
'';
|
||||
}
|
||||
)
|
149
nixos/tests/replace-dependencies/guest.nix
Normal file
149
nixos/tests/replace-dependencies/guest.nix
Normal file
@ -0,0 +1,149 @@
|
||||
# This needs to be run in a NixOS test, because Hydra cannot do IFD.
|
||||
let
|
||||
pkgs = import ../../.. { };
|
||||
inherit (pkgs)
|
||||
runCommand
|
||||
writeShellScriptBin
|
||||
replaceDependency
|
||||
replaceDependencies
|
||||
;
|
||||
inherit (pkgs.lib) escapeShellArg;
|
||||
mkCheckOutput =
|
||||
name: test: output:
|
||||
runCommand name { } ''
|
||||
actualOutput="$(${escapeShellArg "${test}/bin/test"})"
|
||||
if [ "$(${escapeShellArg "${test}/bin/test"})" != ${escapeShellArg output} ]; then
|
||||
echo >&2 "mismatched output: expected \""${escapeShellArg output}"\", got \"$actualOutput\""
|
||||
exit 1
|
||||
fi
|
||||
touch "$out"
|
||||
'';
|
||||
oldDependency = writeShellScriptBin "dependency" ''
|
||||
echo "got old dependency"
|
||||
'';
|
||||
oldDependency-ca = oldDependency.overrideAttrs { __contentAddressed = true; };
|
||||
newDependency = writeShellScriptBin "dependency" ''
|
||||
echo "got new dependency"
|
||||
'';
|
||||
newDependency-ca = newDependency.overrideAttrs { __contentAddressed = true; };
|
||||
basic = writeShellScriptBin "test" ''
|
||||
${oldDependency}/bin/dependency
|
||||
'';
|
||||
basic-ca = writeShellScriptBin "test" ''
|
||||
${oldDependency-ca}/bin/dependency
|
||||
'';
|
||||
transitive = writeShellScriptBin "test" ''
|
||||
${basic}/bin/test
|
||||
'';
|
||||
weirdDependency = writeShellScriptBin "dependency" ''
|
||||
echo "got weird dependency"
|
||||
${basic}/bin/test
|
||||
'';
|
||||
oldDependency1 = writeShellScriptBin "dependency1" ''
|
||||
echo "got old dependency 1"
|
||||
'';
|
||||
newDependency1 = writeShellScriptBin "dependency1" ''
|
||||
echo "got new dependency 1"
|
||||
'';
|
||||
oldDependency2 = writeShellScriptBin "dependency2" ''
|
||||
${oldDependency1}/bin/dependency1
|
||||
echo "got old dependency 2"
|
||||
'';
|
||||
newDependency2 = writeShellScriptBin "dependency2" ''
|
||||
${oldDependency1}/bin/dependency1
|
||||
echo "got new dependency 2"
|
||||
'';
|
||||
deep = writeShellScriptBin "test" ''
|
||||
${oldDependency2}/bin/dependency2
|
||||
'';
|
||||
in
|
||||
{
|
||||
replacedependency-basic = mkCheckOutput "replacedependency-basic" (replaceDependency {
|
||||
drv = basic;
|
||||
inherit oldDependency newDependency;
|
||||
}) "got new dependency";
|
||||
|
||||
replacedependency-basic-old-ca = mkCheckOutput "replacedependency-basic" (replaceDependency {
|
||||
drv = basic-ca;
|
||||
oldDependency = oldDependency-ca;
|
||||
inherit newDependency;
|
||||
}) "got new dependency";
|
||||
|
||||
replacedependency-basic-new-ca = mkCheckOutput "replacedependency-basic" (replaceDependency {
|
||||
drv = basic;
|
||||
inherit oldDependency;
|
||||
newDependency = newDependency-ca;
|
||||
}) "got new dependency";
|
||||
|
||||
replacedependency-transitive = mkCheckOutput "replacedependency-transitive" (replaceDependency {
|
||||
drv = transitive;
|
||||
inherit oldDependency newDependency;
|
||||
}) "got new dependency";
|
||||
|
||||
replacedependency-weird =
|
||||
mkCheckOutput "replacedependency-weird"
|
||||
(replaceDependency {
|
||||
drv = basic;
|
||||
inherit oldDependency;
|
||||
newDependency = weirdDependency;
|
||||
})
|
||||
''
|
||||
got weird dependency
|
||||
got old dependency'';
|
||||
|
||||
replacedependencies-precedence = mkCheckOutput "replacedependencies-precedence" (replaceDependencies
|
||||
{
|
||||
drv = basic;
|
||||
replacements = [ { inherit oldDependency newDependency; } ];
|
||||
cutoffPackages = [ oldDependency ];
|
||||
}
|
||||
) "got new dependency";
|
||||
|
||||
replacedependencies-self = mkCheckOutput "replacedependencies-self" (replaceDependencies {
|
||||
drv = basic;
|
||||
replacements = [
|
||||
{
|
||||
inherit oldDependency;
|
||||
newDependency = oldDependency;
|
||||
}
|
||||
];
|
||||
}) "got old dependency";
|
||||
|
||||
replacedependencies-deep-order1 =
|
||||
mkCheckOutput "replacedependencies-deep-order1"
|
||||
(replaceDependencies {
|
||||
drv = deep;
|
||||
replacements = [
|
||||
{
|
||||
oldDependency = oldDependency1;
|
||||
newDependency = newDependency1;
|
||||
}
|
||||
{
|
||||
oldDependency = oldDependency2;
|
||||
newDependency = newDependency2;
|
||||
}
|
||||
];
|
||||
})
|
||||
''
|
||||
got new dependency 1
|
||||
got new dependency 2'';
|
||||
|
||||
replacedependencies-deep-order2 =
|
||||
mkCheckOutput "replacedependencies-deep-order2"
|
||||
(replaceDependencies {
|
||||
drv = deep;
|
||||
replacements = [
|
||||
{
|
||||
oldDependency = oldDependency2;
|
||||
newDependency = newDependency2;
|
||||
}
|
||||
{
|
||||
oldDependency = oldDependency1;
|
||||
newDependency = newDependency1;
|
||||
}
|
||||
];
|
||||
})
|
||||
''
|
||||
got new dependency 1
|
||||
got new dependency 2'';
|
||||
}
|
73
nixos/tests/scion/freestanding-deployment/bootstrap.sh
Normal file
73
nixos/tests/scion/freestanding-deployment/bootstrap.sh
Normal file
@ -0,0 +1,73 @@
|
||||
set -euo pipefail
|
||||
|
||||
mkdir /tmp/tutorial-scion-certs && cd /tmp/tutorial-scion-certs
|
||||
mkdir AS{1..5}
|
||||
|
||||
# Create voting and root keys and (self-signed) certificates for core ASes
|
||||
pushd AS1
|
||||
scion-pki certificate create --not-after=3650d --profile=sensitive-voting <(echo '{"isd_as": "42-ffaa:1:1", "common_name": "42-ffaa:1:1 sensitive voting cert"}') sensitive-voting.pem sensitive-voting.key
|
||||
scion-pki certificate create --not-after=3650d --profile=regular-voting <(echo '{"isd_as": "42-ffaa:1:1", "common_name": "42-ffaa:1:1 regular voting cert"}') regular-voting.pem regular-voting.key
|
||||
scion-pki certificate create --not-after=3650d --profile=cp-root <(echo '{"isd_as": "42-ffaa:1:1", "common_name": "42-ffaa:1:1 cp root cert"}') cp-root.pem cp-root.key
|
||||
popd
|
||||
|
||||
pushd AS2
|
||||
scion-pki certificate create --not-after=3650d --profile=cp-root <(echo '{"isd_as": "42-ffaa:1:2", "common_name": "42-ffaa:1:2 cp root cert"}') cp-root.pem cp-root.key
|
||||
popd
|
||||
|
||||
pushd AS3
|
||||
scion-pki certificate create --not-after=3650d --profile=sensitive-voting <(echo '{"isd_as": "42-ffaa:1:3", "common_name": "42-ffaa:1:3 sensitive voting cert"}') sensitive-voting.pem sensitive-voting.key
|
||||
scion-pki certificate create --not-after=3650d --profile=regular-voting <(echo '{"isd_as": "42-ffaa:1:3", "common_name": "42-ffaa:1:3 regular voting cert"}') regular-voting.pem regular-voting.key
|
||||
popd
|
||||
|
||||
# Create the TRC (Trust Root Configuration)
|
||||
mkdir tmp
|
||||
echo '
|
||||
isd = 42
|
||||
description = "Demo ISD 42"
|
||||
serial_version = 1
|
||||
base_version = 1
|
||||
voting_quorum = 2
|
||||
|
||||
core_ases = ["ffaa:1:1", "ffaa:1:2", "ffaa:1:3"]
|
||||
authoritative_ases = ["ffaa:1:1", "ffaa:1:2", "ffaa:1:3"]
|
||||
cert_files = ["AS1/sensitive-voting.pem", "AS1/regular-voting.pem", "AS1/cp-root.pem", "AS2/cp-root.pem", "AS3/sensitive-voting.pem", "AS3/regular-voting.pem"]
|
||||
|
||||
[validity]
|
||||
not_before = '$(date +%s)'
|
||||
validity = "365d"' \
|
||||
> trc-B1-S1-pld.tmpl
|
||||
|
||||
scion-pki trc payload --out=tmp/ISD42-B1-S1.pld.der --template trc-B1-S1-pld.tmpl
|
||||
rm trc-B1-S1-pld.tmpl
|
||||
|
||||
# Sign and bundle the TRC
|
||||
scion-pki trc sign tmp/ISD42-B1-S1.pld.der AS1/sensitive-voting.{pem,key} --out tmp/ISD42-B1-S1.AS1-sensitive.trc
|
||||
scion-pki trc sign tmp/ISD42-B1-S1.pld.der AS1/regular-voting.{pem,key} --out tmp/ISD42-B1-S1.AS1-regular.trc
|
||||
scion-pki trc sign tmp/ISD42-B1-S1.pld.der AS3/sensitive-voting.{pem,key} --out tmp/ISD42-B1-S1.AS3-sensitive.trc
|
||||
scion-pki trc sign tmp/ISD42-B1-S1.pld.der AS3/regular-voting.{pem,key} --out tmp/ISD42-B1-S1.AS3-regular.trc
|
||||
|
||||
scion-pki trc combine tmp/ISD42-B1-S1.AS{1,3}-{sensitive,regular}.trc --payload tmp/ISD42-B1-S1.pld.der --out ISD42-B1-S1.trc
|
||||
rm tmp -r
|
||||
|
||||
# Create CA key and certificate for issuing ASes
|
||||
pushd AS1
|
||||
scion-pki certificate create --profile=cp-ca <(echo '{"isd_as": "42-ffaa:1:1", "common_name": "42-ffaa:1:1 CA cert"}') cp-ca.pem cp-ca.key --ca cp-root.pem --ca-key cp-root.key
|
||||
popd
|
||||
pushd AS2
|
||||
scion-pki certificate create --profile=cp-ca <(echo '{"isd_as": "42-ffaa:1:2", "common_name": "42-ffaa:1:2 CA cert"}') cp-ca.pem cp-ca.key --ca cp-root.pem --ca-key cp-root.key
|
||||
popd
|
||||
|
||||
# Create AS key and certificate chains
|
||||
scion-pki certificate create --profile=cp-as <(echo '{"isd_as": "42-ffaa:1:1", "common_name": "42-ffaa:1:1 AS cert"}') AS1/cp-as.pem AS1/cp-as.key --ca AS1/cp-ca.pem --ca-key AS1/cp-ca.key --bundle
|
||||
scion-pki certificate create --profile=cp-as <(echo '{"isd_as": "42-ffaa:1:2", "common_name": "42-ffaa:1:2 AS cert"}') AS2/cp-as.pem AS2/cp-as.key --ca AS2/cp-ca.pem --ca-key AS2/cp-ca.key --bundle
|
||||
scion-pki certificate create --profile=cp-as <(echo '{"isd_as": "42-ffaa:1:3", "common_name": "42-ffaa:1:3 AS cert"}') AS3/cp-as.pem AS3/cp-as.key --ca AS1/cp-ca.pem --ca-key AS1/cp-ca.key --bundle
|
||||
scion-pki certificate create --profile=cp-as <(echo '{"isd_as": "42-ffaa:1:4", "common_name": "42-ffaa:1:4 AS cert"}') AS4/cp-as.pem AS4/cp-as.key --ca AS1/cp-ca.pem --ca-key AS1/cp-ca.key --bundle
|
||||
scion-pki certificate create --profile=cp-as <(echo '{"isd_as": "42-ffaa:1:5", "common_name": "42-ffaa:1:5 AS cert"}') AS5/cp-as.pem AS5/cp-as.key --ca AS2/cp-ca.pem --ca-key AS2/cp-ca.key --bundle
|
||||
|
||||
for i in {1..5}
|
||||
do
|
||||
mkdir -p $out/AS$i
|
||||
cp AS$i/cp-as.{key,pem} $out/AS$i
|
||||
done
|
||||
|
||||
mv *.trc $out
|
@ -5,81 +5,8 @@ let
|
||||
buildInputs = [
|
||||
pkgs.scion
|
||||
];
|
||||
} ''
|
||||
set -euo pipefail
|
||||
} (builtins.readFile ./bootstrap.sh);
|
||||
|
||||
mkdir /tmp/tutorial-scion-certs && cd /tmp/tutorial-scion-certs
|
||||
mkdir AS{1..5}
|
||||
|
||||
# Create voting and root keys and (self-signed) certificates for core ASes
|
||||
pushd AS1
|
||||
scion-pki certificate create --not-after=3650d --profile=sensitive-voting <(echo '{"isd_as": "42-ffaa:1:1", "common_name": "42-ffaa:1:1 sensitive voting cert"}') sensitive-voting.pem sensitive-voting.key
|
||||
scion-pki certificate create --not-after=3650d --profile=regular-voting <(echo '{"isd_as": "42-ffaa:1:1", "common_name": "42-ffaa:1:1 regular voting cert"}') regular-voting.pem regular-voting.key
|
||||
scion-pki certificate create --not-after=3650d --profile=cp-root <(echo '{"isd_as": "42-ffaa:1:1", "common_name": "42-ffaa:1:1 cp root cert"}') cp-root.pem cp-root.key
|
||||
popd
|
||||
|
||||
pushd AS2
|
||||
scion-pki certificate create --not-after=3650d --profile=cp-root <(echo '{"isd_as": "42-ffaa:1:2", "common_name": "42-ffaa:1:2 cp root cert"}') cp-root.pem cp-root.key
|
||||
popd
|
||||
|
||||
pushd AS3
|
||||
scion-pki certificate create --not-after=3650d --profile=sensitive-voting <(echo '{"isd_as": "42-ffaa:1:3", "common_name": "42-ffaa:1:3 sensitive voting cert"}') sensitive-voting.pem sensitive-voting.key
|
||||
scion-pki certificate create --not-after=3650d --profile=regular-voting <(echo '{"isd_as": "42-ffaa:1:3", "common_name": "42-ffaa:1:3 regular voting cert"}') regular-voting.pem regular-voting.key
|
||||
popd
|
||||
|
||||
# Create the TRC (Trust Root Configuration)
|
||||
mkdir tmp
|
||||
echo '
|
||||
isd = 42
|
||||
description = "Demo ISD 42"
|
||||
serial_version = 1
|
||||
base_version = 1
|
||||
voting_quorum = 2
|
||||
|
||||
core_ases = ["ffaa:1:1", "ffaa:1:2", "ffaa:1:3"]
|
||||
authoritative_ases = ["ffaa:1:1", "ffaa:1:2", "ffaa:1:3"]
|
||||
cert_files = ["AS1/sensitive-voting.pem", "AS1/regular-voting.pem", "AS1/cp-root.pem", "AS2/cp-root.pem", "AS3/sensitive-voting.pem", "AS3/regular-voting.pem"]
|
||||
|
||||
[validity]
|
||||
not_before = '$(date +%s)'
|
||||
validity = "365d"' \
|
||||
> trc-B1-S1-pld.tmpl
|
||||
|
||||
scion-pki trc payload --out=tmp/ISD42-B1-S1.pld.der --template trc-B1-S1-pld.tmpl
|
||||
rm trc-B1-S1-pld.tmpl
|
||||
|
||||
# Sign and bundle the TRC
|
||||
scion-pki trc sign tmp/ISD42-B1-S1.pld.der AS1/sensitive-voting.{pem,key} --out tmp/ISD42-B1-S1.AS1-sensitive.trc
|
||||
scion-pki trc sign tmp/ISD42-B1-S1.pld.der AS1/regular-voting.{pem,key} --out tmp/ISD42-B1-S1.AS1-regular.trc
|
||||
scion-pki trc sign tmp/ISD42-B1-S1.pld.der AS3/sensitive-voting.{pem,key} --out tmp/ISD42-B1-S1.AS3-sensitive.trc
|
||||
scion-pki trc sign tmp/ISD42-B1-S1.pld.der AS3/regular-voting.{pem,key} --out tmp/ISD42-B1-S1.AS3-regular.trc
|
||||
|
||||
scion-pki trc combine tmp/ISD42-B1-S1.AS{1,3}-{sensitive,regular}.trc --payload tmp/ISD42-B1-S1.pld.der --out ISD42-B1-S1.trc
|
||||
rm tmp -r
|
||||
|
||||
# Create CA key and certificate for issuing ASes
|
||||
pushd AS1
|
||||
scion-pki certificate create --profile=cp-ca <(echo '{"isd_as": "42-ffaa:1:1", "common_name": "42-ffaa:1:1 CA cert"}') cp-ca.pem cp-ca.key --ca cp-root.pem --ca-key cp-root.key
|
||||
popd
|
||||
pushd AS2
|
||||
scion-pki certificate create --profile=cp-ca <(echo '{"isd_as": "42-ffaa:1:2", "common_name": "42-ffaa:1:2 CA cert"}') cp-ca.pem cp-ca.key --ca cp-root.pem --ca-key cp-root.key
|
||||
popd
|
||||
|
||||
# Create AS key and certificate chains
|
||||
scion-pki certificate create --profile=cp-as <(echo '{"isd_as": "42-ffaa:1:1", "common_name": "42-ffaa:1:1 AS cert"}') AS1/cp-as.pem AS1/cp-as.key --ca AS1/cp-ca.pem --ca-key AS1/cp-ca.key --bundle
|
||||
scion-pki certificate create --profile=cp-as <(echo '{"isd_as": "42-ffaa:1:2", "common_name": "42-ffaa:1:2 AS cert"}') AS2/cp-as.pem AS2/cp-as.key --ca AS2/cp-ca.pem --ca-key AS2/cp-ca.key --bundle
|
||||
scion-pki certificate create --profile=cp-as <(echo '{"isd_as": "42-ffaa:1:3", "common_name": "42-ffaa:1:3 AS cert"}') AS3/cp-as.pem AS3/cp-as.key --ca AS1/cp-ca.pem --ca-key AS1/cp-ca.key --bundle
|
||||
scion-pki certificate create --profile=cp-as <(echo '{"isd_as": "42-ffaa:1:4", "common_name": "42-ffaa:1:4 AS cert"}') AS4/cp-as.pem AS4/cp-as.key --ca AS1/cp-ca.pem --ca-key AS1/cp-ca.key --bundle
|
||||
scion-pki certificate create --profile=cp-as <(echo '{"isd_as": "42-ffaa:1:5", "common_name": "42-ffaa:1:5 AS cert"}') AS5/cp-as.pem AS5/cp-as.key --ca AS2/cp-ca.pem --ca-key AS2/cp-ca.key --bundle
|
||||
|
||||
for i in {1..5}
|
||||
do
|
||||
mkdir -p $out/AS$i
|
||||
cp AS$i/cp-as.{key,pem} $out/AS$i
|
||||
done
|
||||
|
||||
mv *.trc $out
|
||||
'';
|
||||
imports = hostId: [
|
||||
({
|
||||
services.scion = {
|
||||
@ -121,9 +48,47 @@ in
|
||||
};
|
||||
scion04 = { ... }: {
|
||||
imports = (imports 4);
|
||||
networking.interfaces."lo".ipv4.addresses = [{ address = "172.16.1.1"; prefixLength = 32; }];
|
||||
services.scion.scion-ip-gateway = {
|
||||
enable = true;
|
||||
config = {
|
||||
tunnel = {
|
||||
src_ipv4 = "172.16.1.1";
|
||||
};
|
||||
};
|
||||
trafficConfig = {
|
||||
ASes = {
|
||||
"42-ffaa:1:5" = {
|
||||
Nets = [
|
||||
"172.16.100.0/24"
|
||||
];
|
||||
};
|
||||
};
|
||||
ConfigVersion = 9001;
|
||||
};
|
||||
};
|
||||
};
|
||||
scion05 = { ... }: {
|
||||
imports = (imports 5);
|
||||
networking.interfaces."lo".ipv4.addresses = [{ address = "172.16.100.1"; prefixLength = 32; }];
|
||||
services.scion.scion-ip-gateway = {
|
||||
enable = true;
|
||||
config = {
|
||||
tunnel = {
|
||||
src_ipv4 = "172.16.100.1";
|
||||
};
|
||||
};
|
||||
trafficConfig = {
|
||||
ASes = {
|
||||
"42-ffaa:1:4" = {
|
||||
Nets = [
|
||||
"172.16.1.0/24"
|
||||
];
|
||||
};
|
||||
};
|
||||
ConfigVersion = 9001;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
testScript = let
|
||||
@ -131,25 +96,35 @@ in
|
||||
addresses="42-ffaa:1:1 42-ffaa:1:2 42-ffaa:1:3 42-ffaa:1:4 42-ffaa:1:5"
|
||||
timeout=100
|
||||
wait_for_all() {
|
||||
ret=0
|
||||
for as in "$@"
|
||||
do
|
||||
scion showpaths $as --no-probe > /dev/null
|
||||
return 1
|
||||
ret=$?
|
||||
if [ "$ret" -ne "0" ]; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
return 0
|
||||
return $ret
|
||||
}
|
||||
ping_all() {
|
||||
ret=0
|
||||
for as in "$@"
|
||||
do
|
||||
scion ping "$as,127.0.0.1" -c 3
|
||||
ret=$?
|
||||
if [ "$ret" -ne "0" ]; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
return 0
|
||||
return $ret
|
||||
}
|
||||
for i in $(seq 0 $timeout); do
|
||||
wait_for_all $addresses && exit 0
|
||||
ping_all $addresses && exit 0
|
||||
sleep 1
|
||||
wait_for_all $addresses || continue
|
||||
ping_all $addresses && exit 0
|
||||
done
|
||||
exit 1
|
||||
'';
|
||||
in
|
||||
''
|
||||
@ -183,9 +158,16 @@ in
|
||||
# Wait for scion-control.service on all instances
|
||||
wait_for_unit("scion-control.service")
|
||||
|
||||
# Ensure cert is valid against TRC
|
||||
succeed("scion-pki certificate verify --trc /etc/scion/certs/*.trc /etc/scion/crypto/as/*.pem >&2")
|
||||
|
||||
# Execute pingAll command on all instances
|
||||
succeed("${pingAll} >&2")
|
||||
|
||||
# Execute ICMP pings across scion-ip-gateway
|
||||
scion04.succeed("ping -c 3 172.16.100.1 >&2")
|
||||
scion05.succeed("ping -c 3 172.16.1.1 >&2")
|
||||
|
||||
# Restart all scion services and ping again to test robustness
|
||||
succeed("systemctl restart scion-* >&2")
|
||||
succeed("${pingAll} >&2")
|
||||
|
@ -36,5 +36,11 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"sigs": {
|
||||
"sig-1": {
|
||||
"ctrl_addr": "127.0.0.1:30256",
|
||||
"data_addr": "127.0.0.1:30056"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,5 +36,11 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"sigs": {
|
||||
"sig-1": {
|
||||
"ctrl_addr": "127.0.0.1:30256",
|
||||
"data_addr": "127.0.0.1:30056"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ import ./make-test-python.nix ({ lib, pkgs, ... }: {
|
||||
libDir = pkgs.stdenv.hostPlatform.libDir;
|
||||
ldsoBasename = lib.last (lib.splitString "/" pkgs.stdenv.cc.bintools.dynamicLinker);
|
||||
|
||||
check32 = pkgs.stdenv.isx86_64;
|
||||
check32 = pkgs.stdenv.hostPlatform.isx86_64;
|
||||
pkgs32 = pkgs.pkgsi686Linux;
|
||||
|
||||
libDir32 = pkgs32.stdenv.hostPlatform.libDir;
|
||||
|
@ -2,7 +2,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: {
|
||||
name = "sunshine";
|
||||
meta = {
|
||||
# test is flaky on aarch64
|
||||
broken = pkgs.stdenv.isAarch64;
|
||||
broken = pkgs.stdenv.hostPlatform.isAarch64;
|
||||
maintainers = [ lib.maintainers.devusb ];
|
||||
};
|
||||
|
||||
|
51
nixos/tests/web-apps/immich.nix
Normal file
51
nixos/tests/web-apps/immich.nix
Normal file
@ -0,0 +1,51 @@
|
||||
import ../make-test-python.nix (
|
||||
{ ... }:
|
||||
{
|
||||
name = "immich-nixos";
|
||||
|
||||
nodes.machine =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
# These tests need a little more juice
|
||||
virtualisation = {
|
||||
cores = 2;
|
||||
memorySize = 2048;
|
||||
diskSize = 4096;
|
||||
};
|
||||
|
||||
environment.systemPackages = with pkgs; [ immich-cli ];
|
||||
|
||||
services.immich = {
|
||||
enable = true;
|
||||
environment.IMMICH_LOG_LEVEL = "verbose";
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
import json
|
||||
|
||||
machine.wait_for_unit("immich-server.service")
|
||||
|
||||
machine.wait_for_open_port(3001) # Server
|
||||
machine.wait_for_open_port(3003) # Machine learning
|
||||
machine.succeed("curl --fail http://localhost:3001/")
|
||||
|
||||
machine.succeed("""
|
||||
curl -H 'Content-Type: application/json' --data '{ "email": "test@example.com", "name": "Admin", "password": "admin" }' -X POST http://localhost:3001/api/auth/admin-sign-up
|
||||
""")
|
||||
res = machine.succeed("""
|
||||
curl -H 'Content-Type: application/json' --data '{ "email": "test@example.com", "password": "admin" }' -X POST http://localhost:3001/api/auth/login
|
||||
""")
|
||||
token = json.loads(res)['accessToken']
|
||||
|
||||
res = machine.succeed("""
|
||||
curl -H 'Content-Type: application/json' -H 'Cookie: immich_access_token=%s' --data '{ "name": "API Key", "permissions": ["all"] }' -X POST http://localhost:3001/api/api-keys
|
||||
""" % token)
|
||||
key = json.loads(res)['secret']
|
||||
|
||||
machine.succeed(f"immich login http://localhost:3001/api {key}")
|
||||
res = machine.succeed("immich server-info")
|
||||
print(res)
|
||||
'';
|
||||
}
|
||||
)
|
@ -43,7 +43,7 @@ let
|
||||
in
|
||||
listToAttrs (
|
||||
map (makeWineTest "winePackages" [ hello32 ]) variants
|
||||
++ optionals pkgs.stdenv.is64bit
|
||||
++ optionals pkgs.stdenv.hostPlatform.is64bit
|
||||
(map (makeWineTest "wineWowPackages" [ hello32 hello64 ])
|
||||
# This wayland combination times out after spending many hours.
|
||||
# https://hydra.nixos.org/job/nixos/trunk-combined/nixos.tests.wine.wineWowPackages-wayland.x86_64-linux
|
||||
|
@ -204,12 +204,12 @@ in {
|
||||
|
||||
unstable = makeZfsTest rec {
|
||||
zfsPackage = pkgs.zfs_unstable;
|
||||
kernelPackages = zfsPackage.latestCompatibleLinuxPackages;
|
||||
kernelPackages = pkgs.linuxPackages;
|
||||
};
|
||||
|
||||
unstableWithSystemdStage1 = makeZfsTest rec {
|
||||
zfsPackage = pkgs.zfs_unstable;
|
||||
kernelPackages = zfsPackage.latestCompatibleLinuxPackages;
|
||||
kernelPackages = pkgs.linuxPackages;
|
||||
enableSystemdStage1 = true;
|
||||
};
|
||||
|
||||
|
@ -1,79 +0,0 @@
|
||||
{ lib
|
||||
, stdenv
|
||||
, fetchFromGitLab
|
||||
, rustPlatform
|
||||
, cargo
|
||||
, desktop-file-utils
|
||||
, appstream-glib
|
||||
, meson
|
||||
, ninja
|
||||
, pkg-config
|
||||
, reuse
|
||||
, rustc
|
||||
, m4
|
||||
, wrapGAppsHook4
|
||||
, glib
|
||||
, gtk4
|
||||
, gst_all_1
|
||||
, libadwaita
|
||||
, dbus
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "amberol";
|
||||
version = "0.10.3";
|
||||
|
||||
src = fetchFromGitLab {
|
||||
domain = "gitlab.gnome.org";
|
||||
owner = "World";
|
||||
repo = pname;
|
||||
rev = version;
|
||||
hash = "sha256-nAoUO0bGToNGD2W8qJmTegrETOJDdM04hI1jjiYkZXI=";
|
||||
};
|
||||
|
||||
cargoDeps = rustPlatform.fetchCargoTarball {
|
||||
inherit src;
|
||||
name = "${pname}-${version}";
|
||||
hash = "sha256-4ZoliqQ665KPDFl+1eBCE+1fZgr+FA7vesPstoRs0RU=";
|
||||
};
|
||||
|
||||
postPatch = ''
|
||||
patchShebangs build-aux
|
||||
'';
|
||||
|
||||
nativeBuildInputs = [
|
||||
appstream-glib
|
||||
desktop-file-utils
|
||||
meson
|
||||
ninja
|
||||
pkg-config
|
||||
reuse
|
||||
m4
|
||||
wrapGAppsHook4
|
||||
rustPlatform.cargoSetupHook
|
||||
cargo
|
||||
rustc
|
||||
];
|
||||
|
||||
buildInputs = [
|
||||
glib
|
||||
gtk4
|
||||
libadwaita
|
||||
gst_all_1.gstreamer
|
||||
gst_all_1.gst-plugins-base
|
||||
gst_all_1.gst-plugins-good
|
||||
gst_all_1.gst-plugins-bad
|
||||
gst_all_1.gst-plugins-ugly
|
||||
gst_all_1.gst-libav
|
||||
dbus
|
||||
];
|
||||
|
||||
meta = with lib; {
|
||||
homepage = "https://gitlab.gnome.org/World/amberol";
|
||||
description = "Small and simple sound and music player";
|
||||
maintainers = with maintainers; [ linsui ];
|
||||
license = licenses.gpl3Plus;
|
||||
platforms = platforms.linux;
|
||||
mainProgram = "amberol";
|
||||
};
|
||||
}
|
@ -44,7 +44,7 @@ stdenv.mkDerivation rec {
|
||||
taglib
|
||||
];
|
||||
|
||||
postInstall = lib.optionalString stdenv.isDarwin ''
|
||||
postInstall = lib.optionalString stdenv.hostPlatform.isDarwin ''
|
||||
for file in $out/lib/ario/plugins/*.dylib; do
|
||||
ln -s $file $out/lib/ario/plugins/$(basename $file .dylib).so
|
||||
done
|
||||
|
@ -25,7 +25,7 @@ stdenv.mkDerivation rec {
|
||||
dontUseCmakeConfigure = true;
|
||||
nativeBuildInputs = [ cmake pkg-config meson ninja ];
|
||||
buildInputs = [ libmpdclient yaml-cpp ]
|
||||
++ lib.optionals stdenv.isDarwin [ darwin.apple_sdk.frameworks.CoreFoundation ];
|
||||
++ lib.optionals stdenv.hostPlatform.isDarwin [ darwin.apple_sdk.frameworks.CoreFoundation ];
|
||||
|
||||
mesonFlags = [ "-Dunsupported_use_system_yamlcpp=true" ];
|
||||
|
||||
|
@ -10,7 +10,7 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
};
|
||||
|
||||
buildInputs = [ sndio ]
|
||||
++ lib.optional (!stdenv.isDarwin && !stdenv.hostPlatform.isBSD)
|
||||
++ lib.optional (!stdenv.hostPlatform.isDarwin && !stdenv.hostPlatform.isBSD)
|
||||
libbsd;
|
||||
|
||||
outputs = [ "out" "man" ];
|
||||
@ -18,7 +18,7 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
preBuild = ''
|
||||
makeFlagsArray+=("PREFIX=$out")
|
||||
'' + lib.optionalString
|
||||
(!stdenv.isDarwin && !stdenv.hostPlatform.isBSD) ''
|
||||
(!stdenv.hostPlatform.isDarwin && !stdenv.hostPlatform.isBSD) ''
|
||||
makeFlagsArray+=(LDADD="-lsndio -lbsd")
|
||||
|
||||
# Fix warning about implicit declaration of function 'strlcpy'
|
||||
|
@ -13,13 +13,13 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "audacious";
|
||||
version = "4.4";
|
||||
version = "4.4.1";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "audacious-media-player";
|
||||
repo = "audacious";
|
||||
rev = "${pname}-${version}";
|
||||
hash = "sha256-qAJztvNI3uGmQfECJJ7tJ/xLLgMU5OiW0O3ZSJhvt0k=";
|
||||
hash = "sha256-Bz/OI38+IFTHlBH3p2NTzSj8YD/7Xd4JeWpHgCSpMXw=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
|
@ -46,13 +46,13 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "audacious-plugins";
|
||||
version = "4.4";
|
||||
version = "4.4.1";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "audacious-media-player";
|
||||
repo = "audacious-plugins";
|
||||
rev = "${pname}-${version}";
|
||||
hash = "sha256-J9jgBl8J4W9Yvrlg1KlzYgGTmdxUZM9L11rCftKFSlE=";
|
||||
hash = "sha256-F2kcGc6VCaBsL5Zx7qtZjPvqzaxmR87Q9LTFEU+nqmo=";
|
||||
};
|
||||
|
||||
patches = [ ./0001-Set-plugindir-to-PREFIX-lib-audacious.patch ];
|
||||
|
@ -75,10 +75,10 @@ stdenv.mkDerivation rec {
|
||||
mkdir src/private
|
||||
substituteInPlace scripts/build/macOS/fix_bundle.py \
|
||||
--replace "path.startswith('/usr/lib/')" "path.startswith('${builtins.storeDir}')"
|
||||
'' + lib.optionalString stdenv.isLinux ''
|
||||
'' + lib.optionalString stdenv.hostPlatform.isLinux ''
|
||||
substituteInPlace libraries/lib-files/FileNames.cpp \
|
||||
--replace /usr/include/linux/magic.h ${linuxHeaders}/include/linux/magic.h
|
||||
'' + lib.optionalString (stdenv.isDarwin && lib.versionOlder stdenv.hostPlatform.darwinMinVersion "11.0") ''
|
||||
'' + lib.optionalString (stdenv.hostPlatform.isDarwin && lib.versionOlder stdenv.hostPlatform.darwinMinVersion "11.0") ''
|
||||
sed -z -i "s/NSAppearanceName.*systemAppearance//" src/AudacityApp.mm
|
||||
'';
|
||||
|
||||
@ -89,7 +89,7 @@ stdenv.mkDerivation rec {
|
||||
python3
|
||||
makeWrapper
|
||||
wrapGAppsHook3
|
||||
] ++ lib.optionals stdenv.isLinux [
|
||||
] ++ lib.optionals stdenv.hostPlatform.isLinux [
|
||||
linuxHeaders
|
||||
];
|
||||
|
||||
@ -125,7 +125,7 @@ stdenv.mkDerivation rec {
|
||||
portaudio
|
||||
wavpack
|
||||
wxGTK32
|
||||
] ++ lib.optionals stdenv.isLinux [
|
||||
] ++ lib.optionals stdenv.hostPlatform.isLinux [
|
||||
alsa-lib # for portaudio
|
||||
at-spi2-core
|
||||
dbus
|
||||
@ -138,7 +138,7 @@ stdenv.mkDerivation rec {
|
||||
libsepol
|
||||
libuuid
|
||||
util-linux
|
||||
] ++ lib.optionals stdenv.isDarwin [
|
||||
] ++ lib.optionals stdenv.hostPlatform.isDarwin [
|
||||
AppKit
|
||||
CoreAudioKit # for portaudio
|
||||
libpng
|
||||
@ -176,13 +176,13 @@ stdenv.mkDerivation rec {
|
||||
# Replace audacity's wrapper, to:
|
||||
# - put it in the right place, it shouldn't be in "$out/audacity"
|
||||
# - Add the ffmpeg dynamic dependency
|
||||
postFixup = lib.optionalString stdenv.isLinux ''
|
||||
postFixup = lib.optionalString stdenv.hostPlatform.isLinux ''
|
||||
wrapProgram "$out/bin/audacity" \
|
||||
"''${gappsWrapperArgs[@]}" \
|
||||
--prefix LD_LIBRARY_PATH : "$out/lib/audacity":${lib.makeLibraryPath [ ffmpeg_7 ]} \
|
||||
--suffix AUDACITY_MODULES_PATH : "$out/lib/audacity/modules" \
|
||||
--suffix AUDACITY_PATH : "$out/share/audacity"
|
||||
'' + lib.optionalString stdenv.isDarwin ''
|
||||
'' + lib.optionalString stdenv.hostPlatform.isDarwin ''
|
||||
mkdir -p $out/{Applications,bin}
|
||||
mv $out/Audacity.app $out/Applications/
|
||||
makeWrapper $out/Applications/Audacity.app/Contents/MacOS/Audacity $out/bin/audacity
|
||||
|
@ -26,11 +26,11 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "cardinal";
|
||||
version = "24.05";
|
||||
version = "24.09";
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://github.com/DISTRHO/Cardinal/releases/download/${version}/cardinal+deps-${version}.tar.xz";
|
||||
hash = "sha256-ZUJI5utUtST+idlL7WKBIs850EpK98cnmO47g8/iZcI=";
|
||||
hash = "sha256-vJxKtZ0rVjf0RJfTNRxpzps1F2k0hHuiPnd1OwpULhQ=";
|
||||
};
|
||||
|
||||
prePatch = ''
|
||||
@ -89,6 +89,6 @@ stdenv.mkDerivation rec {
|
||||
mainProgram = "Cardinal";
|
||||
platforms = lib.platforms.all;
|
||||
# never built on aarch64-darwin, x86_64-darwin since first introduction in nixpkgs
|
||||
broken = stdenv.isDarwin;
|
||||
broken = stdenv.hostPlatform.isDarwin;
|
||||
};
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ stdenv.mkDerivation rec {
|
||||
installFlags = [ "PREFIX=$(out)" "INSTALL=install" ];
|
||||
|
||||
buildInputs = []
|
||||
++ lib.optional stdenv.isDarwin IOKit;
|
||||
++ lib.optional stdenv.hostPlatform.isDarwin IOKit;
|
||||
|
||||
meta = with lib; {
|
||||
homepage = "http://linukz.org/cd-discid.shtml";
|
||||
|
@ -12,7 +12,7 @@ stdenv.mkDerivation rec {
|
||||
sha256 = "1pv4zrajm46za0f6lv162iqffih57a8ly4pc69f7y0gfyigb8p80";
|
||||
};
|
||||
|
||||
patches = lib.optionals stdenv.isDarwin [
|
||||
patches = lib.optionals stdenv.hostPlatform.isDarwin [
|
||||
(fetchpatch {
|
||||
url = "https://trac.macports.org/export/70964/trunk/dports/audio/cdparanoia/files/osx_interface.patch";
|
||||
sha256 = "0hq3lvfr0h1m3p0r33jij0s1aspiqlpy533rwv19zrfllb39qvr8";
|
||||
@ -37,7 +37,7 @@ stdenv.mkDerivation rec {
|
||||
autoreconfHook
|
||||
];
|
||||
|
||||
propagatedBuildInputs = lib.optionals stdenv.isDarwin [
|
||||
propagatedBuildInputs = lib.optionals stdenv.hostPlatform.isDarwin [
|
||||
Carbon
|
||||
IOKit
|
||||
];
|
||||
|
@ -12,16 +12,16 @@ stdenv.mkDerivation rec {
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ flex bison which ]
|
||||
++ lib.optionals stdenv.isDarwin [ DarwinTools xcbuild ];
|
||||
++ lib.optionals stdenv.hostPlatform.isDarwin [ DarwinTools xcbuild ];
|
||||
|
||||
buildInputs = [ libsndfile ]
|
||||
++ lib.optional (!stdenv.isDarwin) alsa-lib
|
||||
++ lib.optionals stdenv.isDarwin [ AppKit Carbon CoreAudio CoreMIDI CoreServices Kernel MultitouchSupport ];
|
||||
++ lib.optional (!stdenv.hostPlatform.isDarwin) alsa-lib
|
||||
++ lib.optionals stdenv.hostPlatform.isDarwin [ AppKit Carbon CoreAudio CoreMIDI CoreServices Kernel MultitouchSupport ];
|
||||
|
||||
patches = [ ./darwin-limits.patch ];
|
||||
|
||||
makeFlags = [ "-C src" "DESTDIR=$(out)/bin" ];
|
||||
buildFlags = [ (if stdenv.isDarwin then "mac" else "linux-alsa") ];
|
||||
buildFlags = [ (if stdenv.hostPlatform.isDarwin then "mac" else "linux-alsa") ];
|
||||
|
||||
meta = with lib; {
|
||||
description = "Programming language for real-time sound synthesis and music creation";
|
||||
|
@ -9,10 +9,11 @@ appimageTools.wrapType2 rec {
|
||||
sha256 = "sha256-NwoV1eeAN0u9VXWpu5mANXhmgqe8u3h7BlsREP1f/pI=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ makeWrapper ];
|
||||
|
||||
extraInstallCommands =
|
||||
let contents = appimageTools.extract { inherit pname version src; };
|
||||
in ''
|
||||
source "${makeWrapper}/nix-support/setup-hook"
|
||||
wrapProgram $out/bin/${pname} \
|
||||
--add-flags "\''${NIXOS_OZONE_WL:+\''${WAYLAND_DISPLAY:+--ozone-platform-hint=auto --enable-features=WaylandWindowDecorations}}"
|
||||
|
||||
|
@ -1,15 +1,15 @@
|
||||
{ config, lib, stdenv, fetchFromGitHub, ncurses, pkg-config
|
||||
, libiconv, CoreAudio, AudioUnit, VideoToolbox
|
||||
|
||||
, alsaSupport ? stdenv.isLinux, alsa-lib ? null
|
||||
, alsaSupport ? stdenv.hostPlatform.isLinux, alsa-lib ? null
|
||||
# simple fallback for everyone else
|
||||
, aoSupport ? !stdenv.isLinux, libao ? null
|
||||
, aoSupport ? !stdenv.hostPlatform.isLinux, libao ? null
|
||||
, jackSupport ? false, libjack ? null
|
||||
, samplerateSupport ? jackSupport, libsamplerate ? null
|
||||
, ossSupport ? false, alsa-oss ? null
|
||||
, pulseaudioSupport ? config.pulseaudio or false, libpulseaudio ? null
|
||||
, sndioSupport ? false, sndio ? null
|
||||
, mprisSupport ? stdenv.isLinux, systemd ? null
|
||||
, mprisSupport ? stdenv.hostPlatform.isLinux, systemd ? null
|
||||
|
||||
# TODO: add these
|
||||
#, artsSupport
|
||||
@ -103,7 +103,7 @@ stdenv.mkDerivation rec {
|
||||
|
||||
nativeBuildInputs = [ pkg-config ];
|
||||
buildInputs = [ ncurses ]
|
||||
++ lib.optionals stdenv.isDarwin [ libiconv CoreAudio AudioUnit VideoToolbox ]
|
||||
++ lib.optionals stdenv.hostPlatform.isDarwin [ libiconv CoreAudio AudioUnit VideoToolbox ]
|
||||
++ lib.flatten (lib.concatMap (a: a.deps) opts);
|
||||
|
||||
prefixKey = "prefix=";
|
||||
|
@ -1,5 +1,5 @@
|
||||
{ lib, stdenv, fetchFromGitHub, autoreconfHook, pkg-config, curl, libnotify
|
||||
, gdk-pixbuf, libnotifySupport ? stdenv.isLinux, debug ? false }:
|
||||
, gdk-pixbuf, libnotifySupport ? stdenv.hostPlatform.isLinux, debug ? false }:
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "cmusfm";
|
||||
|
@ -31,21 +31,21 @@ stdenv.mkDerivation rec {
|
||||
};
|
||||
|
||||
cmakeFlags = [ "-DBUILD_CSOUND_AC=0" ] # fails to find Score.hpp
|
||||
++ lib.optional stdenv.isDarwin "-DCS_FRAMEWORK_DEST=${placeholder "out"}/lib"
|
||||
++ lib.optional stdenv.hostPlatform.isDarwin "-DCS_FRAMEWORK_DEST=${placeholder "out"}/lib"
|
||||
# Ignore gettext in CMAKE_PREFIX_PATH on cross to prevent find_program picking up the wrong gettext
|
||||
++ lib.optional (stdenv.hostPlatform != stdenv.buildPlatform) "-DCMAKE_IGNORE_PATH=${lib.getBin gettext}/bin";
|
||||
|
||||
nativeBuildInputs = [ cmake flex bison gettext ];
|
||||
buildInputs = [ libsndfile libsamplerate boost ]
|
||||
++ lib.optionals stdenv.isDarwin [
|
||||
++ lib.optionals stdenv.hostPlatform.isDarwin [
|
||||
Accelerate AudioUnit CoreAudio CoreMIDI portaudio
|
||||
] ++ lib.optionals stdenv.isLinux (builtins.filter (optional: optional != null) [
|
||||
] ++ lib.optionals stdenv.hostPlatform.isLinux (builtins.filter (optional: optional != null) [
|
||||
alsa-lib libpulseaudio libjack2
|
||||
liblo ladspa-sdk fluidsynth eigen
|
||||
curl tcltk fltk
|
||||
]);
|
||||
|
||||
postInstall = lib.optional stdenv.isDarwin ''
|
||||
postInstall = lib.optional stdenv.hostPlatform.isDarwin ''
|
||||
mkdir -p $out/Library/Frameworks
|
||||
ln -s $out/lib/CsoundLib64.framework $out/Library/Frameworks
|
||||
'';
|
||||
|
@ -50,7 +50,7 @@ python3Packages.buildPythonApplication rec {
|
||||
gobject-introspection
|
||||
wrapGAppsHook4
|
||||
blueprint-compiler
|
||||
] ++ lib.optional stdenv.isDarwin gtk4; # for gtk4-update-icon-cache
|
||||
] ++ lib.optional stdenv.hostPlatform.isDarwin gtk4; # for gtk4-update-icon-cache
|
||||
|
||||
buildInputs = [
|
||||
librsvg
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user