Update to 2021-12-01 19:13

This commit is contained in:
Daniel Berteaud
2021-12-01 19:13:34 +01:00
commit 4c4556c660
2153 changed files with 60999 additions and 0 deletions

View File

@@ -0,0 +1 @@
In developpment, not usable yet

View File

@@ -0,0 +1,28 @@
---
jitsi_root_dir: /opt/jitsi
jitsi_jibri_user: jibri
jitsi_jibri_git_url: https://github.com/jitsi/jibri.git
# Should ansible manage upgrades or only initial install
jitsi_jibri_manage_upgrade: "{{ jitsi_manage_upgrade | default(True) }}"
jitsi_jibri_domain: "{{ jitsi_domain | default(inventory_hostname) }}"
jitsi_jibri_auth_domain: "{{ jitsi_auth_domain | default('auth.' ~ jitsi_domain) }}"
jitsi_jibri_internal_auth_domain: internal.{{ jitsi_jibri_auth_domain }}
# XMPP password to connect to
jitsi_jibri_xmpp_server: "{{ jitsi_xmpp_server | default(inventory_hostname) }}"
jitsi_jibri_xmpp_user: jibri
jitsi_jibri_xmpp_domain: recorder.{{ jitsi_jibri_domain }}
# A random pass will be created if not defined
# jitsi_jibri_xmpp_pass: s3cr3t.
jitsi_jibri_recorder_xmpp_user: recorder
# jitsi_jibri_recorder_xmpp_pass: p@ssw0rd
# List of email address which will be notified when a recording is finished
jitsi_jibri_recording_notify: []
# Base URL where you can reach your Jitsi host.
# Might need to be adjusted if running behing a reverse proxy
jitsi_jibri_recordings_base_url: https://{{ inventory_hostname }}/recordings

View File

@@ -0,0 +1,5 @@
---
- name: restart jitsi-jibri
service: name=jitsi-jibri state=restarted

View File

@@ -0,0 +1,6 @@
---
dependencies:
- role: repo_rpmfusion # For ffmpeg
- role: repo_google_chrome # For, well, Google Chrome ;-)
- role: nginx # For nginx, to expose recordings

View File

@@ -0,0 +1,8 @@
---
- name: Remove tmp and obsolete files
file: path={{ item }} state=absent
loop:
- "{{ jitsi_root_dir }}/tmp/chromedriver_linux64.zip"
- "{{ jitsi_root_dir }}/tmp/chromedriver"
tags: jitsi

View File

@@ -0,0 +1,60 @@
---
- name: Deploy configuration
template: src={{ item.src }} dest={{ item.dest }}
loop:
- src: xorg-video-dummy.conf.j2
dest: /etc/X11/xorg.conf.d/jibri.conf
- src: jibri.conf.j2
dest: "{{ jitsi_root_dir }}/etc/jibri/jibri.conf"
notify: restart jitsi-jibri
tags: jitsi
- name: Configure pam
copy:
content: |
#%PAM-1.0
auth required pam_permit.so
account required pam_permit.so
dest: /etc/pam.d/xserver
tags: jitsi
- name: Allow any user to run Xorg
copy:
content: allowed_users = anybody
dest: /etc/X11/Xwrapper.config
tags: jitsi
- name: Create Chrome policy dir
file: path=/etc/opt/chrome/policies/managed/ state=directory
tags: jitsi
- name: Configure Chrome policy
copy:
content: |
{ "CommandLineFlagSecurityWarningsEnabled": false }
dest: /etc/opt/chrome/policies/managed/managed_policies.json
tags: jitsi
- name: Ensure snd-aloop is loaded
modprobe: name=snd-aloop state=present
tags: jitsi
- name: Configure snd-aloop to be loaded on boot
copy:
content: snd-aloop
dest: /etc/modules-load.d/jibri.conf
tags: jitsi
- name: Configure asound
template: src=asound.conf.j2 dest={{ jitsi_root_dir }}/jibri/.asoundrc owner={{ jitsi_jibri_user }}
tags: jitsi
- name: Configure nginx to serve recordings
template: src=nginx.conf.j2 dest=/etc/nginx/ansible_location.d/10-jitsi-jibri.conf
notify: reload nginx
tags: jitsi
- name: Configure the finalize script
template: src=finalize.yml.j2 dest={{ jitsi_root_dir }}/etc/jibri/finalize.yml
tags: jitsi

