Installation de paquets hors ppa

Introduction

#!/usr/bin/sh


# Script de post-installation de machine debian destinée à héberger un
# serveur LAMP-FPM, avec environnement de développement VSCodium/Xdebug
# ainsi que Docker.
#
# Les différentes fonctions sont à effectuer dans un certain ordre :
#    Xdebug après php-fmp pour être sûr que les fichiers et liens sont bien créés
#    PHP après apache pour activer fastcgi
#
# La fonction d'installation de MariaDB permet de changer le mot de passe root de MariaDB
#
# On peut diriger la sortie vers la console ou vers un fichier de log
#
# Des fichiers témoins permettent la reprise en cas d'erreur à une étape

PHPVERSION="8.2"
NODEJSVERSION="18"
MODEL="laptop"
INSTALLDIR="/var/log/install"
LOGDIR="$INSTALLDIR/log"
LOGFILE="/dev/stdout"
SEPARATOR="\n===========================================\n"
RUN="false"
GROUPUSER=$USER
MYSQLROOT1="root"
MYSQLROOT2="mysql"
DISTRIBUTION=""
ADDITIONAL=""

usage() {
    echo
    echo "post-install.sh [-hfrtx] [-u username] [-d distribution] [-a additional]"
    echo "   -h : cette aide"
    echo "   -a additional : liste à virgule sans espace d'outils supplémentaires à installer"
    echo "   -d distribution : debian ou ubuntu"
    echo "   -f : installation d'un ordinateur fixe (pas de firmware-iwlwifi)"
    echo "   -r : run, effectue les opérations"
    echo "   -t : trace, stocke les logs dans un fichier. Sinon, affiche dans le stdout"
    echo "   -u username : ajoute username aux groupes utiles. \$USER par défaut si vous êtes en sudo"
    echo "   -x : set -x, mode affichage des commandes"
    echo
    echo "ATTENTION : Exécuter en tant que root pour avoir les droits de modification et si sudo n'est pas encore configuré"
    echo
}

while getopts hfrxtu:d:a: OPTION;do
    case $OPTION in
	a) ADDITIONAL=$OPTARG;;
	d) DISTRIBUTION=$OPTARG;;
	f) MODEL="fixe";;
	h) usage
	   exit 1;;
	r) RUN="true";;
	t) LOGFILE="$LOGDIR/post-install.`date +%Y%m%d-%H%M%S`.log";;
	u) GROUPUSER=$OPTARG;;
	x) set -x;;
	*) usage
	   exit 2;;
    esac
done

manageError() {
    if [ $1 != 0 ]; then
	echo $2
	exit 2
    fi
}

prerun() {
    if [ "$DISTRIBUTION" = "" ]; then
	echo
	echo "ERREUR : Indiquez la distibution à configurer (debian ou ubuntu)"
	echo
	usage
	exit 2
    fi
    if [ "$ADDITIONAL" != "" ]; then
	echo
	echo "Nous allons installer les produits supplémentaires suivants :"
	for tool in `echo $ADDITIONAL | sed 's/,/ /g'`; do
	    echo "       " $tool
	    exists=`type optional_install$tool`
	    if [ ! "$exists" = "optional_install$tool is a shell function" ]; then
		echo "ERREUR : pas de méthode pour installer $tool"
		echo
		echo "Le script doit contenir une fonction nommée optional_install$tool"
		echo
		echo "Les fonctions optionnelles disponibles sont :"
		echo
		grep '^optional_install' $0
		echo
		exit 2
	    fi
	done
	echo
    fi
    if [ "$DISTRIBUTION" = "ubuntu" ]; then
	PHPVERSION="8.1"
    fi
    echo
    if [ "$RUN" = false ]; then
	echo "Les opérations ne seront pas effectuées, lancer avec l'option -r pour appliquer les modifications, -h pour l'aide"
	echo
    else
	while [ $MYSQLROOT1 != $MYSQLROOT2 ]; do
	    echo "Nouveau mot de passe root pour mysql :"
	    read MYSQLROOT1
	    echo "Confirmation : ressaisissez le mot de passe"
	    read MYSQLROOT2
	    if [ $MYSQLROOT2 != $MYSQLROOT1 ]; then
		echo "ERREUR: les deux saisies ne correspondent pas"
	    fi
	done
    echo	
    fi
    if [ "$LOGFILE" != "/dev/stdout" ]; then
	echo "Fichier de log : $LOGFILE"
	echo
    fi
    echo "Installation sous $INSTALLDIR avec droits pour $GROUPUSER"
    echo $SEPARATOR
    mkdir -p $INSTALLDIR
    mkdir -p $LOGDIR
    for conf in php xdebug_config_codium; do
	cp -pr $conf $INSTALLDIR
	manageError $? "ERREUR lors de la copie de $conf vers $INSTALLDIR"
    done
    cd $INSTALLDIR
}

