Merge master into staging-next

This commit is contained in:
github-actions[bot] 2023-12-02 12:01:25 +00:00 committed by GitHub
commit df742c9c0e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
46 changed files with 1263 additions and 136 deletions

View File

@ -18,6 +18,8 @@ In addition to numerous new and upgraded packages, this release has the followin
- [Anki Sync Server](https://docs.ankiweb.net/sync-server.html), the official sync server built into recent versions of Anki. Available as [services.anki-sync-server](#opt-services.anki-sync-server.enable).
- [Clevis](https://github.com/latchset/clevis), a pluggable framework for automated decryption, used to unlock encrypted devices in initrd. Available as [boot.initrd.clevis.enable](#opt-boot.initrd.clevis.enable).
## Backward Incompatibilities {#sec-release-24.05-incompatibilities}
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
@ -40,4 +42,8 @@ In addition to numerous new and upgraded packages, this release has the followin
existing process, but will need to start that process from gdb (so it is a
child). Or you can set `boot.kernel.sysctl."kernel.yama.ptrace_scope"` to 0.
- Gitea 1.21 upgrade has several breaking changes, including:
- Custom themes and other assets that were previously stored in `custom/public/*` now belong in `custom/public/assets/*`
- New instances of Gitea using MySQL now ignore the `[database].CHARSET` config option and always use the `utf8mb4` charset, existing instances should migrate via the `gitea doctor convert` CLI command.
- The `hardware.pulseaudio` module now sets permission of pulse user home directory to 755 when running in "systemWide" mode. It fixes [issue 114399](https://github.com/NixOS/nixpkgs/issues/114399).

View File

@ -442,6 +442,7 @@
./services/databases/surrealdb.nix
./services/databases/victoriametrics.nix
./services/desktops/accountsservice.nix
./services/desktops/ayatana-indicators.nix
./services/desktops/bamf.nix
./services/desktops/blueman.nix
./services/desktops/cpupower-gui.nix
@ -1423,6 +1424,7 @@
./system/activation/bootspec.nix
./system/activation/top-level.nix
./system/boot/binfmt.nix
./system/boot/clevis.nix
./system/boot/emergency-mode.nix
./system/boot/grow-partition.nix
./system/boot/initrd-network.nix

View File

@ -0,0 +1,58 @@
{ config
, pkgs
, lib
, ...
}:
let
cfg = config.services.ayatana-indicators;
in
{
options.services.ayatana-indicators = {
enable = lib.mkEnableOption (lib.mdDoc ''
Ayatana Indicators, a continuation of Canonical's Application Indicators
'');
packages = lib.mkOption {
type = lib.types.listOf lib.types.package;
default = [ ];
example = lib.literalExpression "with pkgs; [ ayatana-indicator-messages ]";
description = lib.mdDoc ''
List of packages containing Ayatana Indicator services
that should be brought up by the SystemD "ayatana-indicators" user target.
Packages specified here must have passthru.ayatana-indicators set correctly.
If, how, and where these indicators are displayed will depend on your DE.
'';
};
};
config = lib.mkIf cfg.enable {
environment = {
systemPackages = cfg.packages;
pathsToLink = [
"/share/ayatana"
];
};
# libayatana-common's ayatana-indicators.target with explicit Wants & Before to bring up requested indicator services
systemd.user.targets."ayatana-indicators" =
let
indicatorServices = lib.lists.flatten
(map
(pkg:
(map (ind: "${ind}.service") pkg.passthru.ayatana-indicators))
cfg.packages);
in
{
description = "Target representing the lifecycle of the Ayatana Indicators. Each indicator should be bound to it in its individual service file";
partOf = [ "graphical-session.target" ];
wants = indicatorServices;
before = indicatorServices;
};
};
meta.maintainers = with lib.maintainers; [ OPNA2608 ];
}

View File

@ -0,0 +1,51 @@
# Clevis {#module-boot-clevis}
[Clevis](https://github.com/latchset/clevis)
is a framework for automated decryption of resources.
Clevis allows for secure unattended disk decryption during boot, using decryption policies that must be satisfied for the data to decrypt.
## Create a JWE file containing your secret {#module-boot-clevis-create-secret}
The first step is to embed your secret in a [JWE](https://en.wikipedia.org/wiki/JSON_Web_Encryption) file.
JWE files have to be created through the clevis command line. 3 types of policies are supported:
1) TPM policies
Secrets are pinned against the presence of a TPM2 device, for example:
```
echo hi | clevis encrypt tpm2 '{}' > hi.jwe
```
2) Tang policies
Secrets are pinned against the presence of a Tang server, for example:
```
echo hi | clevis encrypt tang '{"url": "http://tang.local"}' > hi.jwe
```
3) Shamir Secret Sharing
Using Shamir's Secret Sharing ([sss](https://en.wikipedia.org/wiki/Shamir%27s_secret_sharing)), secrets are pinned using a combination of the two preceding policies. For example:
```
echo hi | clevis encrypt sss \
'{"t": 2, "pins": {"tpm2": {"pcr_ids": "0"}, "tang": {"url": "http://tang.local"}}}' \
> hi.jwe
```
For more complete documentation on how to generate a secret with clevis, see the [clevis documentation](https://github.com/latchset/clevis).
## Activate unattended decryption of a resource at boot {#module-boot-clevis-activate}
In order to activate unattended decryption of a resource at boot, enable the `clevis` module:
```
boot.initrd.clevis.enable = true;
```
Then, specify the device you want to decrypt using a given clevis secret. Clevis will automatically try to decrypt the device at boot and will fallback to interactive unlocking if the decryption policy is not fulfilled.
```
boot.initrd.clevis.devices."/dev/nvme0n1p1".secretFile = ./nvme0n1p1.jwe;
```
Only `bcachefs`, `zfs` and `luks` encrypted devices are supported at this time.

View File

@ -0,0 +1,107 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.boot.initrd.clevis;
systemd = config.boot.initrd.systemd;
supportedFs = [ "zfs" "bcachefs" ];
in
{
meta.maintainers = with maintainers; [ julienmalka camillemndn ];
meta.doc = ./clevis.md;
options = {
boot.initrd.clevis.enable = mkEnableOption (lib.mdDoc "Clevis in initrd");
boot.initrd.clevis.package = mkOption {
type = types.package;
default = pkgs.clevis;
defaultText = "pkgs.clevis";
description = lib.mdDoc "Clevis package";
};
boot.initrd.clevis.devices = mkOption {
description = "Encrypted devices that need to be unlocked at boot using Clevis";
default = { };
type = types.attrsOf (types.submodule ({
options.secretFile = mkOption {
description = lib.mdDoc "Clevis JWE file used to decrypt the device at boot, in concert with the chosen pin (one of TPM2, Tang server, or SSS).";
type = types.path;
};
}));
};
boot.initrd.clevis.useTang = mkOption {
description = "Whether the Clevis JWE file used to decrypt the devices uses a Tang server as a pin.";
default = false;
type = types.bool;
};
};
config = mkIf cfg.enable {
# Implementation of clevis unlocking for the supported filesystems are located directly in the respective modules.
assertions = (attrValues (mapAttrs
(device: _: {
assertion = (any (fs: fs.device == device && (elem fs.fsType supportedFs)) config.system.build.fileSystems) || (hasAttr device config.boot.initrd.luks.devices);
message = ''
No filesystem or LUKS device with the name ${device} is declared in your configuration.'';
})
cfg.devices));
warnings =
if cfg.useTang && !config.boot.initrd.network.enable && !config.boot.initrd.systemd.network.enable
then [ "In order to use a Tang pinned secret you must configure networking in initrd" ]
else [ ];
boot.initrd = {
extraUtilsCommands = mkIf (!systemd.enable) ''
copy_bin_and_libs ${pkgs.jose}/bin/jose
copy_bin_and_libs ${pkgs.curl}/bin/curl
copy_bin_and_libs ${pkgs.bash}/bin/bash
copy_bin_and_libs ${pkgs.tpm2-tools}/bin/.tpm2-wrapped
mv $out/bin/{.tpm2-wrapped,tpm2}
cp {${pkgs.tpm2-tss},$out}/lib/libtss2-tcti-device.so.0
copy_bin_and_libs ${cfg.package}/bin/.clevis-wrapped
mv $out/bin/{.clevis-wrapped,clevis}
for BIN in ${cfg.package}/bin/clevis-decrypt*; do
copy_bin_and_libs $BIN
done
for BIN in $out/bin/clevis{,-decrypt{,-null,-tang,-tpm2}}; do
sed -i $BIN -e 's,${pkgs.bash},,' -e 's,${pkgs.coreutils},,'
done
sed -i $out/bin/clevis-decrypt-tpm2 -e 's,tpm2_,tpm2 ,'
'';
secrets = lib.mapAttrs' (name: value: nameValuePair "/etc/clevis/${name}.jwe" value.secretFile) cfg.devices;
systemd = {
extraBin = mkIf systemd.enable {
clevis = "${cfg.package}/bin/clevis";
curl = "${pkgs.curl}/bin/curl";
};
storePaths = mkIf systemd.enable [
cfg.package
"${pkgs.jose}/bin/jose"
"${pkgs.curl}/bin/curl"
"${pkgs.tpm2-tools}/bin/tpm2_createprimary"
"${pkgs.tpm2-tools}/bin/tpm2_flushcontext"
"${pkgs.tpm2-tools}/bin/tpm2_load"
"${pkgs.tpm2-tools}/bin/tpm2_unseal"
];
};
};
};
}

View File

@ -1,9 +1,11 @@
{ config, options, lib, pkgs, ... }:
{ config, options, lib, utils, pkgs, ... }:
with lib;
let
luks = config.boot.initrd.luks;
clevis = config.boot.initrd.clevis;
systemd = config.boot.initrd.systemd;
kernelPackages = config.boot.kernelPackages;
defaultPrio = (mkOptionDefault {}).priority;
@ -594,7 +596,7 @@ in
'';
type = with types; attrsOf (submodule (
{ name, ... }: { options = {
{ config, name, ... }: { options = {
name = mkOption {
visible = false;
@ -894,6 +896,19 @@ in
'';
};
};
config = mkIf (clevis.enable && (hasAttr name clevis.devices)) {
preOpenCommands = mkIf (!systemd.enable) ''
mkdir -p /clevis-${name}
mount -t ramfs none /clevis-${name}
clevis decrypt < /etc/clevis/${name}.jwe > /clevis-${name}/decrypted
'';
keyFile = "/clevis-${name}/decrypted";
fallbackToPassword = !systemd.enable;
postOpenCommands = mkIf (!systemd.enable) ''
umount /clevis-${name}
'';
};
}));
};
@ -1081,6 +1096,35 @@ in
boot.initrd.preLVMCommands = mkIf (!config.boot.initrd.systemd.enable) (commonFunctions + preCommands + concatStrings (mapAttrsToList openCommand preLVM) + postCommands);
boot.initrd.postDeviceCommands = mkIf (!config.boot.initrd.systemd.enable) (commonFunctions + preCommands + concatStrings (mapAttrsToList openCommand postLVM) + postCommands);
boot.initrd.systemd.services = let devicesWithClevis = filterAttrs (device: _: (hasAttr device clevis.devices)) luks.devices; in
mkIf (clevis.enable && systemd.enable) (
(mapAttrs'
(name: _: nameValuePair "cryptsetup-clevis-${name}" {
wantedBy = [ "systemd-cryptsetup@${utils.escapeSystemdPath name}.service" ];
before = [
"systemd-cryptsetup@${utils.escapeSystemdPath name}.service"
"initrd-switch-root.target"
"shutdown.target"
];
wants = [ "systemd-udev-settle.service" ] ++ optional clevis.useTang "network-online.target";
after = [ "systemd-modules-load.service" "systemd-udev-settle.service" ] ++ optional clevis.useTang "network-online.target";
script = ''
mkdir -p /clevis-${name}
mount -t ramfs none /clevis-${name}
umask 277
clevis decrypt < /etc/clevis/${name}.jwe > /clevis-${name}/decrypted
'';
conflicts = [ "initrd-switch-root.target" "shutdown.target" ];
unitConfig.DefaultDependencies = "no";
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
ExecStop = "${config.boot.initrd.systemd.package.util-linux}/bin/umount /clevis-${name}";
};
})
devicesWithClevis)
);
environment.systemPackages = [ pkgs.cryptsetup ];
};
}

View File

@ -57,7 +57,15 @@ let
# bcachefs does not support mounting devices with colons in the path, ergo we don't (see #49671)
firstDevice = fs: lib.head (lib.splitString ":" fs.device);
openCommand = name: fs: ''
openCommand = name: fs: if config.boot.initrd.clevis.enable && (lib.hasAttr (firstDevice fs) config.boot.initrd.clevis.devices) then ''
if clevis decrypt < /etc/clevis/${firstDevice fs}.jwe | bcachefs unlock ${firstDevice fs}
then
printf "unlocked ${name} using clevis\n"
else
printf "falling back to interactive unlocking...\n"
tryUnlock ${name} ${firstDevice fs}
fi
'' else ''
tryUnlock ${name} ${firstDevice fs}
'';

View File

@ -17,6 +17,9 @@ let
cfgZED = config.services.zfs.zed;
selectModulePackage = package: config.boot.kernelPackages.${package.kernelModuleAttribute};
clevisDatasets = map (e: e.device) (filter (e: (hasAttr e.device config.boot.initrd.clevis.devices) && e.fsType == "zfs" && (fsNeededForBoot e)) config.system.build.fileSystems);
inInitrd = any (fs: fs == "zfs") config.boot.initrd.supportedFilesystems;
inSystem = any (fs: fs == "zfs") config.boot.supportedFilesystems;
@ -120,12 +123,12 @@ let
# but don't *require* it, because mounts shouldn't be killed if it's stopped.
# In the future, hopefully someone will complete this:
# https://github.com/zfsonlinux/zfs/pull/4943
wants = [ "systemd-udev-settle.service" ];
wants = [ "systemd-udev-settle.service" ] ++ optional (config.boot.initrd.clevis.useTang) "network-online.target";
after = [
"systemd-udev-settle.service"
"systemd-modules-load.service"
"systemd-ask-password-console.service"
];
] ++ optional (config.boot.initrd.clevis.useTang) "network-online.target";
requiredBy = getPoolMounts prefix pool ++ [ "zfs-import.target" ];
before = getPoolMounts prefix pool ++ [ "zfs-import.target" ];
unitConfig = {
@ -154,6 +157,9 @@ let
poolImported "${pool}" || poolImport "${pool}" # Try one last time, e.g. to import a degraded pool.
fi
if poolImported "${pool}"; then
${concatMapStringsSep "\n" (elem: "clevis decrypt < /etc/clevis/${elem}.jwe | zfs load-key ${elem} || true ") (filter (p: (elemAt (splitString "/" p) 0) == pool) clevisDatasets)}
${optionalString keyLocations.hasKeys ''
${keyLocations.command} | while IFS=$'\t' read ds kl ks; do
{
@ -623,6 +629,9 @@ in
fi
poolImported "${pool}" || poolImport "${pool}" # Try one last time, e.g. to import a degraded pool.
fi
${concatMapStringsSep "\n" (elem: "clevis decrypt < /etc/clevis/${elem}.jwe | zfs load-key ${elem}") (filter (p: (elemAt (splitString "/" p) 0) == pool) clevisDatasets)}
${if isBool cfgZfs.requestEncryptionCredentials
then optionalString cfgZfs.requestEncryptionCredentials ''
zfs load-key -a

View File

@ -135,6 +135,7 @@ in {
authelia = handleTest ./authelia.nix {};
avahi = handleTest ./avahi.nix {};
avahi-with-resolved = handleTest ./avahi.nix { networkd = true; };
ayatana-indicators = handleTest ./ayatana-indicators.nix {};
babeld = handleTest ./babeld.nix {};
bazarr = handleTest ./bazarr.nix {};
bcachefs = handleTestOn ["x86_64-linux" "aarch64-linux"] ./bcachefs.nix {};

View File

@ -0,0 +1,71 @@
import ./make-test-python.nix ({ pkgs, lib, ... }: let
user = "alice";
in {
name = "ayatana-indicators";
meta = {
maintainers = with lib.maintainers; [ OPNA2608 ];
};
nodes.machine = { config, ... }: {
imports = [
./common/auto.nix
./common/user-account.nix
];
test-support.displayManager.auto = {
enable = true;
inherit user;
};
services.xserver = {
enable = true;
desktopManager.mate.enable = true;
displayManager.defaultSession = lib.mkForce "mate";
};
services.ayatana-indicators = {
enable = true;
packages = with pkgs; [
ayatana-indicator-messages
];
};
# Services needed by some indicators
services.accounts-daemon.enable = true; # messages
};
# TODO session indicator starts up in a semi-broken state, but works fine after a restart. maybe being started before graphical session is truly up & ready?
testScript = { nodes, ... }: let
runCommandPerIndicatorService = command: lib.strings.concatMapStringsSep "\n" command nodes.machine.systemd.user.targets."ayatana-indicators".wants;
in ''
start_all()
machine.wait_for_x()
# Desktop environment should reach graphical-session.target
machine.wait_for_unit("graphical-session.target", "${user}")
# MATE relies on XDG autostart to bring up the indicators.
# Not sure *when* XDG autostart fires them up, and awaiting pgrep success seems to misbehave?
machine.sleep(10)
# Now check if all indicators were brought up successfully, and kill them for later
'' + (runCommandPerIndicatorService (service: let serviceExec = builtins.replaceStrings [ "." ] [ "-" ] service; in ''
machine.succeed("pgrep -f ${serviceExec}")
machine.succeed("pkill -f ${serviceExec}")
'')) + ''
# Ayatana target is the preferred way of starting up indicators on SystemD session, the graphical session is responsible for starting this if it supports them.
# Mate currently doesn't do this, so start it manually for checking (https://github.com/mate-desktop/mate-indicator-applet/issues/63)
machine.systemctl("start ayatana-indicators.target", "${user}")
machine.wait_for_unit("ayatana-indicators.target", "${user}")
# Let all indicator services do their startups, potential post-launch crash & restart cycles so we can properly check for failures
# Not sure if there's a better way of awaiting this without false-positive potential
machine.sleep(10)
# Now check if all indicator services were brought up successfully
'' + runCommandPerIndicatorService (service: ''
machine.wait_for_unit("${service}", "${user}")
'');
})

View File

@ -32,6 +32,10 @@
stratisRoot
swraid
zfsroot
clevisLuks
clevisLuksFallback
clevisZfs
clevisZfsFallback
;
}

View File

@ -12,6 +12,7 @@ let
# The configuration to install.
makeConfig = { bootLoader, grubDevice, grubIdentifier, grubUseEfi
, extraConfig, forceGrubReinstallCount ? 0, flake ? false
, clevisTest
}:
pkgs.writeText "configuration.nix" ''
{ config, lib, pkgs, modulesPath, ... }:
@ -52,6 +53,15 @@ let
boot.initrd.secrets."/etc/secret" = ./secret;
${optionalString clevisTest ''
boot.kernelParams = [ "console=tty0" "ip=192.168.1.1:::255.255.255.0::eth1:none" ];
boot.initrd = {
availableKernelModules = [ "tpm_tis" ];
clevis = { enable = true; useTang = true; };
network.enable = true;
};
''}
users.users.alice = {
isNormalUser = true;
home = "/home/alice";
@ -71,7 +81,7 @@ let
# partitions and filesystems.
testScriptFun = { bootLoader, createPartitions, grubDevice, grubUseEfi, grubIdentifier
, postInstallCommands, preBootCommands, postBootCommands, extraConfig
, testSpecialisationConfig, testFlakeSwitch
, testSpecialisationConfig, testFlakeSwitch, clevisTest, clevisFallbackTest
}:
let iface = "virtio";
isEfi = bootLoader == "systemd-boot" || (bootLoader == "grub" && grubUseEfi);
@ -79,12 +89,16 @@ let
in if !isEfi && !pkgs.stdenv.hostPlatform.isx86 then ''
machine.succeed("true")
'' else ''
import subprocess
tpm_folder = os.environ['NIX_BUILD_TOP']
def assemble_qemu_flags():
flags = "-cpu max"
${if (system == "x86_64-linux" || system == "i686-linux")
then ''flags += " -m 1024"''
else ''flags += " -m 768 -enable-kvm -machine virt,gic-version=host"''
}
${optionalString clevisTest ''flags += f" -chardev socket,id=chrtpm,path={tpm_folder}/swtpm-sock -tpmdev emulator,id=tpm0,chardev=chrtpm -device tpm-tis,tpmdev=tpm0"''}
${optionalString clevisTest ''flags += " -device virtio-net-pci,netdev=vlan1,mac=52:54:00:12:11:02 -netdev vde,id=vlan1,sock=\"$QEMU_VDE_SOCKET_1\""''}
return flags
@ -110,8 +124,45 @@ let
def create_machine_named(name):
return create_machine({**default_flags, "name": name})
class Tpm:
def __init__(self):
self.start()
def start(self):
self.proc = subprocess.Popen(["${pkgs.swtpm}/bin/swtpm",
"socket",
"--tpmstate", f"dir={tpm_folder}/swtpm",
"--ctrl", f"type=unixio,path={tpm_folder}/swtpm-sock",
"--tpm2"
])
# Check whether starting swtpm failed
try:
exit_code = self.proc.wait(timeout=0.2)
if exit_code is not None and exit_code != 0:
raise Exception("failed to start swtpm")
except subprocess.TimeoutExpired:
pass
"""Check whether the swtpm process exited due to an error"""
def check(self):
exit_code = self.proc.poll()
if exit_code is not None and exit_code != 0:
raise Exception("swtpm process died")
os.mkdir(f"{tpm_folder}/swtpm")
tpm = Tpm()
tpm.check()
start_all()
${optionalString clevisTest ''
tang.wait_for_unit("sockets.target")
tang.wait_for_unit("network-online.target")
machine.wait_for_unit("network-online.target")
''}
machine.wait_for_unit("multi-user.target")
machine.start()
with subtest("Assert readiness of login prompt"):
machine.succeed("echo hello")
@ -127,13 +178,23 @@ let
machine.copy_from_host(
"${ makeConfig {
inherit bootLoader grubDevice grubIdentifier
grubUseEfi extraConfig;
grubUseEfi extraConfig clevisTest;
}
}",
"/mnt/etc/nixos/configuration.nix",
)
machine.copy_from_host("${pkgs.writeText "secret" "secret"}", "/mnt/etc/nixos/secret")
${optionalString clevisTest ''
with subtest("Create the Clevis secret with Tang"):
machine.wait_for_unit("network-online.target")
machine.succeed('echo -n password | clevis encrypt sss \'{"t": 2, "pins": {"tpm2": {}, "tang": {"url": "http://192.168.1.2"}}}\' -y > /mnt/etc/nixos/clevis-secret.jwe')''}
${optionalString clevisFallbackTest ''
with subtest("Shutdown Tang to check fallback to interactive prompt"):
tang.shutdown()
''}
with subtest("Perform the installation"):
machine.succeed("nixos-install < /dev/null >&2")
@ -200,7 +261,7 @@ let
machine.copy_from_host_via_shell(
"${ makeConfig {
inherit bootLoader grubDevice grubIdentifier
grubUseEfi extraConfig;
grubUseEfi extraConfig clevisTest;
forceGrubReinstallCount = 1;
}
}",
@ -229,7 +290,7 @@ let
machine.copy_from_host_via_shell(
"${ makeConfig {
inherit bootLoader grubDevice grubIdentifier
grubUseEfi extraConfig;
grubUseEfi extraConfig clevisTest;
forceGrubReinstallCount = 2;
}
}",
@ -303,7 +364,7 @@ let
""")
machine.copy_from_host_via_shell(
"${makeConfig {
inherit bootLoader grubDevice grubIdentifier grubUseEfi extraConfig;
inherit bootLoader grubDevice grubIdentifier grubUseEfi extraConfig clevisTest;
forceGrubReinstallCount = 1;
flake = true;
}}",
@ -379,6 +440,8 @@ let
, enableOCR ? false, meta ? {}
, testSpecialisationConfig ? false
, testFlakeSwitch ? false
, clevisTest ? false
, clevisFallbackTest ? false
}:
makeTest {
inherit enableOCR;
@ -416,13 +479,13 @@ let
virtualisation.rootDevice = "/dev/vdb";
virtualisation.bootLoaderDevice = "/dev/vda";
virtualisation.qemu.diskInterface = "virtio";
# We don't want to have any networking in the guest whatsoever.
# Also, if any vlans are enabled, the guest will reboot
# (with a different configuration for legacy reasons),
# and spend 5 minutes waiting for the vlan interface to show up
# (which will never happen).
virtualisation.vlans = [];
virtualisation.qemu.options = mkIf (clevisTest) [
"-chardev socket,id=chrtpm,path=$NIX_BUILD_TOP/swtpm-sock"
"-tpmdev emulator,id=tpm0,chardev=chrtpm"
"-device tpm-tis,tpmdev=tpm0"
];
# We don't want to have any networking in the guest apart from the clevis tests.
virtualisation.vlans = mkIf (!clevisTest) [];
boot.loader.systemd-boot.enable = mkIf (bootLoader == "systemd-boot") true;
@ -471,7 +534,7 @@ let
in [
(pkgs.grub2.override { inherit zfsSupport; })
(pkgs.grub2_efi.override { inherit zfsSupport; })
]);
]) ++ optionals clevisTest [ pkgs.klibc ];
nix.settings = {
substituters = mkForce [];
@ -480,12 +543,21 @@ let
};
};
} // optionalAttrs clevisTest {
tang = {
services.tang = {
enable = true;
listenStream = [ "80" ];
ipAddressAllow = [ "192.168.1.0/24" ];
};
networking.firewall.allowedTCPPorts = [ 80 ];
};
};
testScript = testScriptFun {
inherit bootLoader createPartitions postInstallCommands preBootCommands postBootCommands
grubDevice grubIdentifier grubUseEfi extraConfig
testSpecialisationConfig testFlakeSwitch;
testSpecialisationConfig testFlakeSwitch clevisTest clevisFallbackTest;
};
};
@ -586,6 +658,145 @@ let
zfs = super.zfs.overrideAttrs(_: {meta.platforms = [];});}
)];
};
mkClevisBcachefsTest = { fallback ? false }: makeInstallerTest "clevis-bcachefs${optionalString fallback "-fallback"}" {
clevisTest = true;
clevisFallbackTest = fallback;
enableOCR = fallback;
extraInstallerConfig = {
imports = [ no-zfs-module ];
boot.supportedFilesystems = [ "bcachefs" ];
environment.systemPackages = with pkgs; [ keyutils clevis ];
};
createPartitions = ''
machine.succeed(
"flock /dev/vda parted --script /dev/vda -- mklabel msdos"
+ " mkpart primary ext2 1M 100MB"
+ " mkpart primary linux-swap 100M 1024M"
+ " mkpart primary 1024M -1s",
"udevadm settle",
"mkswap /dev/vda2 -L swap",
"swapon -L swap",
"keyctl link @u @s",
"echo -n password | mkfs.bcachefs -L root --encrypted /dev/vda3",
"echo -n password | bcachefs unlock /dev/vda3",
"echo -n password | mount -t bcachefs /dev/vda3 /mnt",
"mkfs.ext3 -L boot /dev/vda1",
"mkdir -p /mnt/boot",
"mount LABEL=boot /mnt/boot",
"udevadm settle")
'';
extraConfig = ''
boot.initrd.clevis.devices."/dev/vda3".secretFile = "/etc/nixos/clevis-secret.jwe";
# We override what nixos-generate-config has generated because we do
# not know the UUID in advance.
fileSystems."/" = lib.mkForce { device = "/dev/vda3"; fsType = "bcachefs"; };
'';
preBootCommands = ''
tpm = Tpm()
tpm.check()
'' + optionalString fallback ''
machine.start()
machine.wait_for_text("enter passphrase for")
machine.send_chars("password\n")
'';
};
mkClevisLuksTest = { fallback ? false }: makeInstallerTest "clevis-luks${optionalString fallback "-fallback"}" {
clevisTest = true;
clevisFallbackTest = fallback;
enableOCR = fallback;
extraInstallerConfig = {
environment.systemPackages = with pkgs; [ clevis ];
};
createPartitions = ''
machine.succeed(
"flock /dev/vda parted --script /dev/vda -- mklabel msdos"
+ " mkpart primary ext2 1M 100MB"
+ " mkpart primary linux-swap 100M 1024M"
+ " mkpart primary 1024M -1s",
"udevadm settle",
"mkswap /dev/vda2 -L swap",
"swapon -L swap",
"modprobe dm_mod dm_crypt",
"echo -n password | cryptsetup luksFormat -q /dev/vda3 -",
"echo -n password | cryptsetup luksOpen --key-file - /dev/vda3 crypt-root",
"mkfs.ext3 -L nixos /dev/mapper/crypt-root",
"mount LABEL=nixos /mnt",
"mkfs.ext3 -L boot /dev/vda1",
"mkdir -p /mnt/boot",
"mount LABEL=boot /mnt/boot",
"udevadm settle")
'';
extraConfig = ''
boot.initrd.clevis.devices."crypt-root".secretFile = "/etc/nixos/clevis-secret.jwe";
'';
preBootCommands = ''
tpm = Tpm()
tpm.check()
'' + optionalString fallback ''
machine.start()
${if systemdStage1 then ''
machine.wait_for_text("Please enter")
'' else ''
machine.wait_for_text("Passphrase for")
''}
machine.send_chars("password\n")
'';
};
mkClevisZfsTest = { fallback ? false }: makeInstallerTest "clevis-zfs${optionalString fallback "-fallback"}" {
clevisTest = true;
clevisFallbackTest = fallback;
enableOCR = fallback;
extraInstallerConfig = {
boot.supportedFilesystems = [ "zfs" ];
environment.systemPackages = with pkgs; [ clevis ];
};
createPartitions = ''
machine.succeed(
"flock /dev/vda parted --script /dev/vda -- mklabel msdos"
+ " mkpart primary ext2 1M 100MB"
+ " mkpart primary linux-swap 100M 1024M"
+ " mkpart primary 1024M -1s",
"udevadm settle",
"mkswap /dev/vda2 -L swap",
"swapon -L swap",
"zpool create -O mountpoint=legacy rpool /dev/vda3",
"echo -n password | zfs create"
+ " -o encryption=aes-256-gcm -o keyformat=passphrase rpool/root",
"mount -t zfs rpool/root /mnt",
"mkfs.ext3 -L boot /dev/vda1",
"mkdir -p /mnt/boot",
"mount LABEL=boot /mnt/boot",
"udevadm settle")
'';
extraConfig = ''
boot.initrd.clevis.devices."rpool/root".secretFile = "/etc/nixos/clevis-secret.jwe";
boot.zfs.requestEncryptionCredentials = true;
# Using by-uuid overrides the default of by-id, and is unique
# to the qemu disks, as they don't produce by-id paths for
# some reason.
boot.zfs.devNodes = "/dev/disk/by-uuid/";
networking.hostId = "00000000";
'';
preBootCommands = ''
tpm = Tpm()
tpm.check()
'' + optionalString fallback ''
machine.start()
${if systemdStage1 then ''
machine.wait_for_text("Enter key for rpool/root")
'' else ''
machine.wait_for_text("Key load error")
''}
machine.send_chars("password\n")
'';
};
in {
# !!! `parted mkpart' seems to silently create overlapping partitions.
@ -1175,6 +1386,13 @@ in {
)
'';
};
} // {
clevisBcachefs = mkClevisBcachefsTest { };
clevisBcachefsFallback = mkClevisBcachefsTest { fallback = true; };
clevisLuks = mkClevisLuksTest { };
clevisLuksFallback = mkClevisLuksTest { fallback = true; };
clevisZfs = mkClevisZfsTest { };
clevisZfsFallback = mkClevisZfsTest { fallback = true; };
} // optionalAttrs systemdStage1 {
stratisRoot = makeInstallerTest "stratisRoot" {
createPartitions = ''

View File

@ -1,12 +1,12 @@
{ lib, fetchurl, buildPythonApplication, libjack2, pydbus, pyliblo, pyqt5, which, bash, qt5 }:
{ lib, fetchurl, buildPythonApplication, libjack2, pyliblo, pyqt5, which, bash, qt5 }:
buildPythonApplication rec {
pname = "raysession";
version = "0.13.1";
version = "0.14.2";
src = fetchurl {
url = "https://github.com/Houston4444/RaySession/releases/download/v${version}/RaySession-${version}-source.tar.gz";
sha256 = "sha256-iiFRtX43u9BHe7a4ojza7kav+dMW9e05dPi7Gf9d1GM=";
sha256 = "sha256-qEN3zBK/goRLIZaU06XXm8H5yj4Qjj/NH+bkHkjhLaw=";
};
postPatch = ''
@ -25,7 +25,7 @@ buildPythonApplication rec {
qt5.wrapQtAppsHook
];
buildInputs = [ libjack2 bash ];
propagatedBuildInputs = [ pydbus pyliblo pyqt5 ];
propagatedBuildInputs = [ pyliblo pyqt5 ];
dontWrapQtApps = true; # The program is a python script.

View File

@ -1,52 +0,0 @@
# From NUR https://github.com/nix-community/nur-combined/blob/6bddae47680482383b5769dd3aa7d82b88e6cbc8/repos/renesat/pkgs/normcap/default.nix
{
lib,
stdenv,
python3,
fetchFromGitHub,
tesseract4,
leptonica,
wl-clipboard
}:
python3.pkgs.buildPythonApplication rec {
pname = "normcap";
version = "0.4.4";
format = "pyproject";
src = fetchFromGitHub {
owner = "dynobo";
repo = "normcap";
rev = "v${version}";
hash = "sha256-dShtmoqS9TC3PHuwq24OEOhYfBHGhDCma8Du8QCkFuI=";
};
buildInputs = [
wl-clipboard
];
nativeBuildInputs = with python3.pkgs; [
poetry-core
];
propagatedBuildInputs = with python3.pkgs; [
tesseract4
leptonica
pyside6
# Test
toml
pytest-qt
];
postPatch = ''
substituteInPlace pyproject.toml --replace 'PySide6-Essentials = "6.5.1"' ""
'';
meta = with lib; {
description = "OCR powered screen-capture tool to capture information instead of images";
homepage = "https://dynobo.github.io/normcap/";
license = licenses.gpl3Plus;
maintainers = with maintainers; [ cafkafk ];
};
}

View File

@ -35,13 +35,13 @@ in appimageTools.wrapType2 rec {
$out/share/applications/Chrysalis.desktop \
--replace 'Exec=Chrysalis' 'Exec=${pname}'
cp -r ${appimageContents}/usr/share/icons $out/share
install -Dm444 ${appimageContents}/usr/share/icons/hicolor/256x256/chrysalis.png -t $out/share/pixmaps
'';
meta = with lib; {
description = "A graphical configurator for Kaleidoscope-powered keyboards";
homepage = "https://github.com/keyboardio/Chrysalis";
license = licenses.gpl3;
license = licenses.gpl3Only;
maintainers = with maintainers; [ aw ];
platforms = [ "x86_64-linux" ];
mainProgram = pname;

View File

@ -8,10 +8,10 @@ buildGoModule rec {
pname = "itd";
version = "1.1.0";
# https://gitea.arsenm.dev/Arsen6331/itd/tags
# https://gitea.elara.ws/Elara6331/itd/tags
src = fetchFromGitea {
domain = "gitea.arsenm.dev";
owner = "Arsen6331";
domain = "gitea.elara.ws";
owner = "Elara6331";
repo = "itd";
rev = "v${version}";
hash = "sha256-95/9Qy0HhrX+ORuv6g1T4/Eq1hf539lYG5fTkLeY6B0=";
@ -34,7 +34,7 @@ buildGoModule rec {
meta = with lib; {
description = "itd is a daemon to interact with the PineTime running InfiniTime";
homepage = "https://gitea.arsenm.dev/Arsen6331/itd";
homepage = "https://gitea.elara.ws/Elara6331/itd";
license = licenses.gpl3Plus;
platforms = platforms.linux;
maintainers = with maintainers; [ mindavi raphaelr ];

View File

@ -9,6 +9,7 @@
, gtk2-x11
, withGTK3 ? true
, gtk3
, libglvnd
, libXt
, libpulseaudio
, makeDesktopItem
@ -18,7 +19,7 @@
stdenv.mkDerivation (finalAttrs: {
pname = "palemoon-bin";
version = "32.5.0";
version = "32.5.1";
src = fetchzip {
urls = [
@ -26,9 +27,9 @@ stdenv.mkDerivation (finalAttrs: {
"https://rm-us.palemoon.org/release/palemoon-${finalAttrs.version}.linux-x86_64-gtk${if withGTK3 then "3" else "2"}.tar.xz"
];
hash = if withGTK3 then
"sha256-1MJ5K9Zc/BHeQwwlq3XyUV8XTFEpPytNyTnsDpE1tBI="
"sha256-hWqL/WoRRigw8cNeJImOQLM8hewyS3PYNGr2WYP+cMk="
else
"sha256-xXunZTqoc2A+ilosRUUluxDwewD3xwITF5nb5Lbyv7Y=";
"sha256-dlBnXP3WUgQ0spkLRowfzMcPArhGfpowsvwgCA+kvUA=";
};
preferLocalBuild = true;
@ -147,6 +148,7 @@ stdenv.mkDerivation (finalAttrs: {
gappsWrapperArgs+=(
--prefix LD_LIBRARY_PATH : "${lib.makeLibraryPath [
ffmpeg
libglvnd
libpulseaudio
]}"
)

View File

@ -2,14 +2,14 @@
stdenv.mkDerivation rec {
pname = "libutp";
version = "unstable-2023-10-16";
version = "unstable-2023-11-14";
src = fetchFromGitHub {
# Use transmission fork from post-3.4-transmission branch
owner = "transmission";
repo = pname;
rev = "2589200eac82fc91b65979680e4b3c026dff0278";
hash = "sha256-wsDqdbMWVm3ubTbg5XClEWutJz1irSIazVLFeCyAAL4=";
rev = "52645d6d0fb16009e11d2f84469d2e43b7b6b48a";
hash = "sha256-pcPVkDEEtriN9zlEcVFKwKhhh51wpJGxYlcu7bH1RkI=";
};
nativeBuildInputs = [ cmake ];

View File

@ -1,13 +1,18 @@
{ callPackage, fetchurl, lib, stdenv
, ocamlPackages, coqPackages, rubber, hevea, emacs }:
, ocamlPackages, coqPackages, rubber, hevea, emacs
, version ? "1.7.0"
}:
stdenv.mkDerivation rec {
pname = "why3";
version = "1.6.0";
inherit version;
src = fetchurl {
url = "https://why3.gitlabpages.inria.fr/releases/${pname}-${version}.tar.gz";
hash = "sha256-hFvM6kHScaCtcHCc6Vezl9CR7BFbiKPoTEh7kj0ZJxw=";
hash = {
"1.7.0" = "sha256-rygrjzuJVukOvpuXTG/yeoEP98ZFkLQHObgc3My1PVY=";
"1.6.0" = "sha256-hFvM6kHScaCtcHCc6Vezl9CR7BFbiKPoTEh7kj0ZJxw=";
}."${version}";
};
strictDeps = true;

View File

@ -70,11 +70,11 @@ in
mkDerivation rec {
pname = "recoll";
version = "1.36.0";
version = "1.36.2";
src = fetchurl {
url = "https://www.lesbonscomptes.com/${pname}/${pname}-${version}.tar.gz";
hash = "sha256-vf0o0wBcG3878YD4mTUhni2aTUU9AJkG4an1oaRc4yw=";
hash = "sha256-GyQqI3ciRO0TRaAeM4rGu+j/eB4bJlQ7VBTTxUGMNt4=";
};
configureFlags = [
@ -169,7 +169,7 @@ mkDerivation rec {
members, email attachments.
'';
homepage = "https://www.lesbonscomptes.com/recoll/";
changelog = "https://www.lesbonscomptes.com/recoll/pages/release-${version}.html";
changelog = "https://www.lesbonscomptes.com/recoll/pages/release-${versions.majorMinor version}.html";
license = licenses.gpl2Plus;
platforms = platforms.unix;
maintainers = with maintainers; [ jcumming ehmry ];

View File

@ -20,12 +20,12 @@
buildGoModule rec {
pname = "gitea";
version = "1.20.5";
version = "1.21.1";
# not fetching directly from the git repo, because that lacks several vendor files for the web UI
src = fetchurl {
url = "https://dl.gitea.com/gitea/${version}/gitea-src-${version}.tar.gz";
hash = "sha256-cH/AHsFXOdvfSfj9AZUd3l/RlYE06o1ByZu0vvGQuXw=";
hash = "sha256-5WEHUMQsQNgrglS+xJ4IWHUl0a6RLLPyx0l+ECJ4R9g=";
};
vendorHash = null;

View File

@ -14,6 +14,7 @@ in
, recursiveHash ? true
, postFetch ? ""
, postUnpack ? ""
, meta ? {}
}:
let
afterSuccess = writeShellScript "fetch-bittorrent-done.sh" ''
@ -30,6 +31,7 @@ let
jsonConfig = (formats.json {}).generate "jsonConfig" config;
in
runCommand name {
inherit meta;
nativeBuildInputs = [ cacert ] ++ (if (backend == "transmission" ) then [ transmission_noSystemd ] else if (backend == "rqbit") then [ rqbit ] else throw "rqbit or transmission are the only available backends for fetchtorrent");
outputHashAlgo = if hash != "" then null else "sha256";
outputHash = hash;

View File

@ -1,25 +1,47 @@
{ testers, fetchtorrent, ... }:
{ testers, fetchtorrent, lib, ... }:
let
wired-cd.meta.license = [
# track 1, 4 and 11
{
spdxID = "CC NC-SAMPLING+ 1.0 Deed";
fullName = "NonCommercial Sampling Plus 1.0 Generic";
url = "https://creativecommons.org/licenses/nc-sampling+/1.0/";
free = false; # for noncommercial purposes only
}
# the rest
{
spdxID = "CC SAMPLING+ 1.0 Deed";
fullName = "Sampling Plus 1.0 Generic";
url = "https://creativecommons.org/licenses/sampling+/1.0/";
free = true; # no use in advertisement
}
];
in
{
http-link = testers.invalidateFetcherByDrvHash fetchtorrent {
url = "https://webtorrent.io/torrents/wired-cd.torrent";
hash = "sha256-OCsC22WuanqoN6lPv5wDT5ZxPcEHDpZ1EgXGvz1SDYo=";
backend = "transmission";
inherit (wired-cd) meta;
};
magnet-link = testers.invalidateFetcherByDrvHash fetchtorrent {
url = "magnet:?xt=urn:btih:a88fda5954e89178c372716a6a78b8180ed4dad3&dn=The+WIRED+CD+-+Rip.+Sample.+Mash.+Share&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.empire-js.us%3A1337&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=wss%3A%2F%2Ftracker.btorrent.xyz&tr=wss%3A%2F%2Ftracker.fastcast.nz&tr=wss%3A%2F%2Ftracker.openwebtorrent.com&ws=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2F&xs=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2Fwired-cd.torrent";
hash = "sha256-OCsC22WuanqoN6lPv5wDT5ZxPcEHDpZ1EgXGvz1SDYo=";
backend = "transmission";
inherit (wired-cd) meta;
};
http-link-rqbit = testers.invalidateFetcherByDrvHash fetchtorrent {
url = "https://webtorrent.io/torrents/wired-cd.torrent";
hash = "sha256-OCsC22WuanqoN6lPv5wDT5ZxPcEHDpZ1EgXGvz1SDYo=";
backend = "rqbit";
inherit (wired-cd) meta;
};
magnet-link-rqbit = testers.invalidateFetcherByDrvHash fetchtorrent {
url = "magnet:?xt=urn:btih:a88fda5954e89178c372716a6a78b8180ed4dad3&dn=The+WIRED+CD+-+Rip.+Sample.+Mash.+Share&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.empire-js.us%3A1337&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=wss%3A%2F%2Ftracker.btorrent.xyz&tr=wss%3A%2F%2Ftracker.fastcast.nz&tr=wss%3A%2F%2Ftracker.openwebtorrent.com&ws=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2F&xs=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2Fwired-cd.torrent";
hash = "sha256-OCsC22WuanqoN6lPv5wDT5ZxPcEHDpZ1EgXGvz1SDYo=";
backend = "rqbit";
inherit (wired-cd) meta;
};
}

View File

@ -0,0 +1,147 @@
{ stdenv
, lib
, fetchFromGitHub
, gitUpdater
, nixosTests
, testers
, accountsservice
, cmake
, dbus-test-runner
, withDocumentation ? true
, docbook_xsl
, docbook_xml_dtd_45
, glib
, gobject-introspection
, gtest
, gtk-doc
, intltool
, lomiri
, pkg-config
, python3
, systemd
, vala
, wrapGAppsHook
}:
stdenv.mkDerivation (finalAttrs: {
pname = "ayatana-indicator-messages";
version = "23.10.0";
src = fetchFromGitHub {
owner = "AyatanaIndicators";
repo = "ayatana-indicator-messages";
rev = finalAttrs.version;
hash = "sha256-FBJeP5hOXJcOk04cRJpw+oN7L3w3meDX3ivLmFWkhVI=";
};
outputs = [
"out"
"dev"
] ++ lib.optionals withDocumentation [
"devdoc"
];
postPatch = ''
# Uses pkg_get_variable, cannot substitute prefix with that
substituteInPlace data/CMakeLists.txt \
--replace "\''${SYSTEMD_USER_DIR}" "$out/lib/systemd/user"
# Bad concatenation
substituteInPlace libmessaging-menu/messaging-menu.pc.in \
--replace "\''${exec_prefix}/@CMAKE_INSTALL_LIBDIR@" '@CMAKE_INSTALL_FULL_LIBDIR@' \
--replace "\''${prefix}/@CMAKE_INSTALL_INCLUDEDIR@" '@CMAKE_INSTALL_FULL_INCLUDEDIR@'
'' + lib.optionalString (!withDocumentation) ''
sed -i CMakeLists.txt \
'/add_subdirectory(doc)/d'
'';
strictDeps = true;
nativeBuildInputs = [
cmake
glib # For glib-compile-schemas
intltool
pkg-config
vala
wrapGAppsHook
] ++ lib.optionals withDocumentation [
docbook_xsl
docbook_xml_dtd_45
gtk-doc
];
buildInputs = [
accountsservice
lomiri.cmake-extras
glib
gobject-introspection
systemd
];
nativeCheckInputs = [
(python3.withPackages (ps: with ps; [
pygobject3
python-dbusmock
]))
];
checkInputs = [
dbus-test-runner
gtest
];
cmakeFlags = [
"-DENABLE_TESTS=${lib.boolToString finalAttrs.doCheck}"
"-DGSETTINGS_LOCALINSTALL=ON"
"-DGSETTINGS_COMPILE=ON"
];
makeFlags = lib.optionals withDocumentation [
# gtk-doc doesn't call ld with the correct arguments
# ld: ...: undefined reference to symbol 'strncpy@@GLIBC_2.2.5', 'qsort@@GLIBC_2.2.5'
"LD=${stdenv.cc.targetPrefix}cc"
];
doCheck = stdenv.buildPlatform.canExecute stdenv.hostPlatform;
preCheck = ''
# test-client imports gir, whose solib entry points to final store location
install -Dm644 libmessaging-menu/libmessaging-menu.so.0.0.0 $out/lib/libmessaging-menu.so.0
'';
postCheck = ''
# remove the above solib-installation, let it be done properly
rm -r $out
'';
preInstall = lib.optionalString withDocumentation ''
# installing regenerates docs, generated files are created without write permissions, errors out while trying to overwrite them
chmod +w doc/reference/html/*
'';
passthru = {
ayatana-indicators = [
"ayatana-indicator-messages"
];
tests = {
pkg-config = testers.testMetaPkgConfig finalAttrs.finalPackage;
vm = nixosTests.ayatana-indicators;
};
updateScript = gitUpdater { };
};
meta = with lib; {
description = "Ayatana Indicator Messages Applet";
longDescription = ''
The -messages Ayatana System Indicator is the messages menu indicator for Unity7, MATE and Lomiri (optionally for
others, e.g. XFCE, LXDE).
'';
homepage = "https://github.com/AyatanaIndicators/ayatana-indicator-messages";
license = licenses.gpl3Only;
platforms = platforms.linux;
maintainers = with maintainers; [ OPNA2608 ];
pkgConfigModules = [
"messaging-menu"
];
};
})

View File

@ -19,13 +19,13 @@ let
pieBuild = stdenv.hostPlatform.isMusl;
in buildGoModule rec {
pname = "frankenphp";
version = "1.0.0-rc.3";
version = "1.0.0-rc.4";
src = fetchFromGitHub {
owner = "dunglas";
repo = "frankenphp";
rev = "v${version}";
hash = "sha256-Al0gCxTb6s41ugX9J8N8lshop9kP3RPGCzlq5etk1RY=";
hash = "sha256-4jNCKHt4eYI1BNaonIdS1Eq2OnJwgrU6qWZoiSpeIYk=";
};
sourceRoot = "source/caddy";

View File

@ -0,0 +1,117 @@
{ lib
, stdenv
, python3
, fetchFromGitHub
, tesseract4
, leptonica
, wl-clipboard
, libnotify
, xorg
}:
let
ps = python3.pkgs;
wrapperDeps = [
leptonica
tesseract4
libnotify
] ++ lib.optionals stdenv.isLinux [
wl-clipboard
];
in
ps.buildPythonApplication rec {
pname = "normcap";
version = "0.4.4";
format = "pyproject";
disabled = ps.pythonOlder "3.9";
src = fetchFromGitHub {
owner = "dynobo";
repo = "normcap";
rev = "refs/tags/v${version}";
hash = "sha256-dShtmoqS9TC3PHuwq24OEOhYfBHGhDCma8Du8QCkFuI=";
};
pythonRemoveDeps = [
"PySide6-Essentials"
];
nativeBuildInputs = [
ps.pythonRelaxDepsHook
ps.poetry-core
];
propagatedBuildInputs = [
ps.pyside6
];
preFixup = ''
makeWrapperArgs+=(
"''${qtWrapperArgs[@]}"
--set QT_QPA_PLATFORM xcb
--prefix PATH : ${lib.makeBinPath wrapperDeps}
)
'';
nativeCheckInputs = wrapperDeps ++ [
ps.pytestCheckHook
ps.pytest-qt
ps.toml
] ++ lib.optionals stdenv.isLinux [
ps.pytest-xvfb
xorg.xorgserver
];
preCheck = ''
export HOME=$(mktemp -d)
'' + lib.optionalString stdenv.isLinux ''
# setup a virtual x11 display
export DISPLAY=:$((2000 + $RANDOM % 1000))
Xvfb $DISPLAY -screen 5 1024x768x8 &
xvfb_pid=$!
'';
postCheck = lib.optionalString stdenv.isLinux ''
# cleanup the virtual x11 display
kill $xvfb_pid
'';
disabledTests = [
# requires a wayland session (no xclip support)
"test_wl_copy"
# times out, unknown why
"test_update_checker_triggers_checked_signal"
# touches network
"test_urls_reachable"
# requires xdg
"test_synchronized_capture"
] ++ lib.optionals stdenv.isDarwin [
# requires impure pbcopy
"test_get_copy_func_with_pbcopy"
"test_get_copy_func_without_pbcopy"
"test_perform_pbcopy"
];
disabledTestPaths = [
# touches network
"tests/tests_gui/test_downloader.py"
# fails to import, causes pytest to freeze
"tests/tests_gui/test_language_manager.py"
] ++ lib.optionals stdenv.isDarwin [
# requires a display
"tests/integration/test_normcap.py"
];
meta = with lib; {
description = "OCR powered screen-capture tool to capture information instead of images";
homepage = "https://dynobo.github.io/normcap/";
license = licenses.gpl3Plus;
maintainers = with maintainers; [ cafkafk pbsds ];
mainProgram = "normcap";
};
}

View File

@ -2,13 +2,13 @@
php.buildComposerProject (finalAttrs: {
pname = "phpunit";
version = "10.5.0";
version = "10.5.1";
src = fetchFromGitHub {
owner = "sebastianbergmann";
repo = "phpunit";
rev = finalAttrs.version;
hash = "sha256-CpgYMUJE7c2eRBYkK/vMRdGgzY7Y7K/wMmyUH+Bssjs=";
hash = "sha256-uYSVzKLefcBMqfrHaF6pg4gohAeb6LVg8QGaTS8jwfE=";
};
vendorHash = "sha256-uUdgz3ZZ+3nU07pUC1sdkNgU1b1beo3sS/yySUzdZwU=";

View File

@ -11,17 +11,18 @@
, libxkbcommon
, wayland
, wayland-protocols
, gitUpdater
}:
stdenv.mkDerivation (finalAttrs: {
pname = "sov";
version = "0.92b";
version = "0.93";
src = fetchFromGitHub {
owner = "milgra";
repo = "sov";
rev = finalAttrs.version;
hash = "sha256-1L5D0pzcXbkz3VS7VB6ID8BJEbGeNxjo3xCr71CGcIo=";
hash = "sha256-Oc25ixrl0QX0jBBMV34BPAixyBikvevXJ1JNGZymPhg=";
};
patches = [
@ -54,6 +55,8 @@ stdenv.mkDerivation (finalAttrs: {
wayland-protocols
];
passthru.updateScript = gitUpdater { };
meta = {
description = "Workspace overview app for sway";
homepage = "https://github.com/milgra/sov";

View File

@ -17,6 +17,9 @@ let
gmenuharness = callPackage ./development/gmenuharness { };
libusermetrics = callPackage ./development/libusermetrics { };
lomiri-api = callPackage ./development/lomiri-api { };
#### Services
biometryd = callPackage ./services/biometryd { };
};
in
lib.makeScope libsForQt5.newScope packages

View File

@ -0,0 +1,137 @@
{ stdenv
, lib
, fetchFromGitLab
, fetchpatch
, gitUpdater
, testers
, boost
, cmake
, cmake-extras
, dbus
, dbus-cpp
, gtest
, libapparmor
, libelf
, pkg-config
, process-cpp
, properties-cpp
, qtbase
, qtdeclarative
, sqlite
}:
stdenv.mkDerivation (finalAttrs: {
pname = "biometryd";
version = "0.3.0";
src = fetchFromGitLab {
owner = "ubports";
repo = "development/core/biometryd";
rev = finalAttrs.version;
hash = "sha256-b095rsQnd63Ziqe+rn3ROo4LGXZxZ3Sa6h3apzCuyCs=";
};
outputs = [
"out"
"dev"
];
patches = [
# https://gitlab.com/ubports/development/core/biometryd/-/merge_requests/31
(fetchpatch {
url = "https://gitlab.com/OPNA2608/biometryd/-/commit/d01d979e4f98c6473761d1ace308aa182017804e.patch";
hash = "sha256-JxL3BLuh33ptfneU1y2qNGFKpeMlZlTMwCK97Rk3aTA=";
})
(fetchpatch {
url = "https://gitlab.com/OPNA2608/biometryd/-/commit/3cec6a3d42ea6aba8892da2c771b317f44daf9e2.patch";
hash = "sha256-Ij/aio38WmZ+NsUSbM195Gwb83goWIcCnJvGwAOJi50=";
})
(fetchpatch {
url = "https://gitlab.com/OPNA2608/biometryd/-/commit/e89bd9444bc1cfe84a9aa93faa23057c80f39564.patch";
hash = "sha256-1vEG349X9+SvY/f3no/l5cMVGpdzC8h/8XOZwL/70Dc=";
})
# https://gitlab.com/ubports/development/core/biometryd/-/merge_requests/32
(fetchpatch {
url = "https://gitlab.com/OPNA2608/biometryd/-/commit/9e52fad0139c5a45f69e6a6256b2b5ff54f77740.patch";
hash = "sha256-DZSdzKq6EYgAllKSDgkGk2g57zHN+gI5fOoj7U5AcKY=";
})
];
postPatch = ''
# Remove with !31 patches, fetchpatch can't apply renames
pushd data
for type in conf service; do
mv biometryd.$type biometryd.$type.in
substituteInPlace biometryd.$type.in \
--replace '/usr/bin' "\''${CMAKE_INSTALL_FULL_BINDIR}"
done
popd
# Uses pkg_get_variable, cannot substitute prefix with that
substituteInPlace CMakeLists.txt \
--replace 'pkg_get_variable(SYSTEMD_SYSTEM_UNIT_DIR systemd systemdsystemunitdir)' 'set(SYSTEMD_SYSTEM_UNIT_DIR "${placeholder "out"}/lib/systemd/system")'
substituteInPlace src/biometry/qml/Biometryd/CMakeLists.txt \
--replace "\''${CMAKE_INSTALL_LIBDIR}/qt5/qml" "\''${CMAKE_INSTALL_PREFIX}/${qtbase.qtQmlPrefix}"
'' + lib.optionalString (!finalAttrs.doCheck) ''
sed -i -e '/add_subdirectory(tests)/d' CMakeLists.txt
'';
strictDeps = true;
nativeBuildInputs = [
cmake
pkg-config
qtdeclarative # qmlplugindump
];
buildInputs = [
boost
cmake-extras
dbus
dbus-cpp
libapparmor
libelf
process-cpp
properties-cpp
qtbase
qtdeclarative
sqlite
];
checkInputs = [
gtest
];
dontWrapQtApps = true;
cmakeFlags = [
"-DENABLE_WERROR=OFF"
"-DWITH_HYBRIS=OFF"
];
preBuild = ''
# Generating plugins.qmltypes (also used in checkPhase?)
export QT_PLUGIN_PATH=${lib.getBin qtbase}/${qtbase.qtPluginPrefix}
'';
doCheck = stdenv.buildPlatform.canExecute stdenv.hostPlatform;
meta = with lib; {
description = "Mediates/multiplexes access to biometric devices";
longDescription = ''
biometryd mediates and multiplexes access to biometric devices present
on the system, enabling applications and system components to leverage
them for identification and verification of users.
'';
homepage = "https://gitlab.com/ubports/development/core/biometryd";
license = licenses.lgpl3Only;
maintainers = teams.lomiri.members;
mainProgram = "biometryd";
platforms = platforms.linux;
pkgConfigModules = [
"biometryd"
];
};
})

View File

@ -2,11 +2,11 @@
stdenvNoCC.mkDerivation rec {
pname = "flix";
version = "0.41.0";
version = "0.42.0";
src = fetchurl {
url = "https://github.com/flix/flix/releases/download/v${version}/flix.jar";
sha256 = "sha256-bDeqwk+grkCxmGE9H8Ks7Q8KvLxNCzaLe44DlR6E7YE=";
sha256 = "sha256-fkYyJxBlJWUkXGgcszerNKFNEFRIOm6tUyiTZj0q11k=";
};
dontUnpack = true;

View File

@ -24,13 +24,13 @@ let
in
stdenv.mkDerivation rec {
pname = "ctranslate2";
version = "3.22.0";
version = "3.23.0";
src = fetchFromGitHub {
owner = "OpenNMT";
repo = "CTranslate2";
rev = "v${version}";
hash = "sha256-Fw0pMTc0Zmr4RfH2rdPgpOODZW9CL5UbDbIeH6A4zZQ=";
hash = "sha256-jqeLNKOGdGtAVx7ExGGDxxgi5zDmQgmJ6bxIuguaM3k=";
fetchSubmodules = true;
};

View File

@ -21,7 +21,7 @@
stdenv.mkDerivation rec {
pname = "libadwaita";
version = "1.4.0";
version = "1.4.1";
outputs = [ "out" "dev" "devdoc" ];
outputBin = "devdoc"; # demo app
@ -31,7 +31,7 @@ stdenv.mkDerivation rec {
owner = "GNOME";
repo = "libadwaita";
rev = version;
hash = "sha256-LXrlTca50ALo+Nm55fwXNb4k3haLqHNnzLPc08VhA5s=";
hash = "sha256-ztbvVRkNbkeAomRIxToUEQrYB5XnG1WPcfSB/iXHKoA=";
};
depsBuildBuild = [

View File

@ -0,0 +1,59 @@
{ stdenv
, lib
, fetchFromGitHub
, nix-update-script
, testers
, qmake
, qtmultimedia
}:
stdenv.mkDerivation (finalAttrs: {
pname = "qzxing";
version = "3.3.0";
src = fetchFromGitHub {
owner = "ftylitak";
repo = "qzxing";
rev = "v${finalAttrs.version}";
hash = "sha256-ASgsF5ocNWAiIy2jm6ygpDkggBcEpno6iVNWYkuWcVI=";
};
# QMake can't find qtmultimedia in buildInputs
strictDeps = false;
nativeBuildInputs = [
qmake
];
buildInputs = [
qtmultimedia
];
dontWrapQtApps = true;
preConfigure = ''
cd src
'';
qmakeFlags = [
"CONFIG+=qzxing_qml"
"CONFIG+=qzxing_multimedia"
"QMAKE_PKGCONFIG_PREFIX=${placeholder "out"}"
];
passthru = {
tests.pkg-config = testers.testMetaPkgConfig finalAttrs.finalPackage;
updateScript = nix-update-script { };
};
meta = with lib; {
description = "Qt/QML wrapper library for the ZXing library";
homepage = "https://github.com/ftylitak/qzxing";
license = licenses.asl20;
maintainers = with maintainers; [ OPNA2608 ];
platforms = platforms.unix;
pkgConfigModules = [
"QZXing"
];
};
})

View File

@ -1,26 +1,29 @@
{ lib
, buildPythonPackage
, docopt
, fetchFromGitHub
, jsonconversion
, six
, pytestCheckHook
, pythonOlder
, setuptools
, six
, tabulate
}:
buildPythonPackage rec {
pname = "amazon-ion";
version = "0.10.0";
format = "setuptools";
version = "0.11.2";
pyproject = true;
disabled = pythonOlder "3.7";
# test vectors require git submodule
src = fetchFromGitHub {
owner = "amzn";
owner = "amazon-ion";
repo = "ion-python";
rev = "refs/tags/v${version}";
# Test vectors require git submodule
fetchSubmodules = true;
hash = "sha256-pCm3jd/dVqO/uIvT5N/w5yoUWU6ni62Pl2A862e+qSk=";
hash = "sha256-0/+bX02qTbOydWDxex4OWL7woP7dW1yJZBmDZAivE7U=";
};
postPatch = ''
@ -28,13 +31,19 @@ buildPythonPackage rec {
--replace "'pytest-runner'," ""
'';
nativeBuildInputs = [
setuptools
];
propagatedBuildInputs = [
jsonconversion
six
];
nativeCheckInputs = [
docopt
pytestCheckHook
tabulate
];
disabledTests = [
@ -42,13 +51,19 @@ buildPythonPackage rec {
"test_roundtrips"
];
disabledTestPaths = [
# Exclude benchmarks
"tests/test_benchmark_cli.py"
];
pythonImportsCheck = [
"amazon.ion"
];
meta = with lib; {
description = "Python implementation of Amazon Ion";
homepage = "https://github.com/amzn/ion-python";
homepage = "https://github.com/amazon-ion/ion-python";
changelog = "https://github.com/amazon-ion/ion-python/releases/tag/v${version}";
sourceProvenance = with sourceTypes; [
fromSource
binaryNativeCode

View File

@ -0,0 +1,42 @@
{ lib
, buildPythonPackage
, fetchPypi
, setuptools
, wheel
, psutil
}:
buildPythonPackage rec {
pname = "vprof";
version = "0.38";
pyproject = true;
# We use the Pypi source rather than the GitHub ones because the former include the javascript
# dependency for the UI.
src = fetchPypi {
inherit pname version;
hash = "sha256-fxAAkS7rekUMfJTTzJZzmvRa0P8B1avMCwmhddQP+ts=";
};
nativeBuildInputs = [
setuptools
wheel
];
propagatedBuildInputs = [
psutil
];
pythonImportsCheck = [ "vprof" ];
# The tests are not included in the Pypi sources
doCheck = false;
meta = with lib; {
description = "Visual profiler for Python";
homepage = "https://github.com/nvdv/vprof";
license = licenses.bsd2;
maintainers = with maintainers; [ GaetanLepage ];
mainProgram = "vprof";
};
}

View File

@ -123,13 +123,13 @@ let
in
stdenv.mkDerivation rec {
pname = "hydra";
version = "2023-11-17";
version = "2023-12-01";
src = fetchFromGitHub {
owner = "NixOS";
repo = "hydra";
rev = "8f48e4ddecbf403be35f8243b97d73cb39dd61bb";
hash = "sha256-5q/7yz6jJedD8YU3SuYyXtN3qEAlOBRKGZxOcYt/0X8=";
rev = "4d1c8505120961f10897b8fe9a070d4e193c9a13";
hash = "sha256-vXTuE83GL15mgZHegbllVAsVdDFcWWSayPfZxTJN5ys=";
};
buildInputs = [

View File

@ -3,28 +3,40 @@
, fetchCrate
, pkg-config
, udev
, nix-update-script
, testers
, ravedude
}:
rustPlatform.buildRustPackage rec {
pname = "ravedude";
version = "0.1.5";
version = "0.1.6";
src = fetchCrate {
inherit pname version;
hash = "sha256-wcY9fvfIn1pWMAh5FI/QFl18CV2xjmRGSwwoRfGvujo=";
hash = "sha256-LhPRz3DUMDoe50Hq3yO+2BHpyh5fQ4sMNGLttjkdSZw=";
};
cargoHash = "sha256-AOIrB0FRagbA2+JEURF41d+th0AbR++U5WKCcZmh4Os=";
cargoHash = "sha256-Uo8wlTAHBkn/WeGPhPP+BU80wjSyNHsWQj8QvA7mHrk=";
nativeBuildInputs = [ pkg-config ];
buildInputs = [ udev ];
passthru = {
updateScript = nix-update-script { };
tests.version = testers.testVersion {
package = ravedude;
version = "v${version}";
};
};
meta = with lib; {
description = "Tool to easily flash code onto an AVR microcontroller with avrdude";
homepage = "https://crates.io/crates/ravedude";
license = with licenses; [ mit /* or */ asl20 ];
platforms = platforms.linux;
maintainers = with maintainers; [ rvarago ];
mainProgram = "ravedude";
};
}

View File

@ -27,16 +27,16 @@ in
buildGoModule rec {
pname = "berglas";
version = "1.0.3";
version = "2.0.1";
src = fetchFromGitHub {
owner = "GoogleCloudPlatform";
repo = pname;
rev = "v${version}";
sha256 = "sha256-4hbRX0kKMWixcu5SWjrM5lVvhLMOaeBdG4GH5NVAh70=";
sha256 = "sha256-Jf6yPVydM7UnG1yiLEFe+7FMkWANIQebZ3QAwg6/OQs=";
};
vendorHash = "sha256-qcFS07gma7GVxhdrYca0E6rcczNcZmU8JcjjcpEaxp0=";
vendorHash = "sha256-3WDBl/GqCgRFMmh6TQvtHhACCRzf9sdIO8fel8CAMP0=";
ldflags = [
"-s"

View File

@ -16,6 +16,7 @@
, ninja
, pkg-config
, tpm2-tools
, nixosTests
}:
stdenv.mkDerivation rec {
@ -29,6 +30,12 @@ stdenv.mkDerivation rec {
hash = "sha256-3J3ti/jRiv+p3eVvJD7u0ko28rPd8Gte0mCJaVaqyOs=";
};
patches = [
# Replaces the clevis-decrypt 300s timeout to a 10s timeout
# https://github.com/latchset/clevis/issues/289
./tang-timeout.patch
];
postPatch = ''
for f in $(find src/ -type f); do
grep -q "/bin/cat" "$f" && substituteInPlace "$f" \
@ -65,6 +72,14 @@ stdenv.mkDerivation rec {
"man"
];
passthru.tests = {
inherit (nixosTests.installer) clevisBcachefs clevisBcachefsFallback clevisLuks clevisLuksFallback clevisZfs clevisZfsFallback;
clevisLuksSystemdStage1 = nixosTests.installer-systemd-stage-1.clevisLuks;
clevisLuksFallbackSystemdStage1 = nixosTests.installer-systemd-stage-1.clevisLuksFallback;
clevisZfsSystemdStage1 = nixosTests.installer-systemd-stage-1.clevisZfs;
clevisZfsFallbackSystemdStage1 = nixosTests.installer-systemd-stage-1.clevisZfsFallback;
};
meta = with lib; {
description = "Automated Encryption Framework";
homepage = "https://github.com/latchset/clevis";

View File

@ -0,0 +1,13 @@
diff --git a/src/pins/tang/clevis-decrypt-tang b/src/pins/tang/clevis-decrypt-tang
index 72393b4..40b660f 100755
--- a/src/pins/tang/clevis-decrypt-tang
+++ b/src/pins/tang/clevis-decrypt-tang
@@ -101,7 +101,7 @@ xfr="$(jose jwk exc -i '{"alg":"ECMR"}' -l- -r- <<< "$clt$eph")"
rec_url="$url/rec/$kid"
ct="Content-Type: application/jwk+json"
-if ! rep="$(curl -sfg -X POST -H "$ct" --data-binary @- "$rec_url" <<< "$xfr")"; then
+if ! rep="$(curl --connect-timeout 10 -sfg -X POST -H "$ct" --data-binary @- "$rec_url" <<< "$xfr")"; then
echo "Error communicating with server $url" >&2
exit 1
fi

View File

@ -2,6 +2,7 @@
, mkDerivation
, fetchurl
, cmake
, flatbuffers
, gettext
, pkg-config
, libdigidocpp
@ -16,12 +17,12 @@
mkDerivation rec {
pname = "qdigidoc";
version = "4.2.12";
version = "4.4.0";
src = fetchurl {
url =
"https://github.com/open-eid/DigiDoc4-Client/releases/download/v${version}/qdigidoc4-${version}.tar.gz";
hash = "sha256-6bso1qvhVhbBfrcTq4S+aHtHli7X2A926N4r45ztq4E=";
hash = "sha256-5zo0yoY0wufm9DWRIccxJ5g4DXn75nT4fd2h+5QP4oQ=";
};
tsl = fetchurl {
@ -37,6 +38,7 @@ mkDerivation rec {
'';
buildInputs = [
flatbuffers
libdigidocpp
opensc
openldap

View File

@ -2114,6 +2114,8 @@ with pkgs;
vopono = callPackage ../tools/networking/vopono { };
vprof = with python3Packages; toPythonApplication vprof;
vrc-get = callPackage ../tools/misc/vrc-get {
inherit (darwin.apple_sdk.frameworks) Security;
};
@ -4778,8 +4780,6 @@ with pkgs;
slurp = callPackage ../tools/wayland/slurp { };
sov = callPackage ../tools/wayland/sov { };
swaykbdd = callPackage ../tools/wayland/swaykbdd { };
swayr = callPackage ../tools/wayland/swayr { };
@ -18291,8 +18291,6 @@ with pkgs;
karma-runner = callPackage ../development/tools/karma-runner { };
phpunit = callPackage ../development/tools/misc/phpunit { };
teller = callPackage ../development/tools/teller { };
yakut = python3Packages.callPackage ../development/tools/misc/yakut { };
@ -19160,7 +19158,9 @@ with pkgs;
fprettify = callPackage ../development/tools/fprettify { };
framac = callPackage ../development/tools/analysis/frama-c { };
framac = callPackage ../development/tools/analysis/frama-c {
why3 = pkgs.why3.override { version = "1.6.0"; };
};
frame = callPackage ../development/libraries/frame { };
@ -22062,7 +22062,7 @@ with pkgs;
hwloc = callPackage ../development/libraries/hwloc { };
hydra_unstable = callPackage ../development/tools/misc/hydra/unstable.nix { nix = nixVersions.nix_2_17; };
hydra_unstable = callPackage ../development/tools/misc/hydra/unstable.nix { nix = nixVersions.nix_2_18; };
hydra-cli = callPackage ../development/tools/misc/hydra-cli { };
@ -34379,8 +34379,6 @@ with pkgs;
nomacs = libsForQt5.callPackage ../applications/graphics/nomacs { };
normcap = callPackage ../applications/graphics/normcap { };
notepad-next = libsForQt5.callPackage ../applications/editors/notepad-next { };
notepadqq = libsForQt5.callPackage ../applications/editors/notepadqq { };

View File

@ -15585,6 +15585,8 @@ self: super: with self; {
vpk = callPackage ../development/python-modules/vpk { };
vprof = callPackage ../development/python-modules/vprof { };
vqgan-jax = callPackage ../development/python-modules/vqgan-jax { };
vsts = callPackage ../development/python-modules/vsts { };

View File

@ -246,6 +246,8 @@ in (noExtraAttrs (kdeFrameworks // plasmaMobileGear // plasma5 // plasma5.thirdP
qxlsx = callPackage ../development/libraries/qxlsx { };
qzxing = callPackage ../development/libraries/qzxing { };
soqt = callPackage ../development/libraries/soqt { };
telepathy = callPackage ../development/libraries/telepathy/qt { };

View File

@ -50,6 +50,8 @@ makeScopeWithSplicing' {
qxlsx = callPackage ../development/libraries/qxlsx { };
qzxing = callPackage ../development/libraries/qzxing { };
poppler = callPackage ../development/libraries/poppler {
lcms = pkgs.lcms2;
qt6Support = true;