View File

@@ -0,0 +1,18 @@
---
- name: Create directories
file: path={{ item.dir }} state=directory owner={{ item.owner | default(omit) }} group={{ item.group | default(omit) }} mode={{ item.mode | default(omit) }}
loop:
- dir: "{{ jitsi_root_dir }}/src/jibri"
owner: "{{ jitsi_jibri_user }}"
- dir: "{{ jitsi_root_dir }}/jibri"
owner: "{{ jitsi_jibri_user }}"
mode: 700
- dir: "{{ jitsi_root_dir }}/etc/jibri"
group: "{{ jitsi_jibri_user }}"
mode: 750
- dir: "{{ jitsi_root_dir }}/data/recordings"
owner: "{{ jitsi_jibri_user }}"
group: nginx
mode: 750
tags: jitsi

View File

@@ -0,0 +1,43 @@
---
- name: Generate a random pass for jibri
block:
- import_tasks: ../includes/get_rand_pass.yml
vars:
- pass_file: "{{ jitsi_root_dir }}/meta/ansible_jibri_xmpp_pass"
- set_fact: jitsi_jibri_xmpp_pass={{ rand_pass }}
when: jitsi_jibri_xmpp_pass is not defined
tags: jitsi
- name: Generate a random pass for recorder
block:
- import_tasks: ../includes/get_rand_pass.yml
vars:
- pass_file: "{{ jitsi_root_dir }}/meta/ansible_jibri_recorder_xmpp_pass"
- set_fact: jitsi_jibri_recorder_xmpp_pass={{ rand_pass }}
when: jitsi_jibri_recorder_xmpp_pass is not defined
tags: jitsi
- name: Check if jibri is built
stat: path={{ jitsi_root_dir }}/jibri/jibri.jar
register: jitsi_jibri_jar
tags: jitsi
- name: Check latest version of ChromeDriver
uri:
url: https://chromedriver.storage.googleapis.com/LATEST_RELEASE
return_content: True
register: jitsi_jibri_chromedriver_latest_version
tags: jitsi
- name: Check if ChromeDriver is installed
stat: path=/usr/local/bin/chromedriver
register: jitsi_jibri_chromedriver_bin
tags: jitsi
- name: Detect ChromeDriver version
shell: chromedriver --version | perl -pe 's/ChromeDriver (\d+(\.\d+)+).*/$1/'
register: jitsi_jibri_chromedriver_current_version
when: jitsi_jibri_chromedriver_bin.stat.exists
changed_when: False
tags: jitsi

View File

