Merge master into staging-next

This commit is contained in:
github-actions[bot] 2021-10-26 06:01:02 +00:00 committed by GitHub
commit 7e0da80ec9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 812 additions and 107 deletions

View File

@ -2143,6 +2143,12 @@
githubId = 199180;
name = "Claes Wallin";
};
cleeyv = {
email = "cleeyv@riseup.net";
github = "cleeyv";
githubId = 71959829;
name = "Cleeyv";
};
cleverca22 = {
email = "cleverca22@gmail.com";
matrix = "@cleverca22:matrix.org";

View File

@ -145,6 +145,7 @@ with lib.maintainers; {
jitsi = {
members = [
cleeyv
petabyteboy
ryantm
yuka

View File

@ -136,6 +136,14 @@
<link xlink:href="options.html#opt-services.geoipupdate.enable">services.geoipupdate</link>.
</para>
</listitem>
<listitem>
<para>
<link xlink:href="https://github.com/jitsi/jibri">Jibri</link>,
a service for recording or streaming a Jitsi Meet conference.
Available as
<link xlink:href="options.html#opt-services.jibri.enable">services.jibri</link>.
</para>
</listitem>
<listitem>
<para>
<link xlink:href="https://www.isc.org/kea/">Kea</link>, ISCs

View File

@ -45,6 +45,8 @@ In addition to numerous new and upgraded packages, this release has the followin
- [geoipupdate](https://github.com/maxmind/geoipupdate), a GeoIP database updater from MaxMind. Available as [services.geoipupdate](options.html#opt-services.geoipupdate.enable).
- [Jibri](https://github.com/jitsi/jibri), a service for recording or streaming a Jitsi Meet conference. Available as [services.jibri](options.html#opt-services.jibri.enable).
- [Kea](https://www.isc.org/kea/), ISCs 2nd generation DHCP and DDNS server suite. Available at [services.kea](options.html#opt-services.kea).
- [owncast](https://owncast.online/), self-hosted video live streaming solution. Available at [services.owncast](options.html#opt-services.owncast).

View File

@ -756,6 +756,7 @@
./services/networking/iscsi/root-initiator.nix
./services/networking/iscsi/target.nix
./services/networking/iwd.nix
./services/networking/jibri/default.nix
./services/networking/jicofo.nix
./services/networking/jitsi-videobridge.nix
./services/networking/kea.nix

View File

@ -0,0 +1,417 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.jibri;
# Copied from the jitsi-videobridge.nix file.
toHOCON = x:
if isAttrs x && x ? __hocon_envvar then ("\${" + x.__hocon_envvar + "}")
else if isAttrs x then "{${ concatStringsSep "," (mapAttrsToList (k: v: ''"${k}":${toHOCON v}'') x) }}"
else if isList x then "[${ concatMapStringsSep "," toHOCON x }]"
else builtins.toJSON x;
# We're passing passwords in environment variables that have names generated
# from an attribute name, which may not be a valid bash identifier.
toVarName = s: "XMPP_PASSWORD_" + stringAsChars (c: if builtins.match "[A-Za-z0-9]" c != null then c else "_") s;
defaultJibriConfig = {
id = "";
single-use-mode = false;
api = {
http.external-api-port = 2222;
http.internal-api-port = 3333;
xmpp.environments = flip mapAttrsToList cfg.xmppEnvironments (name: env: {
inherit name;
xmpp-server-hosts = env.xmppServerHosts;
xmpp-domain = env.xmppDomain;
control-muc = {
domain = env.control.muc.domain;
room-name = env.control.muc.roomName;
nickname = env.control.muc.nickname;
};
control-login = {
domain = env.control.login.domain;
username = env.control.login.username;
password.__hocon_envvar = toVarName "${name}_control";
};
call-login = {
domain = env.call.login.domain;
username = env.call.login.username;
password.__hocon_envvar = toVarName "${name}_call";
};
strip-from-room-domain = env.stripFromRoomDomain;
usage-timeout = env.usageTimeout;
trust-all-xmpp-certs = env.disableCertificateVerification;
});
};
recording = {
recordings-directory = "/tmp/recordings";
finalize-script = "${cfg.finalizeScript}";
};
streaming.rtmp-allow-list = [ ".*" ];
chrome.flags = [
"--use-fake-ui-for-media-stream"
"--start-maximized"
"--kiosk"
"--enabled"
"--disable-infobars"
"--autoplay-policy=no-user-gesture-required"
]
++ lists.optional cfg.ignoreCert
"--ignore-certificate-errors";
stats.enable-stats-d = true;
webhook.subscribers = [ ];
jwt-info = { };
call-status-checks = {
no-media-timout = "30 seconds";
all-muted-timeout = "10 minutes";
default-call-empty-timout = "30 seconds";
};
};
# Allow overriding leaves of the default config despite types.attrs not doing any merging.
jibriConfig = recursiveUpdate defaultJibriConfig cfg.config;
configFile = pkgs.writeText "jibri.conf" (toHOCON { jibri = jibriConfig; });
in
{
options.services.jibri = with types; {
enable = mkEnableOption "Jitsi BRoadcasting Infrastructure. Currently Jibri must be run on a host that is also running <option>services.jitsi-meet.enable</option>, so for most use cases it will be simpler to run <option>services.jitsi-meet.jibri.enable</option>";
config = mkOption {
type = attrs;
default = { };
description = ''
Jibri configuration.
See <link xlink:href="https://github.com/jitsi/jibri/blob/master/src/main/resources/reference.conf" />
for default configuration with comments.
'';
};
finalizeScript = mkOption {
type = types.path;
default = pkgs.writeScript "finalize_recording.sh" ''
#!/bin/sh
RECORDINGS_DIR=$1
echo "This is a dummy finalize script" > /tmp/finalize.out
echo "The script was invoked with recordings directory $RECORDINGS_DIR." >> /tmp/finalize.out
echo "You should put any finalize logic (renaming, uploading to a service" >> /tmp/finalize.out
echo "or storage provider, etc.) in this script" >> /tmp/finalize.out
exit 0
'';
defaultText = literalExpression ''
pkgs.writeScript "finalize_recording.sh" ''''''
#!/bin/sh
RECORDINGS_DIR=$1
echo "This is a dummy finalize script" > /tmp/finalize.out
echo "The script was invoked with recordings directory $RECORDINGS_DIR." >> /tmp/finalize.out
echo "You should put any finalize logic (renaming, uploading to a service" >> /tmp/finalize.out
echo "or storage provider, etc.) in this script" >> /tmp/finalize.out
exit 0
'''''';
'';
example = literalExpression ''
pkgs.writeScript "finalize_recording.sh" ''''''
#!/bin/sh
RECORDINGS_DIR=$1
${pkgs.rclone}/bin/rclone copy $RECORDINGS_DIR RCLONE_REMOTE:jibri-recordings/ -v --log-file=/var/log/jitsi/jibri/recording-upload.txt
exit 0
'''''';
'';
description = ''
This script runs when jibri finishes recording a video of a conference.
'';
};
ignoreCert = mkOption {
type = bool;
default = false;
example = true;
description = ''
Whether to enable the flag "--ignore-certificate-errors" for the Chromium browser opened by Jibri.
Intended for use in automated tests or anywhere else where using a verified cert for Jitsi-Meet is not possible.
'';
};
xmppEnvironments = mkOption {
description = ''
XMPP servers to connect to.
'';
example = literalExpression ''
"jitsi-meet" = {
xmppServerHosts = [ "localhost" ];
xmppDomain = config.services.jitsi-meet.hostName;
control.muc = {
domain = "internal.''${config.services.jitsi-meet.hostName}";
roomName = "JibriBrewery";
nickname = "jibri";
};
control.login = {
domain = "auth.''${config.services.jitsi-meet.hostName}";
username = "jibri";
passwordFile = "/var/lib/jitsi-meet/jibri-auth-secret";
};
call.login = {
domain = "recorder.''${config.services.jitsi-meet.hostName}";
username = "recorder";
passwordFile = "/var/lib/jitsi-meet/jibri-recorder-secret";
};
usageTimeout = "0";
disableCertificateVerification = true;
stripFromRoomDomain = "conference.";
};
'';
default = { };
type = attrsOf (submodule ({ name, ... }: {
options = {
xmppServerHosts = mkOption {
type = listOf str;
example = [ "xmpp.example.org" ];
description = ''
Hostnames of the XMPP servers to connect to.
'';
};
xmppDomain = mkOption {
type = str;
example = "xmpp.example.org";
description = ''
The base XMPP domain.
'';
};
control.muc.domain = mkOption {
type = str;
description = ''
The domain part of the MUC to connect to for control.
'';
};
control.muc.roomName = mkOption {
type = str;
default = "JibriBrewery";
description = ''
The room name of the MUC to connect to for control.
'';
};
control.muc.nickname = mkOption {
type = str;
default = "jibri";
description = ''
The nickname for this Jibri instance in the MUC.
'';
};
control.login.domain = mkOption {
type = str;
description = ''
The domain part of the JID for this Jibri instance.
'';
};
control.login.username = mkOption {
type = str;
default = "jvb";
description = ''
User part of the JID.
'';
};
control.login.passwordFile = mkOption {
type = str;
example = "/run/keys/jibri-xmpp1";
description = ''
File containing the password for the user.
'';
};
call.login.domain = mkOption {
type = str;
example = "recorder.xmpp.example.org";
description = ''
The domain part of the JID for the recorder.
'';
};
call.login.username = mkOption {
type = str;
default = "recorder";
description = ''
User part of the JID for the recorder.
'';
};
call.login.passwordFile = mkOption {
type = str;
example = "/run/keys/jibri-recorder-xmpp1";
description = ''
File containing the password for the user.
'';
};
disableCertificateVerification = mkOption {
type = bool;
default = false;
description = ''
Whether to skip validation of the server's certificate.
'';
};
stripFromRoomDomain = mkOption {
type = str;
default = "0";
example = "conference.";
description = ''
The prefix to strip from the room's JID domain to derive the call URL.
'';
};
usageTimeout = mkOption {
type = str;
default = "0";
example = "1 hour";
description = ''
The duration that the Jibri session can be.
A value of zero means indefinitely.
'';
};
};
config =
let
nick = mkDefault (builtins.replaceStrings [ "." ] [ "-" ] (
config.networking.hostName + optionalString (config.networking.domain != null) ".${config.networking.domain}"
));
in
{
call.login.username = nick;
control.muc.nickname = nick;
};
}));
};
};
config = mkIf cfg.enable {
users.groups.jibri = { };
users.groups.plugdev = { };
users.users.jibri = {
isSystemUser = true;
group = "jibri";
home = "/var/lib/jibri";
extraGroups = [ "jitsi-meet" "adm" "audio" "video" "plugdev" ];
};
systemd.services.jibri-xorg = {
description = "Jitsi Xorg Process";
after = [ "network.target" ];
wantedBy = [ "jibri.service" "jibri-icewm.service" ];
preStart = ''
cp --no-preserve=mode,ownership ${pkgs.jibri}/etc/jitsi/jibri/* /var/lib/jibri
mv /var/lib/jibri/{,.}asoundrc
'';
environment.DISPLAY = ":0";
serviceConfig = {
Type = "simple";
User = "jibri";
Group = "jibri";
KillMode = "process";
Restart = "on-failure";
RestartPreventExitStatus = 255;
StateDirectory = "jibri";
ExecStart = "${pkgs.xorg.xorgserver}/bin/Xorg -nocursor -noreset +extension RANDR +extension RENDER -config ${pkgs.jibri}/etc/jitsi/jibri/xorg-video-dummy.conf -logfile /dev/null :0";
};
};
systemd.services.jibri-icewm = {
description = "Jitsi Window Manager";
requires = [ "jibri-xorg.service" ];
after = [ "jibri-xorg.service" ];
wantedBy = [ "jibri.service" ];
environment.DISPLAY = ":0";
serviceConfig = {
Type = "simple";
User = "jibri";
Group = "jibri";
Restart = "on-failure";
RestartPreventExitStatus = 255;
StateDirectory = "jibri";
ExecStart = "${pkgs.icewm}/bin/icewm-session";
};
};
systemd.services.jibri = {
description = "Jibri Process";
requires = [ "jibri-icewm.service" "jibri-xorg.service" ];
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
path = with pkgs; [ chromedriver chromium ffmpeg-full ];
script = (concatStrings (mapAttrsToList
(name: env: ''
export ${toVarName "${name}_control"}=$(cat ${env.control.login.passwordFile})
export ${toVarName "${name}_call"}=$(cat ${env.call.login.passwordFile})
'')
cfg.xmppEnvironments))
+ ''
${pkgs.jre8_headless}/bin/java -Djava.util.logging.config.file=${./logging.properties-journal} -Dconfig.file=${configFile} -jar ${pkgs.jibri}/opt/jitsi/jibri/jibri.jar --config /var/lib/jibri/jibri.json
'';
environment.HOME = "/var/lib/jibri";
serviceConfig = {
Type = "simple";
User = "jibri";
Group = "jibri";
Restart = "always";
RestartPreventExitStatus = 255;
StateDirectory = "jibri";
};
};
systemd.tmpfiles.rules = [
"d /var/log/jitsi/jibri 755 jibri jibri"
];
# Configure Chromium to not show the "Chrome is being controlled by automatic test software" message.
environment.etc."chromium/policies/managed/managed_policies.json".text = builtins.toJSON { CommandLineFlagSecurityWarningsEnabled = false; };
warnings = [ "All security warnings for Chromium have been disabled. This is necessary for Jibri, but it also impacts all other uses of Chromium on this system." ];
boot = {
extraModprobeConfig = ''
options snd-aloop enable=1,1,1,1,1,1,1,1
'';
kernelModules = [ "snd-aloop" ];
};
};
meta.maintainers = lib.teams.jitsi.members;
}

View File

@ -0,0 +1,32 @@
handlers = java.util.logging.FileHandler
java.util.logging.FileHandler.level = FINE
java.util.logging.FileHandler.pattern = /var/log/jitsi/jibri/log.%g.txt
java.util.logging.FileHandler.formatter = net.java.sip.communicator.util.ScLogFormatter
java.util.logging.FileHandler.count = 10
java.util.logging.FileHandler.limit = 10000000
org.jitsi.jibri.capture.ffmpeg.util.FfmpegFileHandler.level = FINE
org.jitsi.jibri.capture.ffmpeg.util.FfmpegFileHandler.pattern = /var/log/jitsi/jibri/ffmpeg.%g.txt
org.jitsi.jibri.capture.ffmpeg.util.FfmpegFileHandler.formatter = net.java.sip.communicator.util.ScLogFormatter
org.jitsi.jibri.capture.ffmpeg.util.FfmpegFileHandler.count = 10
org.jitsi.jibri.capture.ffmpeg.util.FfmpegFileHandler.limit = 10000000
org.jitsi.jibri.sipgateway.pjsua.util.PjsuaFileHandler.level = FINE
org.jitsi.jibri.sipgateway.pjsua.util.PjsuaFileHandler.pattern = /var/log/jitsi/jibri/pjsua.%g.txt
org.jitsi.jibri.sipgateway.pjsua.util.PjsuaFileHandler.formatter = net.java.sip.communicator.util.ScLogFormatter
org.jitsi.jibri.sipgateway.pjsua.util.PjsuaFileHandler.count = 10
org.jitsi.jibri.sipgateway.pjsua.util.PjsuaFileHandler.limit = 10000000
org.jitsi.jibri.selenium.util.BrowserFileHandler.level = FINE
org.jitsi.jibri.selenium.util.BrowserFileHandler.pattern = /var/log/jitsi/jibri/browser.%g.txt
org.jitsi.jibri.selenium.util.BrowserFileHandler.formatter = net.java.sip.communicator.util.ScLogFormatter
org.jitsi.jibri.selenium.util.BrowserFileHandler.count = 10
org.jitsi.jibri.selenium.util.BrowserFileHandler.limit = 10000000
org.jitsi.level = FINE
org.jitsi.jibri.config.level = INFO
org.glassfish.level = INFO
org.osgi.level = INFO
org.jitsi.xmpp.level = INFO

View File

@ -38,6 +38,10 @@ let
};
bosh = "//${cfg.hostName}/http-bind";
websocket = "wss://${cfg.hostName}/xmpp-websocket";
fileRecordingsEnabled = true;
liveStreamingEnabled = true;
hiddenDomain = "recorder.${cfg.hostName}";
};
in
{
@ -48,7 +52,7 @@ in
type = str;
example = "meet.example.org";
description = ''
Hostname of the Jitsi Meet instance.
FQDN of the Jitsi Meet instance.
'';
};
@ -130,6 +134,17 @@ in
'';
};
jibri.enable = mkOption {
type = bool;
default = false;
description = ''
Whether to enable a Jibri instance and configure it to connect to Prosody.
Additional configuration is possible with <option>services.jibri</option>, and
<option>services.jibri.finalizeScript</option> is especially useful.
'';
};
nginx.enable = mkOption {
type = bool;
default = true;
@ -229,6 +244,14 @@ in
key = "/var/lib/jitsi-meet/jitsi-meet.key";
};
};
virtualHosts."recorder.${cfg.hostName}" = {
enabled = true;
domain = "recorder.${cfg.hostName}";
extraConfig = ''
authentication = "internal_plain"
c2s_require_encryption = false
'';
};
};
systemd.services.prosody.serviceConfig = mkIf cfg.prosody.enable {
EnvironmentFile = [ "/var/lib/jitsi-meet/secrets-env" ];
@ -243,12 +266,13 @@ in
systemd.services.jitsi-meet-init-secrets = {
wantedBy = [ "multi-user.target" ];
before = [ "jicofo.service" "jitsi-videobridge2.service" ] ++ (optional cfg.prosody.enable "prosody.service");
path = [ config.services.prosody.package ];
serviceConfig = {
Type = "oneshot";
};
script = let
secrets = [ "jicofo-component-secret" "jicofo-user-secret" ] ++ (optional (cfg.videobridge.passwordFile == null) "videobridge-secret");
secrets = [ "jicofo-component-secret" "jicofo-user-secret" "jibri-auth-secret" "jibri-recorder-secret" ] ++ (optional (cfg.videobridge.passwordFile == null) "videobridge-secret");
videobridgeSecret = if cfg.videobridge.passwordFile != null then cfg.videobridge.passwordFile else "/var/lib/jitsi-meet/videobridge-secret";
in
''
@ -267,9 +291,11 @@ in
chmod 640 secrets-env
''
+ optionalString cfg.prosody.enable ''
${config.services.prosody.package}/bin/prosodyctl register focus auth.${cfg.hostName} "$(cat /var/lib/jitsi-meet/jicofo-user-secret)"
${config.services.prosody.package}/bin/prosodyctl register jvb auth.${cfg.hostName} "$(cat ${videobridgeSecret})"
${config.services.prosody.package}/bin/prosodyctl mod_roster_command subscribe focus.${cfg.hostName} focus@auth.${cfg.hostName}
prosodyctl register focus auth.${cfg.hostName} "$(cat /var/lib/jitsi-meet/jicofo-user-secret)"
prosodyctl register jvb auth.${cfg.hostName} "$(cat ${videobridgeSecret})"
prosodyctl mod_roster_command subscribe focus.${cfg.hostName} focus@auth.${cfg.hostName}
prosodyctl register jibri auth.${cfg.hostName} "$(cat /var/lib/jitsi-meet/jibri-auth-secret)"
prosodyctl register recorder recorder.${cfg.hostName} "$(cat /var/lib/jitsi-meet/jibri-recorder-secret)"
# generate self-signed certificates
if [ ! -f /var/lib/jitsi-meet.crt ]; then
@ -380,8 +406,43 @@ in
userPasswordFile = "/var/lib/jitsi-meet/jicofo-user-secret";
componentPasswordFile = "/var/lib/jitsi-meet/jicofo-component-secret";
bridgeMuc = "jvbbrewery@internal.${cfg.hostName}";
config = {
config = mkMerge [{
"org.jitsi.jicofo.ALWAYS_TRUST_MODE_ENABLED" = "true";
#} (lib.mkIf cfg.jibri.enable {
} (lib.mkIf (config.services.jibri.enable || cfg.jibri.enable) {
"org.jitsi.jicofo.jibri.BREWERY" = "JibriBrewery@internal.${cfg.hostName}";
"org.jitsi.jicofo.jibri.PENDING_TIMEOUT" = "90";
})];
};
services.jibri = mkIf cfg.jibri.enable {
enable = true;
xmppEnvironments."jitsi-meet" = {
xmppServerHosts = [ "localhost" ];
xmppDomain = cfg.hostName;
control.muc = {
domain = "internal.${cfg.hostName}";
roomName = "JibriBrewery";
nickname = "jibri";
};
control.login = {
domain = "auth.${cfg.hostName}";
username = "jibri";
passwordFile = "/var/lib/jitsi-meet/jibri-auth-secret";
};
call.login = {
domain = "recorder.${cfg.hostName}";
username = "recorder";
passwordFile = "/var/lib/jitsi-meet/jibri-recorder-secret";
};
usageTimeout = "0";
disableCertificateVerification = true;
stripFromRoomDomain = "conference.";
};
};
};

View File

@ -207,6 +207,7 @@ in
jackett = handleTest ./jackett.nix {};
jellyfin = handleTest ./jellyfin.nix {};
jenkins = handleTest ./jenkins.nix {};
jibri = handleTest ./jibri.nix {};
jirafeau = handleTest ./jirafeau.nix {};
jitsi-meet = handleTest ./jitsi-meet.nix {};
k3s = handleTest ./k3s.nix {};

69
nixos/tests/jibri.nix Normal file
View File

@ -0,0 +1,69 @@
import ./make-test-python.nix ({ pkgs, ... }: {
name = "jibri";
meta = with pkgs.lib; {
maintainers = teams.jitsi.members;
};
machine = { config, pkgs, ... }: {
virtualisation.memorySize = 5120;
services.jitsi-meet = {
enable = true;
hostName = "machine";
jibri.enable = true;
};
services.jibri.ignoreCert = true;
services.jitsi-videobridge.openFirewall = true;
networking.firewall.allowedTCPPorts = [ 80 443 ];
services.nginx.virtualHosts.machine = {
enableACME = true;
forceSSL = true;
};
security.acme.email = "me@example.org";
security.acme.acceptTerms = true;
security.acme.server = "https://example.com"; # self-signed only
};
testScript = ''
machine.wait_for_unit("jitsi-videobridge2.service")
machine.wait_for_unit("jicofo.service")
machine.wait_for_unit("nginx.service")
machine.wait_for_unit("prosody.service")
machine.wait_for_unit("jibri.service")
machine.wait_until_succeeds(
"journalctl -b -u jitsi-videobridge2 -o cat | grep -q 'Performed a successful health check'", timeout=30
)
machine.wait_until_succeeds(
"journalctl -b -u prosody -o cat | grep -q 'Authenticated as focus@auth.machine'", timeout=31
)
machine.wait_until_succeeds(
"journalctl -b -u prosody -o cat | grep -q 'Authenticated as jvb@auth.machine'", timeout=32
)
machine.wait_until_succeeds(
"journalctl -b -u prosody -o cat | grep -q 'Authenticated as jibri@auth.machine'", timeout=33
)
machine.wait_until_succeeds(
"cat /var/log/jitsi/jibri/log.0.txt | grep -q 'Joined MUC: jibribrewery@internal.machine'", timeout=34
)
assert '"busyStatus":"IDLE","health":{"healthStatus":"HEALTHY"' in machine.succeed(
"curl -X GET http://machine:2222/jibri/api/v1.0/health"
)
machine.succeed(
"""curl -H "Content-Type: application/json" -X POST http://localhost:2222/jibri/api/v1.0/startService -d '{"sessionId": "RecordTest","callParams":{"callUrlInfo":{"baseUrl": "https://machine","callName": "TestCall"}},"callLoginParams":{"domain": "recorder.machine", "username": "recorder", "password": "'"$(cat /var/lib/jitsi-meet/jibri-recorder-secret)"'" },"sinkType": "file"}'"""
)
machine.wait_until_succeeds(
"cat /var/log/jitsi/jibri/log.0.txt | grep -q 'File recording service transitioning from state Starting up to Running'", timeout=35
)
machine.succeed(
"""sleep 15 && curl -H "Content-Type: application/json" -X POST http://localhost:2222/jibri/api/v1.0/stopService -d '{"sessionId": "RecordTest","callParams":{"callUrlInfo":{"baseUrl": "https://machine","callName": "TestCall"}},"callLoginParams":{"domain": "recorder.machine", "username": "recorder", "password": "'"$(cat /var/lib/jitsi-meet/jibri-recorder-secret)"'" },"sinkType": "file"}'"""
)
machine.wait_until_succeeds(
"cat /var/log/jitsi/jibri/log.0.txt | grep -q 'Recording finalize script finished with exit value 0'", timeout=36
)
'';
})

View File

@ -0,0 +1,58 @@
{ lib, stdenv, fetchurl, dpkg, autoPatchelfHook, makeWrapper, electron_12,
alsa-lib, gtk3, libXScrnSaver, libXtst, mesa, nss }:
let
# Using Electron 12 to solve errors regarding threading
electron = electron_12;
in stdenv.mkDerivation rec {
pname = "pocket-casts";
version = "0.5.0";
src = fetchurl {
url = "https://github.com/felicianotech/pocket-casts-desktop-app/releases/download/v${version}/${pname}_${version}_amd64.deb";
sha256 = "sha256-frBtIxwRO/6k6j0itqN10t+9AyNadqXm8vC1YP960ts=";
};
nativeBuildInputs = [
dpkg
autoPatchelfHook
makeWrapper
];
buildInputs = [ alsa-lib gtk3 libXScrnSaver libXtst mesa nss ];
dontBuild = true;
dontConfigure = true;
unpackPhase = ''
dpkg-deb -x ${src} ./
'';
installPhase = ''
runHook preInstall
mv usr $out
mv opt $out
mv "$out/opt/Pocket Casts" $out/opt/pocket-casts
mv $out/share/icons/hicolor/0x0 $out/share/icons/hicolor/256x256
runHook postInstall
'';
postFixup = ''
substituteInPlace $out/share/applications/pocket-casts.desktop --replace '"/opt/Pocket Casts/pocket-casts"' $out/bin/pocket-casts
substituteInPlace $out/share/applications/pocket-casts.desktop --replace '/usr/share/icons/hicolor/0x0/apps/pocket-casts.png' "pocket-casts"
makeWrapper ${electron}/bin/electron \
$out/bin/pocket-casts \
--add-flags $out/opt/pocket-casts/resources/app.asar
'';
meta = with lib; {
description = "Pocket Casts webapp, packaged for the Linux Desktop";
homepage = "https://github.com/felicianotech/pocket-casts-desktop-app";
license = licenses.mit;
maintainers = with maintainers; [ wolfangaukang ];
platforms = [ "x86_64-linux" ];
};
}

View File

@ -36,13 +36,13 @@
mkDerivation rec {
pname = "strawberry";
version = "0.9.3";
version = "1.0.0";
src = fetchFromGitHub {
owner = "jonaski";
repo = pname;
rev = version;
sha256 = "sha256-OOdHsii6O4okVHDhrqCNJ7WVB0VKPs8q0AhEY+IvflE=";
sha256 = "sha256-m1BB5OIeCIQuJpxEO1xmb/Z8tzeHF31jYg67OpVWWRM=";
};
buildInputs = [

View File

@ -10,6 +10,7 @@
, LASzip
, libLAS
, pdal
, pcl
, qtbase
, qtsvg
, qttools
@ -19,30 +20,23 @@
mkDerivation rec {
pname = "cloudcompare";
version = "2.11.2"; # Remove below patch with the next version bump.
# Released version doesn't work with packaged PCL
# because it's too new. Considering that a release
# is a year ago it's unreasonable to wait for it.
version = "unstable-2021-10-14";
src = fetchFromGitHub {
owner = "CloudCompare";
repo = "CloudCompare";
rev = "v${version}";
sha256 = "0sb2h08iaf6zrf54sg6ql6wm63q5vq0kpd3gffdm26z8w6j6wv3s";
rev = "1f65ba63756e23291ae91ff52d04da468ade8249";
sha256 = "x1bDjFjXIl3r+yo1soWvRB+4KGP50/WBoGlrH013JQo=";
# As of writing includes (https://github.com/CloudCompare/CloudCompare/blob/a1c589c006fc325e8b560c77340809b9c7e7247a/.gitmodules):
# * libE57Format
# * PoissonRecon
# In a future version it will also contain
# * CCCoreLib
fetchSubmodules = true;
};
patches = [
# TODO: Remove with next CloudCompare release (see https://github.com/CloudCompare/CloudCompare/pull/1478)
(fetchpatch {
name = "CloudCompare-fix-for-PDAL-2.3.0.patch";
url = "https://github.com/CloudCompare/CloudCompare/commit/f3038dcdeb0491c4a653c2ee6fb017326eb676a3.patch";
sha256 = "0ca5ry987mcgsdawz5yd4xhbsdb5k44qws30srxymzx2djvamwli";
})
];
nativeBuildInputs = [
cmake
eigen # header-only
@ -55,6 +49,7 @@ mkDerivation rec {
LASzip
libLAS
pdal
pcl
qtbase
qtsvg
qttools
@ -63,15 +58,14 @@ mkDerivation rec {
];
cmakeFlags = [
# TODO: This will become -DCCCORELIB_USE_TBB=ON in a future version, see
# https://github.com/CloudCompare/CloudCompare/commit/f5a0c9fd788da26450f3fa488b2cf0e4a08d255f
"-DCOMPILE_CC_CORE_LIB_WITH_TBB=ON"
"-DCCCORELIB_USE_TBB=ON"
"-DOPTION_USE_DXF_LIB=ON"
"-DOPTION_USE_GDAL=ON"
"-DOPTION_USE_SHAPE_LIB=ON"
"-DPLUGIN_GL_QEDL=ON"
"-DPLUGIN_GL_QSSAO=ON"
"-DPLUGIN_IO_QADDITIONAL=ON"
"-DPLUGIN_IO_QCORE=ON"
"-DPLUGIN_IO_QCSV_MATRIX=ON"
@ -80,6 +74,8 @@ mkDerivation rec {
"-DPLUGIN_IO_QPDAL=ON" # required for .las/.laz support
"-DPLUGIN_IO_QPHOTOSCAN=ON"
"-DPLUGIN_IO_QRDB=OFF" # Riegl rdblib is proprietary; not packaged in nixpkgs
"-DPLUGIN_STANDARD_QPCL=ON" # Adds PCD import and export support
];
meta = with lib; {

View File

@ -27,19 +27,20 @@
mkDerivation rec {
pname = "calibre";
version = "5.29.0";
version = "5.30.0";
src = fetchurl {
url = "https://download.calibre-ebook.com/${version}/${pname}-${version}.tar.xz";
sha256 = "sha256-9ymHEpTHDUM3NAGoeSETzKRLKgJLRY4eEli6N5lbZug=";
};
# https://sources.debian.org/patches/calibre/5.29.0+dfsg-1
# https://sources.debian.org/patches/calibre/5.30.0+dfsg-1
patches = [
# allow for plugin update check, but no calibre version check
(fetchpatch {
name = "0001_only_plugin_update.patch";
url = "https://sources.debian.org/data/main/c/calibre/5.29.0%2Bdfsg-1/debian/patches/0001-only-plugin-update.patch";
url =
"https://sources.debian.org/data/main/c/calibre/${version}%2Bdfsg-1/debian/patches/0001-only-plugin-update.patch";
sha256 = "sha256-aGT8rJ/eQKAkmyHBWdY0ouZuWvDwtLVJU5xY6d3hY3k=";
})
]

View File

@ -1,7 +1,7 @@
{ lib, stdenv, fetchFromGitHub, cmake }:
stdenv.mkDerivation rec {
pname = "vulkan-headers";
version = "1.2.182.0";
version = "1.2.189.1";
nativeBuildInputs = [ cmake ];
@ -9,7 +9,7 @@ stdenv.mkDerivation rec {
owner = "KhronosGroup";
repo = "Vulkan-Headers";
rev = "sdk-${version}";
sha256 = "03j0kzq2qxhy0y82l10m8am26zrms2sjrdb1dcbpv9zh5vkxhcla";
sha256 = "1qggc7dv9jr83xr9w2h375wl3pz3rfgrk9hnrjmylkg9gz4p9q03";
};
meta = with lib; {

View File

@ -3,14 +3,14 @@
stdenv.mkDerivation rec {
pname = "vulkan-loader";
version = "1.2.182.0";
version = "1.2.189.1";
src = (assert version == vulkan-headers.version;
fetchFromGitHub {
owner = "KhronosGroup";
repo = "Vulkan-Loader";
rev = "sdk-${version}";
sha256 = "0gmr9q3a6s8xvaa74fs9zbi9c305i2b3rx768qvl79nhbdj8nc02";
sha256 = "1745fdzi0n5qj2s41q6z1y52cq8pwswvh1a32d3n7kl6bhksagp6";
});
nativeBuildInputs = [ cmake pkg-config ];

View File

@ -13,12 +13,12 @@
buildPythonPackage rec {
pname = "Shapely";
version = "1.7.1";
disabled = pythonOlder "3.5";
version = "1.8.0";
disabled = pythonOlder "3.6";
src = fetchPypi {
inherit pname version;
sha256 = "0adiz4jwmwxk7k1awqifb1a9bj5x4nx4gglb5dz9liam21674h8n";
sha256 = "177g8wxsgnphhhn4634n6ca1qrk462ijqlznpj5ry6d49ghpwc7m";
};
nativeBuildInputs = [
@ -38,16 +38,6 @@ buildPythonPackage rec {
GEOS_LIBRARY_PATH = "${geos}/lib/libgeos_c${stdenv.hostPlatform.extensions.sharedLibrary}";
patches = [
# Fix with geos 3.9. This patch will be part of the next release after 1.7.1
(fetchpatch {
url = "https://github.com/Toblerity/Shapely/commit/77879a954d24d1596f986d16ba3eff5e13861164.patch";
sha256 = "1w7ngjqbpf9vnvrfg4nyv34kckim9a60gvx20h6skc79xwihd4m5";
excludes = [
"tests/test_create_inconsistent_dimensionality.py"
"appveyor.yml"
".travis.yml"
];
})
# Patch to search form GOES .so/.dylib files in a Nix-aware way
(substituteAll {
src = ./library-paths.patch;

View File

@ -1,27 +1,45 @@
diff --git a/shapely/geos.py b/shapely/geos.py
index d5a67d2..19b7ffc 100644
index 4619732..1abdb5e 100644
--- a/shapely/geos.py
+++ b/shapely/geos.py
@@ -61,127 +61,17 @@ def load_dll(libname, fallbacks=None, mode=DEFAULT_MODE):
@@ -55,148 +55,21 @@ def load_dll(libname, fallbacks=None, mode=DEFAULT_MODE):
"Could not find lib {} or load any of its variants {}.".format(
libname, fallbacks or []))
-_lgeos = None
def exists_conda_env():
"""Does this module exist in a conda environment?"""
return os.path.exists(os.path.join(sys.prefix, 'conda-meta'))
-
-if sys.platform.startswith('linux'):
- # Test to see if we have a wheel repaired by 'auditwheel' containing its
- # own libgeos_c
- geos_whl_so = glob.glob(os.path.abspath(os.path.join(os.path.dirname(
- __file__), '.libs/libgeos_c-*.so.*')))
- if len(geos_whl_so) == 1:
- _lgeos = CDLL(geos_whl_so[0])
- # Test to see if we have a wheel repaired by auditwheel which contains its
- # own libgeos_c. Note: auditwheel 3.1 changed the location of libs.
- geos_whl_so = glob.glob(
- os.path.abspath(os.path.join(os.path.dirname(__file__), ".libs/libgeos*.so*"))
- ) or glob.glob(
- os.path.abspath(
- os.path.join(
- os.path.dirname(__file__), "..", "Shapely.libs", "libgeos*.so*"
- )
- )
- )
-
- if len(geos_whl_so) > 0:
- # We have observed problems with CDLL of libgeos_c not automatically
- # loading the sibling c++ library since the change made by auditwheel
- # 3.1, so we explicitly load them both.
- geos_whl_so = sorted(geos_whl_so)
- CDLL(geos_whl_so[0])
- _lgeos = CDLL(geos_whl_so[-1])
- LOG.debug("Found GEOS DLL: %r, using it.", _lgeos)
-
- elif hasattr(sys, 'frozen'):
- geos_pyinstaller_so = glob.glob(os.path.join(sys.prefix, 'libgeos_c-*.so.*'))
- if len(geos_pyinstaller_so) == 1:
- if len(geos_pyinstaller_so) >= 1:
- _lgeos = CDLL(geos_pyinstaller_so[0])
- LOG.debug("Found GEOS DLL: %r, using it.", _lgeos)
- elif os.getenv('CONDA_PREFIX', ''):
- elif exists_conda_env():
- # conda package.
- _lgeos = CDLL(os.path.join(sys.prefix, 'lib', 'libgeos_c.so'))
- else:
@ -30,11 +48,14 @@ index d5a67d2..19b7ffc 100644
- 'libgeos_c.so',
- ]
- _lgeos = load_dll('geos_c', fallbacks=alt_paths)
- # Necessary for environments with only libc.musl
- c_alt_paths = [
- 'libc.musl-x86_64.so.1'
- ]
- free = load_dll('c', fallbacks=c_alt_paths).free
-
+_lgeos = CDLL('@libgeos_c@')
+if sys.platform == 'darwin':
# ctypes.CDLL(None) internally calls dlopen(NULL), and as the dlopen
# manpage says, "If filename is NULL, then the returned handle is for the
# main program". This way we can let the linker do the work to figure out
# which libc Python is actually using.
free = CDLL(None).free
- free.argtypes = [c_void_p]
- free.restype = None
-
@ -52,7 +73,7 @@ index d5a67d2..19b7ffc 100644
- _lgeos = CDLL(geos_whl_dylib)
- LOG.debug("Found GEOS DLL: %r, using it.", _lgeos)
-
- elif os.getenv('CONDA_PREFIX', ''):
- elif exists_conda_env():
- # conda package.
- _lgeos = CDLL(os.path.join(sys.prefix, 'lib', 'libgeos_c.dylib'))
- else:
@ -63,9 +84,11 @@ index d5a67d2..19b7ffc 100644
- os.environ['RESOURCEPATH'], '..', 'Frameworks',
- 'libgeos_c.dylib')]
- except KeyError:
- # binary from pyinstaller
- alt_paths = [
- os.path.join(sys.executable, 'libgeos_c.dylib')]
- # binary from pyinstaller
- os.path.join(sys.executable, 'libgeos_c.dylib'),
- # .app from cx_Freeze
- os.path.join(os.path.dirname(sys.executable), 'libgeos_c.1.dylib')]
- if hasattr(sys, '_MEIPASS'):
- alt_paths.append(
- os.path.join(sys._MEIPASS, 'libgeos_c.1.dylib'))
@ -75,23 +98,22 @@ index d5a67d2..19b7ffc 100644
- "/Library/Frameworks/GEOS.framework/Versions/Current/GEOS",
- # macports
- '/opt/local/lib/libgeos_c.dylib',
- # homebrew
- # homebrew Intel
- '/usr/local/lib/libgeos_c.dylib',
- # homebrew Apple Silicon
- '/opt/homebrew/lib/libgeos_c.dylib',
- ]
- _lgeos = load_dll('geos_c', fallbacks=alt_paths)
-
- # ctypes.CDLL(None) internally calls dlopen(NULL), and as the dlopen
- # manpage says, "If filename is NULL, then the returned handle is for the
- # main program". This way we can let the linker do the work to figure out
- # which libc Python is actually using.
- free = CDLL(None).free
- free.argtypes = [c_void_p]
- free.restype = None
-
-elif sys.platform == 'win32':
- if os.getenv('CONDA_PREFIX', ''):
- _conda_dll_path = os.path.join(sys.prefix, 'Library', 'bin', 'geos_c.dll')
- if exists_conda_env() and os.path.exists(_conda_dll_path):
- # conda package.
- _lgeos = CDLL(os.path.join(sys.prefix, 'Library', 'bin', 'geos_c.dll'))
- _lgeos = CDLL(_conda_dll_path)
- else:
- try:
- egg_dlls = os.path.abspath(
@ -119,21 +141,15 @@ index d5a67d2..19b7ffc 100644
-
-elif sys.platform == 'sunos5':
- _lgeos = load_dll('geos_c', fallbacks=['libgeos_c.so.1', 'libgeos_c.so'])
- free = CDLL('libc.so.1').free
- free.restype = None
- free.argtypes = [c_void_p]
- free.restype = None
-
-else: # other *nix systems
- _lgeos = load_dll('geos_c', fallbacks=['libgeos_c.so.1', 'libgeos_c.so'])
- free = load_dll('c', fallbacks=['libc.so.6']).free
- free = CDLL(None).free
- free.argtypes = [c_void_p]
- free.restype = None
+_lgeos = CDLL('@libgeos_c@')
+if sys.platform == 'darwin':
+ # ctypes.CDLL(None) internally calls dlopen(NULL), and as the dlopen
+ # manpage says, "If filename is NULL, then the returned handle is for the
+ # main program". This way we can let the linker do the work to figure out
+ # which libc Python is actually using.
+ free = CDLL(None).free
+else:
+ free = CDLL('@libc@').free
+free.argtypes = [c_void_p]
@ -142,20 +158,18 @@ index d5a67d2..19b7ffc 100644
def _geos_version():
diff --git a/tests/test_dlls.py b/tests/test_dlls.py
index 35f9cc2..3dfcaac 100644
index c71da8e..fae9da6 100644
--- a/tests/test_dlls.py
+++ b/tests/test_dlls.py
@@ -12,12 +12,7 @@ class LoadingTestCase(unittest.TestCase):
@@ -12,10 +12,4 @@ class LoadingTestCase(unittest.TestCase):
@unittest.skipIf(sys.platform == "win32", "FIXME: adapt test for win32")
def test_fallbacks(self):
load_dll('geos_c', fallbacks=[
- os.path.join(sys.prefix, "lib", "libgeos_c.dylib"), # anaconda (Mac OS X)
- '/opt/local/lib/libgeos_c.dylib', # MacPorts
- '/usr/local/lib/libgeos_c.dylib', # homebrew (Mac OS X)
- '/opt/local/lib/libgeos_c.dylib', # MacPorts
- '/usr/local/lib/libgeos_c.dylib', # homebrew (Mac OS X)
- '/opt/homebrew/lib/libgeos_c.dylib', # homebrew (macOS)
- os.path.join(sys.prefix, "lib", "libgeos_c.so"), # anaconda (Linux)
- 'libgeos_c.so.1',
- 'libgeos_c.so'])
+ '@libgeos_c@'])
def test_suite():

View File

@ -23,8 +23,8 @@ let
src = fetchFromGitHub {
owner = "KhronosGroup";
repo = "SPIRV-Headers";
rev = "dafead1765f6c1a5f9f8a76387dcb2abe4e54acd"; # pin
sha256 = "1kj6wcx9y7r1xyg8n7ai2pzrg9ira7hbakr45wh5p4zyxh0m45n8";
rev = "449bc986ba6f4c5e10e32828783f9daef2a77644"; # pin
sha256 = "1249pvk4iz09caxm3kwckzwcx2hbw97cr2h8h770l6c061kb14z5";
};
});
localGlslang = (glslang.override {
@ -32,8 +32,8 @@ let
src = fetchFromGitHub {
owner = "KhronosGroup";
repo = "SPIRV-Tools";
rev = "dc72924cb31cd9f3dbc3eb47e9d926cf641e3a07"; # pin
sha256 = "0pxgbq6xapw9hgrzb3rk5cylzgg1y1bkqz5wxzwqls63pwga5912";
rev = "1fbed83c8aab8517d821fcb4164c08567951938f"; # pin
sha256 = "0faz468bnxpvbg1np13gnbwf35s0hl9ad7r2p9wi9si5k336qjmj";
};
});
argSpirv-headers = localSpirvHeaders;
@ -41,20 +41,20 @@ let
src = fetchFromGitHub {
owner = "KhronosGroup";
repo = "glslang";
rev = "18eef33bd7a4bf5ad8c69f99cb72022608cf6e73"; # pin
sha256 = "0wwj7q509pkp8wj7120g1n2ddl4x2r03ljf5czd9794ji6yraidn";
rev = "2fb89a0072ae7316af1c856f22663fde4928128a"; # pin
sha256 = "04kkmphv0a5mb5javhmkc4kab8r0n107kb7djakj5h238ni2j7q9";
};
});
robin-hood-hashing = fetchFromGitHub {
owner = "martinus";
repo = "robin-hood-hashing";
rev = "3.11.2"; # pin
sha256 = "0103mnqpmka1smy0arnrbihlvi7i8xr5im0px8wn4faw4flikkcm";
rev = "3.11.3"; # pin
sha256 = "1gm3lwjkh6h8m7lfykzd0jzhfqjmjchindkmxc008rwvxafsd1pl";
};
in
stdenv.mkDerivation rec {
pname = "vulkan-validation-layers";
version = "1.2.182.0";
version = "1.2.189.1";
# If we were to use "dev" here instead of headers, the setupHook would be
# placed in that output instead of "out".
@ -66,7 +66,7 @@ stdenv.mkDerivation rec {
owner = "KhronosGroup";
repo = "Vulkan-ValidationLayers";
rev = "sdk-${version}";
sha256 = "1fnmb7vbm7y1x67bf1xiwdrpj9j4lkvhk9xhb6hp6x2aryvcyrnc";
sha256 = "0a5plvvffidgnqh5ymq315xscl08w298sn9da48b3x2rdbdqgw90";
});
# Include absolute paths to layer libraries in their associated

View File

@ -0,0 +1,31 @@
{ lib, stdenv, fetchFromGitHub, bison, libressl, libevent }:
stdenv.mkDerivation rec {
pname = "gmid";
version = "1.7.5";
src = fetchFromGitHub {
owner = "omar-polo";
repo = pname;
rev = version;
sha256 = "sha256-BBd0AL5jRRslxzDnxcTZRR+8J5D23NAQ7mp9K+leXAQ=";
};
nativeBuildInputs = [ bison ];
buildInputs = [ libressl libevent ];
configurePhase = ''
runHook preConfigure
./configure PREFIX=$out
runHook postConfigure
'';
meta = with lib; {
description = "Simple and secure Gemini server";
homepage = "https://gmid.omarpolo.com/";
license = licenses.isc;
maintainers = with maintainers; [ sikmir ];
platforms = platforms.linux;
};
}

View File

@ -1,5 +1,16 @@
{ lib, stdenv, fetchurl, dpkg, jre_headless, makeWrapper }:
{ lib, stdenv, fetchurl, dpkg, jre8_headless, makeWrapper, writeText, xorg }:
let
xorgModulePaths = writeText "module-paths" ''
Section "Files"
ModulePath "${xorg.xorgserver}/lib/xorg/modules
ModulePath "${xorg.xorgserver}/lib/xorg/extensions
ModulePath "${xorg.xorgserver}/lib/xorg/drivers
ModulePath "${xorg.xf86videodummy}/lib/xorg/modules/drivers
EndSection
'';
in
stdenv.mkDerivation rec {
pname = "jibri";
version = "8.0-93-g51fe7a2";
@ -19,7 +30,9 @@ stdenv.mkDerivation rec {
mv etc/jitsi/jibri/* $out/etc/jitsi/jibri/
mv opt/jitsi/jibri/* $out/opt/jitsi/jibri/
makeWrapper ${jre_headless}/bin/java $out/bin/jibri --add-flags "-jar $out/opt/jitsi/jibri/jibri.jar"
cat '${xorgModulePaths}' >> $out/etc/jitsi/jibri/xorg-video-dummy.conf
makeWrapper ${jre8_headless}/bin/java $out/bin/jibri --add-flags "-jar $out/opt/jitsi/jibri/jibri.jar"
runHook postInstall
'';

View File

@ -2,14 +2,14 @@
stdenv.mkDerivation rec {
pname = "vulkan-extension-layer";
version = "1.2.182.0";
version = "1.2.189.1";
src = (assert version == vulkan-headers.version;
fetchFromGitHub {
owner = "KhronosGroup";
repo = "Vulkan-ExtensionLayer";
rev = "sdk-${version}";
sha256 = "0by2kp48jbd55xk26rmlvc4wm77g1zvidx8czn1587ng2yzi7acr";
sha256 = "0qi9ps215pmrh8vgi81wvlzjyxs44bama2x3d43a1bbvcyp9s6kp";
});
nativeBuildInputs = [ cmake jq ];

View File

@ -23,14 +23,14 @@
stdenv.mkDerivation rec {
pname = "vulkan-tools-lunarg";
# The version must match that in vulkan-headers
version = "1.2.182.0";
version = "1.2.189.1";
src = (assert version == vulkan-headers.version;
fetchFromGitHub {
owner = "LunarG";
repo = "VulkanTools";
rev = "sdk-${version}";
sha256 = "1b7762fcbakfvj2b2l68qj25pc7pz9jhfabf1x80b9w3q205hl2f";
sha256 = "0431dgplv5wiz8bj0ja91mbpc2qhjgdhqhrgaqarvyvjr1f7jw52";
fetchSubmodules = true;
});

View File

@ -3,7 +3,7 @@
stdenv.mkDerivation rec {
pname = "vulkan-tools";
version = "1.2.182.0";
version = "1.2.189.1";
# It's not strictly necessary to have matching versions here, however
# since we're using the SDK version we may as well be consistent with
@ -13,7 +13,7 @@ stdenv.mkDerivation rec {
owner = "KhronosGroup";
repo = "Vulkan-Tools";
rev = "sdk-${version}";
sha256 = "028l2l7jx4443k8207q8jmjq1mnnm9kgyl2417jrkrvylcbv8ji9";
sha256 = "0izmzyj6gb51d71vbdjcgd9qw34aidvbmz0mg4bkc13n48w8s9vj";
});
nativeBuildInputs = [ cmake ];

View File

@ -11,13 +11,13 @@ assert systemdSupport -> stdenv.isLinux;
stdenv.mkDerivation rec {
pname = "htop";
version = "3.1.0";
version = "3.1.1";
src = fetchFromGitHub {
owner = "htop-dev";
repo = pname;
rev = version;
sha256 = "sha256-/48Ca7JPzhPS4eYsPbwbSVcx9aS1f0LHcqsbNVWL+9k=";
sha256 = "JnpuBa09U086wWp0OtsDnStF4aLjhvtEj371u5XFtqc=";
};
nativeBuildInputs = [ autoreconfHook ];

View File

@ -2,11 +2,11 @@
stdenv.mkDerivation rec {
pname = "LanguageTool";
version = "5.4";
version = "5.5";
src = fetchzip {
url = "https://www.languagetool.org/download/${pname}-${version}.zip";
sha256 = "sha256-2khadADfzwkW+J0uafPWJ6xUQRSQDm8seiBHueQGmKI=";
sha256 = "sha256-v9p+G1aSzrvuoJLfRqWQXGVJ+2vysxdTgrD+ZUt6Yg4=";
};
nativeBuildInputs = [ makeWrapper ];
buildInputs = [ jre ];

View File

@ -1723,6 +1723,8 @@ with pkgs;
glasgow = with python3Packages; toPythonApplication glasgow;
gmid = callPackage ../servers/gemini/gmid { };
gmni = callPackage ../applications/networking/browsers/gmni { };
gmnisrv = callPackage ../servers/gemini/gmnisrv { };
@ -3402,6 +3404,8 @@ with pkgs;
pn = callPackage ../tools/text/pn { };
pocket-casts = callPackage ../applications/audio/pocket-casts { };
poweralertd = callPackage ../tools/misc/poweralertd { };
ps_mem = callPackage ../tools/system/ps_mem { };