Merge master into staging-next

authored by github-actions[bot] and committed by GitHub 7e0da80e 07534976

+812 -107
+6
maintainers/maintainer-list.nix
··· 2143 2143 githubId = 199180; 2144 2144 name = "Claes Wallin"; 2145 2145 }; 2146 + cleeyv = { 2147 + email = "cleeyv@riseup.net"; 2148 + github = "cleeyv"; 2149 + githubId = 71959829; 2150 + name = "Cleeyv"; 2151 + }; 2146 2152 cleverca22 = { 2147 2153 email = "cleverca22@gmail.com"; 2148 2154 matrix = "@cleverca22:matrix.org";
+1
maintainers/team-list.nix
··· 145 145 146 146 jitsi = { 147 147 members = [ 148 + cleeyv 148 149 petabyteboy 149 150 ryantm 150 151 yuka
+8
nixos/doc/manual/from_md/release-notes/rl-2111.section.xml
··· 138 138 </listitem> 139 139 <listitem> 140 140 <para> 141 + <link xlink:href="https://github.com/jitsi/jibri">Jibri</link>, 142 + a service for recording or streaming a Jitsi Meet conference. 143 + Available as 144 + <link xlink:href="options.html#opt-services.jibri.enable">services.jibri</link>. 145 + </para> 146 + </listitem> 147 + <listitem> 148 + <para> 141 149 <link xlink:href="https://www.isc.org/kea/">Kea</link>, ISCs 142 150 2nd generation DHCP and DDNS server suite. Available at 143 151 <link xlink:href="options.html#opt-services.kea">services.kea</link>.
+2
nixos/doc/manual/release-notes/rl-2111.section.md
··· 45 45 46 46 - [geoipupdate](https://github.com/maxmind/geoipupdate), a GeoIP database updater from MaxMind. Available as [services.geoipupdate](options.html#opt-services.geoipupdate.enable). 47 47 48 + - [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). 49 + 48 50 - [Kea](https://www.isc.org/kea/), ISCs 2nd generation DHCP and DDNS server suite. Available at [services.kea](options.html#opt-services.kea). 49 51 50 52 - [owncast](https://owncast.online/), self-hosted video live streaming solution. Available at [services.owncast](options.html#opt-services.owncast).
+1
nixos/modules/module-list.nix
··· 756 756 ./services/networking/iscsi/root-initiator.nix 757 757 ./services/networking/iscsi/target.nix 758 758 ./services/networking/iwd.nix 759 + ./services/networking/jibri/default.nix 759 760 ./services/networking/jicofo.nix 760 761 ./services/networking/jitsi-videobridge.nix 761 762 ./services/networking/kea.nix
+417
nixos/modules/services/networking/jibri/default.nix
··· 1 + { config, lib, pkgs, ... }: 2 + 3 + with lib; 4 + 5 + let 6 + cfg = config.services.jibri; 7 + 8 + # Copied from the jitsi-videobridge.nix file. 9 + toHOCON = x: 10 + if isAttrs x && x ? __hocon_envvar then ("\${" + x.__hocon_envvar + "}") 11 + else if isAttrs x then "{${ concatStringsSep "," (mapAttrsToList (k: v: ''"${k}":${toHOCON v}'') x) }}" 12 + else if isList x then "[${ concatMapStringsSep "," toHOCON x }]" 13 + else builtins.toJSON x; 14 + 15 + # We're passing passwords in environment variables that have names generated 16 + # from an attribute name, which may not be a valid bash identifier. 17 + toVarName = s: "XMPP_PASSWORD_" + stringAsChars (c: if builtins.match "[A-Za-z0-9]" c != null then c else "_") s; 18 + 19 + defaultJibriConfig = { 20 + id = ""; 21 + single-use-mode = false; 22 + 23 + api = { 24 + http.external-api-port = 2222; 25 + http.internal-api-port = 3333; 26 + 27 + xmpp.environments = flip mapAttrsToList cfg.xmppEnvironments (name: env: { 28 + inherit name; 29 + 30 + xmpp-server-hosts = env.xmppServerHosts; 31 + xmpp-domain = env.xmppDomain; 32 + control-muc = { 33 + domain = env.control.muc.domain; 34 + room-name = env.control.muc.roomName; 35 + nickname = env.control.muc.nickname; 36 + }; 37 + 38 + control-login = { 39 + domain = env.control.login.domain; 40 + username = env.control.login.username; 41 + password.__hocon_envvar = toVarName "${name}_control"; 42 + }; 43 + 44 + call-login = { 45 + domain = env.call.login.domain; 46 + username = env.call.login.username; 47 + password.__hocon_envvar = toVarName "${name}_call"; 48 + }; 49 + 50 + strip-from-room-domain = env.stripFromRoomDomain; 51 + usage-timeout = env.usageTimeout; 52 + trust-all-xmpp-certs = env.disableCertificateVerification; 53 + }); 54 + }; 55 + 56 + recording = { 57 + recordings-directory = "/tmp/recordings"; 58 + finalize-script = "${cfg.finalizeScript}"; 59 + }; 60 + 61 + streaming.rtmp-allow-list = [ ".*" ]; 62 + 63 + chrome.flags = [ 64 + "--use-fake-ui-for-media-stream" 65 + "--start-maximized" 66 + "--kiosk" 67 + "--enabled" 68 + "--disable-infobars" 69 + "--autoplay-policy=no-user-gesture-required" 70 + ] 71 + ++ lists.optional cfg.ignoreCert 72 + "--ignore-certificate-errors"; 73 + 74 + 75 + stats.enable-stats-d = true; 76 + webhook.subscribers = [ ]; 77 + 78 + jwt-info = { }; 79 + 80 + call-status-checks = { 81 + no-media-timout = "30 seconds"; 82 + all-muted-timeout = "10 minutes"; 83 + default-call-empty-timout = "30 seconds"; 84 + }; 85 + }; 86 + # Allow overriding leaves of the default config despite types.attrs not doing any merging. 87 + jibriConfig = recursiveUpdate defaultJibriConfig cfg.config; 88 + configFile = pkgs.writeText "jibri.conf" (toHOCON { jibri = jibriConfig; }); 89 + in 90 + { 91 + options.services.jibri = with types; { 92 + 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>"; 93 + config = mkOption { 94 + type = attrs; 95 + default = { }; 96 + description = '' 97 + Jibri configuration. 98 + See <link xlink:href="https://github.com/jitsi/jibri/blob/master/src/main/resources/reference.conf" /> 99 + for default configuration with comments. 100 + ''; 101 + }; 102 + 103 + finalizeScript = mkOption { 104 + type = types.path; 105 + default = pkgs.writeScript "finalize_recording.sh" '' 106 + #!/bin/sh 107 + 108 + RECORDINGS_DIR=$1 109 + 110 + echo "This is a dummy finalize script" > /tmp/finalize.out 111 + echo "The script was invoked with recordings directory $RECORDINGS_DIR." >> /tmp/finalize.out 112 + echo "You should put any finalize logic (renaming, uploading to a service" >> /tmp/finalize.out 113 + echo "or storage provider, etc.) in this script" >> /tmp/finalize.out 114 + 115 + exit 0 116 + ''; 117 + defaultText = literalExpression '' 118 + pkgs.writeScript "finalize_recording.sh" '''''' 119 + #!/bin/sh 120 + 121 + RECORDINGS_DIR=$1 122 + 123 + echo "This is a dummy finalize script" > /tmp/finalize.out 124 + echo "The script was invoked with recordings directory $RECORDINGS_DIR." >> /tmp/finalize.out 125 + echo "You should put any finalize logic (renaming, uploading to a service" >> /tmp/finalize.out 126 + echo "or storage provider, etc.) in this script" >> /tmp/finalize.out 127 + 128 + exit 0 129 + ''''''; 130 + ''; 131 + example = literalExpression '' 132 + pkgs.writeScript "finalize_recording.sh" '''''' 133 + #!/bin/sh 134 + RECORDINGS_DIR=$1 135 + ${pkgs.rclone}/bin/rclone copy $RECORDINGS_DIR RCLONE_REMOTE:jibri-recordings/ -v --log-file=/var/log/jitsi/jibri/recording-upload.txt 136 + exit 0 137 + ''''''; 138 + ''; 139 + description = '' 140 + This script runs when jibri finishes recording a video of a conference. 141 + ''; 142 + }; 143 + 144 + ignoreCert = mkOption { 145 + type = bool; 146 + default = false; 147 + example = true; 148 + description = '' 149 + Whether to enable the flag "--ignore-certificate-errors" for the Chromium browser opened by Jibri. 150 + Intended for use in automated tests or anywhere else where using a verified cert for Jitsi-Meet is not possible. 151 + ''; 152 + }; 153 + 154 + xmppEnvironments = mkOption { 155 + description = '' 156 + XMPP servers to connect to. 157 + ''; 158 + example = literalExpression '' 159 + "jitsi-meet" = { 160 + xmppServerHosts = [ "localhost" ]; 161 + xmppDomain = config.services.jitsi-meet.hostName; 162 + 163 + control.muc = { 164 + domain = "internal.''${config.services.jitsi-meet.hostName}"; 165 + roomName = "JibriBrewery"; 166 + nickname = "jibri"; 167 + }; 168 + 169 + control.login = { 170 + domain = "auth.''${config.services.jitsi-meet.hostName}"; 171 + username = "jibri"; 172 + passwordFile = "/var/lib/jitsi-meet/jibri-auth-secret"; 173 + }; 174 + 175 + call.login = { 176 + domain = "recorder.''${config.services.jitsi-meet.hostName}"; 177 + username = "recorder"; 178 + passwordFile = "/var/lib/jitsi-meet/jibri-recorder-secret"; 179 + }; 180 + 181 + usageTimeout = "0"; 182 + disableCertificateVerification = true; 183 + stripFromRoomDomain = "conference."; 184 + }; 185 + ''; 186 + default = { }; 187 + type = attrsOf (submodule ({ name, ... }: { 188 + options = { 189 + xmppServerHosts = mkOption { 190 + type = listOf str; 191 + example = [ "xmpp.example.org" ]; 192 + description = '' 193 + Hostnames of the XMPP servers to connect to. 194 + ''; 195 + }; 196 + xmppDomain = mkOption { 197 + type = str; 198 + example = "xmpp.example.org"; 199 + description = '' 200 + The base XMPP domain. 201 + ''; 202 + }; 203 + control.muc.domain = mkOption { 204 + type = str; 205 + description = '' 206 + The domain part of the MUC to connect to for control. 207 + ''; 208 + }; 209 + control.muc.roomName = mkOption { 210 + type = str; 211 + default = "JibriBrewery"; 212 + description = '' 213 + The room name of the MUC to connect to for control. 214 + ''; 215 + }; 216 + control.muc.nickname = mkOption { 217 + type = str; 218 + default = "jibri"; 219 + description = '' 220 + The nickname for this Jibri instance in the MUC. 221 + ''; 222 + }; 223 + control.login.domain = mkOption { 224 + type = str; 225 + description = '' 226 + The domain part of the JID for this Jibri instance. 227 + ''; 228 + }; 229 + control.login.username = mkOption { 230 + type = str; 231 + default = "jvb"; 232 + description = '' 233 + User part of the JID. 234 + ''; 235 + }; 236 + control.login.passwordFile = mkOption { 237 + type = str; 238 + example = "/run/keys/jibri-xmpp1"; 239 + description = '' 240 + File containing the password for the user. 241 + ''; 242 + }; 243 + 244 + call.login.domain = mkOption { 245 + type = str; 246 + example = "recorder.xmpp.example.org"; 247 + description = '' 248 + The domain part of the JID for the recorder. 249 + ''; 250 + }; 251 + call.login.username = mkOption { 252 + type = str; 253 + default = "recorder"; 254 + description = '' 255 + User part of the JID for the recorder. 256 + ''; 257 + }; 258 + call.login.passwordFile = mkOption { 259 + type = str; 260 + example = "/run/keys/jibri-recorder-xmpp1"; 261 + description = '' 262 + File containing the password for the user. 263 + ''; 264 + }; 265 + disableCertificateVerification = mkOption { 266 + type = bool; 267 + default = false; 268 + description = '' 269 + Whether to skip validation of the server's certificate. 270 + ''; 271 + }; 272 + 273 + stripFromRoomDomain = mkOption { 274 + type = str; 275 + default = "0"; 276 + example = "conference."; 277 + description = '' 278 + The prefix to strip from the room's JID domain to derive the call URL. 279 + ''; 280 + }; 281 + usageTimeout = mkOption { 282 + type = str; 283 + default = "0"; 284 + example = "1 hour"; 285 + description = '' 286 + The duration that the Jibri session can be. 287 + A value of zero means indefinitely. 288 + ''; 289 + }; 290 + }; 291 + 292 + config = 293 + let 294 + nick = mkDefault (builtins.replaceStrings [ "." ] [ "-" ] ( 295 + config.networking.hostName + optionalString (config.networking.domain != null) ".${config.networking.domain}" 296 + )); 297 + in 298 + { 299 + call.login.username = nick; 300 + control.muc.nickname = nick; 301 + }; 302 + })); 303 + }; 304 + }; 305 + 306 + config = mkIf cfg.enable { 307 + users.groups.jibri = { }; 308 + users.groups.plugdev = { }; 309 + users.users.jibri = { 310 + isSystemUser = true; 311 + group = "jibri"; 312 + home = "/var/lib/jibri"; 313 + extraGroups = [ "jitsi-meet" "adm" "audio" "video" "plugdev" ]; 314 + }; 315 + 316 + systemd.services.jibri-xorg = { 317 + description = "Jitsi Xorg Process"; 318 + 319 + after = [ "network.target" ]; 320 + wantedBy = [ "jibri.service" "jibri-icewm.service" ]; 321 + 322 + preStart = '' 323 + cp --no-preserve=mode,ownership ${pkgs.jibri}/etc/jitsi/jibri/* /var/lib/jibri 324 + mv /var/lib/jibri/{,.}asoundrc 325 + ''; 326 + 327 + environment.DISPLAY = ":0"; 328 + serviceConfig = { 329 + Type = "simple"; 330 + 331 + User = "jibri"; 332 + Group = "jibri"; 333 + KillMode = "process"; 334 + Restart = "on-failure"; 335 + RestartPreventExitStatus = 255; 336 + 337 + StateDirectory = "jibri"; 338 + 339 + 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"; 340 + }; 341 + }; 342 + 343 + systemd.services.jibri-icewm = { 344 + description = "Jitsi Window Manager"; 345 + 346 + requires = [ "jibri-xorg.service" ]; 347 + after = [ "jibri-xorg.service" ]; 348 + wantedBy = [ "jibri.service" ]; 349 + 350 + environment.DISPLAY = ":0"; 351 + serviceConfig = { 352 + Type = "simple"; 353 + 354 + User = "jibri"; 355 + Group = "jibri"; 356 + Restart = "on-failure"; 357 + RestartPreventExitStatus = 255; 358 + 359 + StateDirectory = "jibri"; 360 + 361 + ExecStart = "${pkgs.icewm}/bin/icewm-session"; 362 + }; 363 + }; 364 + 365 + systemd.services.jibri = { 366 + description = "Jibri Process"; 367 + 368 + requires = [ "jibri-icewm.service" "jibri-xorg.service" ]; 369 + after = [ "network.target" ]; 370 + wantedBy = [ "multi-user.target" ]; 371 + 372 + path = with pkgs; [ chromedriver chromium ffmpeg-full ]; 373 + 374 + script = (concatStrings (mapAttrsToList 375 + (name: env: '' 376 + export ${toVarName "${name}_control"}=$(cat ${env.control.login.passwordFile}) 377 + export ${toVarName "${name}_call"}=$(cat ${env.call.login.passwordFile}) 378 + '') 379 + cfg.xmppEnvironments)) 380 + + '' 381 + ${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 382 + ''; 383 + 384 + environment.HOME = "/var/lib/jibri"; 385 + 386 + serviceConfig = { 387 + Type = "simple"; 388 + 389 + User = "jibri"; 390 + Group = "jibri"; 391 + Restart = "always"; 392 + RestartPreventExitStatus = 255; 393 + 394 + StateDirectory = "jibri"; 395 + }; 396 + }; 397 + 398 + systemd.tmpfiles.rules = [ 399 + "d /var/log/jitsi/jibri 755 jibri jibri" 400 + ]; 401 + 402 + 403 + 404 + # Configure Chromium to not show the "Chrome is being controlled by automatic test software" message. 405 + environment.etc."chromium/policies/managed/managed_policies.json".text = builtins.toJSON { CommandLineFlagSecurityWarningsEnabled = false; }; 406 + 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." ]; 407 + 408 + boot = { 409 + extraModprobeConfig = '' 410 + options snd-aloop enable=1,1,1,1,1,1,1,1 411 + ''; 412 + kernelModules = [ "snd-aloop" ]; 413 + }; 414 + }; 415 + 416 + meta.maintainers = lib.teams.jitsi.members; 417 + }
+32
nixos/modules/services/networking/jibri/logging.properties-journal
··· 1 + handlers = java.util.logging.FileHandler 2 + 3 + java.util.logging.FileHandler.level = FINE 4 + java.util.logging.FileHandler.pattern = /var/log/jitsi/jibri/log.%g.txt 5 + java.util.logging.FileHandler.formatter = net.java.sip.communicator.util.ScLogFormatter 6 + java.util.logging.FileHandler.count = 10 7 + java.util.logging.FileHandler.limit = 10000000 8 + 9 + org.jitsi.jibri.capture.ffmpeg.util.FfmpegFileHandler.level = FINE 10 + org.jitsi.jibri.capture.ffmpeg.util.FfmpegFileHandler.pattern = /var/log/jitsi/jibri/ffmpeg.%g.txt 11 + org.jitsi.jibri.capture.ffmpeg.util.FfmpegFileHandler.formatter = net.java.sip.communicator.util.ScLogFormatter 12 + org.jitsi.jibri.capture.ffmpeg.util.FfmpegFileHandler.count = 10 13 + org.jitsi.jibri.capture.ffmpeg.util.FfmpegFileHandler.limit = 10000000 14 + 15 + org.jitsi.jibri.sipgateway.pjsua.util.PjsuaFileHandler.level = FINE 16 + org.jitsi.jibri.sipgateway.pjsua.util.PjsuaFileHandler.pattern = /var/log/jitsi/jibri/pjsua.%g.txt 17 + org.jitsi.jibri.sipgateway.pjsua.util.PjsuaFileHandler.formatter = net.java.sip.communicator.util.ScLogFormatter 18 + org.jitsi.jibri.sipgateway.pjsua.util.PjsuaFileHandler.count = 10 19 + org.jitsi.jibri.sipgateway.pjsua.util.PjsuaFileHandler.limit = 10000000 20 + 21 + org.jitsi.jibri.selenium.util.BrowserFileHandler.level = FINE 22 + org.jitsi.jibri.selenium.util.BrowserFileHandler.pattern = /var/log/jitsi/jibri/browser.%g.txt 23 + org.jitsi.jibri.selenium.util.BrowserFileHandler.formatter = net.java.sip.communicator.util.ScLogFormatter 24 + org.jitsi.jibri.selenium.util.BrowserFileHandler.count = 10 25 + org.jitsi.jibri.selenium.util.BrowserFileHandler.limit = 10000000 26 + 27 + org.jitsi.level = FINE 28 + org.jitsi.jibri.config.level = INFO 29 + 30 + org.glassfish.level = INFO 31 + org.osgi.level = INFO 32 + org.jitsi.xmpp.level = INFO
+67 -6
nixos/modules/services/web-apps/jitsi-meet.nix
··· 38 38 }; 39 39 bosh = "//${cfg.hostName}/http-bind"; 40 40 websocket = "wss://${cfg.hostName}/xmpp-websocket"; 41 + 42 + fileRecordingsEnabled = true; 43 + liveStreamingEnabled = true; 44 + hiddenDomain = "recorder.${cfg.hostName}"; 41 45 }; 42 46 in 43 47 { ··· 48 52 type = str; 49 53 example = "meet.example.org"; 50 54 description = '' 51 - Hostname of the Jitsi Meet instance. 55 + FQDN of the Jitsi Meet instance. 52 56 ''; 53 57 }; 54 58 ··· 130 134 ''; 131 135 }; 132 136 137 + jibri.enable = mkOption { 138 + type = bool; 139 + default = false; 140 + description = '' 141 + Whether to enable a Jibri instance and configure it to connect to Prosody. 142 + 143 + Additional configuration is possible with <option>services.jibri</option>, and 144 + <option>services.jibri.finalizeScript</option> is especially useful. 145 + ''; 146 + }; 147 + 133 148 nginx.enable = mkOption { 134 149 type = bool; 135 150 default = true; ··· 229 244 key = "/var/lib/jitsi-meet/jitsi-meet.key"; 230 245 }; 231 246 }; 247 + virtualHosts."recorder.${cfg.hostName}" = { 248 + enabled = true; 249 + domain = "recorder.${cfg.hostName}"; 250 + extraConfig = '' 251 + authentication = "internal_plain" 252 + c2s_require_encryption = false 253 + ''; 254 + }; 232 255 }; 233 256 systemd.services.prosody.serviceConfig = mkIf cfg.prosody.enable { 234 257 EnvironmentFile = [ "/var/lib/jitsi-meet/secrets-env" ]; ··· 243 266 systemd.services.jitsi-meet-init-secrets = { 244 267 wantedBy = [ "multi-user.target" ]; 245 268 before = [ "jicofo.service" "jitsi-videobridge2.service" ] ++ (optional cfg.prosody.enable "prosody.service"); 269 + path = [ config.services.prosody.package ]; 246 270 serviceConfig = { 247 271 Type = "oneshot"; 248 272 }; 249 273 250 274 script = let 251 - secrets = [ "jicofo-component-secret" "jicofo-user-secret" ] ++ (optional (cfg.videobridge.passwordFile == null) "videobridge-secret"); 275 + secrets = [ "jicofo-component-secret" "jicofo-user-secret" "jibri-auth-secret" "jibri-recorder-secret" ] ++ (optional (cfg.videobridge.passwordFile == null) "videobridge-secret"); 252 276 videobridgeSecret = if cfg.videobridge.passwordFile != null then cfg.videobridge.passwordFile else "/var/lib/jitsi-meet/videobridge-secret"; 253 277 in 254 278 '' ··· 267 291 chmod 640 secrets-env 268 292 '' 269 293 + optionalString cfg.prosody.enable '' 270 - ${config.services.prosody.package}/bin/prosodyctl register focus auth.${cfg.hostName} "$(cat /var/lib/jitsi-meet/jicofo-user-secret)" 271 - ${config.services.prosody.package}/bin/prosodyctl register jvb auth.${cfg.hostName} "$(cat ${videobridgeSecret})" 272 - ${config.services.prosody.package}/bin/prosodyctl mod_roster_command subscribe focus.${cfg.hostName} focus@auth.${cfg.hostName} 294 + prosodyctl register focus auth.${cfg.hostName} "$(cat /var/lib/jitsi-meet/jicofo-user-secret)" 295 + prosodyctl register jvb auth.${cfg.hostName} "$(cat ${videobridgeSecret})" 296 + prosodyctl mod_roster_command subscribe focus.${cfg.hostName} focus@auth.${cfg.hostName} 297 + prosodyctl register jibri auth.${cfg.hostName} "$(cat /var/lib/jitsi-meet/jibri-auth-secret)" 298 + prosodyctl register recorder recorder.${cfg.hostName} "$(cat /var/lib/jitsi-meet/jibri-recorder-secret)" 273 299 274 300 # generate self-signed certificates 275 301 if [ ! -f /var/lib/jitsi-meet.crt ]; then ··· 380 406 userPasswordFile = "/var/lib/jitsi-meet/jicofo-user-secret"; 381 407 componentPasswordFile = "/var/lib/jitsi-meet/jicofo-component-secret"; 382 408 bridgeMuc = "jvbbrewery@internal.${cfg.hostName}"; 383 - config = { 409 + config = mkMerge [{ 384 410 "org.jitsi.jicofo.ALWAYS_TRUST_MODE_ENABLED" = "true"; 411 + #} (lib.mkIf cfg.jibri.enable { 412 + } (lib.mkIf (config.services.jibri.enable || cfg.jibri.enable) { 413 + "org.jitsi.jicofo.jibri.BREWERY" = "JibriBrewery@internal.${cfg.hostName}"; 414 + "org.jitsi.jicofo.jibri.PENDING_TIMEOUT" = "90"; 415 + })]; 416 + }; 417 + 418 + services.jibri = mkIf cfg.jibri.enable { 419 + enable = true; 420 + 421 + xmppEnvironments."jitsi-meet" = { 422 + xmppServerHosts = [ "localhost" ]; 423 + xmppDomain = cfg.hostName; 424 + 425 + control.muc = { 426 + domain = "internal.${cfg.hostName}"; 427 + roomName = "JibriBrewery"; 428 + nickname = "jibri"; 429 + }; 430 + 431 + control.login = { 432 + domain = "auth.${cfg.hostName}"; 433 + username = "jibri"; 434 + passwordFile = "/var/lib/jitsi-meet/jibri-auth-secret"; 435 + }; 436 + 437 + call.login = { 438 + domain = "recorder.${cfg.hostName}"; 439 + username = "recorder"; 440 + passwordFile = "/var/lib/jitsi-meet/jibri-recorder-secret"; 441 + }; 442 + 443 + usageTimeout = "0"; 444 + disableCertificateVerification = true; 445 + stripFromRoomDomain = "conference."; 385 446 }; 386 447 }; 387 448 };
+1
nixos/tests/all-tests.nix
··· 207 207 jackett = handleTest ./jackett.nix {}; 208 208 jellyfin = handleTest ./jellyfin.nix {}; 209 209 jenkins = handleTest ./jenkins.nix {}; 210 + jibri = handleTest ./jibri.nix {}; 210 211 jirafeau = handleTest ./jirafeau.nix {}; 211 212 jitsi-meet = handleTest ./jitsi-meet.nix {}; 212 213 k3s = handleTest ./k3s.nix {};
+69
nixos/tests/jibri.nix
··· 1 + import ./make-test-python.nix ({ pkgs, ... }: { 2 + name = "jibri"; 3 + meta = with pkgs.lib; { 4 + maintainers = teams.jitsi.members; 5 + }; 6 + 7 + machine = { config, pkgs, ... }: { 8 + virtualisation.memorySize = 5120; 9 + 10 + services.jitsi-meet = { 11 + enable = true; 12 + hostName = "machine"; 13 + jibri.enable = true; 14 + }; 15 + services.jibri.ignoreCert = true; 16 + services.jitsi-videobridge.openFirewall = true; 17 + 18 + networking.firewall.allowedTCPPorts = [ 80 443 ]; 19 + 20 + services.nginx.virtualHosts.machine = { 21 + enableACME = true; 22 + forceSSL = true; 23 + }; 24 + 25 + security.acme.email = "me@example.org"; 26 + security.acme.acceptTerms = true; 27 + security.acme.server = "https://example.com"; # self-signed only 28 + }; 29 + 30 + testScript = '' 31 + machine.wait_for_unit("jitsi-videobridge2.service") 32 + machine.wait_for_unit("jicofo.service") 33 + machine.wait_for_unit("nginx.service") 34 + machine.wait_for_unit("prosody.service") 35 + machine.wait_for_unit("jibri.service") 36 + 37 + machine.wait_until_succeeds( 38 + "journalctl -b -u jitsi-videobridge2 -o cat | grep -q 'Performed a successful health check'", timeout=30 39 + ) 40 + machine.wait_until_succeeds( 41 + "journalctl -b -u prosody -o cat | grep -q 'Authenticated as focus@auth.machine'", timeout=31 42 + ) 43 + machine.wait_until_succeeds( 44 + "journalctl -b -u prosody -o cat | grep -q 'Authenticated as jvb@auth.machine'", timeout=32 45 + ) 46 + machine.wait_until_succeeds( 47 + "journalctl -b -u prosody -o cat | grep -q 'Authenticated as jibri@auth.machine'", timeout=33 48 + ) 49 + machine.wait_until_succeeds( 50 + "cat /var/log/jitsi/jibri/log.0.txt | grep -q 'Joined MUC: jibribrewery@internal.machine'", timeout=34 51 + ) 52 + 53 + assert '"busyStatus":"IDLE","health":{"healthStatus":"HEALTHY"' in machine.succeed( 54 + "curl -X GET http://machine:2222/jibri/api/v1.0/health" 55 + ) 56 + machine.succeed( 57 + """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"}'""" 58 + ) 59 + machine.wait_until_succeeds( 60 + "cat /var/log/jitsi/jibri/log.0.txt | grep -q 'File recording service transitioning from state Starting up to Running'", timeout=35 61 + ) 62 + machine.succeed( 63 + """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"}'""" 64 + ) 65 + machine.wait_until_succeeds( 66 + "cat /var/log/jitsi/jibri/log.0.txt | grep -q 'Recording finalize script finished with exit value 0'", timeout=36 67 + ) 68 + ''; 69 + })
+58
pkgs/applications/audio/pocket-casts/default.nix
··· 1 + { lib, stdenv, fetchurl, dpkg, autoPatchelfHook, makeWrapper, electron_12, 2 + alsa-lib, gtk3, libXScrnSaver, libXtst, mesa, nss }: 3 + 4 + let 5 + # Using Electron 12 to solve errors regarding threading 6 + electron = electron_12; 7 + 8 + in stdenv.mkDerivation rec { 9 + pname = "pocket-casts"; 10 + version = "0.5.0"; 11 + 12 + src = fetchurl { 13 + url = "https://github.com/felicianotech/pocket-casts-desktop-app/releases/download/v${version}/${pname}_${version}_amd64.deb"; 14 + sha256 = "sha256-frBtIxwRO/6k6j0itqN10t+9AyNadqXm8vC1YP960ts="; 15 + }; 16 + 17 + nativeBuildInputs = [ 18 + dpkg 19 + autoPatchelfHook 20 + makeWrapper 21 + ]; 22 + 23 + buildInputs = [ alsa-lib gtk3 libXScrnSaver libXtst mesa nss ]; 24 + 25 + dontBuild = true; 26 + dontConfigure = true; 27 + 28 + unpackPhase = '' 29 + dpkg-deb -x ${src} ./ 30 + ''; 31 + 32 + installPhase = '' 33 + runHook preInstall 34 + 35 + mv usr $out 36 + mv opt $out 37 + mv "$out/opt/Pocket Casts" $out/opt/pocket-casts 38 + mv $out/share/icons/hicolor/0x0 $out/share/icons/hicolor/256x256 39 + 40 + runHook postInstall 41 + ''; 42 + 43 + postFixup = '' 44 + substituteInPlace $out/share/applications/pocket-casts.desktop --replace '"/opt/Pocket Casts/pocket-casts"' $out/bin/pocket-casts 45 + substituteInPlace $out/share/applications/pocket-casts.desktop --replace '/usr/share/icons/hicolor/0x0/apps/pocket-casts.png' "pocket-casts" 46 + makeWrapper ${electron}/bin/electron \ 47 + $out/bin/pocket-casts \ 48 + --add-flags $out/opt/pocket-casts/resources/app.asar 49 + ''; 50 + 51 + meta = with lib; { 52 + description = "Pocket Casts webapp, packaged for the Linux Desktop"; 53 + homepage = "https://github.com/felicianotech/pocket-casts-desktop-app"; 54 + license = licenses.mit; 55 + maintainers = with maintainers; [ wolfangaukang ]; 56 + platforms = [ "x86_64-linux" ]; 57 + }; 58 + }
+2 -2
pkgs/applications/audio/strawberry/default.nix
··· 36 36 37 37 mkDerivation rec { 38 38 pname = "strawberry"; 39 - version = "0.9.3"; 39 + version = "1.0.0"; 40 40 41 41 src = fetchFromGitHub { 42 42 owner = "jonaski"; 43 43 repo = pname; 44 44 rev = version; 45 - sha256 = "sha256-OOdHsii6O4okVHDhrqCNJ7WVB0VKPs8q0AhEY+IvflE="; 45 + sha256 = "sha256-m1BB5OIeCIQuJpxEO1xmb/Z8tzeHF31jYg67OpVWWRM="; 46 46 }; 47 47 48 48 buildInputs = [
+12 -16
pkgs/applications/graphics/cloudcompare/default.nix
··· 10 10 , LASzip 11 11 , libLAS 12 12 , pdal 13 + , pcl 13 14 , qtbase 14 15 , qtsvg 15 16 , qttools ··· 19 20 20 21 mkDerivation rec { 21 22 pname = "cloudcompare"; 22 - version = "2.11.2"; # Remove below patch with the next version bump. 23 + # Released version doesn't work with packaged PCL 24 + # because it's too new. Considering that a release 25 + # is a year ago it's unreasonable to wait for it. 26 + version = "unstable-2021-10-14"; 23 27 24 28 src = fetchFromGitHub { 25 29 owner = "CloudCompare"; 26 30 repo = "CloudCompare"; 27 - rev = "v${version}"; 28 - sha256 = "0sb2h08iaf6zrf54sg6ql6wm63q5vq0kpd3gffdm26z8w6j6wv3s"; 31 + rev = "1f65ba63756e23291ae91ff52d04da468ade8249"; 32 + sha256 = "x1bDjFjXIl3r+yo1soWvRB+4KGP50/WBoGlrH013JQo="; 29 33 # As of writing includes (https://github.com/CloudCompare/CloudCompare/blob/a1c589c006fc325e8b560c77340809b9c7e7247a/.gitmodules): 30 34 # * libE57Format 31 35 # * PoissonRecon 32 - # In a future version it will also contain 33 36 # * CCCoreLib 34 37 fetchSubmodules = true; 35 38 }; 36 39 37 - patches = [ 38 - # TODO: Remove with next CloudCompare release (see https://github.com/CloudCompare/CloudCompare/pull/1478) 39 - (fetchpatch { 40 - name = "CloudCompare-fix-for-PDAL-2.3.0.patch"; 41 - url = "https://github.com/CloudCompare/CloudCompare/commit/f3038dcdeb0491c4a653c2ee6fb017326eb676a3.patch"; 42 - sha256 = "0ca5ry987mcgsdawz5yd4xhbsdb5k44qws30srxymzx2djvamwli"; 43 - }) 44 - ]; 45 - 46 40 nativeBuildInputs = [ 47 41 cmake 48 42 eigen # header-only ··· 55 49 LASzip 56 50 libLAS 57 51 pdal 52 + pcl 58 53 qtbase 59 54 qtsvg 60 55 qttools ··· 63 58 ]; 64 59 65 60 cmakeFlags = [ 66 - # TODO: This will become -DCCCORELIB_USE_TBB=ON in a future version, see 67 - # https://github.com/CloudCompare/CloudCompare/commit/f5a0c9fd788da26450f3fa488b2cf0e4a08d255f 68 - "-DCOMPILE_CC_CORE_LIB_WITH_TBB=ON" 61 + "-DCCCORELIB_USE_TBB=ON" 69 62 "-DOPTION_USE_DXF_LIB=ON" 70 63 "-DOPTION_USE_GDAL=ON" 71 64 "-DOPTION_USE_SHAPE_LIB=ON" 72 65 73 66 "-DPLUGIN_GL_QEDL=ON" 74 67 "-DPLUGIN_GL_QSSAO=ON" 68 + 75 69 "-DPLUGIN_IO_QADDITIONAL=ON" 76 70 "-DPLUGIN_IO_QCORE=ON" 77 71 "-DPLUGIN_IO_QCSV_MATRIX=ON" ··· 80 74 "-DPLUGIN_IO_QPDAL=ON" # required for .las/.laz support 81 75 "-DPLUGIN_IO_QPHOTOSCAN=ON" 82 76 "-DPLUGIN_IO_QRDB=OFF" # Riegl rdblib is proprietary; not packaged in nixpkgs 77 + 78 + "-DPLUGIN_STANDARD_QPCL=ON" # Adds PCD import and export support 83 79 ]; 84 80 85 81 meta = with lib; {
+4 -3
pkgs/applications/misc/calibre/default.nix
··· 27 27 28 28 mkDerivation rec { 29 29 pname = "calibre"; 30 - version = "5.29.0"; 30 + version = "5.30.0"; 31 31 32 32 src = fetchurl { 33 33 url = "https://download.calibre-ebook.com/${version}/${pname}-${version}.tar.xz"; 34 34 sha256 = "sha256-9ymHEpTHDUM3NAGoeSETzKRLKgJLRY4eEli6N5lbZug="; 35 35 }; 36 36 37 - # https://sources.debian.org/patches/calibre/5.29.0+dfsg-1 37 + # https://sources.debian.org/patches/calibre/5.30.0+dfsg-1 38 38 patches = [ 39 39 # allow for plugin update check, but no calibre version check 40 40 (fetchpatch { 41 41 name = "0001_only_plugin_update.patch"; 42 - url = "https://sources.debian.org/data/main/c/calibre/5.29.0%2Bdfsg-1/debian/patches/0001-only-plugin-update.patch"; 42 + url = 43 + "https://sources.debian.org/data/main/c/calibre/${version}%2Bdfsg-1/debian/patches/0001-only-plugin-update.patch"; 43 44 sha256 = "sha256-aGT8rJ/eQKAkmyHBWdY0ouZuWvDwtLVJU5xY6d3hY3k="; 44 45 }) 45 46 ]
+2 -2
pkgs/development/libraries/vulkan-headers/default.nix
··· 1 1 { lib, stdenv, fetchFromGitHub, cmake }: 2 2 stdenv.mkDerivation rec { 3 3 pname = "vulkan-headers"; 4 - version = "1.2.182.0"; 4 + version = "1.2.189.1"; 5 5 6 6 nativeBuildInputs = [ cmake ]; 7 7 ··· 9 9 owner = "KhronosGroup"; 10 10 repo = "Vulkan-Headers"; 11 11 rev = "sdk-${version}"; 12 - sha256 = "03j0kzq2qxhy0y82l10m8am26zrms2sjrdb1dcbpv9zh5vkxhcla"; 12 + sha256 = "1qggc7dv9jr83xr9w2h375wl3pz3rfgrk9hnrjmylkg9gz4p9q03"; 13 13 }; 14 14 15 15 meta = with lib; {
+2 -2
pkgs/development/libraries/vulkan-loader/default.nix
··· 3 3 4 4 stdenv.mkDerivation rec { 5 5 pname = "vulkan-loader"; 6 - version = "1.2.182.0"; 6 + version = "1.2.189.1"; 7 7 8 8 src = (assert version == vulkan-headers.version; 9 9 fetchFromGitHub { 10 10 owner = "KhronosGroup"; 11 11 repo = "Vulkan-Loader"; 12 12 rev = "sdk-${version}"; 13 - sha256 = "0gmr9q3a6s8xvaa74fs9zbi9c305i2b3rx768qvl79nhbdj8nc02"; 13 + sha256 = "1745fdzi0n5qj2s41q6z1y52cq8pwswvh1a32d3n7kl6bhksagp6"; 14 14 }); 15 15 16 16 nativeBuildInputs = [ cmake pkg-config ];
+3 -13
pkgs/development/python-modules/shapely/default.nix
··· 13 13 14 14 buildPythonPackage rec { 15 15 pname = "Shapely"; 16 - version = "1.7.1"; 17 - disabled = pythonOlder "3.5"; 16 + version = "1.8.0"; 17 + disabled = pythonOlder "3.6"; 18 18 19 19 src = fetchPypi { 20 20 inherit pname version; 21 - sha256 = "0adiz4jwmwxk7k1awqifb1a9bj5x4nx4gglb5dz9liam21674h8n"; 21 + sha256 = "177g8wxsgnphhhn4634n6ca1qrk462ijqlznpj5ry6d49ghpwc7m"; 22 22 }; 23 23 24 24 nativeBuildInputs = [ ··· 38 38 GEOS_LIBRARY_PATH = "${geos}/lib/libgeos_c${stdenv.hostPlatform.extensions.sharedLibrary}"; 39 39 40 40 patches = [ 41 - # Fix with geos 3.9. This patch will be part of the next release after 1.7.1 42 - (fetchpatch { 43 - url = "https://github.com/Toblerity/Shapely/commit/77879a954d24d1596f986d16ba3eff5e13861164.patch"; 44 - sha256 = "1w7ngjqbpf9vnvrfg4nyv34kckim9a60gvx20h6skc79xwihd4m5"; 45 - excludes = [ 46 - "tests/test_create_inconsistent_dimensionality.py" 47 - "appveyor.yml" 48 - ".travis.yml" 49 - ]; 50 - }) 51 41 # Patch to search form GOES .so/.dylib files in a Nix-aware way 52 42 (substituteAll { 53 43 src = ./library-paths.patch;
+55 -41
pkgs/development/python-modules/shapely/library-paths.patch
··· 1 1 diff --git a/shapely/geos.py b/shapely/geos.py 2 - index d5a67d2..19b7ffc 100644 2 + index 4619732..1abdb5e 100644 3 3 --- a/shapely/geos.py 4 4 +++ b/shapely/geos.py 5 - @@ -61,127 +61,17 @@ def load_dll(libname, fallbacks=None, mode=DEFAULT_MODE): 5 + @@ -55,148 +55,21 @@ def load_dll(libname, fallbacks=None, mode=DEFAULT_MODE): 6 6 "Could not find lib {} or load any of its variants {}.".format( 7 7 libname, fallbacks or [])) 8 8 9 9 -_lgeos = None 10 + def exists_conda_env(): 11 + """Does this module exist in a conda environment?""" 12 + return os.path.exists(os.path.join(sys.prefix, 'conda-meta')) 13 + 10 14 - 11 15 -if sys.platform.startswith('linux'): 12 - - # Test to see if we have a wheel repaired by 'auditwheel' containing its 13 - - # own libgeos_c 14 - - geos_whl_so = glob.glob(os.path.abspath(os.path.join(os.path.dirname( 15 - - __file__), '.libs/libgeos_c-*.so.*'))) 16 - - if len(geos_whl_so) == 1: 17 - - _lgeos = CDLL(geos_whl_so[0]) 16 + - # Test to see if we have a wheel repaired by auditwheel which contains its 17 + - # own libgeos_c. Note: auditwheel 3.1 changed the location of libs. 18 + - geos_whl_so = glob.glob( 19 + - os.path.abspath(os.path.join(os.path.dirname(__file__), ".libs/libgeos*.so*")) 20 + - ) or glob.glob( 21 + - os.path.abspath( 22 + - os.path.join( 23 + - os.path.dirname(__file__), "..", "Shapely.libs", "libgeos*.so*" 24 + - ) 25 + - ) 26 + - ) 27 + - 28 + - if len(geos_whl_so) > 0: 29 + - # We have observed problems with CDLL of libgeos_c not automatically 30 + - # loading the sibling c++ library since the change made by auditwheel 31 + - # 3.1, so we explicitly load them both. 32 + - geos_whl_so = sorted(geos_whl_so) 33 + - CDLL(geos_whl_so[0]) 34 + - _lgeos = CDLL(geos_whl_so[-1]) 18 35 - LOG.debug("Found GEOS DLL: %r, using it.", _lgeos) 36 + - 19 37 - elif hasattr(sys, 'frozen'): 20 38 - geos_pyinstaller_so = glob.glob(os.path.join(sys.prefix, 'libgeos_c-*.so.*')) 21 - - if len(geos_pyinstaller_so) == 1: 39 + - if len(geos_pyinstaller_so) >= 1: 22 40 - _lgeos = CDLL(geos_pyinstaller_so[0]) 23 41 - LOG.debug("Found GEOS DLL: %r, using it.", _lgeos) 24 - - elif os.getenv('CONDA_PREFIX', ''): 42 + - elif exists_conda_env(): 25 43 - # conda package. 26 44 - _lgeos = CDLL(os.path.join(sys.prefix, 'lib', 'libgeos_c.so')) 27 45 - else: ··· 30 48 - 'libgeos_c.so', 31 49 - ] 32 50 - _lgeos = load_dll('geos_c', fallbacks=alt_paths) 33 - - # Necessary for environments with only libc.musl 34 - - c_alt_paths = [ 35 - - 'libc.musl-x86_64.so.1' 36 - - ] 37 - - free = load_dll('c', fallbacks=c_alt_paths).free 51 + - 52 + +_lgeos = CDLL('@libgeos_c@') 53 + +if sys.platform == 'darwin': 54 + # ctypes.CDLL(None) internally calls dlopen(NULL), and as the dlopen 55 + # manpage says, "If filename is NULL, then the returned handle is for the 56 + # main program". This way we can let the linker do the work to figure out 57 + # which libc Python is actually using. 58 + free = CDLL(None).free 38 59 - free.argtypes = [c_void_p] 39 60 - free.restype = None 40 61 - ··· 52 73 - _lgeos = CDLL(geos_whl_dylib) 53 74 - LOG.debug("Found GEOS DLL: %r, using it.", _lgeos) 54 75 - 55 - - elif os.getenv('CONDA_PREFIX', ''): 76 + - elif exists_conda_env(): 56 77 - # conda package. 57 78 - _lgeos = CDLL(os.path.join(sys.prefix, 'lib', 'libgeos_c.dylib')) 58 79 - else: ··· 63 84 - os.environ['RESOURCEPATH'], '..', 'Frameworks', 64 85 - 'libgeos_c.dylib')] 65 86 - except KeyError: 66 - - # binary from pyinstaller 67 87 - alt_paths = [ 68 - - os.path.join(sys.executable, 'libgeos_c.dylib')] 88 + - # binary from pyinstaller 89 + - os.path.join(sys.executable, 'libgeos_c.dylib'), 90 + - # .app from cx_Freeze 91 + - os.path.join(os.path.dirname(sys.executable), 'libgeos_c.1.dylib')] 69 92 - if hasattr(sys, '_MEIPASS'): 70 93 - alt_paths.append( 71 94 - os.path.join(sys._MEIPASS, 'libgeos_c.1.dylib')) ··· 75 98 - "/Library/Frameworks/GEOS.framework/Versions/Current/GEOS", 76 99 - # macports 77 100 - '/opt/local/lib/libgeos_c.dylib', 78 - - # homebrew 101 + - # homebrew Intel 79 102 - '/usr/local/lib/libgeos_c.dylib', 103 + - # homebrew Apple Silicon 104 + - '/opt/homebrew/lib/libgeos_c.dylib', 80 105 - ] 81 106 - _lgeos = load_dll('geos_c', fallbacks=alt_paths) 82 107 - 83 - - # ctypes.CDLL(None) internally calls dlopen(NULL), and as the dlopen 84 - - # manpage says, "If filename is NULL, then the returned handle is for the 85 - - # main program". This way we can let the linker do the work to figure out 86 - - # which libc Python is actually using. 87 108 - free = CDLL(None).free 88 109 - free.argtypes = [c_void_p] 89 110 - free.restype = None 90 111 - 91 112 -elif sys.platform == 'win32': 92 - - if os.getenv('CONDA_PREFIX', ''): 113 + - _conda_dll_path = os.path.join(sys.prefix, 'Library', 'bin', 'geos_c.dll') 114 + - if exists_conda_env() and os.path.exists(_conda_dll_path): 93 115 - # conda package. 94 - - _lgeos = CDLL(os.path.join(sys.prefix, 'Library', 'bin', 'geos_c.dll')) 116 + - _lgeos = CDLL(_conda_dll_path) 95 117 - else: 96 118 - try: 97 119 - egg_dlls = os.path.abspath( ··· 119 141 - 120 142 -elif sys.platform == 'sunos5': 121 143 - _lgeos = load_dll('geos_c', fallbacks=['libgeos_c.so.1', 'libgeos_c.so']) 122 - - free = CDLL('libc.so.1').free 144 + - free.restype = None 123 145 - free.argtypes = [c_void_p] 124 146 - free.restype = None 147 + - 125 148 -else: # other *nix systems 126 149 - _lgeos = load_dll('geos_c', fallbacks=['libgeos_c.so.1', 'libgeos_c.so']) 127 - - free = load_dll('c', fallbacks=['libc.so.6']).free 150 + - free = CDLL(None).free 128 151 - free.argtypes = [c_void_p] 129 152 - free.restype = None 130 - +_lgeos = CDLL('@libgeos_c@') 131 - +if sys.platform == 'darwin': 132 - + # ctypes.CDLL(None) internally calls dlopen(NULL), and as the dlopen 133 - + # manpage says, "If filename is NULL, then the returned handle is for the 134 - + # main program". This way we can let the linker do the work to figure out 135 - + # which libc Python is actually using. 136 - + free = CDLL(None).free 137 153 +else: 138 154 + free = CDLL('@libc@').free 139 155 +free.argtypes = [c_void_p] ··· 142 158 143 159 def _geos_version(): 144 160 diff --git a/tests/test_dlls.py b/tests/test_dlls.py 145 - index 35f9cc2..3dfcaac 100644 161 + index c71da8e..fae9da6 100644 146 162 --- a/tests/test_dlls.py 147 163 +++ b/tests/test_dlls.py 148 - @@ -12,12 +12,7 @@ class LoadingTestCase(unittest.TestCase): 164 + @@ -12,10 +12,4 @@ class LoadingTestCase(unittest.TestCase): 149 165 @unittest.skipIf(sys.platform == "win32", "FIXME: adapt test for win32") 150 166 def test_fallbacks(self): 151 167 load_dll('geos_c', fallbacks=[ 152 168 - os.path.join(sys.prefix, "lib", "libgeos_c.dylib"), # anaconda (Mac OS X) 153 - - '/opt/local/lib/libgeos_c.dylib', # MacPorts 154 - - '/usr/local/lib/libgeos_c.dylib', # homebrew (Mac OS X) 169 + - '/opt/local/lib/libgeos_c.dylib', # MacPorts 170 + - '/usr/local/lib/libgeos_c.dylib', # homebrew (Mac OS X) 171 + - '/opt/homebrew/lib/libgeos_c.dylib', # homebrew (macOS) 155 172 - os.path.join(sys.prefix, "lib", "libgeos_c.so"), # anaconda (Linux) 156 173 - 'libgeos_c.so.1', 157 174 - 'libgeos_c.so']) 158 175 + '@libgeos_c@']) 159 - 160 - 161 - def test_suite():
+10 -10
pkgs/development/tools/vulkan-validation-layers/default.nix
··· 23 23 src = fetchFromGitHub { 24 24 owner = "KhronosGroup"; 25 25 repo = "SPIRV-Headers"; 26 - rev = "dafead1765f6c1a5f9f8a76387dcb2abe4e54acd"; # pin 27 - sha256 = "1kj6wcx9y7r1xyg8n7ai2pzrg9ira7hbakr45wh5p4zyxh0m45n8"; 26 + rev = "449bc986ba6f4c5e10e32828783f9daef2a77644"; # pin 27 + sha256 = "1249pvk4iz09caxm3kwckzwcx2hbw97cr2h8h770l6c061kb14z5"; 28 28 }; 29 29 }); 30 30 localGlslang = (glslang.override { ··· 32 32 src = fetchFromGitHub { 33 33 owner = "KhronosGroup"; 34 34 repo = "SPIRV-Tools"; 35 - rev = "dc72924cb31cd9f3dbc3eb47e9d926cf641e3a07"; # pin 36 - sha256 = "0pxgbq6xapw9hgrzb3rk5cylzgg1y1bkqz5wxzwqls63pwga5912"; 35 + rev = "1fbed83c8aab8517d821fcb4164c08567951938f"; # pin 36 + sha256 = "0faz468bnxpvbg1np13gnbwf35s0hl9ad7r2p9wi9si5k336qjmj"; 37 37 }; 38 38 }); 39 39 argSpirv-headers = localSpirvHeaders; ··· 41 41 src = fetchFromGitHub { 42 42 owner = "KhronosGroup"; 43 43 repo = "glslang"; 44 - rev = "18eef33bd7a4bf5ad8c69f99cb72022608cf6e73"; # pin 45 - sha256 = "0wwj7q509pkp8wj7120g1n2ddl4x2r03ljf5czd9794ji6yraidn"; 44 + rev = "2fb89a0072ae7316af1c856f22663fde4928128a"; # pin 45 + sha256 = "04kkmphv0a5mb5javhmkc4kab8r0n107kb7djakj5h238ni2j7q9"; 46 46 }; 47 47 }); 48 48 robin-hood-hashing = fetchFromGitHub { 49 49 owner = "martinus"; 50 50 repo = "robin-hood-hashing"; 51 - rev = "3.11.2"; # pin 52 - sha256 = "0103mnqpmka1smy0arnrbihlvi7i8xr5im0px8wn4faw4flikkcm"; 51 + rev = "3.11.3"; # pin 52 + sha256 = "1gm3lwjkh6h8m7lfykzd0jzhfqjmjchindkmxc008rwvxafsd1pl"; 53 53 }; 54 54 in 55 55 stdenv.mkDerivation rec { 56 56 pname = "vulkan-validation-layers"; 57 - version = "1.2.182.0"; 57 + version = "1.2.189.1"; 58 58 59 59 # If we were to use "dev" here instead of headers, the setupHook would be 60 60 # placed in that output instead of "out". ··· 66 66 owner = "KhronosGroup"; 67 67 repo = "Vulkan-ValidationLayers"; 68 68 rev = "sdk-${version}"; 69 - sha256 = "1fnmb7vbm7y1x67bf1xiwdrpj9j4lkvhk9xhb6hp6x2aryvcyrnc"; 69 + sha256 = "0a5plvvffidgnqh5ymq315xscl08w298sn9da48b3x2rdbdqgw90"; 70 70 }); 71 71 72 72 # Include absolute paths to layer libraries in their associated
+31
pkgs/servers/gemini/gmid/default.nix
··· 1 + { lib, stdenv, fetchFromGitHub, bison, libressl, libevent }: 2 + 3 + stdenv.mkDerivation rec { 4 + pname = "gmid"; 5 + version = "1.7.5"; 6 + 7 + src = fetchFromGitHub { 8 + owner = "omar-polo"; 9 + repo = pname; 10 + rev = version; 11 + sha256 = "sha256-BBd0AL5jRRslxzDnxcTZRR+8J5D23NAQ7mp9K+leXAQ="; 12 + }; 13 + 14 + nativeBuildInputs = [ bison ]; 15 + 16 + buildInputs = [ libressl libevent ]; 17 + 18 + configurePhase = '' 19 + runHook preConfigure 20 + ./configure PREFIX=$out 21 + runHook postConfigure 22 + ''; 23 + 24 + meta = with lib; { 25 + description = "Simple and secure Gemini server"; 26 + homepage = "https://gmid.omarpolo.com/"; 27 + license = licenses.isc; 28 + maintainers = with maintainers; [ sikmir ]; 29 + platforms = platforms.linux; 30 + }; 31 + }
+15 -2
pkgs/servers/jibri/default.nix
··· 1 - { lib, stdenv, fetchurl, dpkg, jre_headless, makeWrapper }: 1 + { lib, stdenv, fetchurl, dpkg, jre8_headless, makeWrapper, writeText, xorg }: 2 + 3 + let 4 + xorgModulePaths = writeText "module-paths" '' 5 + Section "Files" 6 + ModulePath "${xorg.xorgserver}/lib/xorg/modules 7 + ModulePath "${xorg.xorgserver}/lib/xorg/extensions 8 + ModulePath "${xorg.xorgserver}/lib/xorg/drivers 9 + ModulePath "${xorg.xf86videodummy}/lib/xorg/modules/drivers 10 + EndSection 11 + ''; 2 12 13 + in 3 14 stdenv.mkDerivation rec { 4 15 pname = "jibri"; 5 16 version = "8.0-93-g51fe7a2"; ··· 19 30 mv etc/jitsi/jibri/* $out/etc/jitsi/jibri/ 20 31 mv opt/jitsi/jibri/* $out/opt/jitsi/jibri/ 21 32 22 - makeWrapper ${jre_headless}/bin/java $out/bin/jibri --add-flags "-jar $out/opt/jitsi/jibri/jibri.jar" 33 + cat '${xorgModulePaths}' >> $out/etc/jitsi/jibri/xorg-video-dummy.conf 34 + 35 + makeWrapper ${jre8_headless}/bin/java $out/bin/jibri --add-flags "-jar $out/opt/jitsi/jibri/jibri.jar" 23 36 24 37 runHook postInstall 25 38 '';
+2 -2
pkgs/tools/graphics/vulkan-extension-layer/default.nix
··· 2 2 3 3 stdenv.mkDerivation rec { 4 4 pname = "vulkan-extension-layer"; 5 - version = "1.2.182.0"; 5 + version = "1.2.189.1"; 6 6 7 7 src = (assert version == vulkan-headers.version; 8 8 fetchFromGitHub { 9 9 owner = "KhronosGroup"; 10 10 repo = "Vulkan-ExtensionLayer"; 11 11 rev = "sdk-${version}"; 12 - sha256 = "0by2kp48jbd55xk26rmlvc4wm77g1zvidx8czn1587ng2yzi7acr"; 12 + sha256 = "0qi9ps215pmrh8vgi81wvlzjyxs44bama2x3d43a1bbvcyp9s6kp"; 13 13 }); 14 14 15 15 nativeBuildInputs = [ cmake jq ];
+2 -2
pkgs/tools/graphics/vulkan-tools-lunarg/default.nix
··· 23 23 stdenv.mkDerivation rec { 24 24 pname = "vulkan-tools-lunarg"; 25 25 # The version must match that in vulkan-headers 26 - version = "1.2.182.0"; 26 + version = "1.2.189.1"; 27 27 28 28 src = (assert version == vulkan-headers.version; 29 29 fetchFromGitHub { 30 30 owner = "LunarG"; 31 31 repo = "VulkanTools"; 32 32 rev = "sdk-${version}"; 33 - sha256 = "1b7762fcbakfvj2b2l68qj25pc7pz9jhfabf1x80b9w3q205hl2f"; 33 + sha256 = "0431dgplv5wiz8bj0ja91mbpc2qhjgdhqhrgaqarvyvjr1f7jw52"; 34 34 fetchSubmodules = true; 35 35 }); 36 36
+2 -2
pkgs/tools/graphics/vulkan-tools/default.nix
··· 3 3 4 4 stdenv.mkDerivation rec { 5 5 pname = "vulkan-tools"; 6 - version = "1.2.182.0"; 6 + version = "1.2.189.1"; 7 7 8 8 # It's not strictly necessary to have matching versions here, however 9 9 # since we're using the SDK version we may as well be consistent with ··· 13 13 owner = "KhronosGroup"; 14 14 repo = "Vulkan-Tools"; 15 15 rev = "sdk-${version}"; 16 - sha256 = "028l2l7jx4443k8207q8jmjq1mnnm9kgyl2417jrkrvylcbv8ji9"; 16 + sha256 = "0izmzyj6gb51d71vbdjcgd9qw34aidvbmz0mg4bkc13n48w8s9vj"; 17 17 }); 18 18 19 19 nativeBuildInputs = [ cmake ];
+2 -2
pkgs/tools/system/htop/default.nix
··· 11 11 12 12 stdenv.mkDerivation rec { 13 13 pname = "htop"; 14 - version = "3.1.0"; 14 + version = "3.1.1"; 15 15 16 16 src = fetchFromGitHub { 17 17 owner = "htop-dev"; 18 18 repo = pname; 19 19 rev = version; 20 - sha256 = "sha256-/48Ca7JPzhPS4eYsPbwbSVcx9aS1f0LHcqsbNVWL+9k="; 20 + sha256 = "JnpuBa09U086wWp0OtsDnStF4aLjhvtEj371u5XFtqc="; 21 21 }; 22 22 23 23 nativeBuildInputs = [ autoreconfHook ];
+2 -2
pkgs/tools/text/languagetool/default.nix
··· 2 2 3 3 stdenv.mkDerivation rec { 4 4 pname = "LanguageTool"; 5 - version = "5.4"; 5 + version = "5.5"; 6 6 7 7 src = fetchzip { 8 8 url = "https://www.languagetool.org/download/${pname}-${version}.zip"; 9 - sha256 = "sha256-2khadADfzwkW+J0uafPWJ6xUQRSQDm8seiBHueQGmKI="; 9 + sha256 = "sha256-v9p+G1aSzrvuoJLfRqWQXGVJ+2vysxdTgrD+ZUt6Yg4="; 10 10 }; 11 11 nativeBuildInputs = [ makeWrapper ]; 12 12 buildInputs = [ jre ];
+4
pkgs/top-level/all-packages.nix
··· 1723 1723 1724 1724 glasgow = with python3Packages; toPythonApplication glasgow; 1725 1725 1726 + gmid = callPackage ../servers/gemini/gmid { }; 1727 + 1726 1728 gmni = callPackage ../applications/networking/browsers/gmni { }; 1727 1729 1728 1730 gmnisrv = callPackage ../servers/gemini/gmnisrv { }; ··· 3401 3403 playerctl = callPackage ../tools/audio/playerctl { }; 3402 3404 3403 3405 pn = callPackage ../tools/text/pn { }; 3406 + 3407 + pocket-casts = callPackage ../applications/audio/pocket-casts { }; 3404 3408 3405 3409 poweralertd = callPackage ../tools/misc/poweralertd { }; 3406 3410