@@ -0,0 +1,94 @@
---
- name: Install dependencies
yum:
name:
- java-1.8.0-openjdk
- git
- google-chrome-stable
- ffmpeg
- curl
- alsa-utils
- xdotool
#- xorg-x11-drv-void
- xorg-x11-drv-dummy
- perl-YAML-Tiny
- perl-Email-MIME
- perl-Email-Sender
tags: jitsi
# If the repo changed since the last run, we rebuild and restart the bridge
- name: Clone jibri repo
git:
repo: "{{ jitsi_jibri_git_url }}"
dest: "{{ jitsi_root_dir }}/src/jibri"
force: True
become_user: "{{ jitsi_jibri_user }}"
register: jitsi_jibri_git
tags: jitsi
- name: Install or update ChromeDriver
block:
- name: Download ChromeDriver
get_url:
url: http://chromedriver.storage.googleapis.com/{{ jitsi_jibri_chromedriver_latest_version.content }}/chromedriver_linux64.zip
dest: "{{ jitsi_root_dir }}/tmp"
- name: Extract ChromeDriver
unarchive:
src: "{{ jitsi_root_dir }}/tmp/chromedriver_linux64.zip"
dest: "{{ jitsi_root_dir }}/tmp"
remote_src: True
- name: Move ChromeDriver bin
copy:
src: "{{ jitsi_root_dir }}/tmp/chromedriver"
dest: /usr/local/bin/chromedriver
mode: 755
remote_src: True
when: not jitsi_jibri_chromedriver_bin.stat.exists or jitsi_jibri_chromedriver_current_version.stdout != jitsi_jibri_chromedriver_latest_version.content
tags: jitsi
- name: Install or update jibri
block:
- name: Build jibri
command: /opt/maven/apache-maven/bin/mvn package -DskipTests -Dassembly.skipAssembly=false
args:
chdir: "{{ jitsi_root_dir }}/src/jibri"
become_user: "{{ jitsi_jibri_user }}"
- name: Move jibri to its final directory
copy:
src: "{{ jitsi_root_dir }}/src/jibri/target/jibri-8.0-SNAPSHOT-jar-with-dependencies.jar"
dest: "{{ jitsi_root_dir }}/jibri/jibri.jar"
remote_src: True
notify: restart jitsi-jibri
when: (jitsi_jibri_git.changed and jitsi_jibri_manage_upgrade) or not jitsi_jibri_jar.stat.exists
tags: jitsi
- name: Deploy systemd units
template: src=jitsi-{{ item }}.j2 dest=/etc/systemd/system/jitsi-{{ item }}
loop:
- jibri.service
- jibri-xorg.service
- jibri-cleaner.service
- jibri-cleaner.timer
register: jitsi_jibri_unit
notify: restart jitsi-jibri
tags: jitsi
- name: Reload systemd
systemd: daemon_reload=True
when: jitsi_jibri_unit.results | selectattr('changed','equalto',True) | list | length > 0
tags: jitsi
- name: Install finalize script
template: src=finalize.pl.j2 dest={{ jitsi_root_dir }}/jibri/finalize.pl mode=755
tags: jitsi
- name: Install record cleaning script
template: src=clean_records.sh.j2 dest={{ jitsi_root_dir }}/jibri/clean_records.sh mode=755
tags: jitsi

View File

@@ -0,0 +1,9 @@
---
- include: user.yml
- include: directories.yml
- include: facts.yml
- include: install.yml
- include: conf.yml
- include: services.yml
- include: cleanup.yml

View File

@@ -0,0 +1,9 @@
---
- name: Start and enable services
service: name=jitsi-jibri state=started enabled=True
tags: jitsi
- name: Start cleaer timer
systemd: name=jitsi-jibri-cleaner.timer state=started enabled=True
tags: jitsi

View File

@@ -0,0 +1,11 @@
---
- name: Create jibri user account
user:
name: "{{ jitsi_jibri_user }}"
home: "{{ jitsi_root_dir }}/jibri"
groups:
- tty
- video
- audio
tags: jitsi

View File

@@ -0,0 +1,46 @@
pcm.amix {
type dmix
ipc_key 219345
slave.pcm "hw:Loopback,0,0"
}
pcm.asnoop {
type dsnoop
ipc_key 219346
slave.pcm "hw:Loopback_1,1,0"
}
pcm.aduplex {
type asym
playback.pcm "amix"
capture.pcm "asnoop"
}
pcm.bmix {
type dmix
ipc_key 219347
slave.pcm "hw:Loopback_1,0,0"
}
pcm.bsnoop {
type dsnoop
ipc_key 219348
slave.pcm "hw:Loopback,1,0"
}
pcm.bduplex {
type asym
playback.pcm "bmix"
capture.pcm "bsnoop"
}
pcm.pjsua {
type plug
slave.pcm "bduplex"
}
pcm.!default {
type plug
slave.pcm "aduplex"
}

View File