initializations() {
    echo "Initialisations..."
    if [ "$RUN" = "true" ]; then
	if [ ! -f $LOGDIR/initializations ]; then
	    echo "    Ajout de $GROUPUSER au groupe sudo"
	    usermod -aG sudo $GROUPUSER
	    echo "    Ajout de packages"
	    apt-get install -y ca-certificates apt-transport-https software-properties-common wget curl lsb-release emacs
	    manageError $? "ERREUR lors de l'installation des premiers packages"
	    touch $LOGDIR/initializations
	else
	    echo "Fichier témoin présent, rien à faire"
	fi
    fi
    echo "fin des initialisations"
    echo $SEPARATOR
}

configApt() {
    echo "Configuration de apt..."
    if [ "$RUN" = "true" -a "$DISTRIBUTION" = "debian" ]; then
	if [ ! -f $LOGDIR/apt ]; then
	    sed -ibak 's/main$/main contrib non-free/g' /etc/apt/sources.list
	    manageError $? "ERREUR lors de la modification de sources.list"
	    apt update
	    if [ $MODEL = "laptop" ]; then
		apt install -y firmware-linux-nonfree firmware-iwlwifi 
		manageError $? "ERREUR lors de l'installation des packages wifi"
	    fi
	    touch $LOGDIR/apt
	else
	    echo "Fichier témoin présent, rien à faire"
	fi
    fi
    echo "fin de la configuration de apt"
    echo $SEPARATOR
}

installApache2() {
    echo "Installation d'Apache..."
    if [ "$RUN" = "true" ]; then
	if [ ! -f $LOGDIR/apache ]; then
	    apt update && apt install -y apache2
	    manageError $? "ERREUR lors de l'installation de apache"
	    apache2 -v |grep '^Server version'
	    touch $LOGDIR/apache
	else
	    echo "Fichier témoin présent, rien à faire"
	fi
    fi
    echo "fin de la configuration d'Apache"
    echo $SEPARATOR    
}

installChrome () {
    echo "Installation de Chrome..."
    if [ "$RUN" = "true" ]; then
        if [ ! -f $LOGDIR/chrome ]; then
            wget -qO - https://dl.google.com/linux/linux_signing_key.pub \
                | sudo gpg --dearmor -o /usr/share/keyrings/googlechrome-linux-keyring.gpg
            echo "deb [arch=amd64 signed-by=/usr/share/keyrings/googlechrome-linux-keyring.gpg] http://dl.google.com/linux/chrome/deb/ stable main" \
	        > /etc/apt/sources.list.d/google-chrome.list
            apt update && apt install -y google-chrome-stable
            manageError $? "ERREUR lors de l'installation de chrome"
	    google-chrome --version
            touch $LOGDIR/chrome
        else
            echo "Fichier témoin présent, rien à faire"
        fi
    fi
    echo "fin de la configuration de Chrome"
    echo $SEPARATOR  
}

