blog-image

Mettre à jour le service MATRIX

  • dHENRY
  • 06/05/2020
  • (Durée de lecture : 9 mn)

La mise à jour va se dérouler en 3 étapes :

  • sauvegarde du code source de production,
  • sauvegarde de la base de données,
  • mise à jour du code Matrix .

Il est important que chacune des étapes démarre quand l’étape précédente s’est bien déroulée.

Base de données et authentification

Le shell qui exécutera l’opération de sauvegarde n’incluera ni le compte, ni le mot de passe d’accès à la base de données de Matrix. Ces informations seront “retrouvées” en utilisant un “parser YAML”, chargé d’extraire ces informations du fichier de configuration MATRIX (homeserver.yaml). La pépite, dans ce processus, est attribuée à Stefan Farestam qui propose cette fonctionnalité au travers de la commande “sed”, et utilisable directement avec bash :

#!/bin/bash
# Ce code source est la propriété de son auteur 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 "Vous devez fournir l'emplacement complet du fichier yaml à lire"
    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"

Automate

Pour exécuter cette opération vous devez disposez du package “mytinydc-automation” (https://www.mytinydc.com/automates/)

Création de l’automate

Tapez la commande : mytinydc-automation.sh -c matrix-update

Collez ce code et ajustez la valeur des variables selon votre environnement :


# 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"

Enregistrer et quitter.

Tapez ensuite :

mytinydc-automation.sh matrix-update -cd
#puis créer le fichier ressource tools-parser-yaml.sh
vi ressources/tools-parser-yaml.sh
# et coller le code bash concernant le parser YAML situé ci-avant
# Enregistrer
# Rendre ce fichier exécutable
chmod 700 ressources/tools-parser-yaml.sh
# puis
exit

Exécutez l’automate en passant l’adresse du serveur qui héberge Matrix, (localhost si le système automate est installé sur le serveur Matrix) : mytinydc-automation.sh matrix-update [FQDN ou adresse ip du serveur Matrix] -exec -dsp

Le service redémarre automatiquement après la mise à jour…

Sans mytinydc-automation

Sur le serveur Matrix, créer le fichier “/tmp/tools-parser-yaml.sh” et coller le code bash concernant le parser YAML situé ci-avant. Enregistrer, puis le rendre exécutable : chmod 700 /tmp/tools-parser-yaml.sh

Créer le fichier /tmp/matrix-update.sh et coller ces lignes (vous devrez adapter les valeurs des variables utilisées selon votre 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"

Exécutez ce shell : bash /tmp/matrix-update.sh

POST exécution

Si la mise à jour de MATRIX n’est pas concluante lors du rédémarrage, vous disposez de l’intégralité des sauvegardes pour remettre Matrix dans son état précédent la mise à jour. Ces éléments (code source et base de données) sont situés dans le répertoire de sauvegarde indiqué dans le shell.

En ayant lu tous les billets concernant Matrix, vous disposez de tous les éléments permettant de mettre en place une automatisation complète de la mise à jour Matrix (détection, sauvegarde, mise à jour). Dans mon cas je n’ai aucune intervention manuelle, tout se déroule automatiquement, dès la détection d’une nouvelle version. N’ayez aucune crainte à mettre à jour votre système Matrix, je n’ai jamais dû restaurer l’ensemble après une mise à jour.

Enjoy+++

Licence de ce document : Creative Commons (CC BY-NC-ND 4.0)

CETTE DOCUMENTATION EST LIVRÉE “EN L’ÉTAT”, SANS GARANTIE D’AUCUNE SORTE ET DISTRIBUÉE DANS UN BUT ÉDUCATIF EXCLUSIVEMENT. L’AUTEUR, CONTRIBUTEURS DE CETTE DOCUMENTATION OU ©MYTINYDC.COM NE SAURAIENT EN AUCUN CAS ÊTRE TENUS RESPONSABLES DES DOMMAGES DIRECTS OU INDIRECTS POUVANT RÉSULTER DE L’APPLICATION DES PROCÉDURES MISES EN ŒUVRE DANS CETTE DOCUMENTATION, OU DE LA MAUVAISE INTERPRÉTATION DE CE DOCUMENT.