@@ -0,0 +1,3 @@
#!/bin/bash -e
find {{ jitsi_root_dir }}/data/recordings -maxdepth 1 -type d -mtime +30 -exec rm -rf "{}" \;

View File

@@ -0,0 +1,83 @@
#!/usr/bin/perl -w
use strict;
use warnings;
use JSON;
use YAML::Tiny;
use Getopt::Long;
use Email::MIME;
use Email::Sender::Simple qw(sendmail);
use File::Basename;
use utf8;
my $conf = {};
my $opt = {
config => '{{ jitsi_root_dir }}/etc/jibri/finalize.yml'
};
GetOptions(
"config=s" => \$opt->{config}
);
sub send_mail {
my ($subject, $dest, $body) = @_;
my $mail = Email::MIME->create(
header_str => [
From => $conf->{from},
To => $dest,
Subject => $subject
],
attributes => {
charset => 'utf-8',
encoding => 'base64'
},
body_str => $body
);
sendmail($mail);
}
# Read config file
if (-e $opt->{config}){
my $yaml = YAML::Tiny->read( $opt->{config} )
or die "Config file " . $opt->{config} . " is invalid\n";
if ( not $yaml->[0] ) {
die "Config file " . $opt->{config} . " is invalid\n";
}
$conf = $yaml->[0];
}
$conf->{notify} ||= [];
my $recording = $ARGV[0];
my $metadata = {};
if (-e "$recording/metadata.json"){
open(my $jst, "$recording/metadata.json") or die "$!";
local $/;
$metadata = from_json(<$jst>);
}
my $video = undef;
opendir ( DIR, $recording ) || die "Error in opening dir $recording\n";
while( (my $filename = readdir(DIR))) {
if ($filename =~ m/\.mp4$/){
$video = basename($filename);
last;
}
}
closedir(DIR);
foreach my $participant (@{$metadata->{participants}}){
push @{$conf->{notify}}, $participant->{user}->{id};
}
if (defined $video){
foreach my $dest (@{$conf->{notify}}){
send_mail(
"Enregistrement Jitsi Meet",
$dest,
"L'enregistrement vidéo est disponible à l'adresse $conf->{base_url}/" .
basename($recording) . "/$video\n"
);
}
}

View File

@@ -0,0 +1,10 @@
---
from: jitsi-noreply@{{ ansible_domain }}
{% if jitsi_jibri_recording_notify | length > 0 %}
notify:
{% for dest in jitsi_jibri_recording_notify %}
- {{ dest }}
{% endfor %}
{% endif %}
base_url: {{ jitsi_jibri_recordings_base_url }}

View File