installComposer() {
    # Procedure from https://getcomposer.org/doc/faqs/how-to-install-composer-programmatically.md
    # difference : --install-dir=/usr/local/bin --filename=composer et gestion du code erreur
    echo "Installation de Composer..."
    if [ "$RUN" = "true" ]; then
	if [ ! -f $LOGDIR/composer ]; then
	    EXPECTED_CHECKSUM="$(php -r 'copy("https://composer.github.io/installer.sig", "php://stdout");')"
	    php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
	    ACTUAL_CHECKSUM="$(php -r "echo hash_file('sha384', 'composer-setup.php');")"
	    
	    if [ "$EXPECTED_CHECKSUM" != "$ACTUAL_CHECKSUM" ]
	    then
		>&2 echo 'ERROR: Invalid installer checksum'
		rm composer-setup.php
		exit 1
	    fi

	    php composer-setup.php --quiet --install-dir=/usr/local/bin --filename=composer
	    manageError $? "ERREUR lors de l'installation de composer"
#	    RESULT=$?
	    rm composer-setup.php
	    composer --version
	    touch $LOGDIR/composer
#	    exit $RESULT
	else
	    echo "Fichier témoin présent, rien à faire"
	fi
    fi
    echo "fin de la configuration de composer"
    echo $SEPARATOR  
}

installDiscord() {
    echo "Installation de Discord..."
    if [ "$RUN" = "true" ]; then
	if [ ! -f $LOGDIR/discord ]; then
	    wget "https://discord.com/api/download?platform=linux&format=deb" -O /tmp/discord.deb
	    apt install -y /tmp/discord.deb
	    manageError $? "ERREUR lors de l'installation de discord"
	    dpkg -l |grep discord| awk '{print $2 " " $3}'
	    touch $LOGDIR/discord
	else
	    echo "Fichier témoin présent, rien à faire"
	fi
    fi
    echo "fin de la configuration de Discord"
    echo $SEPARATOR    
}

installDocker() {
    echo "Installation de Docker..."
    if [ "$RUN" = "true" ]; then
	if [ ! -f $LOGDIR/docker ]; then
	    # Install the packages
	    apt-get remove -y --purge docker docker-engine docker.io containerd runc
	    curl -fsSL https://download.docker.com/linux/$DISTRIBUTION/gpg | gpg --dearmor -o /etc/apt/trusted.gpg.d/docker.gpg
	    echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/trusted.gpg.d/docker.gpg] https://download.docker.com/linux/$DISTRIBUTION $(lsb_release -cs) stable" > /etc/apt/sources.list.d/docker.list
	    apt update && apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
	    manageError $? "ERREUR lors de l'installation de docker"
	    # Configuring permissions
	    echo "    Ajout de $GROUPUSER au groupe docker"
	    usermod -aG docker $GROUPUSER
	    # Configuring docker logrotate
	    cat > /etc/docker/daemon.json <<EOF
{
    "log-driver": "json-file",
    "log-opts": {
        "max-size": "10m",
        "max-file": "3" 
    }
}
EOF
	    docker --version
	    touch $LOGDIR/docker
	else
	    echo "Fichier témoin présent, rien à faire"
	fi
    fi
    echo "fin de la configuration de Docker"
    echo $SEPARATOR    
}

installLaTeX() {
    echo "Installation de LaTeX et Pandoc..."
    if [ "$RUN" = "true" ]; then
	if [ ! -f $LOGDIR/latex ]; then
	    apt update
	    apt install -y texlive-latex-base texlive-fonts-recommended texlive-fonts-extra texlive-latex-extra pandoc
	    manageError $? "ERREUR lors de l'installation de LaTeX et Pandoc"
	    touch $LOGDIR/latex
	else
	    echo "Fichier témoin présent, rien à faire"
	fi
    fi
    echo "fin de la configuration de LaTeX"
    echo $SEPARATOR    
}

