#!/bin/bash ##################################################################### ####### Script instalador Ogclient ####### Autor: Luis Gerardo Romero ##################################################################### function globalSetup () { PROGRAMDIR=$(readlink -e "$(dirname "$0")") PROGRAMNAME=$(basename "$0") OPENGNSYS_CLIENT_USER="ogdhcp" # Comprobar si se ha descargado el paquete comprimido (REMOTE=0) o sólo el instalador (REMOTE=1). OPENGNSYS_SERVER="opengnsys.es" if [ -d "$PROGRAMDIR/../installer" ]; then echo REMOTE=0 REMOTE=0 else echo REMOTE=1 REMOTE=1 fi BRANCH=$1 if [[ -z $BRANCH ]]; then BRANCH="main" fi GIT_REPO="ssh://git@ognproject.evlt.uma.es:21987/opengnsys/ogdhcp.git" # Directorios de instalación y destino de OpenGnsys. WORKDIR=/tmp/ogdhcp_installer INSTALL_TARGET=/opt/ogdhcp PATH=$PATH:$INSTALL_TARGET/bin if which service &>/dev/null; then STARTSERVICE="eval service \$service restart" STOPSERVICE="eval service \$service stop" else STARTSERVICE="eval /etc/init.d/\$service restart" STOPSERVICE="eval /etc/init.d/\$service stop" fi ENABLESERVICE="eval update-rc.d \$service defaults" DISABLESERVICE="eval update-rc.d \$service disable" APACHESERV=apache2 APACHECFGDIR=/etc/apache2 APACHESITESDIR=sites-available APACHEOGSITE=ogdhcp APACHEUSER="www-data" APACHEGROUP="www-data" APACHEENABLEMODS="a2enmod headers ssl rewrite proxy_fcgi fastcgi actions alias" APACHEENABLESSL="a2ensite default-ssl" APACHEENABLEOG="a2ensite $APACHEENABLEOG" APACHEMAKECERT="make-ssl-cert generate-default-snakeoil --force-overwrite" PHPFPMSERV=php7.2-fpm # Registro de incidencias. OGLOGFILE=$INSTALL_TARGET/var/log/${PROGRAMNAME%.sh}.log LOG_FILE=/tmp/$(basename $OGLOGFILE) } function checkDependencies() { echoAndLog "Checking dependencies..." # Lista de dependencias local DEPENDENCIES=(php php-cli php-fpm php-json php-pdo php-mysql php-zip php-gd php-mbstring php-curl php-xml php-pear php-bcmath composer unzip apache2 libapache2-mod-php) # Comprobar cada dependencia for dep in "${DEPENDENCIES[@]}"; do if ! dpkg -s $dep >/dev/null 2>&1; then echoAndLog "$dep is not installed. Installing..." sudo apt-get install -y $dep else echoAndLog "$dep is already installed." fi done echoAndLog "Dependencies checked." } # Función para instalar los paquetes necesarios para KEA-DHCP install_kea() { sudo apt-get install -y isc-kea-common isc-kea-ctrl-agent isc-kea-dhcp4-server isc-kea-dhcp6-server isc-kea-admin } # Función para instalar Composer install_composer() { curl -sS https://getcomposer.org/installer | php sudo mv composer.phar /usr/local/bin/composer } # Función para instalar Swagger UI install_swagger() { sudo apt-get install -y unzip wget https://github.com/swagger-api/swagger-ui/archive/master.zip unzip master.zip -d /var/www/html/ sudo mv /var/www/html/swagger-ui-master /var/www/html/swagger-ui } # Obtiene el código fuente del proyecto desde el repositorio de GitHub. function downloadCode() { if [ $# -ne 1 ]; then errorAndLog "${FUNCNAME}(): invalid number of parameters" exit 1 fi local url="$1" echoAndLog "${FUNCNAME}(): downloading code from '$url'..." GIT_SSH_COMMAND="ssh -o StrictHostKeyChecking=accept-new" git archive --remote=$url --format zip --output opengnsys.zip --prefix=opengnsys/ $BRANCH && unzip opengnsys.zip if [ $? -ne 0 ]; then errorAndLog "${FUNCNAME}(): error getting OpenGnsys code from $url" return 1 fi rm -f opengnsys.zip echoAndLog "${FUNCNAME}(): code was downloaded" return 0 } # Crea la estructura base de la instalación de opengnsys function createDirs() { if [ $# -ne 1 ]; then errorAndLog "${FUNCNAME}(): invalid number of parameters" exit 1 fi local path_opengnsys_base="$1" # Crear estructura de directorios. echoAndLog "${FUNCNAME}(): creating directory paths in $path_opengnsys_base" mkdir -p $path_opengnsys_base mkdir -p $path_opengnsys_base/bin mkdir -p $path_opengnsys_base/config mkdir -p $path_opengnsys_base/docs # Swagger documentation mkdir -p $path_opengnsys_base/public mkdir -p $path_opengnsys_base/src mkdir -p $path_opengnsys_base/etc/kea/backup mkdir -p $path_opengnsys_base/templates mkdir -p $path_opengnsys_base/var/{cache,log} mkdir -p $path_opengnsys_base/vendor if [ $? -ne 0 ]; then errorAndLog "${FUNCNAME}(): error while creating dirs. Do you have write permissions?" return 1 fi # Crear usuario ficticio. if id -u $OPENGNSYS_CLIENT_USER &>/dev/null; then echoAndLog "${FUNCNAME}(): user \"$OPENGNSYS_CLIENT_USER\" is already created" else echoAndLog "${FUNCNAME}(): creating OpenGnsys user" useradd $OPENGNSYS_CLIENT_USER 2>/dev/null if [ $? -ne 0 ]; then errorAndLog "${FUNCNAME}(): error creating OpenGnsys user" return 1 fi fi # Mover el fichero de registro de instalación al directorio de logs. echoAndLog "${FUNCNAME}(): moving installation log file" mv $LOG_FILE $path_opengnsys_base/var/log && LOG_FILE=$OGLOGFILE chmod 777 $LOG_FILE sudo chmod -R 777 $path_opengnsys_base/etc # Mover el fichero de registro de instalación al directorio de logs. echoAndLog "${FUNCNAME}(): moving installation log file" touch $path_opengnsys_base/var/log/dev.log chmod 777 $path_opengnsys_base/var/log/dev.log echoAndLog "${FUNCNAME}(): directory paths created" return 0 echoAndLog "Changing user permission" chown -R $OPENGNSYS_CLIENT_USER:$OPENGNSYS_CLIENT_USER $INSTALL_TARGET # Copia de antemano .env ya que es necesario para montar el esqueleto de symfony cp -a $WORKDIR/ogdhcp/.env "${path_opengnsys_base}/.env" } function create_ogdhcp_project { # Cambia al usuario ogdhcp y crea el proyecto Symfony local path_opengnsys_base="$1" composer create-project symfony/website-skeleton $path_opengnsys_base pushd $path_opengnsys_base # Elimina el archivo composer.lock rm composer.lock popd echoAndLog "Esqueleto de la aplicación creado y archivo composer.lock eliminado." } function copyServerFiles () { if [ $# -ne 1 ]; then errorAndLog "${FUNCNAME}(): invalid number of parameters" exit 1 fi local path_opengnsys_base="$1" # Lista de ficheros y directorios origen y de directorios destino. local SOURCES=( config \ #public \ src \ etc \ templates \ tests \ vendor \ .env \ composer.json \ composer.lock \ phpunit.xml.dist \ symfony.lock ) local TARGETS=( config \ #public \ src \ etc \ templates \ tests \ vendor \ .env \ composer.json \ composer.lock \ phpunit.xml.dist \ symfony.lock ) if [ ${#SOURCES[@]} != ${#TARGETS[@]} ]; then errorAndLog "${FUNCNAME}(): inconsistent number of array items" exit 1 fi # Copiar ficheros. echoAndLog "${FUNCNAME}(): copying files to server directories" pushd $WORKDIR/ogdhcp local i for (( i = 0; i < ${#SOURCES[@]}; i++ )); do if [ -f "${SOURCES[$i]}" ]; then echoAndLog "Copying ${SOURCES[$i]} to $path_opengnsys_base/${TARGETS[$i]}" cp -a "${SOURCES[$i]}" "${path_opengnsys_base}/${TARGETS[$i]}" elif [ -d "${SOURCES[$i]}" ]; then echoAndLog "Copying content of ${SOURCES[$i]} to $path_opengnsys_base/${TARGETS[$i]}" cp -a "${SOURCES[$i]}"/* "${path_opengnsys_base}/${TARGETS[$i]}" else warningAndLog "Unable to copy ${SOURCES[$i]} to $path_opengnsys_base/${TARGETS[$i]}" fi done echoAndLog "Changing user permission" chown -R $OPENGNSYS_CLIENT_USER:$OPENGNSYS_CLIENT_USER $INSTALL_TARGET popd } function downloadComposer() { echoAndLog "Downloading composer.phar..." # Crear el directorio de trabajo si no existe mkdir -p $WORKDIR/ogdhcp/bin # Cambiar al directorio de trabajo pushd $WORKDIR/ogdhcp/bin # Descargar composer.phar curl -sS https://getcomposer.org/installer | php # Comprobar si la descarga fue exitosa if [ ! -f composer.phar ]; then errorAndLog "Failed to download composer.phar" popd return 1 fi # Crear el directorio de destino si no existe mkdir -p /opt/ogdhcp/bin # Mover composer.phar a /opt/ogdhcp/bin mv composer.phar /opt/ogdhcp/bin/ # Comprobar si el movimiento fue exitoso if [ ! -f /opt/ogdhcp/bin/composer.phar ]; then errorAndLog "Failed to move composer.phar to /opt/ogdhcp/bin" popd return 1 fi # Volver al directorio original popd echoAndLog "composer.phar downloaded and moved to /opt/ogdhcp/bin" return 0 } function runComposer() { echoAndLog "Running composer.phar to install dependencies..." # Cambiar al directorio donde está composer.phar pushd /opt/ogdhcp/bin # Ejecutar composer.phar sudo -u $OPENGNSYS_CLIENT_USER php composer.phar install # Comprobar si la ejecución fue exitosa if [ $? -ne 0 ]; then errorAndLog "Failed to run composer.phar" popd return 1 fi # Volver al directorio original popd echoAndLog "composer.phar ran successfully and dependencies were installed" return 0 } function install_swagger_ui { # Define la URL del archivo de Swagger UI que quieres descargar swagger_ui_url="https://github.com/swagger-api/swagger-ui/archive/refs/heads/master.zip" # Define la ruta donde quieres descomprimir Swagger UI swagger_ui_path="/tmp/swagger-ui" # Define la ruta de destino para los archivos de Swagger UI destination_path="/opt/ogdhcp/public" # Crea los directorios si no existen mkdir -p $swagger_ui_path mkdir -p $destination_path # Descarga el archivo de Swagger UI wget $swagger_ui_url -O /tmp/swagger-ui.zip # Descomprime el archivo de Swagger UI en la ruta especificada unzip /tmp/swagger-ui.zip -d $swagger_ui_path # Copia los archivos de Swagger UI al directorio de destino cp -r $swagger_ui_path/swagger-ui-master/dist/* $destination_path # Elimina el archivo descargado y el directorio temporal rm /tmp/swagger-ui.zip rm -r $swagger_ui_path /opt/ogdhcp/vendor/bin/openapi /opt/ogdhcp/src/DhcpBundle/Controller/ -o /opt/ogdhcp/public/swagger.json echo "Swagger UI instalado en $destination_path." } create_kea_source_list() { # Comprobar si el sistema operativo es Ubuntu 18.04 if [[ "$(lsb_release -rs)" == "18.04" ]]; then echo "Creating isc-kea-2-0.list file..." # Crear el archivo isc-kea-2-0.list echo " deb [signed-by=/usr/share/keyrings/isc-kea-2-0-archive-keyring.gpg] https://dl.cloudsmith.io/public/isc/kea-2-0/deb/ubuntu jammy main deb-src [signed-by=/usr/share/keyrings/isc-kea-2-0-archive-keyring.gpg] https://dl.cloudsmith.io/public/isc/kea-2-0/deb/ubuntu jammy main" | sudo tee /etc/apt/sources.list.d/isc-kea-2-0.list echo "File created successfully." else echo "This script is only for Ubuntu 18.04." fi } function installWebConsoleApacheConf() { if [ $# -ne 2 ]; then errorAndLog "${FUNCNAME}(): invalid number of parameters" exit 1 fi local path_opengnsys_base="$1" local path_apache2_confd="$2" local OGHDPCDIR=${path_opengnsys_base}/public local sockfile if [ ! -d $path_apache2_confd ]; then errorAndLog "${FUNCNAME}(): path to apache2 conf.d can not found, verify your server installation" return 1 fi mkdir -p $path_apache2_confd/{sites-available,sites-enabled} echoAndLog "${FUNCNAME}(): creating apache2 config file.." # Avtivar PHP-FPM. echoAndLog "${FUNCNAME}(): configuring PHP-FPM" service=$PHPFPMSERV $ENABLESERVICE; $STARTSERVICE sockfile=$(find /run/php -name "php*.sock" -type s -print 2>/dev/null | tail -1) # Activar módulos de Apache. $APACHEENABLEMODS # Genera configuración de consola web a partir del fichero plantilla. if [ -n "$sockfile" ]; then sed -e "s,OGHDPCDIR,$OGHDPCDIR,g" \ -e "s,proxy:fcgi:.*,proxy:unix:${sockfile%% *}|fcgi://localhost\",g" \ $WORKDIR/ogdhcp/etc/apache.conf.tmpl > $path_apache2_confd/$APACHESITESDIR/${APACHEOGSITE}.conf else sed -e "s,OGHDPCDIR,$OGHDPCDIR,g" \ $WORKDIR/ogdhcp/server/etc/apache.conf.tmpl > $path_apache2_confd/$APACHESITESDIR/${APACHEOGSITE}.conf fi $APACHEENABLEOG if [ $? -ne 0 ]; then errorAndLog "${FUNCNAME}(): config file can't be linked to apache conf, verify your server installation" return 1 fi echoAndLog "${FUNCNAME}(): config file created and linked, restarting apache daemon" service=$APACHESERV $ENABLESERVICE; $STARTSERVICE return 0 } ##################################################################### ####### Algunas funciones útiles de propósito general: ##################################################################### function getDateTime() { date "+%Y%m%d-%H%M%S" } # Escribe a fichero y muestra por pantalla function echoAndLog() { local DATETIME=`getDateTime` echo "$1" echo $LOG_FILE echo "$DATETIME;$SSH_CLIENT;$1" >> $LOG_FILE } # Escribe a fichero y muestra mensaje de error function errorAndLog() { local DATETIME=`getDateTime` echo "ERROR: $1" echo "$DATETIME;$SSH_CLIENT;ERROR: $1" >> $LOG_FILE } # Escribe a fichero y muestra mensaje de aviso function warningAndLog() { local DATETIME=`getDateTime` echo "Warning: $1" echo "$DATETIME;$SSH_CLIENT;Warning: $1" >> $LOG_FILE } ########################################################################## ################################main###################################### # Sólo ejecutable por usuario root if [ "$(whoami)" != 'root' ]; then echo "ERROR: this program must run under root privileges!!" exit 1 fi globalSetup echoAndLog "OpenGnsys installation begins at $(date)" mkdir -p $WORKDIR pushd $WORKDIR create_kea_source_list checkDependencies install_kea # Si es necesario, descarga el repositorio de código en directorio temporal if [ $REMOTE -eq 1 ]; then downloadCode $GIT_REPO if [ $? -ne 0 ]; then errorAndLog "Error while getting code from the repository" exit 1 fi else ln -fs "$(dirname $PROGRAMDIR)" ogdhcp fi create_ogdhcp_project ${INSTALL_TARGET} if [ $? -ne 0 ]; then errorAndLog "Error while creating skeleton directory!" exit 1 fi # Arbol de directorios de OpenGnsys. createDirs ${INSTALL_TARGET} if [ $? -ne 0 ]; then errorAndLog "Error while creating directory paths!" exit 1 fi # Copiar ficheros de servicios OpenGnsys Server. copyServerFiles ${INSTALL_TARGET} if [ $? -ne 0 ]; then errorAndLog "Error while copying the server files!" exit 1 fi downloadComposer runComposer install_swagger_ui # Creando configuración de Apache. installWebConsoleApacheConf $INSTALL_TARGET $APACHECFGDIR if [ $? -ne 0 ]; then errorAndLog "Error configuring Apache for OpenGnsys Admin" exit 1 fi sudo apt-get update # install_kea # install_php # install_composer # install_symfony # install_swagger # Ahora puedes clonar e instalar el componente ogDhcp # git clone # cd # composer install