@@ -0,0 +1,88 @@
jibri {
id = "{{ inventory_hostname }}"
single-use-mode = false
api {
http {
external-api-port = 2222
internal-api-port = 3333
}
xmpp {
// See example_xmpp_envs.conf for an example of what is expected here
environments = [
{
name = "prod environment"
xmpp-server-hosts = ["{{ jitsi_jibri_xmpp_server }}"]
xmpp-domain = "{{ jitsi_jibri_domain }}"
control-muc {
domain = "{{ jitsi_jibri_internal_auth_domain }}"
room-name = "JibriBrewery"
nickname = "{{ inventory_hostname }}"
}
control-login {
domain = "{{ jitsi_jibri_auth_domain }}"
username = "{{ jitsi_jibri_xmpp_user }}"
password = "{{ jitsi_jibri_xmpp_pass }}"
}
call-login {
domain = "{{ jitsi_jibri_xmpp_domain }}"
username = "{{ jitsi_jibri_recorder_xmpp_user }}"
password = "{{ jitsi_jibri_recorder_xmpp_pass }}"
}
strip-from-room-domain = "conference."
usage-timeout = 0
trust-all-xmpp-certs = false
}]
}
}
recording {
recordings-directory = "{{ jitsi_root_dir }}/data/recordings"
finalize-script = "{{ jitsi_root_dir }}/jibri/finalize.pl"
}
streaming {
rtmp-allow-list = [
".*"
]
}
ffmpeg {
//resolution = "1024x768"
// The audio source that will be used to capture audio on Linux
audio-source = "alsa"
// The audio device that will be used to capture audio on Linux
audio-device = "plug:bsnoop"
}
chrome {
// The flags which will be passed to chromium when launching
flags = [
"--use-fake-ui-for-media-stream",
//"--start-maximized",
"--window-size=1920,1080",
"--kiosk",
"--enabled",
"--disable-infobars",
"--autoplay-policy=no-user-gesture-required"
]
}
stats {
enable-stats-d = true
}
call-status-checks {
// If all clients have their audio and video muted and if Jibri does not
// detect any data stream (audio or video) comming in, it will stop
// recording after NO_MEDIA_TIMEOUT expires.
no-media-timeout = 30 seconds
// If all clients have their audio and video muted, Jibri consideres this
// as an empty call and stops the recording after ALL_MUTED_TIMEOUT expires.
all-muted-timeout = 10 minutes
// When detecting if a call is empty, Jibri takes into consideration for how
// long the call has been empty already. If it has been empty for more than
// DEFAULT_CALL_EMPTY_TIMEOUT, it will consider it empty and stop the recording.
default-call-empty-timeout = 30 seconds
}
}

View File

@@ -0,0 +1,10 @@
[Unit]
Description=Jibri Recordings Cleaner
[Service]
Type=oneshot
PrivateTmp=yes
User={{ jitsi_jibri_user }}
Group={{ jitsi_jibri_user }}
ExecStart={{ jitsi_root_dir }}/jibri/clean_records.sh

View File

@@ -0,0 +1,10 @@
[Unit]
Description=Jibri Recordings Cleaner
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.target

View File

@@ -0,0 +1,19 @@
[Unit]
Description=Jibri Xorg Process
After=network.target
[Service]
Type=simple
User={{ jitsi_jibri_user }}
Group={{ jitsi_jibri_user }}
Environment=DISPLAY=:0
WorkingDirectory={{ jitsi_root_dir }}/etc/jibri/
ExecStart=/usr/bin/Xorg -nocursor -noreset +extension RANDR +extension RENDER -config jibri.conf :0
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartPreventExitStatus=255
SyslogIdentifier=jibri-xorg
[Install]
WantedBy=jitsi-jibri.service

View File

@@ -0,0 +1,20 @@
[Unit]
Description=Jitsi Broadcasting Infrastructure
After=network.target
Requires=jitsi-jibri-xorg.service
[Service]
Type=simple
SuccessExitStatus=143
User={{ jitsi_jibri_user }}
Group={{ jitsi_jibri_user }}
PrivateTmp=true
Restart=always
StartLimitInterval=0
RestartSec=30
ExecStart=/bin/java -Dconfig.file={{ jitsi_root_dir }}/etc/jibri/jibri.conf -jar {{ jitsi_root_dir }}/jibri/jibri.jar
SyslogIdentifier=jibri
[Install]
WantedBy=multi-user.target

View File

@@ -0,0 +1,5 @@
# Serve recordings through nginx
location /recordings {
alias /opt/jitsi/data/recordings;
add_header Content-disposition "attachment";
}

View File

@@ -0,0 +1,26 @@
Section "Device"
Identifier "Configured Video Device"
Driver "dummy"
VideoRam 256000
EndSection
Section "Monitor"
Identifier "Configured Monitor"
HorizSync 5.0 - 1000.0
VertRefresh 5.0 - 200.0
ModeLine "1920x1080" 148.50 1920 2448 2492 2640 1080 1084 1089 1125 +Hsync +Vsync
EndSection
Section "Screen"
Identifier "Default Screen"
Monitor "Configured Monitor"
Device "Configured Video Device"
DefaultDepth 24
SubSection "Display"
Depth 24
Modes "1920x1080"
EndSubSection
EndSection