(**) Translated with www.DeepL.com/Translator
The update will take place in 3 steps:
- saving the production source code,
- database backup,
- Matrix code update .
It is important that each of the steps starts when the previous step went well.
Database and authentication
The shell that will perform the backup operation will not include the Matrix database access account or password. This information will be “retrieved” using a “YAML parser”, which will extract this information from the MATRIX configuration file (homeserver.yaml). The nugget, in this process, is assigned to Stefan Farestam which offers this functionality through the “sed” command, and can be used directly with bash :
#!/bin/bash
# This source code is the property of its author Stefan Farestam. ( https://stackoverflow.com/a/21189044)
# Parser yaml source :
# https://stackoverflow.com/questions/5014632/how-can-i-parse-a-yaml-file-from-a-linux-shell-script
#
#
if [ "$1" = "" ];then
echo "You must provide the complete location of the yaml file to read"
exit 1
fi
function parse_yaml {
local prefix=$2
local s='[[:space:]]*' w='[a-zA-Z0-9_]*' fs=$(echo @|tr @ '\034')
sed -ne "s|^\($s\):|\1|" -e "s|^\($s\)\($w\)$s:$s[\"']\(.*\)[\"']$s\$|\1$fs\2$fs\3|p" -e "s|^\($s\)\($w\)$s:$s\(.*\)$s\$|\1$fs\2$fs\3|p" $1 |
awk -F$fs '{
indent = length($1)/2;
vname[indent] = $2;
for (i in vname) {if (i > indent) {delete vname[i]}}
if (length($3) > 0) {
vn=""; for (i=0; i<indent; i++) {vn=(vn)(vname[i])("_")}
printf("%s%s%s=\"%s\"\n", "'$prefix'",vn, $2, $3);
}
}'
}
parse_yaml "$1"
Robot
To perform this operation you need the package “mytinydc-automation” (https://www.mytinydc.com/automates/)
Creating the robot
Type the command: mytinydc-automation.sh -c matrix-update
.
Paste this code and adjust the value of the variables according to your environment:
# Il s'agit d'un automate d'upgrade
# Je considère que les paquets DEBIAN nécessaire ont déjà été
# installés lors de la mise en place de ce service
#RESS tools-parser-yaml.sh
apt -y install postgresql-client
DATEJOUR=`date +%Y-%m-%d-%H-%M-%S`
DIRMATRIX="/opt/synapse"
DIRBACKUP="/opt/synapse/ressources/backupcode"
OPTTAR="--exclude=ressources --exclude=homeserver.log*"
SERVICEMATRIX="matrix-synapse"
# Pré-check
if [ ! -d "$DIRMATRIX" ];then
echo "[ERR] Matrix n'est pas installé sur ce système"
exit 1
fi
if [ ! -d "$DIRBACKUP" ];then
mkdir -p "$DIRBACKUP"
fi
#Parse le fichier de conf yaml de matrix
ENVMATRIXYAML="/tmp/envmatrix"
if [ ! -x "$RESS_1" ];then
echo "[ERR] Impossible de continuer $RESS_1 n'est pas exécutable"
exit 1
fi
$RESS_1 $DIRMATRIX/homeserver.yaml > $ENVMATRIXYAML
# Sécurité
chmod 600 $ENVMATRIXYAML
source $ENVMATRIXYAML
rm $ENVMATRIXYAML
# Upgrade du service avec backup base et code
# Stop matrix
systemctl stop $SERVICEMATRIX
# Sauvegarde du code
TARFILE="$DIRBACKUP/backup-matrix-synapse-$DATEJOUR.tgz"
tar $OPTTAR -cvzf "$TARFILE" "$DIRMATRIX" 2>&1
# Backup Database
BACKUPDONE="0"
if [ "$database_name" = "psycopg2" ];then
echo "[INFO] Database is postgresl - try to backup"
if [ "$database_args_user" != "" ] && [ "$database_args_password" != "" ] && [ "$database_args_database" != "" ] && [ "$database_args_host" != "" ] && [ "database_args_port" != "" ];then
echo "[INFO] backup in progress vers $DIRBACKUP/backup-database-$DATEJOUR.sql"
export PGPASSWORD="$database_args_password"
pg_dump -d "$database_args_database" -h "$database_args_host" -p "$database_args_port" -U "$database_args_user" > "$DIRBACKUP/backup-database-$DATEJOUR.sql"
unset PGPASSWORD
echo "[INFO] backup done"
if [ -f "$DIRBACKUP/backup-database-$DATEJOUR.sql" ];then
BACKUPDONE="1"
fi
fi
fi
if [ "$BACKUPDONE" = "0" ];then
echo "[ERREUR] La mise à jour ne peut être effectuée"
echo " la base de données n'a pas été sauvegardée"
exit 1
fi
# update du service
cd "$DIRMATRIX"
source $DIRMATRIX/env/bin/activate
pip install --upgrade pip
pip install --upgrade setuptools
pip install --upgrade matrix-synapse[all]
deactivate
# Démarrage du service
systemctl start $SERVICEMATRIX
echo "[INFO] Code sauvegardé dans $TARFILE"
echo "[INFO] Database sauvegardée dans $DIRBACKUP/backup-database-$DATEJOUR.sql"
Save and exit
Then type :
mytinydc-automation.sh matrix-update -cd
#then create the resource file tools-parser-yaml.sh
vi resources/tools-parser-yaml.sh
# and paste the bash code for the YAML parser located above
# Save
# Make this file executable
chmod 700 resources/tools-parser-yaml.sh
# then
exit
Run the automaton by passing the address of the server that hosts Matrix, (localhost if the automaton system is installed on the Matrix server): mytinydc-automation.sh matrix-update [FQDN or Matrix server ip address] -exec -dsp
.
The service restarts automatically after the update.
Without mytinydc-automation
On the Matrix server, create the file “/tmp/tools-parser-yaml.sh” and paste the bash code for the YAML parser located above. Save, then make it executable: chmod 700 /tmp/tools-parser-yaml.sh
.
Create the file /tmp/matrix-update.sh and paste these lines (you will have to adapt the values of the variables used according to your configuration):
#!/bin/bash
######################################################################
## Built with mytinydc-automation process - https://www.mytinydc.com
######################################################################
export APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE="DontWarn"
export DEBIAN_FRONTEND="noninteractive"
export DATEBUILT="Wed May 6 23:42:31 CEST 2020"
export SERVER="`uname -n`"
export PARAMSSH="-q -o UserKnownHostsFile=/dev/null -o PasswordAuthentication=no -o ConnectTimeout=5 -o StrictHostKeyChecking=no"
# Il s'agit d'un automate d'upgrade
# Je considère que les paquets DEBIAN nécessaire ont déjà été
# installé lors de la mise en place de ce service
#Ressource accessible sur le serveur géré
RESS_1="/tmp/tools-parser-yaml.sh"
DIRMATRIX="/opt/synapse"
DIRBACKUP="/opt/synapse/ressources/backupcode"
OPTTAR="--exclude=ressources --exclude=homeserver.log*"
SERVICEMATRIX="matrix-synapse"
# Install postgresql client si non installé
apt -y install postgresql-client
ERR=$?
if [ "$ERR" != "0" ];then
echo "[Automate] /var/lib/mytinydc/automates/matrix-service-update/script.mtya" >&2
echo "[Code Erreur] $ERR" >&2
echo "[Serveur] $SERVER" >&2
echo "[Commande] apt -y install postgresql-client" >&2
exit $ERR
fi
DATEJOUR=`date +%Y-%m-%d-%H-%M-%S`
ERR=$?
if [ "$ERR" != "0" ];then
echo "[Automate] /var/lib/mytinydc/automates/matrix-service-update/script.mtya" >&2
echo "[Code Erreur] $ERR" >&2
echo "[Serveur] $SERVER" >&2
echo "[Commande] DATEJOUR=date +%Y-%m-%d-%H-%M-%S" >&2
exit $ERR
fi
# Pré-check
if [ ! -d "$DIRMATRIX" ];then
echo "[ERR] Matrix n'est pas installé sur ce système"
exit 1
fi
if [ ! -d "$DIRBACKUP" ];then
mkdir -p "$DIRBACKUP"
ERR=$?
if [ "$ERR" != "0" ];then
echo "[Automate] /var/lib/mytinydc/automates/matrix-service-update/script.mtya" >&2
echo "[Code Erreur] $ERR" >&2
echo "[Serveur] $SERVER" >&2
echo "[Commande] mkdir -p '$DIRBACKUP'" >&2
exit $ERR
fi
fi
#Parse le fichier de conf yaml de matrix
ENVMATRIXYAML="/tmp/envmatrix"
if [ ! -x "$RESS_1" ];then
echo "[ERR] Impossible de continuer $RESS_1 n'est pas exécutable"
exit 1
fi
$RESS_1 $DIRMATRIX/homeserver.yaml > $ENVMATRIXYAML
ERR=$?
if [ "$ERR" != "0" ];then
echo "[Automate] /var/lib/mytinydc/automates/matrix-service-update/script.mtya" >&2
echo "[Code Erreur] $ERR" >&2
echo "[Serveur] $SERVER" >&2
echo "[Commande] $RESS_1 $DIRMATRIX/homeserver.yaml > $ENVMATRIXYAML" >&2
exit $ERR
fi
# Sécurité
chmod 600 $ENVMATRIXYAML
ERR=$?
if [ "$ERR" != "0" ];then
echo "[Automate] /var/lib/mytinydc/automates/matrix-service-update/script.mtya" >&2
echo "[Code Erreur] $ERR" >&2
echo "[Serveur] $SERVER" >&2
echo "[Commande] chmod 600 $ENVMATRIXYAML" >&2
exit $ERR
fi
source $ENVMATRIXYAML
ERR=$?
if [ "$ERR" != "0" ];then
echo "[Automate] /var/lib/mytinydc/automates/matrix-service-update/script.mtya" >&2
echo "[Code Erreur] $ERR" >&2
echo "[Serveur] $SERVER" >&2
echo "[Commande] source $ENVMATRIXYAML" >&2
exit $ERR
fi
rm $ENVMATRIXYAML
ERR=$?
if [ "$ERR" != "0" ];then
echo "[Automate] /var/lib/mytinydc/automates/matrix-service-update/script.mtya" >&2
echo "[Code Erreur] $ERR" >&2
echo "[Serveur] $SERVER" >&2
echo "[Commande] rm $ENVMATRIXYAML" >&2
exit $ERR
fi
# Upgrade du service avec backup base et code
# Stop matrix
systemctl stop $SERVICEMATRIX
ERR=$?
if [ "$ERR" != "0" ];then
echo "[Automate] /var/lib/mytinydc/automates/matrix-service-update/script.mtya" >&2
echo "[Code Erreur] $ERR" >&2
echo "[Serveur] $SERVER" >&2
echo "[Commande] systemctl stop $SERVICEMATRIX" >&2
exit $ERR
fi
# Sauvegarde du code
TARFILE="$DIRBACKUP/backup-matrix-synapse-$DATEJOUR.tgz"
ERR=$?
if [ "$ERR" != "0" ];then
echo "[Automate] /var/lib/mytinydc/automates/matrix-service-update/script.mtya" >&2
echo "[Code Erreur] $ERR" >&2
echo "[Serveur] $SERVER" >&2
echo "[Commande] TARFILE='$DIRBACKUP/backup-matrix-synapse-$DATEJOUR.tgz'" >&2
exit $ERR
fi
tar $OPTTAR -cvzf "$TARFILE" "$DIRMATRIX" 2>&1
ERR=$?
if [ "$ERR" != "0" ];then
echo "[Automate] /var/lib/mytinydc/automates/matrix-service-update/script.mtya" >&2
echo "[Code Erreur] $ERR" >&2
echo "[Serveur] $SERVER" >&2
echo "[Commande] tar $OPTTAR -cvzf '$TARFILE' '$DIRMATRIX' 2>&1" >&2
exit $ERR
fi
# Backup Database
BACKUPDONE="0"
ERR=$?
if [ "$ERR" != "0" ];then
echo "[Automate] /var/lib/mytinydc/automates/matrix-service-update/script.mtya" >&2
echo "[Code Erreur] $ERR" >&2
echo "[Serveur] $SERVER" >&2
echo "[Commande] BACKUPDONE='0'" >&2
exit $ERR
fi
if [ "$database_name" = "psycopg2" ];then
echo "[INFO] Database is postgresl - try to backup"
if [ "$database_args_user" != "" ] && [ "$database_args_password" != "" ] && [ "$database_args_database" != "" ] && [ "$database_args_host" != "" ] && [ "database_args_port" != "" ];then
echo "[INFO] backup in progress vers $DIRBACKUP/backup-database-$DATEJOUR.sql"
export PGPASSWORD="$database_args_password"
pg_dump -d "$database_args_database" -h "$database_args_host" -p "$database_args_port" -U "$database_args_user" > "$DIRBACKUP/backup-database-$DATEJOUR.sql"
ERR=$?
if [ "$ERR" != "0" ];then
echo "[Automate] /var/lib/mytinydc/automates/matrix-service-update/script.mtya" >&2
echo "[Code Erreur] $ERR" >&2
echo "[Serveur] $SERVER" >&2
echo "[Commande] pg_dump -d '$database_args_database' -h '$database_args_host' -p '$database_args_port' -U '$database_args_user' > '$DIRBACKUP/backup-database-$DATEJOUR.sql'" >&2
exit $ERR
fi
unset PGPASSWORD
echo "[INFO] backup done"
if [ -f "$DIRBACKUP/backup-database-$DATEJOUR.sql" ];then
BACKUPDONE="1"
fi
fi
fi
if [ "$BACKUPDONE" = "0" ];then
echo "[ERREUR] La mise à jour ne peut être effectuée"
echo " la base de données n'a pas été sauvegardée"
exit 1
fi
# update du service
cd "$DIRMATRIX"
ERR=$?
if [ "$ERR" != "0" ];then
echo "[Automate] /var/lib/mytinydc/automates/matrix-service-update/script.mtya" >&2
echo "[Code Erreur] $ERR" >&2
echo "[Serveur] $SERVER" >&2
echo "[Commande] cd '$DIRMATRIX'" >&2
exit $ERR
fi
source $DIRMATRIX/env/bin/activate
ERR=$?
if [ "$ERR" != "0" ];then
echo "[Automate] /var/lib/mytinydc/automates/matrix-service-update/script.mtya" >&2
echo "[Code Erreur] $ERR" >&2
echo "[Serveur] $SERVER" >&2
echo "[Commande] source $DIRMATRIX/env/bin/activate" >&2
exit $ERR
fi
pip install --upgrade pip
ERR=$?
if [ "$ERR" != "0" ];then
echo "[Automate] /var/lib/mytinydc/automates/matrix-service-update/script.mtya" >&2
echo "[Code Erreur] $ERR" >&2
echo "[Serveur] $SERVER" >&2
echo "[Commande] pip install --upgrade pip" >&2
exit $ERR
fi
pip install --upgrade setuptools
ERR=$?
if [ "$ERR" != "0" ];then
echo "[Automate] /var/lib/mytinydc/automates/matrix-service-update/script.mtya" >&2
echo "[Code Erreur] $ERR" >&2
echo "[Serveur] $SERVER" >&2
echo "[Commande] pip install --upgrade setuptools" >&2
exit $ERR
fi
pip install --upgrade matrix-synapse[all]
ERR=$?
if [ "$ERR" != "0" ];then
echo "[Automate] /var/lib/mytinydc/automates/matrix-service-update/script.mtya" >&2
echo "[Code Erreur] $ERR" >&2
echo "[Serveur] $SERVER" >&2
echo "[Commande] pip install --upgrade matrix-synapse[all]" >&2
exit $ERR
fi
deactivate
ERR=$?
if [ "$ERR" != "0" ];then
echo "[Automate] /var/lib/mytinydc/automates/matrix-service-update/script.mtya" >&2
echo "[Code Erreur] $ERR" >&2
echo "[Serveur] $SERVER" >&2
echo "[Commande] deactivate" >&2
exit $ERR
fi
# Démarrage du service
systemctl start $SERVICEMATRIX
ERR=$?
if [ "$ERR" != "0" ];then
echo "[Automate] /var/lib/mytinydc/automates/matrix-service-update/script.mtya" >&2
echo "[Code Erreur] $ERR" >&2
echo "[Serveur] $SERVER" >&2
echo "[Commande] systemctl start $SERVICEMATRIX" >&2
exit $ERR
fi
echo "[INFO] Code sauvegardé dans $TARFILE"
echo "[INFO] Database sauvegardée dans $DIRBACKUP/backup-database-$DATEJOUR.sql"
#--- ATTENTION CE SHELL DEPEND DE RESSOURCES COMPLEMENTAIRES ---
# Sans les ressources ce shell ne fonctionnera pas
# Les ressources à fournir sont situées dans le répertoire :
# /var/lib/mytinydc/automates/matrix-service-update/ressources/
#
# Vous devrez copier ces ressources sur le système qui exécutera ce shell.
# Puis modifier ce shell en modifiant l'emplacement de ces ressources
# pour les variable qui suivent :
# - RESS_1="/tmp/tools-parser-yaml.sh"
Run this shell: bash /tmp/matrix-update.sh
.
POST execution
If the update of MATRIX is not conclusive at the time of the reboot, you have all the backups at your disposal to put back Matrix in its state before the update. These elements (source code and database) are located in the backup directory indicated in the shell.
Having read all the posts concerning Matrix, you have all the elements to set up a complete automation of the Matrix update (detection, backup, update). In my case I have no manual intervention, everything happens automatically, as soon as a new version is detected. Don’t be afraid to update your Matrix system, I never had to restore the whole system after an update.
Enjoy+++
Document licence : Creative Commons (CC BY-NC-ND 4.0)
THIS DOCUMENTATION IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND AND DISTRIBUTED FOR EDUCATIONAL PURPOSES ONLY. THE AUTHOR, CONTRIBUTORS TO THIS DOCUMENTATION OR ©MYTINYDC.COM SHALL IN NO EVENT BE LIABLE FOR ANY DIRECT OR INDIRECT DAMAGE THAT MAY RESULT FROM THE APPLICATION OF THE PROCEDURES IMPLEMENTED IN THIS DOCUMENTATION, OR FROM THE INCORRECT INTERPRETATION OF THIS DOCUMENT.