installMariaDB() {
    # MariaDB install with databases relocated in /home/mysql via symbolic link
    # Set root password
    echo "Installation de MariaDB..."
    if [ "$RUN" = "true" ]; then
	if [ ! -f $LOGDIR/mariadb ]; then
	    # Relocate databases
	    apt update && apt install -y mariadb-*
	    systemctl stop mariadb
	    mv /var/lib/mysql/ /home/
	    ln -s /home/mysql/ /var/lib/mysql
	    sed -ibak 's/ProtectHome=true/ProtectHome=false/g' /usr/lib/systemd/system/mariadb.service
	    systemctl daemon-reload
	    systemctl start mariadb
	    manageError $? "ERREUR lors de l'installation de MariaDB"
	    # Set root password
	    mysql_secure_installation <<EOF

n
Y
$MYSQLROOT1
$MYSQLROOT1
Y
Y
Y
Y
EOF
	    manageError $? "ERREUR lors de la configuration de MariaDB"
	    mariadb --version
	    touch $LOGDIR/mariadb
	else
	    echo "Fichier témoin présent, rien à faire"
	fi
    fi
    echo "fin de la configuration de MariaDB"
    echo $SEPARATOR  
}

installNodeJS() {
    echo "Installation de NodeJS et npm..."
    if [ "$RUN" = "true" ]; then
	if [ ! -f $LOGDIR/nodejs ]; then
	    echo "    Version : $NODEJSVERSION.x"
	    curl -sL https://deb.nodesource.com/setup_$NODEJSVERSION.x | bash -
	    apt update && apt install -y nodejs
	    manageError $? "ERREUR lors de l'installation de NodeJS"
#	    apt install -y npm
#	    manageError $? "ERREUR lors de l'installation de npm"
	    npm install -g npm@latest
	    manageError $? "ERREUR lors de la mise à jour de npm"
	    npm install npm-watch
	    manageError $? "ERREUR lors de l'installation de npm-watch (npm install npm-watch)"
	    npm install --global yarn
	    manageError $? "ERREUR lors de l'installation de yarn (npm install --global yarn)"
	    echo "Node version : " `node --version`
	    echo "Npm version : " `npm --version`
	    echo "Yarn version : " `yarn --version`
	    touch $LOGDIR/nodejs
	else
	    echo "Fichier témoin présent, rien à faire"
	fi
    fi
    echo "fin de la configuration de NodeJS et npm"
    echo $SEPARATOR  
}

installPhp8() {
    
    echo "Installation de PHP $PHPVERSION..."
    if [ "$RUN" = "true" ]; then
	if [ ! -f $LOGDIR/php$PHPVERSION ]; then
	    if [ "$DISTRIBUTION" = "debian" ]; then
		curl -sSL https://packages.sury.org/php/README.txt | bash -x
	    fi
	    apt-get update
	    apt install -y php$PHPVERSION php$PHPVERSION-cli php$PHPVERSION-fpm php$PHPVERSION-pdo php$PHPVERSION-mysql \
		php$PHPVERSION-zip php$PHPVERSION-gd php$PHPVERSION-mbstring php$PHPVERSION-curl php$PHPVERSION-xml \
		php$PHPVERSION-bcmath php$PHPVERSION-intl php$PHPVERSION-opcache php$PHPVERSION-readline
#	    apt install -y php$PHPVERSION php$PHPVERSION-cli php$PHPVERSION-fpm php$PHPVERSION-pdo php$PHPVERSION-mysql \
#		php$PHPVERSION-zip php$PHPVERSION-gd php$PHPVERSION-mbstring php$PHPVERSION-curl php$PHPVERSION-xml \
#		php$PHPVERSION-bcmath php$PHPVERSION-intl php$PHPVERSION-intl-dbgsym php$PHPVERSION-opcache php$PHPVERSION-readline
	    manageError $? "ERREUR lors de l'installation de PHP $PHPVERSION"
	    a2enmod proxy_fcgi setenvif
	    a2enconf php$PHPVERSION-fpm
	    systemctl reload apache2

	    cp php/php.ini /etc/php/$PHPVERSION/fpm/php.ini
	    systemctl restart php$PHPVERSION-fpm
	    manageError $? "ERREUR lors de la configuration de PHP FPM"

	    if [ ! -L /etc/php/$PHPVERSION/fpm/conf.d/20-pdo_mysql.ini ]; then
		echo "Lien manquant : /etc/php/$PHPVERSION/fpm/conf.d/20-pdo_mysql.ini"
		exit 2
	    fi
	    if [ ! -L /etc/php/$PHPVERSION/fpm/conf.d/20-intl.ini ]; then
		echo "Lien manquant : /etc/php/$PHPVERSION/fpm/conf.d/20-intl.ini"
		exit 2
	    fi
	    php --version | grep ^PHP
	    touch $LOGDIR/php$PHPVERSION
	else
	    echo "Fichier témoin présent, rien à faire"
	fi
    fi
    echo "fin de la configuration de PHP"
    echo $SEPARATOR
}

