1
0
Fork 0
mirror of https://github.com/YunoHost-Apps/galene_ynh.git synced 2024-09-03 18:36:31 +02:00

Merge branch 'testing' of https://github.com/YunoHost-Apps/galene_ynh into testing

This commit is contained in:
ericgaspar 2021-09-05 22:08:27 +02:00
commit 73d7ab73b3
No known key found for this signature in database
GPG key ID: 574F281483054D44
30 changed files with 288 additions and 690 deletions

View file

@ -1,2 +0,0 @@
.DS_Store
._.DS_Store

View file

@ -3,14 +3,14 @@ N.B.: This README was automatically generated by https://github.com/YunoHost/app
It shall NOT be edited by hand. It shall NOT be edited by hand.
--> -->
# Galene for YunoHost # Galène for YunoHost
[![Integration level](https://dash.yunohost.org/integration/galene.svg)](https://dash.yunohost.org/appci/app/galene) ![](https://ci-apps.yunohost.org/ci/badges/galene.status.svg) ![](https://ci-apps.yunohost.org/ci/badges/galene.maintain.svg) [![Integration level](https://dash.yunohost.org/integration/galene.svg)](https://dash.yunohost.org/appci/app/galene) ![](https://ci-apps.yunohost.org/ci/badges/galene.status.svg) ![](https://ci-apps.yunohost.org/ci/badges/galene.maintain.svg)
[![Install Galene with YunoHost](https://install-app.yunohost.org/install-with-yunohost.svg)](https://install-app.yunohost.org/?app=galene) [![Install Galene with YunoHost](https://install-app.yunohost.org/install-with-yunohost.svg)](https://install-app.yunohost.org/?app=galene)
*[Lire ce readme en français.](./README_fr.md)* *[Lire ce readme en français.](./README_fr.md)*
> *This package allows you to install Galene quickly and simply on a YunoHost server. > *This package allows you to install Galène quickly and simply on a YunoHost server.
If you don't have YunoHost, please consult [the guide](https://yunohost.org/#/install) to learn how to install it.* If you don't have YunoHost, please consult [the guide](https://yunohost.org/#/install) to learn how to install it.*
## Overview ## Overview
@ -27,41 +27,51 @@ Videoconferencing server that is easy to deploy
## Disclaimers / important information ## Disclaimers / important information
### How to creat groups ### Accessing groups
Groups are defined by files in the `/opt/yunohost/galene/groups` directory. Various options are available (see https://github.com/YunoHost-Apps/galene_ynh/wiki/Configuration-file) *Galène* meeting rooms are called "groups". Any group is accessible at `https://domain.tld/group/GroupName`, by typing its name in the home page search field, or by selecting it in the public list (if the group is configured as publicly visible, see below).
### TURN server #### Creating and configuring groups
For VoIP and video conferencing a TURN server is also installed and configured. The TURN server listens on two UDP and TCP ports. You can get them with these commands: Groups are defined by JSON files located in the *Galène* folder (`/opt/yunohost/galene/groups`). Each group is represented by a `GroupName.json` file.
To create a new group, you need to create a `GroupNameExample.json` file (you can also make subfolder groups, and the groups will be accessible with `https://domain.tld/group/subfolder/GroupName`). Various configuration options are available (see https://github.com/YunoHost-Apps/galene_ynh/wiki/Configuration-file).
*NB: spaces are supported in group file names.*
### Configuring your TURN server
#### Using *Galène*'s TURN server
Galène comes with a built-in TURN server that should work out-of-the-box.
- If your server is behind NAT, allow incoming traffic to TCP port `8443` (or whatever is configured with the `-http` option in `/etc/systemd/system/galene.service`) and TCP/UDP port `1194` (or whatever is configured with the `-turn` option in `/etc/systemd/system/galene.service`)
#### Using your own TURN server
- Install [coturn_ynh](https://github.com/YunoHost-Apps/coturn_ynh).
- Add `/opt/yunohost/galene/data/ice-servers.json` with these lines and change `turn.example.org` and `secret`
``` ```
sudo yunohost app setting galene turnserver_port [
{
"urls": [
"turn:turn.example.org:5349",
"turn:turn.example.org:5349?transport=tcp"
],
"username": "galene",
"credential": "secret"
}
]
``` ```
- set `/etc/systemd/system/galene.service` `-turn` option to `-turn auto` (or `-turn ""` to disable the built-in TURN server).
The TURN server will also choose a port dynamically when a new call starts. The range is between 49152 - 65535. To check if the TURN server is up and running, type `/relay-test` in the chat box. If the TURN server is properly configured, you should see a message saying that the relay test has been successful.
For security reason the ports range (49152 - 65535) isn't automatically open by default. If you want to use Galène server for VoIP or conferencing you will need to open this port range manually. To do this, just run this command: ### Server Statistics page
``` Some statistics are available under `/opt/yunohost/galene/stats.json`, with a human-readable version at `domain.ltd/stats.html`. This is only available to the server administrator.
sudo yunohost firewall allow Both 49152:65535
```
You might also need to open these ports (if it is not automatically done) on your ISP box.
To prevent the situation when the server is behind a NAT, the public IP is written in the TURN server config. By this the TURN server can send its real public IP to the client. For more information see the [Coturn example config file](https://github.com/coturn/coturn/blob/master/examples/etc/turnserver.conf#L56-L62). So if your IP changes, you could run the script `/opt/yunohost/galene/Coturn_config_rotate.sh` to update your config.
If you have a dynamic IP address, you also might need to update this config automatically. To do that just edit a file named `/etc/cron.d/coturn_config_rotate` and add the following content.
```
*/15 * * * * root bash /opt/yunohost/galene/Coturn_config_rotate.sh;
```
To check if Galène can connect to the TURN server, connect to Galène as operator and type `/relay-test` in the chat box; if the TURN server is properly configured, you should see a message saying that the relay test has been successful.
## Documentation and resources ## Documentation and resources
* Official app website: https://galene.org * Official app website: https://galene.org/
* Official user documentation: https://yunohost.org/en/app_galene
* Official admin documentation: https://galene.org/ * Official admin documentation: https://galene.org/
* Upstream app code repository: https://github.com/jech/galene * Upstream app code repository: https://github.com/jech/galene
* YunoHost documentation for this app: https://yunohost.org/app_galene * YunoHost documentation for this app: https://yunohost.org/app_galene

View file

@ -6,14 +6,15 @@
*[Read this readme in english.](./README.md)* *[Read this readme in english.](./README.md)*
*[Lire ce readme en français.](./README_fr.md)* *[Lire ce readme en français.](./README_fr.md)*
> *Ce package vous permet d'installer Galene rapidement et simplement sur un serveur YunoHost. > *Ce package vous permet d'installer Galène rapidement et simplement sur un serveur YunoHost.
Si vous n'avez pas YunoHost, regardez [ici](https://yunohost.org/#/install) pour savoir comment l'installer et en profiter.* Si vous n'avez pas YunoHost, regardez [ici](https://yunohost.org/#/install) pour savoir comment l'installer et en profiter.*
## Vue d'ensemble ## Vue d'ensemble
Serveur de visioconférence facile à déployer Galène (ou Galene) est un serveur de visioconférence (un « SFU ») facile à déployer et qui nécessite des ressources serveur modérées. Il a été conçu à l'origine pour les cours et les conférences (où un seul orateur diffuse de l'audio et de la vidéo à des centaines ou des milliers d'utilisateurs), mais a évolué par la suite pour être utile pour les travaux pratiques des étudiants (où les utilisateurs sont divisés en plusieurs petits groupes) et les réunions (où un douzaine d'utilisateurs interagissent entre eux).
**Version incluse :** 0.3.5~ynh3
**Version incluse :** 0.4.0~ynh1
**Démo :** https://galene.org:8443/ **Démo :** https://galene.org:8443/
@ -23,43 +24,51 @@ Serveur de visioconférence facile à déployer
## Avertissements / informations importantes ## Avertissements / informations importantes
## Configuration ### Accéder à des groupes
### Comment créer des groupes Les salles de réunion *Galène* sont appelées « groupes ». Tout groupe est accessible sur `https://domain.tld/group/GroupName`, en tapant son nom dans le champ de recherche de la page d'accueil, ou en le sélectionnant dans la liste publique (si le groupe est configuré comme visible publiquement, voir ci-dessous).
Les groupes sont définis par des fichiers dans le répertoire `/opt/yunohost/galene/groups`. Différentes options sont disponibles (voir https://github.com/YunoHost-Apps/galene_ynh/wiki/Configuration-file) #### Ajouter et configurer des groupes
### Serveur TURN Les groupes sont définis par des fichiers JSON situés dans le dossier *Galène* (`/opt/yunohost/galene/groups`). Chaque groupe est représenté par un fichier `GroupName.json`.
Pour créer un nouveau groupe, vous devez créer un fichier `GroupNameExample.json` (vous pouvez également créer un sous-dossier, et les groupes seront accessibles avec` https://domain.tld/group/subfolder/GroupName`). Différentes options de configurations sont disponibles (voir https://github.com/YunoHost-Apps/galene_ynh/wiki/Configuration-file).
Pour la VoIP et la visioconférence, un serveur TURN est également installé et configuré. Le serveur TURN écoute sur deux ports UDP et TCP. Vous pouvez les obtenir avec ces commandes : *NB : les espaces sont pris en charge dans les noms de fichiers de groupe.*
### Configurer votre serveur TURN
#### Utilisation du serveur TURN de *Galène*
Galène est livré avec un serveur TURN intégré qui devrait fonctionner immédiatement.
- Si votre serveur est derrière NAT, autorisez le trafic entrant vers le port TCP `8443` (ou tout ce qui est configuré avec l'option `-http` dans `/etc/systemd/system/galene.service`) et le port TCP/UDP `1194` (ou tout ce qui est configuré avec l'option `-turn` dans `/etc/systemd/system/galene.service`)
#### Utilisation de votre propre serveur TURN
- Installez [coturn_ynh](https://github.com/YunoHost-Apps/coturn_ynh).
- Ajoutez `/opt/yunohost/galene/data/ice-servers.json` avec ces lignes et changez `turn.example.org` et `secret`
``` ```
sudo yunohost app setting galene turnserver_port [
{
"urls": [
"turn:turn.example.org:5349",
"turn:turn.example.org:5349?transport=tcp"
],
"username": "galene",
"credential": "secret"
}
]
``` ```
- définir l'option de virage de `/etc/systemd/system/galene.service` sur `-turn auto` (ou `-turn ""` pour désactiver le serveur TURN intégré).
Le serveur TURN choisira également un port de manière dynamique lors du démarrage d'une nouvelle visioconférence. La plage est comprise entre 49152 et 65535. Pour vérifier si le serveur TURN est opérationnel, tapez `/relay-test` dans la boîte de dialogue ; si le serveur TURN est correctement configuré, vous devriez voir un message indiquant que le test du relai a réussi.
Par sécurité, la plage de ports (49152 - 65535) n'est pas automatiquement ouverte par défaut. Si vous souhaitez utiliser Galène pour la VoIP ou la visioconférence, vous devrez ouvrir cette plage de ports manuellement. Pour ce faire, exécutez simplement cette commande : ### Statistiques du serveur
``` Certaines statistiques sont disponibles sous `/opt/yunohost/galene/stats.json`, avec une version lisible sur `domain.ltd/stats.html`. Ceci n'est disponible que pour l'administrateur du serveur.
sudo yunohost firewall allow Both 49152:65535
```
Vous devrez peut-être également ouvrir ces ports (si ce n'est pas fait automatiquement) sur votre box.
Pour éviter la situation où le serveur est derrière un NAT, l'adresse IP publique est écrite dans la configuration du serveur TURN. De cette manière, le serveur TURN peut envoyer sa véritable adresse IP publique au client. Pour plus d'informations, consultez [le fichier de configuration d'exemple Coturn](https://github.com/coturn/coturn/blob/master/examples/etc/turnserver.conf#L56-L62). Donc, si votre adresse IP change, vous pouvez exécuter le script `/opt/yunohost/galene/Coturn_config_rotate.sh` pour mettre à jour votre configuration.
Si vous avez une adresse IP dynamique, vous devrez peut-être également mettre à jour cette configuration automatiquement. Pour ce faire, éditez simplement un fichier nommé `/etc/cron.d/coturn_config_rotate` et ajoutez le contenu suivant.
```
* / 15 * * * * root bash /opt/yunohost/galene/Coturn_config_rotate.sh;
```
Pour vérifier si Galène peut se connecter au serveur TURN, connectez-vous à Galène en tant qu'opérateur et tapez `/relay-test` dans la boîte de dialogue chat; si le serveur TURN est correctement configuré, vous devriez voir un message indiquant que le test du relais a réussi.
## Documentations et ressources ## Documentations et ressources
* Site officiel de l'app : https://galene.org * Site officiel de l'app : https://galene.org/
* Documentation officielle utilisateur : https://yunohost.org/en/app_galene
* Documentation officielle de l'admin : https://galene.org/ * Documentation officielle de l'admin : https://galene.org/
* Dépôt de code officiel de l'app : https://github.com/jech/galene * Dépôt de code officiel de l'app : https://github.com/jech/galene
* Documentation YunoHost pour cette app : https://yunohost.org/app_galene * Documentation YunoHost pour cette app : https://yunohost.org/app_galene

View file

@ -4,9 +4,8 @@
path="/path" path="/path"
admin="john" admin="john"
is_public=1 is_public=1
password="pass" password="password"
group_name="public" group_name="public with space"
group_description="My public group"
; Checks ; Checks
pkg_linter=1 pkg_linter=1
setup_sub_dir=0 setup_sub_dir=0
@ -15,7 +14,6 @@
setup_private=1 setup_private=1
setup_public=1 setup_public=1
upgrade=1 upgrade=1
upgrade=1 from_commit=c06f6235a93587e16524fa5b124e4d9e138a8109
backup_restore=1 backup_restore=1
multi_instance=0 multi_instance=0
change_url=1 change_url=1
@ -23,6 +21,6 @@
Email= Email=
Notification=none Notification=none
;;; Upgrade options ;;; Upgrade options
; commit=c06f6235a93587e16524fa5b124e4d9e138a8109 ; commit=CommitHash
name=Allow naming groups with spaces (#21) name=Name and date of the commit.
manifest_arg=domain=DOMAIN&path=PATH&admin=USER&language=fr&is_public=1&password=pass&port=666& manifest_arg=domain=DOMAIN&path=PATH&admin=USER&language=fr&is_public=1&password=pass&port=666&

View file

@ -1,5 +1,5 @@
SOURCE_URL=https://github.com/YunoHost-Apps/galene_ynh/releases/download/v0.3.5/galene_0.3.5_Linux_386.tar.gz SOURCE_URL=https://github.com/YunoHost-Apps/galene_ynh/releases/download/v0.4/galene_0.4_Linux_386.tar.gz
SOURCE_SUM=3b0df8926284a3aec5eb9b1bffca18e3ffbdb8749a72bfd839b75775fd48f392 SOURCE_SUM=ef933459f6564e3533bc8ea0db4f5adddee774f480dce4ba7be086116b46bc52
SOURCE_SUM_PRG=sha256sum SOURCE_SUM_PRG=sha256sum
SOURCE_FORMAT=tar.gz SOURCE_FORMAT=tar.gz
SOURCE_IN_SUBDIR=true SOURCE_IN_SUBDIR=true

View file

@ -1,5 +1,5 @@
SOURCE_URL=https://github.com/YunoHost-Apps/galene_ynh/releases/download/v0.3.5/galene_0.3.5_Linux_amd64.tar.gz SOURCE_URL=https://github.com/YunoHost-Apps/galene_ynh/releases/download/v0.4/galene_0.4_Linux_amd64.tar.gz
SOURCE_SUM=bf98a50ae9d906f6b330844dee298b1b853c9b27f4b5a54bded180a02778b7a6 SOURCE_SUM=2530187e021a792753c78e3b8449b23b88b0e9349dda263eb815ef46e8d16330
SOURCE_SUM_PRG=sha256sum SOURCE_SUM_PRG=sha256sum
SOURCE_FORMAT=tar.gz SOURCE_FORMAT=tar.gz
SOURCE_IN_SUBDIR=true SOURCE_IN_SUBDIR=true

View file

@ -1,5 +1,5 @@
SOURCE_URL=https://github.com/YunoHost-Apps/galene_ynh/releases/download/v0.3.5/galene_0.3.5_Linux_arm6.tar.gz SOURCE_URL=https://github.com/YunoHost-Apps/galene_ynh/releases/download/v0.4/galene_0.4_Linux_arm6.tar.gz
SOURCE_SUM=12ff36deab3040587b35c6faab77a42831f6fc0cb79764410a6beb6fa32fd7c9 SOURCE_SUM=56a7be3fe0210b920f1883dfb054268ffeb21f4e822c4b1f1527c40e95b57952
SOURCE_SUM_PRG=sha256sum SOURCE_SUM_PRG=sha256sum
SOURCE_FORMAT=tar.gz SOURCE_FORMAT=tar.gz
SOURCE_IN_SUBDIR=true SOURCE_IN_SUBDIR=true

View file

@ -1,5 +1,5 @@
SOURCE_URL=https://github.com/YunoHost-Apps/galene_ynh/releases/download/v0.3.5/galene_0.3.5_Linux_arm64.tar.gz SOURCE_URL=https://github.com/YunoHost-Apps/galene_ynh/releases/download/v0.4/galene_0.4_Linux_arm64.tar.gz
SOURCE_SUM=1dcac2a4f35d1402d4208541773237b46bc9f75d242b763b21c56c5ae1317fff SOURCE_SUM=5281e7f0918d9df4de4f61028a15d0c876346a5e202f22849e69ffd3153cd82a
SOURCE_SUM_PRG=sha256sum SOURCE_SUM_PRG=sha256sum
SOURCE_FORMAT=tar.gz SOURCE_FORMAT=tar.gz
SOURCE_IN_SUBDIR=true SOURCE_IN_SUBDIR=true

View file

@ -1,5 +1,5 @@
SOURCE_URL=https://github.com/YunoHost-Apps/galene_ynh/releases/download/v0.3.5/galene_0.3.5_Linux_arm7.tar.gz SOURCE_URL=https://github.com/YunoHost-Apps/galene_ynh/releases/download/v0.4/galene_0.4_Linux_arm7.tar.gz
SOURCE_SUM=819794367ec2abaedb1209839047f7a7749391fd9f12f25c65db4f30a4c34e0f SOURCE_SUM=3af918cf297fbc53d6d109fa0b3d465907af87c93c9da87bf78601ad618fb505
SOURCE_SUM_PRG=sha256sum SOURCE_SUM_PRG=sha256sum
SOURCE_FORMAT=tar.gz SOURCE_FORMAT=tar.gz
SOURCE_IN_SUBDIR=true SOURCE_IN_SUBDIR=true

View file

@ -1,27 +0,0 @@
[Unit]
Description=Coturn STUN/TURN Server
Documentation=man:coturn(1) man:turnadmin(1) man:turnserver(1)
After=syslog.target network.target
[Service]
User=turnserver
Group=turnserver
Type=forking
EnvironmentFile=/etc/default/coturn-__APP__
PIDFile=/run/coturn-__APP__/turnserver.pid
RuntimeDirectory=coturn-__APP__
RuntimeDirectoryMode=0755
ExecStart=/usr/bin/turnserver -o -c /etc/__APP__/coturn.conf $EXTRA_OPTIONS
ExecStopPost=/bin/rm -f /run/coturn-__APP__/turnserver.pid
Restart=on-abort
LimitCORE=infinity
LimitNOFILE=999999
LimitNPROC=60000
LimitRTPRIO=infinity
LimitRTTIME=7000000
CPUSchedulingPolicy=other
UMask=0007
[Install]
WantedBy=multi-user.target

View file

@ -1,5 +0,0 @@
#
# Uncomment it if you want to have the turnserver running as
# an automatic system service daemon
#
TURNSERVER_ENABLED=1

View file

@ -1,33 +0,0 @@
# TURN server name and realm
realm=__DOMAIN__
# Enable long-term credential mechanism
lt-cred-mech
# Specify the user for the TURN authentification
user=__APP__:__TURNSERVER_PWD__
# Main listening port
listening-port=__TURNSERVER_PORT__
# Further ports that are open for communication
min-port=49152
max-port=65535
# SSL certificates
cert=/etc/yunohost/certs/__DOMAIN__/crt.pem
pkey=/etc/yunohost/certs/__DOMAIN__/key.pem
dh-file=/etc/ssl/private/dh2048.pem
# Log file path
log-file=/var/log/__APP__/turnserver.log
pidfile=/run/coturn-__APP__/turnserver.pid
simple-log
no-sslv2
no-sslv3
no-tlsv1
no-tlsv1_1
no-loopback-peers
no-multicast-peers
no-cli

View file

@ -1,10 +1,11 @@
[ [
{ {
"urls": [ "urls": [
"turn:__DOMAIN__:__TURNSERVER_PORT__", "turn:turn.example.org:5349",
"turn:__DOMAIN__:__TURNSERVER_PORT__?transport=tcp" "turn:turn.example.org:5349?transport=tcp"
], ],
"username": "__APP__", "username": "galene",
"credential": "__TURNSERVER_PWD__" "credential": "secret",
"credentialType": "hmac-sha1"
} }
] ]

View file

@ -13,7 +13,6 @@ location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name; proxy_set_header X-Forwarded-Host $server_name;
# WebSocket support
proxy_http_version 1.1; proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade"; proxy_set_header Connection "upgrade";

View file

@ -1,2 +1 @@
__ADMIN__:__PASSWORD__ __ADMIN__:__PASSWORD__

View file

@ -8,10 +8,40 @@ Type=simple
WorkingDirectory=__FINALPATH__/ WorkingDirectory=__FINALPATH__/
User=__APP__ User=__APP__
Group=__APP__ Group=__APP__
ExecStart=__FINALPATH__/galene ExecStart=__FINALPATH__/galene -turn __PUBLIC_IP4__:__TURN_PORT__ -udp-range 49152-65535
LimitNOFILE=65536 LimitNOFILE=65536
StandardOutput=append:/var/log/__APP__/__APP__.log StandardOutput=append:/var/log/__APP__/__APP__.log
StandardError=inherit StandardError=inherit
# Sandboxing options to harden security
# Depending on specificities of your service/app, you may need to tweak these
# .. but this should be a good baseline
# Details for these options: https://www.freedesktop.org/software/systemd/man/systemd.exec.html
NoNewPrivileges=yes
PrivateTmp=yes
PrivateDevices=yes
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
RestrictNamespaces=yes
RestrictRealtime=yes
DevicePolicy=closed
ProtectSystem=full
ProtectControlGroups=yes
ProtectKernelModules=yes
ProtectKernelTunables=yes
LockPersonality=yes
SystemCallFilter=~@clock @debug @module @mount @obsolete @reboot @setuid @swap
# Denying access to capabilities that should not be relevant for webapps
# Doc: https://man7.org/linux/man-pages/man7/capabilities.7.html
CapabilityBoundingSet=~CAP_RAWIO CAP_MKNOD
CapabilityBoundingSet=~CAP_AUDIT_CONTROL CAP_AUDIT_READ CAP_AUDIT_WRITE
CapabilityBoundingSet=~CAP_SYS_BOOT CAP_SYS_TIME CAP_SYS_MODULE CAP_SYS_PACCT
CapabilityBoundingSet=~CAP_LEASE CAP_LINUX_IMMUTABLE CAP_IPC_LOCK
CapabilityBoundingSet=~CAP_BLOCK_SUSPEND CAP_WAKE_ALARM
CapabilityBoundingSet=~CAP_SYS_TTY_CONFIG
CapabilityBoundingSet=~CAP_MAC_ADMIN CAP_MAC_OVERRIDE
CapabilityBoundingSet=~CAP_NET_ADMIN CAP_NET_BROADCAST CAP_NET_RAW
CapabilityBoundingSet=~CAP_SYS_ADMIN CAP_SYS_PTRACE CAP_SYSLOG
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target

1
doc/DESCRIPTION.md Normal file
View file

@ -0,0 +1 @@
Galène (or Galene) is a videoconference server (an “SFU”) that is easy to deploy and that requires moderate server resources. It was originally designed for lectures and conferences (where a single speaker streams audio and video to hundreds or thousands of users), but later evolved to be useful for student practicals (where users are divided into many small groups), and meetings (where a dozen users interact with each other).

1
doc/DESCRIPTION_fr.md Normal file
View file

@ -0,0 +1 @@
Galène (ou Galene) est un serveur de visioconférence (un « SFU ») facile à déployer et qui nécessite des ressources serveur modérées. Il a été conçu à l'origine pour les cours et les conférences (où un seul orateur diffuse de l'audio et de la vidéo à des centaines ou des milliers d'utilisateurs), mais a évolué par la suite pour être utile pour les travaux pratiques des étudiants (où les utilisateurs sont divisés en plusieurs petits groupes) et les réunions (où un douzaine d'utilisateurs interagissent entre eux).

View file

@ -1,31 +1,40 @@
### How to creat groups ### Accessing groups
Groups are defined by files in the `/opt/yunohost/galene/groups` directory. Various options are available (see https://github.com/YunoHost-Apps/galene_ynh/wiki/Configuration-file) *Galène* meeting rooms are called "groups". Any group is accessible at `https://domain.tld/group/GroupName`, by typing its name in the home page search field, or by selecting it in the public list (if the group is configured as publicly visible, see below).
### TURN server #### Creating and configuring groups
For VoIP and video conferencing a TURN server is also installed and configured. The TURN server listens on two UDP and TCP ports. You can get them with these commands: Groups are defined by JSON files located in the *Galène* folder (`/opt/yunohost/galene/groups`). Each group is represented by a `GroupName.json` file.
To create a new group, you need to create a `GroupNameExample.json` file (you can also make subfolder groups, and the groups will be accessible with `https://domain.tld/group/subfolder/GroupName`). Various configuration options are available (see https://github.com/YunoHost-Apps/galene_ynh/wiki/Configuration-file).
*NB: spaces are supported in group file names.*
### Configuring your TURN server
#### Using *Galène*'s TURN server
Galène comes with a built-in TURN server that should work out-of-the-box.
- If your server is behind NAT, allow incoming traffic to TCP port `8443` (or whatever is configured with the `-http` option in `/etc/systemd/system/galene.service`) and TCP/UDP port `1194` (or whatever is configured with the `-turn` option in `/etc/systemd/system/galene.service`)
#### Using your own TURN server
- Install [coturn_ynh](https://github.com/YunoHost-Apps/coturn_ynh).
- Add `/opt/yunohost/galene/data/ice-servers.json` with these lines and change `turn.example.org` and `secret`
``` ```
sudo yunohost app setting galene turnserver_port [
{
"urls": [
"turn:turn.example.org:5349",
"turn:turn.example.org:5349?transport=tcp"
],
"username": "galene",
"credential": "secret"
}
]
``` ```
- set `/etc/systemd/system/galene.service` `-turn` option to `-turn auto` (or `-turn ""` to disable the built-in TURN server).
The TURN server will also choose a port dynamically when a new call starts. The range is between 49152 - 65535. To check if the TURN server is up and running, type `/relay-test` in the chat box. If the TURN server is properly configured, you should see a message saying that the relay test has been successful.
For security reason the ports range (49152 - 65535) isn't automatically open by default. If you want to use Galène server for VoIP or conferencing you will need to open this port range manually. To do this, just run this command: ### Server Statistics page
``` Some statistics are available under `/opt/yunohost/galene/stats.json`, with a human-readable version at `domain.ltd/stats.html`. This is only available to the server administrator.
sudo yunohost firewall allow Both 49152:65535
```
You might also need to open these ports (if it is not automatically done) on your ISP box.
To prevent the situation when the server is behind a NAT, the public IP is written in the TURN server config. By this the TURN server can send its real public IP to the client. For more information see the [Coturn example config file](https://github.com/coturn/coturn/blob/master/examples/etc/turnserver.conf#L56-L62). So if your IP changes, you could run the script `/opt/yunohost/galene/Coturn_config_rotate.sh` to update your config.
If you have a dynamic IP address, you also might need to update this config automatically. To do that just edit a file named `/etc/cron.d/coturn_config_rotate` and add the following content.
```
*/15 * * * * root bash /opt/yunohost/galene/Coturn_config_rotate.sh;
```
To check if Galène can connect to the TURN server, connect to Galène as operator and type `/relay-test` in the chat box; if the TURN server is properly configured, you should see a message saying that the relay test has been successful.

View file

@ -1,33 +1,40 @@
## Configuration ### Accéder à des groupes
### Comment créer des groupes Les salles de réunion *Galène* sont appelées « groupes ». Tout groupe est accessible sur `https://domain.tld/group/GroupName`, en tapant son nom dans le champ de recherche de la page d'accueil, ou en le sélectionnant dans la liste publique (si le groupe est configuré comme visible publiquement, voir ci-dessous).
Les groupes sont définis par des fichiers dans le répertoire `/opt/yunohost/galene/groups`. Différentes options sont disponibles (voir https://github.com/YunoHost-Apps/galene_ynh/wiki/Configuration-file) #### Ajouter et configurer des groupes
### Serveur TURN Les groupes sont définis par des fichiers JSON situés dans le dossier *Galène* (`/opt/yunohost/galene/groups`). Chaque groupe est représenté par un fichier `GroupName.json`.
Pour créer un nouveau groupe, vous devez créer un fichier `GroupNameExample.json` (vous pouvez également créer un sous-dossier, et les groupes seront accessibles avec` https://domain.tld/group/subfolder/GroupName`). Différentes options de configurations sont disponibles (voir https://github.com/YunoHost-Apps/galene_ynh/wiki/Configuration-file).
Pour la VoIP et la visioconférence, un serveur TURN est également installé et configuré. Le serveur TURN écoute sur deux ports UDP et TCP. Vous pouvez les obtenir avec ces commandes : *NB : les espaces sont pris en charge dans les noms de fichiers de groupe.*
### Configurer votre serveur TURN
#### Utilisation du serveur TURN de *Galène*
Galène est livré avec un serveur TURN intégré qui devrait fonctionner immédiatement.
- Si votre serveur est derrière NAT, autorisez le trafic entrant vers le port TCP `8443` (ou tout ce qui est configuré avec l'option `-http` dans `/etc/systemd/system/galene.service`) et le port TCP/UDP `1194` (ou tout ce qui est configuré avec l'option `-turn` dans `/etc/systemd/system/galene.service`)
#### Utilisation de votre propre serveur TURN
- Installez [coturn_ynh](https://github.com/YunoHost-Apps/coturn_ynh).
- Ajoutez `/opt/yunohost/galene/data/ice-servers.json` avec ces lignes et changez `turn.example.org` et `secret`
``` ```
sudo yunohost app setting galene turnserver_port [
{
"urls": [
"turn:turn.example.org:5349",
"turn:turn.example.org:5349?transport=tcp"
],
"username": "galene",
"credential": "secret"
}
]
``` ```
- définir l'option de virage de `/etc/systemd/system/galene.service` sur `-turn auto` (ou `-turn ""` pour désactiver le serveur TURN intégré).
Le serveur TURN choisira également un port de manière dynamique lors du démarrage d'une nouvelle visioconférence. La plage est comprise entre 49152 et 65535. Pour vérifier si le serveur TURN est opérationnel, tapez `/relay-test` dans la boîte de dialogue ; si le serveur TURN est correctement configuré, vous devriez voir un message indiquant que le test du relai a réussi.
Par sécurité, la plage de ports (49152 - 65535) n'est pas automatiquement ouverte par défaut. Si vous souhaitez utiliser Galène pour la VoIP ou la visioconférence, vous devrez ouvrir cette plage de ports manuellement. Pour ce faire, exécutez simplement cette commande : ### Statistiques du serveur
``` Certaines statistiques sont disponibles sous `/opt/yunohost/galene/stats.json`, avec une version lisible sur `domain.ltd/stats.html`. Ceci n'est disponible que pour l'administrateur du serveur.
sudo yunohost firewall allow Both 49152:65535
```
Vous devrez peut-être également ouvrir ces ports (si ce n'est pas fait automatiquement) sur votre box.
Pour éviter la situation où le serveur est derrière un NAT, l'adresse IP publique est écrite dans la configuration du serveur TURN. De cette manière, le serveur TURN peut envoyer sa véritable adresse IP publique au client. Pour plus d'informations, consultez [le fichier de configuration d'exemple Coturn](https://github.com/coturn/coturn/blob/master/examples/etc/turnserver.conf#L56-L62). Donc, si votre adresse IP change, vous pouvez exécuter le script `/opt/yunohost/galene/Coturn_config_rotate.sh` pour mettre à jour votre configuration.
Si vous avez une adresse IP dynamique, vous devrez peut-être également mettre à jour cette configuration automatiquement. Pour ce faire, éditez simplement un fichier nommé `/etc/cron.d/coturn_config_rotate` et ajoutez le contenu suivant.
```
* / 15 * * * * root bash /opt/yunohost/galene/Coturn_config_rotate.sh;
```
Pour vérifier si Galène peut se connecter au serveur TURN, connectez-vous à Galène en tant qu'opérateur et tapez `/relay-test` dans la boîte de dialogue chat; si le serveur TURN est correctement configuré, vous devriez voir un message indiquant que le test du relais a réussi.

View file

@ -1,18 +1,19 @@
{ {
"name": "Galene", "name": "Galène",
"id": "galene", "id": "galene",
"packaging_format": 1, "packaging_format": 1,
"description": { "description": {
"en": "Videoconferencing server that is easy to deploy", "en": "Videoconferencing server that is easy to deploy",
"fr": "Serveur de visioconférence facile à déployer" "fr": "Serveur de visioconférence facile à déployer"
}, },
"version": "0.3.5~ynh3", "version": "0.4.0~ynh1",
"url": "https://galene.org", "url": "https://galene.org/",
"upstream": { "upstream": {
"license": "free", "license": "MIT",
"website": "https://galene.org", "website": "https://galene.org/",
"demo": "https://galene.org:8443/", "demo": "https://galene.org:8443/",
"admindoc": "https://galene.org/", "admindoc": "https://galene.org/",
"userdoc": "https://yunohost.org/en/app_galene",
"code": "https://github.com/jech/galene" "code": "https://github.com/jech/galene"
}, },
"license": "MIT", "license": "MIT",
@ -21,7 +22,7 @@
"email": "" "email": ""
}, },
"requirements": { "requirements": {
"yunohost": ">= 4.1.7" "yunohost": ">= 4.2.4"
}, },
"multi_instance": false, "multi_instance": false,
"services": [ "services": [
@ -70,6 +71,7 @@
{ {
"name": "group_description", "name": "group_description",
"type": "string", "type": "string",
"optional": true,
"ask": { "ask": {
"en": "Choose a description for the group you want to create", "en": "Choose a description for the group you want to create",
"fr": "Décrivez le groupe que vous souhaitez créer" "fr": "Décrivez le groupe que vous souhaitez créer"

View file

@ -4,9 +4,6 @@
# COMMON VARIABLES # COMMON VARIABLES
#================================================= #=================================================
# dependencies used by the app
pkg_dependencies="coturn acl"
#================================================= #=================================================
# PERSONAL HELPERS # PERSONAL HELPERS
#================================================= #=================================================

View file

@ -39,15 +39,6 @@ ynh_print_info --message="Declaring files to be backed up..."
#================================================= #=================================================
ynh_backup --src_path="$final_path" ynh_backup --src_path="$final_path"
ynh_backup --src_path="/etc/$app"
#=================================================
# BACKUP SYSTEMD
#=================================================
ynh_backup --src_path="/etc/systemd/system/$app.service"
ynh_backup --src_path="/etc/default/coturn-$app"
ynh_backup --src_path="/etc/systemd/system/coturn-$app.service"
#================================================= #=================================================
# BACKUP THE NGINX CONFIGURATION # BACKUP THE NGINX CONFIGURATION
@ -55,30 +46,14 @@ ynh_backup --src_path="/etc/systemd/system/coturn-$app.service"
ynh_backup --src_path="/etc/nginx/conf.d/$domain.d/$app.conf" ynh_backup --src_path="/etc/nginx/conf.d/$domain.d/$app.conf"
#=================================================
# SPECIFIC BACKUP
#=================================================
# BACKUP LOGROTATE
#=================================================
ynh_backup --src_path="/etc/logrotate.d/$app"
#=================================================
# BACKUP GALÈNE LOG
#=================================================
ynh_backup --src_path="/var/log/$app"
#================================================= #=================================================
# BACKUP SYSTEMD # BACKUP SYSTEMD
#================================================= #=================================================
ynh_backup --src_path="/etc/systemd/system/$app.service" ynh_backup --src_path="/etc/systemd/system/$app.service"
ynh_backup --src_path="/etc/default/coturn-$app"
ynh_backup --src_path="/etc/systemd/system/coturn-$app.service"
#================================================= #=================================================
# END OF SCRIPT # END OF SCRIPT
#================================================= #=================================================
ynh_print_info --message="Backup script completed for Galène. (YunoHost will then actually copy those files to the archive)." ynh_print_info --message="Backup script completed for $app. (YunoHost will then actually copy those files to the archive)."

View file

@ -9,6 +9,8 @@
source _common.sh source _common.sh
source /usr/share/yunohost/helpers source /usr/share/yunohost/helpers
ynh_abort_if_errors
#================================================= #=================================================
# RETRIEVE ARGUMENTS # RETRIEVE ARGUMENTS
#================================================= #=================================================
@ -33,7 +35,7 @@ port=$(ynh_app_setting_get --app=$app --key=port)
#================================================= #=================================================
# BACKUP BEFORE UPGRADE THEN ACTIVE TRAP # BACKUP BEFORE UPGRADE THEN ACTIVE TRAP
#================================================= #=================================================
ynh_script_progression --message="Backing up Galène before changing its URL (may take a while)..." --weight=1 ynh_script_progression --message="Backing up the app before changing its URL (may take a while)..." --weight=1
# Backup the current version of the app # Backup the current version of the app
ynh_backup_before_upgrade ynh_backup_before_upgrade
@ -121,4 +123,4 @@ ynh_systemd_action --service_name=nginx --action=reload
# END OF SCRIPT # END OF SCRIPT
#================================================= #=================================================
ynh_script_progression --message="Change of URL completed for Galène" --last ynh_script_progression --message="Change of URL completed for $app" --last

View file

@ -13,9 +13,6 @@ source /usr/share/yunohost/helpers
# MANAGE SCRIPT FAILURE # MANAGE SCRIPT FAILURE
#================================================= #=================================================
ynh_clean_setup () {
ynh_clean_check_starting
}
# Exit if an error occurs during the execution of the script # Exit if an error occurs during the execution of the script
ynh_abort_if_errors ynh_abort_if_errors
@ -55,23 +52,6 @@ ynh_app_setting_set --app=$app --key=path --value=$path_url
ynh_app_setting_set --app=$app --key=admin --value=$admin ynh_app_setting_set --app=$app --key=admin --value=$admin
ynh_app_setting_set --app=$app --key=group_name --value="$group_name" ynh_app_setting_set --app=$app --key=group_name --value="$group_name"
ynh_app_setting_set --app=$app --key=group_description --value="$group_description" ynh_app_setting_set --app=$app --key=group_description --value="$group_description"
ynh_app_setting_set --app=$app --key=password --value=$password
#=================================================
# CREATE A DH FILE
#=================================================
ynh_script_progression --message="Creating a dhparam file..." --weight=3
# WARNING : theses command are used in INSTALL, UPGRADE, RESTORE
# For any update do it in all files
# Make dhparam cert for Coturn if it doesn't exist
if [ ! -e /etc/ssl/private/dh2048.pem ]
then
ynh_exec_warn_less openssl dhparam -out /etc/ssl/private/dh2048.pem -outform PEM -2 2048 -dsaparam
chown root:ssl-cert /etc/ssl/private/dh2048.pem
chmod 640 /etc/ssl/private/dh2048.pem
fi
#================================================= #=================================================
# STANDARD MODIFICATIONS # STANDARD MODIFICATIONS
@ -85,20 +65,24 @@ port=$(ynh_find_port --port=8443)
ynh_app_setting_set --app=$app --key=port --value=$port ynh_app_setting_set --app=$app --key=port --value=$port
# Find an available port for TURN # Find an available port for TURN
turnserver_port=$(ynh_find_port --port=1194) turn_port=$(ynh_find_port --port=1194)
ynh_app_setting_set --app=$app --key=turnserver_port --value=$turnserver_port ynh_app_setting_set --app=$app --key=turn_port --value=$turn_port
# Open TURN port # Open TURN port
ynh_script_progression --message="Configuring firewall..." --weight=1 ynh_script_progression --message="Configuring firewall..." --weight=1
ynh_exec_warn_less yunohost firewall allow Both $turnserver_port ynh_exec_warn_less yunohost firewall allow Both $turn_port
# Reserve UDP Port range 49152:65535
ynh_exec_warn_less yunohost firewall allow UDP -4 49152:65535
#================================================= #=================================================
# INSTALL DEPENDENCIES # CREATE DEDICATED USER
#================================================= #=================================================
ynh_script_progression --message="Installing dependencies..." --weight=5 ynh_script_progression --message="Configuring system user..." --weight=3
ynh_install_app_dependencies $pkg_dependencies # Create a system user
ynh_system_user_create --username=$app --home_dir="$final_path"
#================================================= #=================================================
# DOWNLOAD, CHECK AND UNPACK SOURCE # DOWNLOAD, CHECK AND UNPACK SOURCE
@ -109,8 +93,12 @@ ynh_app_setting_set --app=$app --key=final_path --value=$final_path
# Download, check integrity, uncompress and patch the source from app.src # Download, check integrity, uncompress and patch the source from app.src
ynh_setup_source --dest_dir="$final_path" --source_id="$architecture" ynh_setup_source --dest_dir="$final_path" --source_id="$architecture"
chmod 750 "$final_path"
chmod -R o-rwx "$final_path"
chown -R $app:www-data "$final_path"
#================================================= #=================================================
# CREATE DATA FOLDER # CREATE DATA AND GROUPS FOLDER
#================================================= #=================================================
# Define app's data directory # Define app's data directory
@ -118,15 +106,10 @@ data="$final_path/data"
# Create data folder # Create data folder
mkdir -p "$data" mkdir -p "$data"
#================================================= # Define app's groups directory
# CREATE A SERVER CERTIFICATE groups="$final_path/groups"
#================================================= # Create groups folder
mkdir -p "$groups"
pushd "$final_path/data"
ynh_exec_warn_less openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 365 -out cert.pem \
-subj "/C=/ST=/L=/O=/OU=/CN=/emailAddress="
chmod 640 {key.pem,cert.pem}
popd
#================================================= #=================================================
# NGINX CONFIGURATION # NGINX CONFIGURATION
@ -136,126 +119,32 @@ ynh_script_progression --message="Configuring NGINX web server..." --weight=2
# Create a dedicated NGINX config # Create a dedicated NGINX config
ynh_add_nginx_config ynh_add_nginx_config
#=================================================
# CREATE DEDICATED USER
#=================================================
ynh_script_progression --message="Configuring system user..." --weight=3
# Create a system user
ynh_system_user_create --username=$app
ynh_system_user_create --username=turnserver
adduser turnserver ssl-cert
#================================================= #=================================================
# SETUP SYSTEMD # SETUP SYSTEMD
#================================================= #=================================================
ynh_script_progression --message="Configuring a systemd service..." --weight=1 ynh_script_progression --message="Configuring a systemd service..." --weight=1
public_ip4="$(curl -s ip.yunohost.org)" || true
# Create a dedicated systemd config # Create a dedicated systemd config
ynh_add_systemd_config ynh_add_systemd_config
mkdir -p /etc/$app
# Create systemd service for turnserver
cp ../conf/coturn/default_coturn /etc/default/coturn-$app
ynh_add_systemd_config --service=coturn-$app --template=coturn-galene.service
#=================================================
# SETUP LOGROTATE
#=================================================
ynh_script_progression --message="Configuring log rotation..." --weight=1
# Create log directory
mkdir -p /var/log/$app
touch /var/log/$app/$app.log
chown $app -R /var/log/$app
# Setup logrotate
ynh_use_logrotate --logfile "/var/log/$app"
#=================================================
# SET COTURN CONFIG
#=================================================
ynh_script_progression --message="Configuring Coturn..." --weight=1
# WARNING: theses command are used in INSTALL, UPGRADE
# For any update do it in all files
# Find password for turnserver
ynh_print_OFF
turnserver_pwd=$(ynh_string_random --length=30)
ynh_app_setting_set --app=$app --key=turnserver_pwd --value=$turnserver_pwd
ynh_print_ON
coturn_config_path="/etc/$app/coturn.conf"
ynh_add_config --template="../conf/coturn/turnserver.conf" --destination="$coturn_config_path"
# Get public IP and set as external IP for coturn
# note: '|| true' is used to ignore the errors if we can't get the public ipv4 or ipv6
public_ip4="$(curl -s ip.yunohost.org)" || true
public_ip6="$(curl -s ipv6.yunohost.org)" || true
if ( [[ -n "$public_ip4" ]] && ynh_validate_ip4 --ip_address="$public_ip4" || [[ -n "$public_ip6" ]] && ynh_validate_ip6 --ip_address="$public_ip6" )
then
echo "external-ip=${public_ip4}/${public_ip6}" >> "$coturn_config_path"
fi
ynh_store_file_checksum --file="$coturn_config_path"
#=================================================
# CREATE GROUPS FOLDER
#=================================================
# Define app's groups directory
groups="$final_path/groups"
# Create groups folder
mkdir -p "$groups"
#================================================= #=================================================
# MODIFY A CONFIG FILES # MODIFY A CONFIG FILES
#================================================= #=================================================
ynh_add_config --template="../conf/passwd" --destination="$final_path/data/passwd" ynh_add_config --template="../conf/passwd" --destination="$final_path/data/passwd"
chmod 400 "$final_path/data/passwd"
chown $app "$final_path/data/passwd"
ynh_add_config --template="../conf/groupname.json" --destination="$final_path/groups/$group_name.json" ynh_add_config --template="../conf/groupname.json" --destination="$final_path/groups/$group_name.json"
ynh_add_config --template="../conf/ice-servers.json" --destination="$final_path/data/ice-servers.json"
#=================================================
# ADD SCRIPT FOR COTURN CRON AND APP SERVICE
#=================================================
# WARNING : theses command are used in INSTALL, UPGRADE
# For any update do it in all files
cp ../sources/Coturn_config_rotate.sh $final_path/Coturn_config_rotate.sh
ynh_replace_string --match_string=__APP__ --replace_string=$app --target_file="$final_path/Coturn_config_rotate.sh"
chmod +x $final_path/Coturn_config_rotate.sh
#=================================================
# GENERIC FINALIZATION
#=================================================
# SECURE FILES AND DIRECTORIES
#=================================================
# Set permissions to app files
chown -R $app: $final_path
chmod -R 755 $final_path
chown -R $app:root /etc/$app
chown turnserver:root /etc/$app/coturn.conf
chmod -R u=rwX,g=rX,o= /etc/$app
chmod 770 $final_path/Coturn_config_rotate.sh
setfacl -R -m user:turnserver:rX /etc/$app
setfacl -R -m user:turnserver:rwX /var/log/$app
chmod 600 $final_path/data/passwd
chmod 600 $final_path/data/ice-servers.json
#================================================= #=================================================
# INTEGRATE SERVICE IN YUNOHOST # INTEGRATE SERVICE IN YUNOHOST
#================================================= #=================================================
ynh_script_progression --message="Integrating service in YunoHost..." --weight=2 ynh_script_progression --message="Integrating service in YunoHost..." --weight=2
yunohost service add $app --description="Videoconferencing server" --log="/var/log/$app/$app.log" yunohost service add $app --description="Videoconferencing server" --log="/var/log/$app/$app.log" --needs_exposed_ports="$turn_port"
yunohost service add coturn-$app --description="Coturn TURN server" --log="/var/log/$app/turnserver.log" --needs_exposed_ports $turnserver_port
#================================================= #=================================================
# START SYSTEMD SERVICE # START SYSTEMD SERVICE
@ -263,8 +152,7 @@ yunohost service add coturn-$app --description="Coturn TURN server" --log="/var/
ynh_script_progression --message="Starting a systemd service..." --weight=1 ynh_script_progression --message="Starting a systemd service..." --weight=1
# Start a systemd service # Start a systemd service
ynh_systemd_action --service_name=$app --action=restart --log_path="/var/log/$app/$app.log" ynh_systemd_action --service_name=$app --action=start --log_path="/var/log/$app/$app.log"
ynh_systemd_action --service_name=coturn-$app.service --action=restart --log_path="/var/log/$app/turnserver.log"
#================================================= #=================================================
# SETUP SSOWAT # SETUP SSOWAT
@ -288,4 +176,4 @@ ynh_systemd_action --service_name=nginx --action=reload
# END OF SCRIPT # END OF SCRIPT
#================================================= #=================================================
ynh_script_progression --message="Installation of Galène completed" --last ynh_script_progression --message="Installation of $app completed" --last

View file

@ -17,28 +17,23 @@ ynh_script_progression --message="Loading installation settings..." --weight=1
app=$YNH_APP_INSTANCE_NAME app=$YNH_APP_INSTANCE_NAME
domain=$(ynh_app_setting_get --app=$app --key=domain) domain=$(ynh_app_setting_get --app=$app --key=domain)
final_path=$(ynh_app_setting_get --app=$app --key=final_path)
port=$(ynh_app_setting_get --app=$app --key=port) port=$(ynh_app_setting_get --app=$app --key=port)
turnserver_port=$(ynh_app_setting_get --app=$app --key=turnserver_port) turn_port=$(ynh_app_setting_get --app=$app --key=turn_port)
final_path=$(ynh_app_setting_get --app=$app --key=final_path)
#================================================= #=================================================
# STANDARD REMOVE # STANDARD REMOVE
#================================================= #=================================================
# REMOVE SERVICE INTEGRATION IN YUNOHOST # REMOVE SERVICE INTEGRATION IN YUNOHOST
#================================================= #=================================================
ynh_script_progression --message="Removing Galène service integration..." --weight=1
# Remove the service from the list of services known by YunoHost (added from `yunohost service add`) # Remove the service from the list of services known by YunoHost (added from `yunohost service add`)
if ynh_exec_warn_less yunohost service status $app >/dev/null if ynh_exec_warn_less yunohost service status $app >/dev/null
then then
ynh_script_progression --message="Removing $app service integration..." --weight=1
yunohost service remove $app yunohost service remove $app
fi fi
if ynh_exec_warn_less yunohost service status coturn-$app >/dev/null
then
yunohost service remove coturn-$app
fi
#================================================= #=================================================
# STOP AND REMOVE SERVICE # STOP AND REMOVE SERVICE
#================================================= #=================================================
@ -46,25 +41,14 @@ ynh_script_progression --message="Stopping and removing the systemd service..."
# Remove the dedicated systemd config # Remove the dedicated systemd config
ynh_remove_systemd_config ynh_remove_systemd_config
ynh_remove_systemd_config --service=coturn-$app
#=================================================
# REMOVE DEPENDENCIES
#=================================================
ynh_script_progression --message="Removing dependencies..." --weight=1
# Remove metapackage and its dependencies
ynh_remove_app_dependencies
#================================================= #=================================================
# REMOVE APP MAIN DIR # REMOVE APP MAIN DIR
#================================================= #=================================================
ynh_script_progression --message="Removing Galène main directory..." --weight=2 ynh_script_progression --message="Removing app main directory..." --weight=2
# Remove the app directory securely # Remove the app directory securely
ynh_secure_remove --file=$final_path ynh_secure_remove --file="$final_path"
ynh_secure_remove --file=/var/log/$app
ynh_secure_remove --file=/etc/default/coturn-$app
#================================================= #=================================================
# REMOVE NGINX CONFIGURATION # REMOVE NGINX CONFIGURATION
@ -74,32 +58,19 @@ ynh_script_progression --message="Removing NGINX web server configuration..." --
# Remove the dedicated NGINX config # Remove the dedicated NGINX config
ynh_remove_nginx_config ynh_remove_nginx_config
#=================================================
# REMOVE LOGROTATE CONFIGURATION
#=================================================
ynh_script_progression --message="Removing logrotate configuration..." --weight=1
# Remove the app-specific logrotate config
ynh_remove_logrotate
#=================================================
# REMOVE THE CRON FILE
#=================================================
ynh_script_progression --message="Removing the cron file..." --weight=1
if [[ ! -f "/etc/cron.d/coturn_config_rotate" ]]; then
# If a cron job as been add by user, remove it
ynh_secure_remove --file="/etc/cron.d/coturn_config_rotate"
fi
#================================================= #=================================================
# CLOSE A PORT # CLOSE A PORT
#================================================= #=================================================
ynh_script_progression --message="Closing ports..." --weight=1 ynh_script_progression --message="Closing ports..." --weight=1
if yunohost firewall list | grep -q "\- $turnserver_port$" if yunohost firewall list | grep -q "\- $turn_port$"
then then
ynh_exec_warn_less yunohost firewall disallow Both $turnserver_port ynh_exec_warn_less yunohost firewall disallow both $turn_port
fi
if yunohost firewall list | grep -q "\- 49152:65535"
then
ynh_exec_warn_less yunohost firewall disallow UDP 49152:65535
fi fi
#================================================= #=================================================
@ -111,10 +82,9 @@ ynh_script_progression --message="Removing the dedicated system user..." --weigh
# Delete a system user # Delete a system user
ynh_system_user_delete --username=$app ynh_system_user_delete --username=$app
ynh_system_user_delete --username=turnserver
#================================================= #=================================================
# END OF SCRIPT # END OF SCRIPT
#================================================= #=================================================
ynh_script_progression --message="Removal of Galène completed" --last ynh_script_progression --message="Removal of $app completed" --last

View file

@ -31,54 +31,42 @@ domain=$(ynh_app_setting_get --app=$app --key=domain)
path_url=$(ynh_app_setting_get --app=$app --key=path) path_url=$(ynh_app_setting_get --app=$app --key=path)
final_path=$(ynh_app_setting_get --app=$app --key=final_path) final_path=$(ynh_app_setting_get --app=$app --key=final_path)
group_name=$(ynh_app_setting_get --app=$app --key=group_name) group_name=$(ynh_app_setting_get --app=$app --key=group_name)
port=$(ynh_app_setting_get --app=$app --key=port) turn_port=$(ynh_app_setting_get --app=$app --key=turn_port)
turnserver_port=$(ynh_app_setting_get --app=$app --key=turnserver_port)
turnserver_pwd=$(ynh_app_setting_get --app=$app --key=turnserver_pwd)
#================================================= #=================================================
# CHECK IF THE APP CAN BE RESTORED # CHECK IF THE APP CAN BE RESTORED
#================================================= #=================================================
ynh_script_progression --message="Validating restoration parameters..." --weight=1 ynh_script_progression --message="Validating restoration parameters..." --weight=1
ynh_webpath_available --domain=$domain --path_url=$path_url \
|| ynh_die --message="Path not available: ${domain}${path_url}"
test ! -d $final_path \ test ! -d $final_path \
|| ynh_die --message="There is already a directory: $final_path " || ynh_die --message="There is already a directory: $final_path "
#================================================= #=================================================
# SPECIFIC RESTORATION # STANDARD RESTORATION STEPS
#=================================================
# REINSTALL DEPENDENCIES
#=================================================
ynh_script_progression --message="Reinstalling dependencies..." --weight=1
# Define and install dependencies
ynh_install_app_dependencies $pkg_dependencies
#================================================= #=================================================
# RESTORE THE NGINX CONFIGURATION # RESTORE THE NGINX CONFIGURATION
#================================================= #=================================================
ynh_restore_file --origin_path="/etc/nginx/conf.d/$domain.d/$app.conf" ynh_restore_file --origin_path="/etc/nginx/conf.d/$domain.d/$app.conf"
#=================================================
# RESTORE THE APP MAIN DIR
#=================================================
ynh_script_progression --message="Restoring Galène main directory..." --weight=1
ynh_restore_file --origin_path="$final_path"
ynh_restore_file --origin_path="/etc/$app"
ynh_restore_file --origin_path="/var/log/$app"
#================================================= #=================================================
# RECREATE THE DEDICATED USER # RECREATE THE DEDICATED USER
#================================================= #=================================================
ynh_script_progression --message="Recreating the dedicated system user..." --weight=2 ynh_script_progression --message="Recreating the dedicated system user..." --weight=2
# Create the dedicated user (if not existing) # Create the dedicated user (if not existing)
ynh_system_user_create --username=$app ynh_system_user_create --username=$app --home_dir="$final_path"
ynh_system_user_create --username=turnserver
adduser turnserver ssl-cert #=================================================
# RESTORE THE APP MAIN DIR
#=================================================
ynh_script_progression --message="Restoring the app main directory..." --weight=1
ynh_restore_file --origin_path="$final_path"
chmod 750 "$final_path"
chmod -R o-rwx "$final_path"
chown -R $app:www-data "$final_path"
#================================================= #=================================================
# RESTORE SYSTEMD # RESTORE SYSTEMD
@ -86,18 +74,14 @@ adduser turnserver ssl-cert
ynh_script_progression --message="Restoring the systemd configuration..." --weight=1 ynh_script_progression --message="Restoring the systemd configuration..." --weight=1
ynh_restore_file --origin_path="/etc/systemd/system/$app.service" ynh_restore_file --origin_path="/etc/systemd/system/$app.service"
ynh_restore_file --origin_path="/etc/default/coturn-$app"
ynh_restore_file --origin_path="/etc/systemd/system/coturn-$app.service"
systemctl enable $app.service --quiet systemctl enable $app.service --quiet
systemctl enable coturn-$app.service --quiet
#================================================= #=================================================
# INTEGRATE SERVICE IN YUNOHOST # INTEGRATE SERVICE IN YUNOHOST
#================================================= #=================================================
ynh_script_progression --message="Integrating service in YunoHost..." --weight=2 ynh_script_progression --message="Integrating service in YunoHost..." --weight=2
yunohost service add $app --description="Videoconferencing server" --log="/var/log/$app/$app.log" yunohost service add $app --description="Videoconferencing server" --log="/var/log/$app/$app.log" --needs_exposed_ports="$turn_port"
yunohost service add coturn-$app --description="Coturn TURN server" --log="/var/log/$app/turnserver.log" --needs_exposed_ports $turnserver_port
#================================================= #=================================================
# START SYSTEMD SERVICE # START SYSTEMD SERVICE
@ -106,55 +90,6 @@ ynh_script_progression --message="Starting a systemd service..." --weight=3
ynh_systemd_action --service_name=$app --action=start --log_path="/var/log/$app/$app.log" ynh_systemd_action --service_name=$app --action=start --log_path="/var/log/$app/$app.log"
#=================================================
# CREATE A DH FILE
#=================================================
ynh_script_progression --message="Creating a dhparam file..." --weight=3
# WARNING : theses command are used in INSTALL, UPGRADE, RESTORE
# For any update do it in all files
# Make dhparam cert for Coturn if it doesn't exist
if [ ! -e /etc/ssl/private/dh2048.pem ]
then
ynh_exec_warn_less openssl dhparam -out /etc/ssl/private/dh2048.pem -outform PEM -2 2048 -dsaparam
chown root:ssl-cert /etc/ssl/private/dh2048.pem
chmod 640 /etc/ssl/private/dh2048.pem
fi
#=================================================
# OPEN THE PORT
#=================================================
# Ouvre le port dans le firewall
ynh_exec_warn_less yunohost firewall allow Both $turnserver_port
#=================================================
# RESTORE USER RIGHTS
#=================================================
ynh_script_progression --message="Restoring permissions..." --weight=1
# Restore permissions on app files
# Set permissions on app files
chown -R $app:$app $final_path
chmod -R 755 $final_path
chown -R $app:root /var/log/$app
chown -R $app:root /etc/$app
chown turnserver:root /etc/$app/coturn.conf
chmod -R u=rwX,g=rX,o= /etc/$app
chmod 770 $final_path/Coturn_config_rotate.sh
setfacl -R -m user:turnserver:rX /etc/$app
setfacl -R -m user:turnserver:rwX /var/log/$app
# Set permissions on config files
chmod 600 $final_path/data/passwd
chmod 600 $final_path/data/ice-servers.json
#=================================================
# RESTORE THE LOGROTATE CONFIGURATION
#=================================================
ynh_restore_file --origin_path="/etc/logrotate.d/$app"
#================================================= #=================================================
# GENERIC FINALIZATION # GENERIC FINALIZATION
#================================================= #=================================================
@ -168,4 +103,4 @@ ynh_systemd_action --service_name=nginx --action=reload
# END OF SCRIPT # END OF SCRIPT
#================================================= #=================================================
ynh_script_progression --message="Restoration completed for Galène" --last ynh_script_progression --message="Restoration completed for $app" --last

View file

@ -20,10 +20,9 @@ domain=$(ynh_app_setting_get --app=$app --key=domain)
path_url=$(ynh_app_setting_get --app=$app --key=path) path_url=$(ynh_app_setting_get --app=$app --key=path)
admin=$(ynh_app_setting_get --app=$app --key=admin) admin=$(ynh_app_setting_get --app=$app --key=admin)
final_path=$(ynh_app_setting_get --app=$app --key=final_path) final_path=$(ynh_app_setting_get --app=$app --key=final_path)
password=$(ynh_app_setting_get --app=$app --key=password) group_name=$(ynh_app_setting_get --app=$app --key=group_name)
port=$(ynh_app_setting_get --app=$app --key=port) port=$(ynh_app_setting_get --app=$app --key=port)
turnserver_port=$(ynh_app_setting_get --app=$app --key=turnserver_port) turn_port=$(ynh_app_setting_get --app=$app --key=turn_port)
turnserver_pwd=$(ynh_app_setting_get --app=$app --key=turnserver_pwd)
architecture=$(ynh_detect_arch) architecture=$(ynh_detect_arch)
#================================================= #=================================================
@ -49,12 +48,6 @@ if [ -z "$final_path" ]; then
ynh_app_setting_set --app=$app --key=final_path --value=$final_path ynh_app_setting_set --app=$app --key=final_path --value=$final_path
fi fi
if [ -z "$turnserver_port" ]; then
turnserver_port=$(ynh_find_port --port=1194)
ynh_app_setting_set --app=$app --key=turnserver_port --value=$turnserver_port
ynh_exec_warn_less yunohost firewall allow Both $turnserver_port
fi
# Cleaning legacy permissions # Cleaning legacy permissions
if ynh_legacy_permissions_exists; then if ynh_legacy_permissions_exists; then
ynh_legacy_permissions_delete_all ynh_legacy_permissions_delete_all
@ -65,7 +58,7 @@ fi
#================================================= #=================================================
# BACKUP BEFORE UPGRADE THEN ACTIVE TRAP # BACKUP BEFORE UPGRADE THEN ACTIVE TRAP
#================================================= #=================================================
ynh_script_progression --message="Backing up Galène before upgrading (may take a while)..." --weight=1 ynh_script_progression --message="Backing up the app before upgrading (may take a while)..." --weight=1
# Backup the current version of the app # Backup the current version of the app
ynh_backup_before_upgrade ynh_backup_before_upgrade
@ -93,125 +86,32 @@ if [ "$upgrade_type" == "UPGRADE_APP" ]
then then
ynh_script_progression --message="Upgrading source files..." --weight=2 ynh_script_progression --message="Upgrading source files..." --weight=2
# Create a temporary directory # # Create a temporary directory
tmpdir="$(mktemp -d)" # tmpdir="$(mktemp -d)"
# Backup the config file in the temp dir # # Backup the config file in the temp dir
cp -ar "$final_path/groups" "$tmpdir/groups" # cp -ar "$final_path/groups" "$tmpdir/groups"
# cp -ar "$final_path/data/passwd" "$tmpdir/passwd"
# Remove the app directory securely # # Remove the app directory securely
ynh_secure_remove --file="$final_path" # ynh_secure_remove --file="$final_path"
ynh_setup_source --dest_dir="$final_path" --source_id="$architecture" ynh_setup_source --dest_dir="$final_path" --source_id="$architecture" --keep="$final_path/groups $final_path/data/passwd"
groups="$final_path/groups" # # Create data and groups folder
data="$final_path/data" # mkdir -p "$final_path/data" "$final_path/groups"
mkdir -p "$groups" # # Copy the admin saved settings from tmp directory to final path
mkdir -p "$data" # cp -ar "$tmpdir/groups" "$final_path/groups"
# cp -ar "$tmpdir/passwd" "$final_path/data/passwd"
# Copy the admin saved settings from tmp directory to final path # # Remove the tmp directory securely
cp -ar "$tmpdir/groups" "$final_path" # ynh_secure_remove --file="$tmpdir"
# Remove the tmp directory securely
ynh_secure_remove --file="$tmpdir"
ynh_add_config --template="../conf/passwd" --destination="$final_path/data/passwd"
chmod 600 $final_path/data/passwd
ynh_add_config --template="../conf/ice-servers.json" --destination="$final_path/data/ice-servers.json"
chmod 600 $final_path/data/ice-servers.json
# Recreate certificates
pushd "$final_path/data"
ynh_exec_warn_less openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 365 -out cert.pem \
-subj "/C=/ST=/L=/O=/OU=/CN=/emailAddress="
chmod 640 {key.pem,cert.pem}
popd
fi fi
#================================================= chmod 750 "$final_path"
# MULTINSTANCE SUPPORT chmod -R o-rwx "$final_path"
#================================================= chown -R $app:www-data "$final_path"
if [ ! -e /etc/$app/coturn.conf ]
then
ynh_script_progression --message="Creating an independant service for Coturn..." --weight=1
#=================================================
# CREATE AN INDEPENDANT SERVICE FOR COTURN
#=================================================
# Disable default config for turnserver and create a new service
systemctl stop coturn.service
# Set by default the system config for coturn
echo "" > /etc/turnserver.conf
ynh_replace_string --match_string="TURNSERVER_ENABLED=1" --replace_string="TURNSERVER_ENABLED=0" --target_file=/etc/default/coturn
# Set a port for each service in turnserver
turnserver_port=$(ynh_find_port --port=1194)
ynh_app_setting_set --app=$app --key=turnserver_port --value=$turnserver_port
ynh_exec_warn_less yunohost firewall allow Both $turnserver_port
#=================================================
# MAKE A CLEAN LOGROTATE CONFIG
#=================================================
ynh_use_logrotate --logfile /var/log/$app --nonappend
fi
#=================================================
# CREATE A DH FILE
#=================================================
ynh_script_progression --message="Creating a dhparam file..." --weight=3
# WARNING : theses command are used in INSTALL, UPGRADE, RESTORE
# For any update do it in all files
# Make dhparam cert for Coturn if it doesn't exist
if [ ! -e /etc/ssl/private/dh2048.pem ]
then
ynh_exec_warn_less openssl dhparam -out /etc/ssl/private/dh2048.pem -outform PEM -2 2048 -dsaparam
chown root:ssl-cert /etc/ssl/private/dh2048.pem
chmod 640 /etc/ssl/private/dh2048.pem
fi
#=================================================
# SPECIFIC UPGRADE
#=================================================
# UPDATE COTURN CONFIG
#=================================================
ynh_script_progression --message="Updating Coturn config..." --weight=1
# WARNING : theses command are used in INSTALL, UPGRADE
# For any update do it in all files
coturn_config_path="/etc/$app/coturn.conf"
ynh_add_config --template="../conf/coturn/turnserver.conf" --destination="$coturn_config_path"
# Get public IP and set as external IP for coturn
# note : '|| true' is used to ignore the errors if we can't get the public ipv4 or ipv6
public_ip4="$(curl -s ip.yunohost.org)" || true
public_ip6="$(curl -s ipv6.yunohost.org)" || true
if ( [[ -n "$public_ip4" ]] && ynh_validate_ip4 --ip_address="$public_ip4" || [[ -n "$public_ip6" ]] && ynh_validate_ip6 --ip_address="$public_ip6" )
then
echo "external-ip=${public_ip4}/${public_ip6}" >> "$coturn_config_path"
fi
ynh_store_file_checksum --file="$coturn_config_path"
#=================================================
# ADD SCRIPT FOR COTURN CRON AND APP SERVICE
#=================================================
# WARNING : theses command are used in INSTALL, UPGRADE
# For any update do it in all files
cp ../sources/Coturn_config_rotate.sh $final_path/Coturn_config_rotate.sh
ynh_replace_string --match_string=__APP__ --replace_string=$app --target_file="$final_path/Coturn_config_rotate.sh"
chmod +x $final_path/Coturn_config_rotate.sh
#================================================= #=================================================
# NGINX CONFIGURATION # NGINX CONFIGURATION
@ -221,70 +121,37 @@ ynh_script_progression --message="Upgrading NGINX web server configuration..." -
# Create a dedicated NGINX config # Create a dedicated NGINX config
ynh_add_nginx_config ynh_add_nginx_config
#=================================================
# UPGRADE DEPENDENCIES
#=================================================
ynh_script_progression --message="Upgrading dependencies..." --weight=1
ynh_install_app_dependencies $pkg_dependencies
#================================================= #=================================================
# CREATE DEDICATED USER # CREATE DEDICATED USER
#================================================= #=================================================
ynh_script_progression --message="Making sure dedicated system user exists..." --weight=1 ynh_script_progression --message="Making sure dedicated system user exists..." --weight=1
# Create a dedicated user (if not existing) # Create a dedicated user (if not existing)
ynh_system_user_create --username=$app ynh_system_user_create --username=$app --home_dir="$final_path"
ynh_system_user_create --username=turnserver
adduser turnserver ssl-cert
#================================================= #=================================================
# SETUP SYSTEMD # SETUP SYSTEMD
#================================================= #=================================================
ynh_script_progression --message="Upgrading systemd configuration..." --weight=1 ynh_script_progression --message="Upgrading systemd configuration..." --weight=1
public_ip4="$(curl -s ip.yunohost.org)" || true
# Create a dedicated systemd config # Create a dedicated systemd config
ynh_add_systemd_config ynh_add_systemd_config
#=================================================
# GENERIC FINALIZATION
#=================================================
# SECURE FILES AND DIRECTORIES
#=================================================
# Set permissions on app files
chown -R $app: $final_path
chmod -R 755 $final_path
chown -R $app:root /etc/$app
chown turnserver:root $coturn_config_path
chmod -R u=rwX,g=rX,o= /etc/$app
chmod 770 $final_path/Coturn_config_rotate.sh
setfacl -R -m user:turnserver:rX /etc/$app
setfacl -R -m user:turnserver:rwX /var/log/$app
#=================================================
# SETUP LOGROTATE
#=================================================
ynh_script_progression --message="Upgrading logrotate configuration..." --weight=1
# # Use logrotate to manage app-specific logfile(s)
ynh_use_logrotate --non-append
#================================================= #=================================================
# INTEGRATE SERVICE IN YUNOHOST # INTEGRATE SERVICE IN YUNOHOST
#================================================= #=================================================
ynh_script_progression --message="Integrating service in YunoHost..." --weight=2 ynh_script_progression --message="Integrating service in YunoHost..." --weight=1
yunohost service add $app --description="Videoconferencing server" --log="/var/log/$app/$app.log" yunohost service add $app --description="Videoconferencing server" --log="/var/log/$app/$app.log" --needs_exposed_ports="$turn_port"
yunohost service add coturn-$app --description="Coturn TURN server" --log="/var/log/$app/turnserver.log" --needs_exposed_ports $turnserver_port
#================================================= #=================================================
# START SYSTEMD SERVICE # START SYSTEMD SERVICE
#================================================= #=================================================
ynh_script_progression --message="Starting a systemd service..." --weight=1 ynh_script_progression --message="Starting a systemd service..." --weight=1
ynh_systemd_action --service_name=coturn-$app.service --action=restart --log_path="/var/log/$app/turnserver.log" ynh_systemd_action --service_name=$app --action=start --log_path="/var/log/$app/$app.log"
ynh_systemd_action --service_name=$app --action=restart --log_path="/var/log/$app/$app.log"
#================================================= #=================================================
# RELOAD NGINX # RELOAD NGINX
@ -297,4 +164,4 @@ ynh_systemd_action --service_name=nginx --action=reload
# END OF SCRIPT # END OF SCRIPT
#================================================= #=================================================
ynh_script_progression --message="Upgrade of Galène completed" --last ynh_script_progression --message="Upgrade of $app completed" --last

View file

@ -1,35 +0,0 @@
#!/bin/bash
source /usr/share/yunohost/helpers
external_IP_line="external-ip=__IPV4__/__IPV6__"
public_ip4="$(curl -s ip.yunohost.org)" || true
public_ip6="$(curl -s ipv6.yunohost.org)" || true
if [ -n "$public_ip4" ] && ynh_validate_ip4 --ip_address="$public_ip4"
then
external_IP_line="${external_IP_line/'__IPV4__'/$public_ip4}"
else
external_IP_line="${external_IP_line/'__IPV4__/'/}"
fi
if [ -n "$public_ip6" ] && ynh_validate_ip6 --ip_address="$public_ip6"
then
external_IP_line="${external_IP_line/'__IPV6__'/$public_ip6}"
else
external_IP_line="${external_IP_line/'/__IPV6__'/}"
fi
old_config_line=$(egrep "^external-ip=.*\$" "/etc/__APP__/coturn.conf")
ynh_replace_string "^external-ip=.*\$" "$external_IP_line" "/etc/__APP__/coturn.conf"
new_config_line=$(egrep "^external-ip=.*\$" "/etc/__APP__/coturn.conf")
setfacl -R -m user:turnserver:rX /etc/__APP__
if [ "$old_config_line" != "$new_config_line" ]
then
systemctl restart coturn-__APP__.service
fi
exit 0