Merge pull request #137003 from yayayayaka/add-pkg-jigasi
jigasi: init at 1.1-311-g3de47d0 + module
This commit is contained in:
commit
b8ca5f4f46
6 changed files with 322 additions and 3 deletions
|
@ -429,6 +429,7 @@ with lib.maintainers; {
|
||||||
cleeyv
|
cleeyv
|
||||||
ryantm
|
ryantm
|
||||||
lassulus
|
lassulus
|
||||||
|
yayayayaka
|
||||||
];
|
];
|
||||||
scope = "Maintain Jitsi.";
|
scope = "Maintain Jitsi.";
|
||||||
shortName = "Jitsi";
|
shortName = "Jitsi";
|
||||||
|
|
|
@ -971,6 +971,7 @@
|
||||||
./services/networking/iwd.nix
|
./services/networking/iwd.nix
|
||||||
./services/networking/jibri/default.nix
|
./services/networking/jibri/default.nix
|
||||||
./services/networking/jicofo.nix
|
./services/networking/jicofo.nix
|
||||||
|
./services/networking/jigasi.nix
|
||||||
./services/networking/jitsi-videobridge.nix
|
./services/networking/jitsi-videobridge.nix
|
||||||
./services/networking/jool.nix
|
./services/networking/jool.nix
|
||||||
./services/networking/kea.nix
|
./services/networking/kea.nix
|
||||||
|
|
237
nixos/modules/services/networking/jigasi.nix
Normal file
237
nixos/modules/services/networking/jigasi.nix
Normal file
|
@ -0,0 +1,237 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.jigasi;
|
||||||
|
homeDirName = "jigasi-home";
|
||||||
|
stateDir = "/tmp";
|
||||||
|
sipCommunicatorPropertiesFile = "${stateDir}/${homeDirName}/sip-communicator.properties";
|
||||||
|
sipCommunicatorPropertiesFileUnsubstituted = "${pkgs.jigasi}/etc/jitsi/jigasi/sip-communicator.properties";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.services.jigasi = with types; {
|
||||||
|
enable = mkEnableOption "Jitsi Gateway to SIP - component of Jitsi Meet";
|
||||||
|
|
||||||
|
xmppHost = mkOption {
|
||||||
|
type = str;
|
||||||
|
example = "localhost";
|
||||||
|
description = ''
|
||||||
|
Hostname of the XMPP server to connect to.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
xmppDomain = mkOption {
|
||||||
|
type = nullOr str;
|
||||||
|
example = "meet.example.org";
|
||||||
|
description = ''
|
||||||
|
Domain name of the XMMP server to which to connect as a component.
|
||||||
|
|
||||||
|
If null, <option>xmppHost</option> is used.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
componentPasswordFile = mkOption {
|
||||||
|
type = str;
|
||||||
|
example = "/run/keys/jigasi-component";
|
||||||
|
description = ''
|
||||||
|
Path to file containing component secret.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
userName = mkOption {
|
||||||
|
type = str;
|
||||||
|
default = "callcontrol";
|
||||||
|
description = ''
|
||||||
|
User part of the JID for XMPP user connection.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
userDomain = mkOption {
|
||||||
|
type = str;
|
||||||
|
example = "internal.meet.example.org";
|
||||||
|
description = ''
|
||||||
|
Domain part of the JID for XMPP user connection.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
userPasswordFile = mkOption {
|
||||||
|
type = str;
|
||||||
|
example = "/run/keys/jigasi-user";
|
||||||
|
description = ''
|
||||||
|
Path to file containing password for XMPP user connection.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
bridgeMuc = mkOption {
|
||||||
|
type = str;
|
||||||
|
example = "jigasibrewery@internal.meet.example.org";
|
||||||
|
description = ''
|
||||||
|
JID of the internal MUC used to communicate with Videobridges.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
defaultJvbRoomName = mkOption {
|
||||||
|
type = str;
|
||||||
|
default = "";
|
||||||
|
example = "siptest";
|
||||||
|
description = ''
|
||||||
|
Name of the default JVB room that will be joined if no special header is included in SIP invite.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
environmentFile = mkOption {
|
||||||
|
type = types.nullOr types.path;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
File containing environment variables to be passed to the jigasi service,
|
||||||
|
in which secret tokens can be specified securely by defining values for
|
||||||
|
<literal>JIGASI_SIPUSER</literal>,
|
||||||
|
<literal>JIGASI_SIPPWD</literal>,
|
||||||
|
<literal>JIGASI_SIPSERVER</literal> and
|
||||||
|
<literal>JIGASI_SIPPORT</literal>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkOption {
|
||||||
|
type = attrsOf str;
|
||||||
|
default = { };
|
||||||
|
example = literalExample ''
|
||||||
|
{
|
||||||
|
"org.jitsi.jigasi.auth.URL" = "XMPP:jitsi-meet.example.com";
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
Contents of the <filename>sip-communicator.properties</filename> configuration file for jigasi.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
services.jicofo.config = {
|
||||||
|
"org.jitsi.jicofo.jigasi.BREWERY" = "${cfg.bridgeMuc}";
|
||||||
|
};
|
||||||
|
|
||||||
|
services.jigasi.config = mapAttrs (_: v: mkDefault v) {
|
||||||
|
"org.jitsi.jigasi.BRIDGE_MUC" = cfg.bridgeMuc;
|
||||||
|
};
|
||||||
|
|
||||||
|
users.groups.jitsi-meet = {};
|
||||||
|
|
||||||
|
systemd.services.jigasi = let
|
||||||
|
jigasiProps = {
|
||||||
|
"-Dnet.java.sip.communicator.SC_HOME_DIR_LOCATION" = "${stateDir}";
|
||||||
|
"-Dnet.java.sip.communicator.SC_HOME_DIR_NAME" = "${homeDirName}";
|
||||||
|
"-Djava.util.logging.config.file" = "${pkgs.jigasi}/etc/jitsi/jigasi/logging.properties";
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
description = "Jitsi Gateway to SIP";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
after = [ "network.target" ];
|
||||||
|
|
||||||
|
preStart = ''
|
||||||
|
[ -f "${sipCommunicatorPropertiesFile}" ] && rm -f "${sipCommunicatorPropertiesFile}"
|
||||||
|
mkdir -p "$(dirname ${sipCommunicatorPropertiesFile})"
|
||||||
|
temp="${sipCommunicatorPropertiesFile}.unsubstituted"
|
||||||
|
|
||||||
|
export DOMAIN_BASE="${cfg.xmppDomain}"
|
||||||
|
export JIGASI_XMPP_PASSWORD=$(cat "${cfg.userPasswordFile}")
|
||||||
|
export JIGASI_DEFAULT_JVB_ROOM_NAME="${cfg.defaultJvbRoomName}"
|
||||||
|
|
||||||
|
# encode the credentials to base64
|
||||||
|
export JIGASI_SIPPWD=$(echo -n "$JIGASI_SIPPWD" | base64 -w 0)
|
||||||
|
export JIGASI_XMPP_PASSWORD_BASE64=$(cat "${cfg.userPasswordFile}" | base64 -w 0)
|
||||||
|
|
||||||
|
cp "${sipCommunicatorPropertiesFileUnsubstituted}" "$temp"
|
||||||
|
chmod 644 "$temp"
|
||||||
|
cat <<EOF >>"$temp"
|
||||||
|
net.java.sip.communicator.impl.protocol.sip.acc1403273890647.SERVER_PORT=$JIGASI_SIPPORT
|
||||||
|
net.java.sip.communicator.impl.protocol.sip.acc1403273890647.PREFERRED_TRANSPORT=udp
|
||||||
|
EOF
|
||||||
|
chmod 444 "$temp"
|
||||||
|
|
||||||
|
# Replace <<$VAR_NAME>> from example config to $VAR_NAME for environment substitution
|
||||||
|
sed -i -E \
|
||||||
|
's/<<([^>]+)>>/\$\1/g' \
|
||||||
|
"$temp"
|
||||||
|
|
||||||
|
sed -i \
|
||||||
|
's|\(net\.java\.sip\.communicator\.impl\.protocol\.jabber\.acc-xmpp-1\.PASSWORD=\).*|\1\$JIGASI_XMPP_PASSWORD_BASE64|g' \
|
||||||
|
"$temp"
|
||||||
|
|
||||||
|
sed -i \
|
||||||
|
's|\(#\)\(org.jitsi.jigasi.DEFAULT_JVB_ROOM_NAME=\).*|\2\$JIGASI_DEFAULT_JVB_ROOM_NAME|g' \
|
||||||
|
"$temp"
|
||||||
|
|
||||||
|
${pkgs.envsubst}/bin/envsubst \
|
||||||
|
-o "${sipCommunicatorPropertiesFile}" \
|
||||||
|
-i "$temp"
|
||||||
|
|
||||||
|
# Set the brewery room name
|
||||||
|
sed -i \
|
||||||
|
's|\(net\.java\.sip\.communicator\.impl\.protocol\.jabber\.acc-xmpp-1\.BREWERY=\).*|\1${cfg.bridgeMuc}|g' \
|
||||||
|
"${sipCommunicatorPropertiesFile}"
|
||||||
|
sed -i \
|
||||||
|
's|\(org\.jitsi\.jigasi\.ALLOWED_JID=\).*|\1${cfg.bridgeMuc}|g' \
|
||||||
|
"${sipCommunicatorPropertiesFile}"
|
||||||
|
|
||||||
|
|
||||||
|
# Disable certificate verification for self-signed certificates
|
||||||
|
sed -i \
|
||||||
|
's|\(# \)\(net.java.sip.communicator.service.gui.ALWAYS_TRUST_MODE_ENABLED=true\)|\2|g' \
|
||||||
|
"${sipCommunicatorPropertiesFile}"
|
||||||
|
'';
|
||||||
|
|
||||||
|
restartTriggers = [
|
||||||
|
config.environment.etc."jitsi/jigasi/sip-communicator.properties".source
|
||||||
|
];
|
||||||
|
environment.JAVA_SYS_PROPS = concatStringsSep " " (mapAttrsToList (k: v: "${k}=${toString v}") jigasiProps);
|
||||||
|
|
||||||
|
script = ''
|
||||||
|
${pkgs.jigasi}/bin/jigasi \
|
||||||
|
--host="${cfg.xmppHost}" \
|
||||||
|
--domain="${if cfg.xmppDomain == null then cfg.xmppHost else cfg.xmppDomain}" \
|
||||||
|
--secret="$(cat ${cfg.componentPasswordFile})" \
|
||||||
|
--user_name="${cfg.userName}" \
|
||||||
|
--user_domain="${cfg.userDomain}" \
|
||||||
|
--user_password="$(cat ${cfg.userPasswordFile})" \
|
||||||
|
--configdir="${stateDir}" \
|
||||||
|
--configdirname="${homeDirName}"
|
||||||
|
'';
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "exec";
|
||||||
|
|
||||||
|
DynamicUser = true;
|
||||||
|
User = "jigasi";
|
||||||
|
Group = "jitsi-meet";
|
||||||
|
|
||||||
|
CapabilityBoundingSet = "";
|
||||||
|
NoNewPrivileges = true;
|
||||||
|
ProtectSystem = "strict";
|
||||||
|
ProtectHome = true;
|
||||||
|
PrivateTmp = true;
|
||||||
|
PrivateDevices = true;
|
||||||
|
ProtectHostname = true;
|
||||||
|
ProtectKernelTunables = true;
|
||||||
|
ProtectKernelModules = true;
|
||||||
|
ProtectControlGroups = true;
|
||||||
|
RestrictAddressFamilies = [ "AF_INET" "AF_INET6" "AF_UNIX" ];
|
||||||
|
RestrictNamespaces = true;
|
||||||
|
LockPersonality = true;
|
||||||
|
RestrictRealtime = true;
|
||||||
|
RestrictSUIDSGID = true;
|
||||||
|
StateDirectory = baseNameOf stateDir;
|
||||||
|
EnvironmentFile = cfg.environmentFile;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
environment.etc."jitsi/jigasi/sip-communicator.properties".source =
|
||||||
|
mkDefault "${sipCommunicatorPropertiesFile}";
|
||||||
|
environment.etc."jitsi/jigasi/logging.properties".source =
|
||||||
|
mkDefault "${stateDir}/logging.properties-journal";
|
||||||
|
};
|
||||||
|
|
||||||
|
meta.maintainers = lib.teams.jitsi.members;
|
||||||
|
}
|
|
@ -35,6 +35,7 @@ let
|
||||||
domain = cfg.hostName;
|
domain = cfg.hostName;
|
||||||
muc = "conference.${cfg.hostName}";
|
muc = "conference.${cfg.hostName}";
|
||||||
focus = "focus.${cfg.hostName}";
|
focus = "focus.${cfg.hostName}";
|
||||||
|
jigasi = "jigasi.${cfg.hostName}";
|
||||||
};
|
};
|
||||||
bosh = "//${cfg.hostName}/http-bind";
|
bosh = "//${cfg.hostName}/http-bind";
|
||||||
websocket = "wss://${cfg.hostName}/xmpp-websocket";
|
websocket = "wss://${cfg.hostName}/xmpp-websocket";
|
||||||
|
@ -145,6 +146,16 @@ in
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
jigasi.enable = mkOption {
|
||||||
|
type = bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Whether to enable jigasi instance and configure it to connect to Prosody.
|
||||||
|
|
||||||
|
Additional configuration is possible with <option>services.jigasi</option>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
nginx.enable = mkOption {
|
nginx.enable = mkOption {
|
||||||
type = bool;
|
type = bool;
|
||||||
default = true;
|
default = true;
|
||||||
|
@ -224,7 +235,7 @@ in
|
||||||
roomDefaultPublicJids = true;
|
roomDefaultPublicJids = true;
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
storage = "memory"
|
storage = "memory"
|
||||||
admins = { "focus@auth.${cfg.hostName}", "jvb@auth.${cfg.hostName}" }
|
admins = { "focus@auth.${cfg.hostName}", "jvb@auth.${cfg.hostName}", "jigasi@auth.${cfg.hostName}" }
|
||||||
'';
|
'';
|
||||||
#-- muc_room_cache_size = 1000
|
#-- muc_room_cache_size = 1000
|
||||||
}
|
}
|
||||||
|
@ -263,6 +274,9 @@ in
|
||||||
Component "focus.${cfg.hostName}" "client_proxy"
|
Component "focus.${cfg.hostName}" "client_proxy"
|
||||||
target_address = "focus@auth.${cfg.hostName}"
|
target_address = "focus@auth.${cfg.hostName}"
|
||||||
|
|
||||||
|
Component "jigasi.${cfg.hostName}" "client_proxy"
|
||||||
|
target_address = "jigasi@auth.${cfg.hostName}"
|
||||||
|
|
||||||
Component "speakerstats.${cfg.hostName}" "speakerstats_component"
|
Component "speakerstats.${cfg.hostName}" "speakerstats_component"
|
||||||
muc_component = "conference.${cfg.hostName}"
|
muc_component = "conference.${cfg.hostName}"
|
||||||
|
|
||||||
|
@ -356,7 +370,10 @@ in
|
||||||
${config.services.prosody.package}/bin/prosodyctl mod_roster_command subscribe focus.${cfg.hostName} focus@auth.${cfg.hostName}
|
${config.services.prosody.package}/bin/prosodyctl mod_roster_command subscribe focus.${cfg.hostName} focus@auth.${cfg.hostName}
|
||||||
${config.services.prosody.package}/bin/prosodyctl register jibri auth.${cfg.hostName} "$(cat /var/lib/jitsi-meet/jibri-auth-secret)"
|
${config.services.prosody.package}/bin/prosodyctl register jibri auth.${cfg.hostName} "$(cat /var/lib/jitsi-meet/jibri-auth-secret)"
|
||||||
${config.services.prosody.package}/bin/prosodyctl register recorder recorder.${cfg.hostName} "$(cat /var/lib/jitsi-meet/jibri-recorder-secret)"
|
${config.services.prosody.package}/bin/prosodyctl register recorder recorder.${cfg.hostName} "$(cat /var/lib/jitsi-meet/jibri-recorder-secret)"
|
||||||
|
'' + optionalString cfg.jigasi.enable ''
|
||||||
|
${config.services.prosody.package}/bin/prosodyctl register jigasi auth.${cfg.hostName} "$(cat /var/lib/jitsi-meet/jigasi-user-secret)"
|
||||||
'';
|
'';
|
||||||
|
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
EnvironmentFile = [ "/var/lib/jitsi-meet/secrets-env" ];
|
EnvironmentFile = [ "/var/lib/jitsi-meet/secrets-env" ];
|
||||||
SupplementaryGroups = [ "jitsi-meet" ];
|
SupplementaryGroups = [ "jitsi-meet" ];
|
||||||
|
@ -371,13 +388,13 @@ in
|
||||||
|
|
||||||
systemd.services.jitsi-meet-init-secrets = {
|
systemd.services.jitsi-meet-init-secrets = {
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
before = [ "jicofo.service" "jitsi-videobridge2.service" ] ++ (optional cfg.prosody.enable "prosody.service");
|
before = [ "jicofo.service" "jitsi-videobridge2.service" ] ++ (optional cfg.prosody.enable "prosody.service") ++ (optional cfg.jigasi.enable "jigasi.service");
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Type = "oneshot";
|
Type = "oneshot";
|
||||||
};
|
};
|
||||||
|
|
||||||
script = let
|
script = let
|
||||||
secrets = [ "jicofo-component-secret" "jicofo-user-secret" "jibri-auth-secret" "jibri-recorder-secret" ] ++ (optional (cfg.videobridge.passwordFile == null) "videobridge-secret");
|
secrets = [ "jicofo-component-secret" "jicofo-user-secret" "jibri-auth-secret" "jibri-recorder-secret" ] ++ (optionals cfg.jigasi.enable [ "jigasi-user-secret" "jigasi-component-secret" ]) ++ (optional (cfg.videobridge.passwordFile == null) "videobridge-secret");
|
||||||
in
|
in
|
||||||
''
|
''
|
||||||
cd /var/lib/jitsi-meet
|
cd /var/lib/jitsi-meet
|
||||||
|
@ -391,6 +408,7 @@ in
|
||||||
|
|
||||||
# for easy access in prosody
|
# for easy access in prosody
|
||||||
echo "JICOFO_COMPONENT_SECRET=$(cat jicofo-component-secret)" > secrets-env
|
echo "JICOFO_COMPONENT_SECRET=$(cat jicofo-component-secret)" > secrets-env
|
||||||
|
echo "JIGASI_COMPONENT_SECRET=$(cat jigasi-component-secret)" >> secrets-env
|
||||||
chown root:jitsi-meet secrets-env
|
chown root:jitsi-meet secrets-env
|
||||||
chmod 640 secrets-env
|
chmod 640 secrets-env
|
||||||
''
|
''
|
||||||
|
@ -592,6 +610,20 @@ in
|
||||||
stripFromRoomDomain = "conference.";
|
stripFromRoomDomain = "conference.";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
services.jigasi = mkIf cfg.jigasi.enable {
|
||||||
|
enable = true;
|
||||||
|
xmppHost = "localhost";
|
||||||
|
xmppDomain = cfg.hostName;
|
||||||
|
userDomain = "auth.${cfg.hostName}";
|
||||||
|
userName = "jigasi";
|
||||||
|
userPasswordFile = "/var/lib/jitsi-meet/jigasi-user-secret";
|
||||||
|
componentPasswordFile = "/var/lib/jitsi-meet/jigasi-component-secret";
|
||||||
|
bridgeMuc = "jigasibrewery@internal.${cfg.hostName}";
|
||||||
|
config = {
|
||||||
|
"org.jitsi.jigasi.ALWAYS_TRUST_MODE_ENABLED" = "true";
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
meta.doc = ./jitsi-meet.md;
|
meta.doc = ./jitsi-meet.md;
|
||||||
|
|
46
pkgs/servers/jigasi/default.nix
Normal file
46
pkgs/servers/jigasi/default.nix
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
{ lib, stdenv, fetchurl, dpkg, jdk11, nixosTests }:
|
||||||
|
|
||||||
|
let
|
||||||
|
pname = "jigasi";
|
||||||
|
version = "1.1-311-g3de47d0";
|
||||||
|
src = fetchurl {
|
||||||
|
url = "https://download.jitsi.org/stable/${pname}_${version}-1_all.deb";
|
||||||
|
hash = "sha256-pwUgkId7AHFjbqYo02fBgm0gsiMqEz+wvwkdy6sgTD0=";
|
||||||
|
};
|
||||||
|
in
|
||||||
|
stdenv.mkDerivation {
|
||||||
|
inherit pname version src;
|
||||||
|
|
||||||
|
nativeBuildInputs = [ dpkg ];
|
||||||
|
|
||||||
|
dontBuild = true;
|
||||||
|
|
||||||
|
unpackCmd = "dpkg-deb -x $src debcontents";
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
runHook preInstall
|
||||||
|
substituteInPlace usr/share/${pname}/${pname}.sh \
|
||||||
|
--replace "exec java" "exec ${jdk11}/bin/java"
|
||||||
|
|
||||||
|
mkdir -p $out/{share,bin}
|
||||||
|
mv usr/share/${pname} $out/share/
|
||||||
|
mv etc $out/
|
||||||
|
ln -s $out/share/${pname}/${pname}.sh $out/bin/${pname}
|
||||||
|
runHook postInstall
|
||||||
|
'';
|
||||||
|
|
||||||
|
passthru.tests = {
|
||||||
|
single-node-smoke-test = nixosTests.jitsi-meet;
|
||||||
|
};
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
description = "A server-side application that allows regular SIP clients to join Jitsi Meet conferences";
|
||||||
|
longDescription = ''
|
||||||
|
Jitsi Gateway to SIP: a server-side application that allows regular SIP clients to join Jitsi Meet conferences hosted by Jitsi Videobridge.
|
||||||
|
'';
|
||||||
|
homepage = "https://github.com/jitsi/jigasi";
|
||||||
|
license = licenses.asl20;
|
||||||
|
maintainers = teams.jitsi.members;
|
||||||
|
platforms = platforms.linux;
|
||||||
|
};
|
||||||
|
}
|
|
@ -26587,6 +26587,8 @@ with pkgs;
|
||||||
|
|
||||||
jitsi-excalidraw = callPackage ../servers/jitsi-excalidraw { };
|
jitsi-excalidraw = callPackage ../servers/jitsi-excalidraw { };
|
||||||
|
|
||||||
|
jigasi = callPackage ../servers/jigasi { };
|
||||||
|
|
||||||
jitsi-meet = callPackage ../servers/web-apps/jitsi-meet { };
|
jitsi-meet = callPackage ../servers/web-apps/jitsi-meet { };
|
||||||
|
|
||||||
jitsi-meet-prosody = callPackage ../misc/jitsi-meet-prosody { };
|
jitsi-meet-prosody = callPackage ../misc/jitsi-meet-prosody { };
|
||||||
|
|
Loading…
Reference in a new issue