installPostgreSQL() {
    echo "Installation de PostgreSQL..."
    if [ "$RUN" = "true" ]; then
	if [ ! -f $LOGDIR/postgresql ]; then
	    apt install -y postgresql postgresql-client postgresql-contrib php$VERSION-pgsql
	    manageError $? "ERREUR lors de l'installation de postgresql"
	    su postgres -c "psql -c \"ALTER USER postgres WITH password '$MYSQLROOT1'\""
	    manageError $? "ERREUR lors de la modification du mot de passe de postgres"
	    postgres -V
	    touch $LOGDIR/postgresql
	else
	    echo "Fichier témoin présent, rien à faire"
	fi
    fi
    echo "fin de la configuration de PostgreSQL"
    echo $SEPARATOR
}

installSymfony() {
    echo "Installation de Symfony..."
    if [ "$RUN" = "true" ]; then
	if [ ! -f $LOGDIR/symfony ]; then
	    curl -1sLf 'https://dl.cloudsmith.io/public/symfony/stable/setup.deb.sh' | bash -
	    apt update && apt install -y symfony-cli
	    manageError $? "ERREUR lors de l'installation de symfony"
	    symfony -V | grep 'Symfony CLI'
	    touch $LOGDIR/symfony
	else
	    echo "Fichier témoin présent, rien à faire"
	fi
    fi
    echo "fin de la configuration de Symfony"
    echo $SEPARATOR  
}

installTemplate() {
    #
    # Template d'outil à installer
    # Si pas de configuaration particulière, remplacer TOOL par le nom du package à installer
    #
    echo "Installation de TOOL..."
    if [ "$RUN" = "true" ]; then
	if [ ! -f $LOGDIR/TOOL ]; then
	    apt update && apt install -y TOOL
	    manageError $? "ERREUR lors de l'installation de TOOL"
	    touch $LOGDIR/TOOL
	else
	    echo "Fichier témoin présent, rien à faire"
	fi
    fi
    echo "fin de la configuration de TOOL"
    echo $SEPARATOR    
}

installVSCodium() {
    echo "Installation de VSCodium..."
    if [ "$RUN" = "true" ]; then
	if [ ! -f $LOGDIR/vscodium ]; then
	    wget -qO - https://gitlab.com/paulcarroty/vscodium-deb-rpm-repo/raw/master/pub.gpg \
		| gpg --dearmor \
		| dd of=/usr/share/keyrings/vscodium.gpg
    
	    echo 'deb [ signed-by=/usr/share/keyrings/vscodium.gpg ] https://download.vscodium.com/debs vscodium main' \
		| tee /etc/apt/sources.list.d/vscodium.list
    
	    apt update && apt install -y codium
	    manageError $? "ERREUR lors de l'installation de VSCodium"
	    echo "codium : " `codium --version | head -1`
	    touch $LOGDIR/vscodium
	else
	    echo "Fichier témoin présent, rien à faire"
	fi
    fi
    echo "fin de la configuration de VSCodium"
    echo $SEPARATOR  
}

