Merge staging-next into staging
This commit is contained in:
commit
e5fe4acb71
27 changed files with 812 additions and 107 deletions
|
@ -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";
|
||||
|
|
|
@ -145,6 +145,7 @@ with lib.maintainers; {
|
|||
|
||||
jitsi = {
|
||||
members = [
|
||||
cleeyv
|
||||
petabyteboy
|
||||
ryantm
|
||||
yuka
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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).
|
||||
|
|
|
@ -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
|
||||
|
|
417
nixos/modules/services/networking/jibri/default.nix
Normal file
417
nixos/modules/services/networking/jibri/default.nix
Normal 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;
|
||||
}
|
|
@ -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
|
|
@ -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.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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
69
nixos/tests/jibri.nix
Normal 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
|
||||
)
|
||||
'';
|
||||
})
|
58
pkgs/applications/audio/pocket-casts/default.nix
Normal file
58
pkgs/applications/audio/pocket-casts/default.nix
Normal 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" ];
|
||||
};
|
||||
}
|
|
@ -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 = [
|
||||
|
|
|
@ -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; {
|
||||
|
|
|
@ -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=";
|
||||
})
|
||||
]
|
||||
|
|
|
@ -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; {
|
||||
|
|
|
@ -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 ];
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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():
|
||||
|
|
|
@ -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
|
||||
|
|
31
pkgs/servers/gemini/gmid/default.nix
Normal file
31
pkgs/servers/gemini/gmid/default.nix
Normal 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;
|
||||
};
|
||||
}
|
|
@ -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
|
||||
'';
|
||||
|
|
|
@ -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 ];
|
||||
|
|
|
@ -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;
|
||||
});
|
||||
|
||||
|
|
|
@ -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 ];
|
||||
|
|
|
@ -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 ];
|
||||
|
|
|
@ -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 ];
|
||||
|
|
|
@ -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 { };
|
||||
|
|
Loading…
Reference in a new issue