installXdebug() {
    echo "Installation de Xdebug..."
    if [ "$RUN" = "true" ]; then
	if [ ! -f $LOGDIR/xdebug ]; then
	    apt install -y php-xdebug
	    manageError $? "ERREUR lors de l'installation de Xdebug"
	    systemctl restart php$PHPVERSION-fpm
	    dpkg -l |grep php-xdebug| awk '{print $2 " " $3}'
	    touch $LOGDIR/xdebug
	else
	    echo "Fichier témoin présent, rien à faire"
	fi
    fi
    echo "fin de la configuration de Xdebug"
    echo $SEPARATOR  
}

optional_installtoolboxjetbrains() {
    echo "Installation de JetBrains..."
    if [ "$RUN" = "true" ]; then
	if [ ! -f $LOGDIR/jetbrains ]; then
	    wget -O /tmp/jetbrains-toolbox.tar.gz 'https://download-cdn.jetbrains.com/toolbox/jetbrains-toolbox-1.27.2.13801.tar.gz'
	    tar -xzf /tmp/jetbrains-toolbox.tar.gz -C /opt
	    manageError $? "ERREUR lors de l'installation de JetBrains"
	    touch $LOGDIR/jetbrains
	else
	    echo "Fichier témoin présent, rien à faire"
	fi
    fi
    echo "fin de la configuration de JetBrains"
    echo $SEPARATOR    
}

optional_installhugo() {
    echo "Installation de Hugo..."
    if [ "$RUN" = "true" ]; then
	if [ ! -f $LOGDIR/hugo ]; then
	    wget https://github.com/gohugoio/hugo/releases/download/v0.79.0/hugo_0.79.0_Linux-64bit.deb -O /tmp/hugo.deb
	    apt install -y /tmp/hugo.deb
	    manageError $? "ERREUR lors de l'installation de Hugo"
	    touch $LOGDIR/hugo
	else
	    echo "Fichier témoin présent, rien à faire"
	fi
    fi
    echo "fin de la configuration de Hugo"
    echo $SEPARATOR
    optional_installgo
    echo "Hugo et go sont installés"
    echo "  Vous devez maintenant les configurer"
    echo "  Pour télécharger le repository hugo-theme-relearn : "
    echo "    git submodule add https://github.com/McShelby/hugo-theme-relearn themes/hugo-theme-relearn"
    echo "  Pour installer la documentation :"
    echo "    git clone --recurse-submodules https://gitlab.com/smartfidelis/smartvotation-doc.git"
    echo "  Pour lancer le serveur Hugo:"
    echo "    hugo server"
    echo $SEPARATOR
}

optional_installgo() {
# Reference : https://go.dev/doc/install
    echo "Installation de Go..."
    if [ "$RUN" = "true" ]; then
	if [ ! -f $LOGDIR/go ]; then
	    wget -O /tmp/go.tar.gz https://go.dev/dl/go1.19.4.linux-amd64.tar.gz
	    rm -rf /usr/local/go && sudo tar -C /usr/local -xzf /tmp/go.tar.gz
	    manageError $? "ERREUR lors de l'installation de Go"
	    touch $LOGDIR/go
	else
	    echo "Fichier témoin présent, rien à faire"
	fi
    fi
    echo "fin de la configuration de Go"
    echo $SEPARATOR    
}

prerun
{
    echo ""
    initializations
    configApt
    installChrome
    installApache2
    installPhp8
    installMariaDB
    installSymfony
    installComposer
    installNodeJS
    installVSCodium
    installXdebug
    installDocker
    installPostgreSQL
    installDiscord
    installLaTeX
    if [ "$ADDITIONAL" != "" ]; then
	for tool in `echo $ADDITIONAL | sed 's/,/ /g'`; do
	    optional_install$tool
	done
    fi
    echo
} > $LOGFILE 2>&1