source: installer/opengnsys_update.sh @ 9c9de82

Last change on this file since 9c9de82 was 87b8c46, checked in by Ramón M. Gómez <ramongomez@…>, 4 years ago

#1048: Installer detects container network interface as "eth0@ifNN".

  • Property mode set to 100755
File size: 48.6 KB
Line 
1#!/bin/bash
2#/**
3#@file    opengnsys_update.sh
4#@brief   Script actualización de OpenGnsys
5#@version 0.9 - basado en opengnsys_installer.sh
6#@author  Ramón Gómez - ETSII Univ. Sevilla
7#@date    2010/01/27
8#@version 1.0 - adaptación a OpenGnSys 1.0
9#@author  Ramón Gómez - ETSII Univ. Sevilla
10#@date    2011/03/02
11#@version 1.0.1 - control de auto actualización del script
12#@author  Ramón Gómez - ETSII Univ. Sevilla
13#@date    2011/05/17
14#@version 1.0.2a - obtiene valor de dirección IP por defecto
15#@author  Ramón Gómez - ETSII Univ. Sevilla
16#@date    2012/01/18
17#@version 1.0.3 - Compatibilidad con Debian y auto configuración de acceso a BD.
18#@author  Ramón Gómez - ETSII Univ. Sevilla
19#@date    2012/03/12
20#@version 1.0.4 - Detector de distribución y compatibilidad con CentOS.
21#@author  Ramón Gómez - ETSII Univ. Sevilla
22#@date    2012/05/04
23#@version 1.0.5 - Actualizar BD en la misma versión, compatibilidad con Fedora (systemd) y configuración de Rsync.
24#@author  Ramón Gómez - ETSII Univ. Sevilla
25#@date    2014/04/03
26#@version 1.0.6 - Redefinir URLs de ficheros de configuración usando HTTPS.
27#@author  Ramón Gómez - ETSII Univ. Sevilla
28#@date    2015/03/12
29#@version 1.1.0 - Instalación de API REST y configuración de zona horaria.
30#@author  Ramón Gómez - ETSII Univ. Sevilla
31#@date    2015/11/09
32#@version 1.1.1a - Elegir versión a actualizar.
33#@author  Ramón Gómez - ETSII Univ. Sevilla
34#@date    2019/12/13
35#*/
36
37
38####  AVISO: NO EDITAR variables de configuración.
39####  WARNING: DO NOT EDIT configuration variables.
40INSTALL_TARGET=/opt/opengnsys           # Directorio de instalación
41PATH=$PATH:$INSTALL_TARGET/bin
42OPENGNSYS_CLIENTUSER="opengnsys"        # Usuario Samba
43
44
45# Sólo ejecutable por usuario root
46if [ "$(whoami)" != 'root' ]; then
47        echo "ERROR: this program must run under root privileges!!"
48        exit 1
49fi
50# Error si OpenGnsys no está instalado (no existe el directorio del proyecto)
51if [ ! -d $INSTALL_TARGET ]; then
52        echo "ERROR: OpenGnsys is not installed, cannot update!!"
53        exit 1
54fi
55
56source $INSTALL_TARGET/lib/ogfunctions.sh || exit 1
57
58echo -n "Current version: "
59if [ -r $INSTALL_TARGET/doc/VERSION.json ]; then
60        jq -j '"OpenGnsys", .version, " ", .release' $INSTALL_TARGET/doc/VERSION.json
61else
62        cat $INSTALL_TARGET/doc/VERSION.txt
63fi
64
65echo -e "\nThe OpenGnsys version 1.2.0 was tested with full functionality on Ubuntu 18.04 with PHP 7.2."
66echo " * If the update is made from a version prior to 1.1.1c, you must disable strict mode in mysql by adding in the configuration file: sql_mode = NO_ENGINE_SUBSTITUTION"
67echo " * If you are going to perform an update from version 1.1.0, it is necessary to start with the operating system, moving it from Ubuntu 16.04 to Ubuntu 18.04, and then perform the OpenGnsys update."
68
69echo -e -n "\nDo you want to continue? [y/N]: "
70read -r GO_ON
71if [ "${GO_ON^^}" != "Y" ]; then
72        echo "We left the installation." && exit
73fi
74
75# Cargar configuración de acceso a la base de datos.
76if [ -r $INSTALL_TARGET/etc/ogserver.json ]; then
77        source_json_config $INSTALL_TARGET/etc/ogserver.json
78elif [ -r $INSTALL_TARGET/etc/ogserver.cfg ]; then
79        source $INSTALL_TARGET/etc/ogserver.cfg
80elif [ -r $INSTALL_TARGET/etc/ogAdmServer.cfg ]; then
81        source $INSTALL_TARGET/etc/ogAdmServer.cfg
82fi
83OPENGNSYS_DATABASE=${OPENGNSYS_DATABASE:-"$CATALOG"}            # Base de datos
84OPENGNSYS_DBUSER=${OPENGNSYS_DBUSER:-"$USUARIO"}                # Usuario de acceso
85OPENGNSYS_DBPASSWORD=${OPENGNSYS_DBPASSWORD:-"$PASSWORD"}       # Clave del usuario
86if [ -z "$OPENGNSYS_DATABASE" -o -z "$OPENGNSYS_DBUSER" -o -z "$OPENGNSYS_DBPASSWORD" ]; then
87        echo "ERROR: set OPENGNSYS_DATABASE, OPENGNSYS_DBUSER and OPENGNSYS_DBPASSWORD"
88        echo "       variables, and run this script again."
89        exit 1
90fi
91
92# Comprobar si se ha descargado el paquete comprimido (REMOTE=0) o sólo el instalador (REMOTE=1).
93PROGRAMDIR=$(readlink -e $(dirname "$0"))
94PROGRAMNAME=$(basename "$0")
95OPENGNSYS_SERVER="opengnsys.es"
96if [ -d "$PROGRAMDIR/../installer" ]; then
97        REMOTE=0
98else
99        REMOTE=1
100fi
101
102WORKDIR=/tmp/opengnsys_update
103mkdir -p $WORKDIR
104
105# Registro de incidencias.
106OGLOGFILE=$INSTALL_TARGET/log/${PROGRAMNAME%.sh}.log
107LOG_FILE=/tmp/$(basename $OGLOGFILE)
108
109
110
111#####################################################################
112####### Algunas funciones útiles de propósito general:
113#####################################################################
114
115# Generar variables de configuración del actualizador
116# Variables globales:
117# - OSDISTRIB - distribución Linux
118# - DEPENDENCIES - array de dependencias que deben estar instaladas
119# - UPDATEPKGLIST, INSTALLPKGS, CHECKPKG - comandos para gestión de paquetes
120# - APACHECFGDIR, APACHESERV, PHPFPMSERV, DHCPSERV, MYSQLSERV, MYSQLCFGDIR, INETDCFGDIR - configuración y servicios
121
122function autoConfigure()
123{
124        local service
125
126        # Detectar sistema operativo del servidor (compatible con fichero os-release y con LSB).
127        if [ -f /etc/os-release ]; then
128                source /etc/os-release
129                OSDISTRIB="$ID"
130                OSVERSION="$VERSION_ID"
131        else
132                OSDISTRIB=$(lsb_release -is 2>/dev/null)
133                OSVERSION=$(lsb_release -rs 2>/dev/null)
134        fi
135        # Convertir distribución a minúsculas y obtener solo el 1er número de versión.
136        OSDISTRIB="${OSDISTRIB,,}"
137        OSVERSION="${OSVERSION%%.*}"
138
139        # Configuración según la distribución de Linux.
140        if [ -f /etc/debian_version ]; then
141                # Distribución basada en paquetes Deb.
142                DEPENDENCIES=( curl rsync btrfs-tools procps arp-scan realpath php-curl gettext moreutils jq wakeonlan udpcast libev-dev libjansson-dev libssl-dev shim-signed grub-efi-amd64-signed php-fpm gawk libdbi-dev libdbi1 libdbd-mysql automake liblz4-tool software-properties-common )
143                # Paquete correcto para realpath.
144                [ -z "$(apt-cache pkgnames realpath)" ] && DEPENDENCIES=( ${DEPENDENCIES[@]//realpath/coreutils} )
145                UPDATEPKGLIST="add-apt-repository -y ppa:ondrej/php; apt-get update"
146                INSTALLPKGS="apt-get -y install"
147                DELETEPKGS="apt-get -y purge"
148                CHECKPKG="dpkg -s \$package 2>/dev/null | grep -q \"Status: install ok\""
149                if which service &>/dev/null; then
150                        STARTSERVICE="eval service \$service restart"
151                        STOPSERVICE="eval service \$service stop"
152                        SERVICESTATUS="eval service \$service status"
153                else
154                        STARTSERVICE="eval /etc/init.d/\$service restart"
155                        STOPSERVICE="eval /etc/init.d/\$service stop"
156                        SERVICESTATUS="eval /etc/init.d/\$service status"
157                fi
158                ENABLESERVICE="eval systemctl enable \$service.service"
159                APACHEENABLEMODS="ssl rewrite proxy_fcgi fastcgi actions alias"
160                APACHEDISABLEMODS="php"
161                APACHEUSER="www-data"
162                APACHEGROUP="www-data"
163                MYSQLCFGDIR=/etc/mysql/mysql.conf.d
164                MYSQLSERV="mysql"
165                PHPFPMSERV="php-fpm"
166                INETDCFGDIR=/etc/xinetd.d
167        elif [ -f /etc/redhat-release ]; then
168                # Distribución basada en paquetes rpm.
169                DEPENDENCIES=( curl rsync btrfs-progs procps-ng arp-scan gettext moreutils jq net-tools udpcast libev-devel jansson-devel openssl-devel shim-x64 grub2-efi-x64 grub2-efi-x64-modules gawk libdbi-devel libdbi libdbi-dbd-mysql automake)
170                # Repositorios para PHP 7 en CentOS.
171                [ "$OSDISTRIB" == "centos" ] && UPDATEPKGLIST="yum update -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-$OSVERSION.noarch.rpm http://rpms.remirepo.net/enterprise/remi-release-$OSVERSION.rpm"
172                INSTALLPKGS="yum install -y"
173                DELETEPKGS="yum remove -y"
174                CHECKPKG="rpm -q --quiet \$package"
175                if which systemctl &>/dev/null; then
176                        STARTSERVICE="eval systemctl restart \$service.service"
177                        STOPSERVICE="eval systemctl stop \$service.service"
178                        ENABLESERVICE="eval systemctl enable \$service.service"
179                        SERVICESTATUS="eval systemctl status \$service.service"
180                else
181                        STARTSERVICE="eval service \$service restart"
182                        STOPSERVICE="eval service \$service stop"
183                        ENABLESERVICE="eval chkconfig \$service on"
184                        SERVICESTATUS="eval service \$service status"
185                fi
186                APACHEUSER="apache"
187                APACHEGROUP="apache"
188                MYSQLCFGDIR=/etc/my.cnf.d
189                MYSQLSERV="mariadb"
190                PHPFPMSERV="php-fpm"
191                INETDCFGDIR=/etc/xinetd.d
192        else
193                # Otras distribuciones.
194                :
195        fi
196        for service in apache2 httpd; do
197                [ -d "/etc/$service" ] && APACHECFGDIR="/etc/$service"
198                if $SERVICESTATUS &>/dev/null; then APACHESERV="$service"; fi
199        done
200        for service in dhcpd dhcpd3-server isc-dhcp-server; do
201                if $SERVICESTATUS &>/dev/null; then DHCPSERV="$service"; fi
202        done
203}
204
205
206# Choose an available version to update.
207function chooseVersion()
208{
209    local RELEASES DOWNLOADS INSTVERSION INSTRELEASE RELDATE
210
211    # Development branch.
212    BRANCH="master"
213    API_URL="https://api.github.com/repos/opengnsys/OpenGnsys/branches/$BRANCH"
214
215    RELEASES=( )
216    DOWNLOADS=( )
217    # If updating from a local or very old version, use the default data.
218    if [ $REMOTE -eq 1 ] && which jq &>/dev/null && [ -f $INSTALL_TARGET/doc/VERSION.json -o -f $INSTALL_TARGET/doc/VERSION.txt ]; then
219        # Installed release.
220        [ -f $INSTALL_TARGET/doc/VERSION.json ] && read -pe INSTVERSION INSTRELEASE <<< $(jq -r '.version+" "+.release' $INSTALL_TARGET/doc/VERSION.json)
221        [ -f $INSTALL_TARGET/doc/VERSION.txt ] && read -pe INSTVERSION INSTRELEASE <<< $(awk '{print $2,$3}' $INSTALL_TARGET/doc/VERSION.txt)
222        # Fetch tags (releases) data from GitHub.
223        while read -pe TAG URL; do
224            if [[ $TAG =~ ^(opengnsys-|v)[0-9] ]]; then
225                [ "${TAG#opengnsys-}" \< "${INSTVERSION%pre}" ] && continue
226                [ "${TAG#v}" \< "${INSTVERSION%pre}" ] && continue
227                RELDATE=$(curl -s "$URL" | jq -r '.commit.committer.date | split("-") | join("")[:8]')
228                RELEASES+=( "${TAG} ($RELDATE)" )
229                DOWNLOADS+=( "$URL" )
230            fi
231        done <<< $(curl -s "$API_URL/../../tags" | jq -r '.[] | .name+" "+.commit.url')
232        # Add development (master) branch.
233        RELEASES+=( "$BRANCH" )
234        DOWNLOADS+=( "$API_URL" )
235        # Show selection menu, if needed.
236        if [ ${#RELEASES[@]} -gt 1 ]; then
237            echo "Installed version: $INSTVERSION $INSTRELEASE"
238            echo "Versions available for update (\"$BRANCH\" is the latest development branch):"
239            PS3="Enter a number (CTRL-C to exit): "
240            select opt in "${RELEASES[@]}"; do
241                if [ -n "$opt" ]; then
242                    BRANCH="${opt%% *}"
243                    API_URL="${DOWNLOADS[REPLY-1]}"
244                    break
245                fi
246            done
247        fi
248    fi
249    # Download URLs.
250    CODE_URL="https://codeload.github.com/opengnsys/OpenGnsys/zip/$BRANCH"
251    RAW_URL="https://raw.githubusercontent.com/opengnsys/OpenGnsys/$BRANCH"
252}
253
254
255# Comprobar auto-actualización.
256function checkAutoUpdate()
257{
258        local update=0
259
260        # Actaulizar el script si ha cambiado o no existe el original.
261        if [ $REMOTE -eq 1 ]; then
262                curl -s $RAW_URL/installer/$PROGRAMNAME -o $PROGRAMNAME
263                chmod +x $PROGRAMNAME
264                if ! diff -q $PROGRAMNAME $INSTALL_TARGET/lib/$PROGRAMNAME 2>/dev/null || ! test -f $INSTALL_TARGET/lib/$PROGRAMNAME; then
265                        mv $PROGRAMNAME $INSTALL_TARGET/lib
266                        update=1
267                else
268                        rm -f $PROGRAMNAME
269                fi
270        else
271                if ! diff -q $PROGRAMDIR/$PROGRAMNAME $INSTALL_TARGET/lib/$PROGRAMNAME 2>/dev/null || ! test -f $INSTALL_TARGET/lib/$PROGRAMNAME; then
272                        cp -a $PROGRAMDIR/$PROGRAMNAME $INSTALL_TARGET/lib
273                        update=1
274                fi
275        fi
276
277        return $update
278}
279
280
281function getDateTime()
282{
283        date "+%Y%m%d-%H%M%S"
284}
285
286# Escribe a fichero y muestra por pantalla
287function echoAndLog()
288{
289        echo "$1"
290        DATETIME=`getDateTime`
291        echo "$DATETIME;$SSH_CLIENT;$1" >> $LOG_FILE
292}
293
294function errorAndLog()
295{
296        echo "ERROR: $1"
297        DATETIME=`getDateTime`
298        echo "$DATETIME;$SSH_CLIENT;ERROR: $1" >> $LOG_FILE
299}
300
301# Escribe a fichero y muestra mensaje de aviso
302function warningAndLog()
303{
304        local DATETIME=`getDateTime`
305        echo "Warning: $1"
306        echo "$DATETIME;$SSH_CLIENT;Warning: $1" >> $LOG_FILE
307}
308
309
310#####################################################################
311####### Funciones de copia de seguridad y restauración de ficheros
312#####################################################################
313
314# Hace un backup del fichero pasado por parámetro
315# deja un -last y uno para el día
316function backupFile()
317{
318        if [ $# -ne 1 ]; then
319                errorAndLog "${FUNCNAME}(): invalid number of parameters"
320                exit 1
321        fi
322
323        local fichero=$1
324        local fecha=`date +%Y%m%d`
325
326        if [ ! -f $fichero ]; then
327                warningAndLog "${FUNCNAME}(): file $fichero doesn't exists"
328                return 1
329        fi
330
331        echoAndLog "${FUNCNAME}(): Making $fichero back-up"
332
333        # realiza una copia de la última configuración como last
334        cp -a $fichero "${fichero}-LAST"
335
336        # si para el día no hay backup lo hace, sino no
337        if [ ! -f "${fichero}-${fecha}" ]; then
338                cp -a $fichero "${fichero}-${fecha}"
339        fi
340}
341
342# Restaura un fichero desde su copia de seguridad
343function restoreFile()
344{
345        if [ $# -ne 1 ]; then
346                errorAndLog "${FUNCNAME}(): invalid number of parameters"
347                exit 1
348        fi
349
350        local fichero=$1
351
352        echoAndLog "${FUNCNAME}(): restoring file $fichero"
353        if [ -f "${fichero}-LAST" ]; then
354                cp -a "$fichero-LAST" "$fichero"
355        fi
356}
357
358
359#####################################################################
360####### Funciones de acceso a base de datos
361#####################################################################
362
363# Actualizar la base datos
364function importSqlFile()
365{
366        if [ $# -ne 4 ]; then
367                errorAndLog "${FNCNAME}(): invalid number of parameters"
368                exit 1
369        fi
370
371        local dbuser="$1"
372        local dbpassword="$2"
373        local database="$3"
374        local sqlfile="$4"
375        local tmpfile=$(mktemp)
376        local mycnf=/tmp/.my.cnf.$$
377        local status
378
379        if [ ! -r $sqlfile ]; then
380                errorAndLog "${FUNCNAME}(): Unable to read $sqlfile!!"
381                return 1
382        fi
383
384        echoAndLog "${FUNCNAME}(): importing SQL file to ${database}..."
385        chmod 600 $tmpfile
386        sed -e "s/SERVERIP/$SERVERIP/g" -e "s/DBUSER/$OPENGNSYS_DB_USER/g" \
387            -e "s/DBPASSWORD/$OPENGNSYS_DB_PASSWD/g" $sqlfile > $tmpfile
388        # Componer fichero con credenciales de conexión. 
389        touch $mycnf
390        chmod 600 $mycnf
391        cat << EOT > $mycnf
392[client]
393user=$dbuser
394password=$dbpassword
395EOT
396        # Antes de actualizar, reasignar valores para campos no nulos con nulo por defecto.
397        mysql --defaults-extra-file=$MYCNF -D "$database" -e \
398                "$(mysql --defaults-extra-file=$MYCNF -Nse "
399SELECT CASE WHEN DATA_TYPE LIKE '%int' THEN
400                 CONCAT_WS(' ', 'ALTER TABLE', TABLE_NAME, 'ALTER', COLUMN_NAME, 'SET DEFAULT 0;')
401            WHEN DATA_TYPE LIKE '%char' THEN
402                 CONCAT_WS(' ', 'ALTER TABLE', TABLE_NAME, 'ALTER', COLUMN_NAME, 'SET DEFAULT \'\';')
403            WHEN DATA_TYPE = 'text' THEN
404                 CONCAT_WS(' ', 'ALTER TABLE', TABLE_NAME, 'MODIFY', COLUMN_NAME, 'TEXT NOT NULL;')
405            ELSE ''
406       END
407  FROM information_schema.COLUMNS
408 WHERE TABLE_SCHEMA='$database'
409   AND IS_NULLABLE='NO'
410   AND COLUMN_DEFAULT IS NULL
411   AND COLUMN_KEY='';")"
412        # Ejecutar actualización y borrar fichero de credenciales.
413        mysql --defaults-extra-file=$mycnf --default-character-set=utf8 -D "$database" < $tmpfile
414        status=$?
415        rm -f $mycnf $tmpfile
416        if [ $status -ne 0 ]; then
417                errorAndLog "${FUNCNAME}(): error importing $sqlfile in database $database"
418                return 1
419        fi
420        echoAndLog "${FUNCNAME}(): file imported to database $database"
421        return 0
422}
423
424# Comprobar configuración de MySQL y recomendar cambios necesarios.
425function checkMysqlConfig()
426{
427        echoAndLog "${FUNCNAME}(): checking MySQL configuration"
428
429        cp -a $WORKDIR/opengnsys/server/etc/mysqld-og.cnf $MYSQLCFGDIR 2>/dev/null
430        service=$MYSQLSERV; $STARTSERVICE
431
432        echoAndLog "${FUNCNAME}(): MySQL configuration has checked"
433        return 0
434}
435
436#####################################################################
437####### Funciones de instalación de paquetes
438#####################################################################
439
440# Instalar las deependencias necesarias para el actualizador.
441function installDependencies()
442{
443        local package
444
445        # Comprobar si hay que actualizar PHP 5 a PHP 7.
446        eval $UPDATEPKGLIST
447        if [ -f /etc/debian_version ]; then
448                # Basado en paquetes Deb.
449                PHP7VERSION="php7.2"
450                PHPFPMSERV="${PHP7VERSION}-fpm"
451                PHP5PKGS=( $(dpkg -l | awk '$2~/^php5/ {print $2}') )
452                if [ -n "$PHP5PKGS" ]; then
453                        $DELETEPKGS ${PHP5PKGS[@]}
454                        PHP5PKGS[0]="$PHP7VERSION"
455                        INSTALLDEPS=${PHP5PKGS[@]//php5*-/${PHP7VERSION}-}
456                fi
457        fi
458        if [ "$OSDISTRIB" == "centos" ]; then
459                PHP7VERSION=$(yum list -q php7\* 2>/dev/null | awk -F. '/^php/ {print $1; exit;}')
460                PHPFPMSERV="${PHP7VERSION}-${PHPFPMSERV}"
461                PHP5PKGS=( $(yum list installed | awk '$1~/^php/ && $2~/^5\./ {sub(/\..*$/, "", $1); print $1}') )
462                if [ -n "$PHP5PKGS" ]; then
463                        $DELETEPKGS ${PHP5PKGS[@]}
464                        PHP5PKGS[0]="$PHP7VERSION-php"
465                        INSTALLDEPS=${PHP5PKGS[@]//php-/${PHP7VERSION}-php}
466                fi
467        fi
468
469        if [ $# = 0 ]; then
470                echoAndLog "${FUNCNAME}(): no dependencies are needed"
471        else
472                while [ $# -gt 0 ]; do
473                        package="${1/php/$PHP7VERSION}"
474                        eval $CHECKPKG || INSTALLDEPS="$INSTALLDEPS $package"
475                        shift
476                done
477                if [ -n "$INSTALLDEPS" ]; then
478                        $INSTALLPKGS $INSTALLDEPS
479                        if [ $? -ne 0 ]; then
480                                errorAndLog "${FUNCNAME}(): cannot install some dependencies: $INSTALLDEPS"
481                                return 1
482                        fi
483                fi
484        fi
485}
486
487
488#####################################################################
489####### Funciones para descargar código
490#####################################################################
491
492function downloadCode()
493{
494        if [ $# -ne 1 ]; then
495                errorAndLog "${FUNCNAME}(): invalid number of parameters"
496                exit 1
497        fi
498
499        local url="$1"
500        echoAndLog "${FUNCNAME}(): downloading code..."
501
502        curl "$url" -o opengnsys.zip && \
503                unzip -qo opengnsys.zip && \
504                rm -fr opengnsys && \
505                mv "OpenGnsys-${BRANCH#v}" opengnsys
506        if [ $? -ne 0 ]; then
507                errorAndLog "${FUNCNAME}(): error getting code from ${url}, verify your user and password"
508                return 1
509        fi
510        rm -f opengnsys.zip
511        echoAndLog "${FUNCNAME}(): code was downloaded"
512        return 0
513}
514
515
516############################################################
517###  Detectar red
518############################################################
519
520# Comprobar si existe conexión.
521function checkNetworkConnection()
522{
523        OPENGNSYS_SERVER=${OPENGNSYS_SERVER:-"opengnsys.es"}
524        if which curl &>/dev/null; then
525                curl --connect-timeout 10 -s "https://$OPENGNSYS_SERVER" -o /dev/null && \
526                        curl --connect-timeout 10 -s "http://$OPENGNSYS_SERVER" -o /dev/null
527        elif which wget &>/dev/null; then
528                wget --spider -q "https://$OPENGNSYS_SERVER" && \
529                        wget --spider -q "http://$OPENGNSYS_SERVER"
530        else
531                echoAndLog "${FUNCNAME}(): Cannot execute \"wget\" nor \"curl\"."
532                return 1
533        fi
534}
535
536# Comprobar si la versión es anterior a la actual.
537function checkVersion()
538{
539        local PRE
540
541        # Obtener versión actual y versión a actualizar.
542        [ -f $INSTALL_TARGET/doc/VERSION.txt ] && OLDVERSION=$(awk '{print $2}' $INSTALL_TARGET/doc/VERSION.txt 2>/dev/null)
543        [ -f $INSTALL_TARGET/doc/VERSION.json ] && OLDVERSION=$(jq -r '.version' $INSTALL_TARGET/doc/VERSION.json 2>/dev/null)
544        if [ $REMOTE -eq 1 ]; then
545                NEWVERSION=$(curl -s $RAW_URL/doc/VERSION.json 2>/dev/null | jq -r '.version')
546        else
547                NEWVERSION=$(jq -r '.version' $PROGRAMDIR/../doc/VERSION.json 2>/dev/null)
548        fi
549        [[ "$NEWVERSION" =~ pre ]] && PRE=1
550
551        # Comparar versiones.
552        [[ "$NEWVERSION" < "${OLDVERSION/pre/}" ]] && return 1
553        [ "${NEWVERSION/pre/}" == "$OLDVERSION" -a "$PRE" == "1" ] && return 1
554
555        return 0
556}
557
558# Obtener los parámetros de red del servidor.
559function getNetworkSettings()
560{
561        # Variables globales definidas:
562        # - SERVERIP:   IP local de la interfaz por defecto.
563
564        local DEVICES
565        local dev
566
567        SERVERIP="$ServidorAdm"
568        DEVICES="$(ip -o link show up | awk '!/loopback/ {sub(/[:@].*/,"",$2); print $2}')"
569        for dev in $DEVICES; do
570                [ -z "$SERVERIP" ] && SERVERIP=$(ip -o addr show dev $dev | awk '$3~/inet$/ {sub (/\/.*/, ""); print ($4); exit;}')
571        done
572}
573
574
575#####################################################################
576####### Funciones específicas de la instalación de Opengnsys
577#####################################################################
578
579# Actualizar cliente OpenGnsys.
580function updateClientFiles()
581{
582        local ENGINECFG=$INSTALL_TARGET/client/etc/engine.cfg
583
584        # Actualizar ficheros del cliente.
585        backupFile $ENGINECFG
586        echoAndLog "${FUNCNAME}(): Updating OpenGnsys Client files"
587        rsync -irplt $WORKDIR/opengnsys/client/shared/* $INSTALL_TARGET/client
588        if [ $? -ne 0 ]; then
589                errorAndLog "${FUNCNAME}(): error while updating client structure"
590                exit 1
591        fi
592
593        # Actualizar librerías del motor de clonación.
594        echoAndLog "${FUNCNAME}(): Updating OpenGnsys Cloning Engine files"
595        rsync -irplt $WORKDIR/opengnsys/client/engine/*.lib* $INSTALL_TARGET/client/lib/engine/bin
596        if [ $? -ne 0 ]; then
597                errorAndLog "${FUNCNAME}(): error while updating engine files"
598                exit 1
599        fi
600        # Actualizar fichero de configuración del motor de clonación.
601        if ! grep -q "^TZ" $ENGINECFG; then
602                TZ=$(timedatectl status | awk -F"[:()]" '/Time.*zone/ {print $2}')
603                cat << EOT >> $ENGINECFG
604# OpenGnsys Server timezone.
605TZ="${TZ// /}"
606EOT
607        fi
608        if ! diff -q ${ENGINECFG}{,-LAST} &>/dev/null; then
609                NEWFILES="$NEWFILES $ENGINECFG"
610        else
611                rm -f ${ENGINECFG}-LAST
612        fi
613        # Obtener URL para descargas adicionales.
614        DOWNLOADURL=$(oglivecli config download-url 2>/dev/null)
615        DOWNLOADURL=${DOWNLOADURL:-"https://$OPENGNSYS_SERVER/trac/downloads"}
616
617        echoAndLog "${FUNCNAME}(): client files successfully updated"
618}
619
620# Crear certificado para la firma de cargadores de arranque, si es necesario.
621function createCerts ()
622{
623        local SSLCFGDIR=$INSTALL_TARGET/client/etc/ssl
624        mkdir -p $SSLCFGDIR/{certs,private}
625        if [ ! -f $SSLCFGDIR/private/opengnsys.key ]; then
626                echoAndLog "${FUNCNAME}(): creating certificate files"
627                openssl req -new -x509 -newkey rsa:2048 -keyout $SSLCFGDIR/private/opengnsys.key -out $SSLCFGDIR/certs/opengnsys.crt -nodes -days 3650 -subj "/CN=OpenGnsys/"
628                openssl x509 -in $SSLCFGDIR/certs/opengnsys.crt -out $SSLCFGDIR/certs/opengnsys.cer -outform DER
629                echoAndLog "${FUNCNAME}(): certificate successfully created"
630        fi
631}
632
633# Configurar HTTPS y exportar usuario y grupo del servicio Apache.
634function apacheConfiguration ()
635{
636        local config template module socketfile
637
638        # Avtivar PHP-FPM.
639        echoAndLog "${FUNCNAME}(): configuring PHP-FPM"
640        service=$PHPFPMSERV
641        $ENABLESERVICE; $STARTSERVICE
642
643        # Activar módulos de Apache.
644        if [ -e $APACHECFGDIR/sites-available/opengnsys.conf ]; then
645                echoAndLog "${FUNCNAME}(): Configuring Apache modules"
646                a2ensite default-ssl
647                for module in $APACHEENABLEMODS; do a2enmod -q "$module"; done
648                for module in $APACHEDISABLEMODS; do a2dismod -q "${module//PHP7VERSION}"; done
649                a2ensite opengnsys
650        elif [ -e $APACHECFGDIR/conf.modules.d ]; then
651                echoAndLog "${FUNCNAME}(): Configuring Apache modules"
652                sed -i '/rewrite/s/^#//' $APACHECFGDIR/*.conf
653        fi
654        # Elegir plantilla según versión de Apache.
655        if [ -n "$(apachectl -v | grep "2\.[0-2]")" ]; then
656               template=$WORKDIR/opengnsys/server/etc/apache-prev2.4.conf.tmpl > $config
657        else
658               template=$WORKDIR/opengnsys/server/etc/apache.conf.tmpl
659        fi
660        sockfile=$(find /run/php -name "php*.sock" -type s -print 2>/dev/null | tail -1)
661        # Actualizar configuración de Apache a partir de fichero de plantilla.
662        for config in $APACHECFGDIR/{,sites-available/}opengnsys.conf; do
663                if [ -e $config ]; then
664                        if [ -n "$sockfile" ]; then
665                                sed -e "s,CONSOLEDIR,$INSTALL_TARGET/www,g; s,proxy:fcgi:.*,proxy:unix:${sockfile%% *}|fcgi://localhost\",g" $template > $config
666                        else
667                                sed -e "s,CONSOLEDIR,$INSTALL_TARGET/www,g" $template > $config
668                        fi
669                fi
670        done
671
672        # Reiniciar Apache.
673        service=$APACHESERV; $STARTSERVICE
674
675        # Variables de ejecución de Apache.
676        # - APACHE_RUN_USER
677        # - APACHE_RUN_GROUP
678        if [ -f $APACHECFGDIR/envvars ]; then
679                source $APACHECFGDIR/envvars
680        fi
681        APACHE_RUN_USER=${APACHE_RUN_USER:-"$APACHEUSER"}
682        APACHE_RUN_GROUP=${APACHE_RUN_GROUP:-"$APACHEGROUP"}
683}
684
685# Configurar servicio Rsync.
686function rsyncConfigure()
687{
688        local service
689
690        # Configurar acceso a Rsync.
691        if [ ! -f /etc/rsyncd.conf ]; then
692                echoAndLog "${FUNCNAME}(): Configuring Rsync service"
693                NEWFILES="$NEWFILES /etc/rsyncd.conf"
694                sed -e "s/CLIENTUSER/$OPENGNSYS_CLIENTUSER/g" \
695                    $WORKDIR/opengnsys/repoman/etc/rsyncd.conf.tmpl > /etc/rsyncd.conf
696                # Habilitar Rsync.
697                if [ -f /etc/default/rsync ]; then
698                        perl -pi -e 's/RSYNC_ENABLE=.*/RSYNC_ENABLE=inetd/' /etc/default/rsync
699                fi
700                if [ -f $INETDCFGDIR/rsync ]; then
701                        perl -pi -e 's/disable.*/disable = no/' $INETDCFGDIR/rsync
702                else
703                        cat << EOT > $INETDCFGDIR/rsync
704service rsync
705{
706        disable = no
707        socket_type = stream
708        wait = no
709        user = root
710        server = $(which rsync)
711        server_args = --daemon
712        log_on_failure += USERID
713        flags = IPv6
714}
715EOT
716                fi
717                # Activar e iniciar Rsync.
718                service="rsync"  $ENABLESERVICE
719                service="xinetd"
720                $ENABLESERVICE; $STARTSERVICE
721        fi
722}
723
724# Copiar ficheros del OpenGnsys Web Console.
725function updateWebFiles()
726{
727        local ERRCODE COMPATDIR f
728
729        echoAndLog "${FUNCNAME}(): Updating web files..."
730
731        # Copiar los ficheros nuevos conservando el archivo de configuración de acceso.
732        backupFile $INSTALL_TARGET/www/controlacceso.php
733        mv $INSTALL_TARGET/www $INSTALL_TARGET/WebConsole
734        rsync -irplt $WORKDIR/opengnsys/admin/WebConsole $INSTALL_TARGET
735        ERRCODE=$?
736        mv $INSTALL_TARGET/WebConsole $INSTALL_TARGET/www
737        rm -fr $INSTALL_TARGET/www/xajax
738        unzip -o $WORKDIR/opengnsys/admin/slim-2.6.1.zip -d $INSTALL_TARGET/www/rest
739        unzip -o $WORKDIR/opengnsys/admin/swagger-ui-2.2.5.zip -d $INSTALL_TARGET/www/rest
740        if [ $ERRCODE != 0 ]; then
741                errorAndLog "${FUNCNAME}(): Error updating web files."
742                exit 1
743        fi
744        restoreFile $INSTALL_TARGET/www/controlacceso.php
745
746        # Cambiar acceso a protocolo HTTPS.
747        if grep -q "http://" $INSTALL_TARGET/www/controlacceso.php 2>/dev/null; then
748                echoAndLog "${FUNCNAME}(): updating web access file"
749                perl -pi -e 's!http://!https://!g' $INSTALL_TARGET/www/controlacceso.php
750                NEWFILES="$NEWFILES $INSTALL_TARGET/www/controlacceso.php"
751        fi
752
753        # Compatibilidad con dispositivos móviles.
754        COMPATDIR="$INSTALL_TARGET/www/principal"
755        for f in acciones administracion aula aulas hardwares imagenes menus repositorios softwares; do
756                sed 's/clickcontextualnodo/clicksupnodo/g' $COMPATDIR/$f.php > $COMPATDIR/$f.device.php
757        done
758        cp -a $COMPATDIR/imagenes.device.php $COMPATDIR/imagenes.device4.php
759        # Acceso al manual de usuario
760        ln -fs ../doc/userManual $INSTALL_TARGET/www/userManual
761        # Fichero de log de la API REST.
762        touch $INSTALL_TARGET/log/{ogagent,rest,remotepc}.log
763
764        echoAndLog "${FUNCNAME}(): Web files successfully updated"
765}
766
767# Copiar ficheros en la zona de descargas de OpenGnsys Web Console.
768function updateDownloadableFiles()
769{
770        local VERSIONFILE OGVERSION FILENAME TARGETFILE
771
772        # Obtener versión a descargar.
773        VERSIONFILE="$INSTALL_TARGET/doc/VERSION.json"
774        OGVERSION="$(jq -r ".ogagent // \"$NEWVERSION\"" $VERSIONFILE 2>/dev/null || echo "$NEWVERSION")"
775        FILENAME="ogagentpkgs-$OGVERSION.tar.gz"
776        TARGETFILE=$WORKDIR/$FILENAME
777
778        # Descargar archivo comprimido, si es necesario.
779        if [ -s $PROGRAMDIR/$FILENAME ]; then
780                echoAndLog "${FUNCNAME}(): Moving $PROGRAMDIR/$FILENAME file to $(dirname $TARGETFILE)"
781                mv $PROGRAMDIR/$FILENAME $TARGETFILE
782        else
783                echoAndLog "${FUNCNAME}(): Downloading $FILENAME"
784                curl $DOWNLOADURL/$FILENAME -o $TARGETFILE
785        fi
786        if [ ! -s $TARGETFILE ]; then
787                errorAndLog "${FUNCNAME}(): Cannot download $FILENAME"
788                return 1
789        fi
790
791        # Descomprimir fichero en zona de descargas.
792        tar xvzf $TARGETFILE -C $INSTALL_TARGET/www/descargas
793        if [ $? != 0 ]; then
794                errorAndLog "${FUNCNAME}(): Error uncompressing archive $FILENAME"
795                return 1
796        fi
797}
798
799# Copiar carpeta de Interface
800function updateInterfaceAdm()
801{
802        local errcode=0
803
804        # Crear carpeta y copiar Interface
805        echoAndLog "${FUNCNAME}(): Copying Administration Interface Folder"
806        mv $INSTALL_TARGET/client/interfaceAdm $INSTALL_TARGET/client/Interface
807        rsync -irplt $WORKDIR/opengnsys/admin/Interface $INSTALL_TARGET/client
808        errcoce=$?
809        mv $INSTALL_TARGET/client/Interface $INSTALL_TARGET/client/interfaceAdm
810        if [ $errcode -ne 0 ]; then
811                echoAndLog "${FUNCNAME}(): error while updating admin interface"
812                exit 1
813        fi
814        echoAndLog "${FUNCNAME}(): Admin interface successfully updated"
815}
816
817# Crear documentación Doxygen para la consola web.
818function makeDoxygenFiles()
819{
820        echoAndLog "${FUNCNAME}(): Making Doxygen web files..."
821        $WORKDIR/opengnsys/installer/ogGenerateDoc.sh \
822                        $WORKDIR/opengnsys/client/engine $INSTALL_TARGET/www
823        if [ ! -d "$INSTALL_TARGET/www/html" ]; then
824                errorAndLog "${FUNCNAME}(): unable to create Doxygen web files"
825                return 1
826        fi
827        rm -fr "$INSTALL_TARGET/www/api"
828        mv "$INSTALL_TARGET/www/html" "$INSTALL_TARGET/www/api"
829        rm -fr $INSTALL_TARGET/www/{man,perlmod,rtf}
830        echoAndLog "${FUNCNAME}(): Doxygen web files created successfully"
831}
832
833
834# Crea la estructura base de la instalación de opengnsys
835function createDirs()
836{
837        # Crear estructura de directorios.
838        echoAndLog "${FUNCNAME}(): creating directory paths in ${INSTALL_TARGET}"
839        local dir MKNETDIR
840
841        mkdir -p ${INSTALL_TARGET}/{bin,doc,etc,lib,sbin,www}
842        mkdir -p ${INSTALL_TARGET}/{client,images/groups}
843        mkdir -p ${INSTALL_TARGET}/log/clients
844        ln -fs ${INSTALL_TARGET}/log /var/log/opengnsys
845        # Detectar directorio de instalación de TFTP.
846        if [ ! -L ${INSTALL_TARGET}/tftpboot ]; then
847                for dir in /var/lib/tftpboot /srv/tftp; do
848                        [ -d $dir ] && ln -fs $dir ${INSTALL_TARGET}/tftpboot
849                done
850        fi
851        mkdir -p $INSTALL_TARGET/tftpboot/{menu.lst,grub}/examples
852        if [ $? -ne 0 ]; then
853                errorAndLog "${FUNCNAME}(): error while creating dirs. Do you have write permissions?"
854                return 1
855        fi
856        ! [ -f $INSTALL_TARGET/tftpboot/menu.lst/templates/00unknown ] && mv $INSTALL_TARGET/tftpboot/menu.lst/templates/* $INSTALL_TARGET/tftpboot/menu.lst/examples
857        ! [ -f $INSTALL_TARGET/tftpboot/grub/templates/10 ] && mv $INSTALL_TARGET/tftpboot/grub/templates/* $INSTALL_TARGET/tftpboot/grub/examples
858
859        # Preparar arranque en red con Grub.
860        for f in grub-mknetdir grub2-mknetdir; do
861                if which $f &>/dev/null; then MKNETDIR=$f; fi
862        done
863        $MKNETDIR --net-directory=${INSTALL_TARGET}/tftpboot --subdir=grub
864
865        # Crear usuario ficticio.
866        if id -u $OPENGNSYS_CLIENTUSER &>/dev/null; then
867                echoAndLog "${FUNCNAME}(): user \"$OPENGNSYS_CLIENTUSER\" is already created"
868        else
869                echoAndLog "${FUNCNAME}(): creating OpenGnsys user"
870                useradd $OPENGNSYS_CLIENTUSER 2>/dev/null
871                if [ $? -ne 0 ]; then
872                        errorAndLog "${FUNCNAME}(): error creating OpenGnsys user"
873                        return 1
874                fi
875        fi
876
877        # Mover el fichero de registro al directorio de logs.
878        echoAndLog "${FUNCNAME}(): moving update log file"
879        mv $LOG_FILE $OGLOGFILE && LOG_FILE=$OGLOGFILE
880        chmod 600 $LOG_FILE
881
882        echoAndLog "${FUNCNAME}(): directory paths created"
883        return 0
884}
885
886# Actualización incremental de la BD (versión actaul a actaul+1, hasta final-1 a final).
887function updateDatabase()
888{
889        local DBDIR="$WORKDIR/opengnsys/admin/Database"
890        local file FILES=""
891
892        echoAndLog "${FUNCNAME}(): looking for database updates"
893        pushd $DBDIR >/dev/null
894        # Bucle de actualización incremental desde versión actual a la final.
895        for file in $OPENGNSYS_DATABASE-*-*.sql; do
896                case "$file" in
897                        $OPENGNSYS_DATABASE-$OLDVERSION-$NEWVERSION.sql)
898                                # Actualización única de versión inicial y final.
899                                FILES="$FILES $file"
900                                break
901                                ;;
902                        $OPENGNSYS_DATABASE-*-postinst.sql)
903                                # Ignorar fichero específico de post-instalación.
904                                ;;
905                        $OPENGNSYS_DATABASE-$OLDVERSION-*.sql)
906                                # Actualización de versión n a n+1.
907                                FILES="$FILES $file"
908                                OLDVERSION="$(echo ${file%.*} | cut -f3 -d-)"
909                                ;;
910                        $OPENGNSYS_DATABASE-*-$NEWVERSION.sql)
911                                # Última actualización de versión final-1 a final.
912                                if [ -n "$FILES" ]; then
913                                        FILES="$FILES $file"
914                                        break
915                                fi
916                                ;;
917                esac
918        done
919        # Aplicar posible actualización propia para la versión final.
920        file=$OPENGNSYS_DATABASE-$NEWVERSION.sql
921        if [ -n "$FILES" -o "$OLDVERSION" = "$NEWVERSION" -a -r $file ]; then
922                FILES="$FILES $file"
923        fi
924
925        popd >/dev/null
926        if [ -n "$FILES" ]; then
927                for file in $FILES; do
928                        importSqlFile $OPENGNSYS_DBUSER $OPENGNSYS_DBPASSWORD $OPENGNSYS_DATABASE $DBDIR/$file
929                done
930                echoAndLog "${FUNCNAME}(): database is update"
931        else
932                echoAndLog "${FUNCNAME}(): database unchanged"
933        fi
934}
935
936# Copia ficheros de configuración y ejecutables genéricos del servidor.
937function updateServerFiles()
938{
939        # No copiar ficheros del antiguo cliente Initrd
940        local SOURCES=( repoman/bin \
941                        server/bin \
942                        server/lib \
943                        admin/Sources/Services/ogAdmRepoAux \
944                        server/tftpboot \
945                        /usr/lib/shim/shimx64.efi.signed \
946                        /usr/lib/grub/x86_64-efi-signed/grubnetx64.efi.signed \
947                        installer/opengnsys_uninstall.sh \
948                        installer/opengnsys_export.sh \
949                        installer/opengnsys_import.sh \
950                        doc )
951        local TARGETS=( bin \
952                        bin \
953                        lib \
954                        sbin/ogAdmRepoAux \
955                        tftpboot \
956                        tftpboot/shimx64.efi.signed \
957                        tftpboot/grubx64.efi \
958                        lib/opengnsys_uninstall.sh \
959                        lib/opengnsys_export.sh \
960                        lib/opengnsys_import.sh \
961                        doc )
962
963        if [ ${#SOURCES[@]} != ${#TARGETS[@]} ]; then
964                errorAndLog "${FUNCNAME}(): inconsistent number of array items"
965                exit 1
966        fi
967
968        echoAndLog "${FUNCNAME}(): updating files in server directories"
969        pushd $WORKDIR/opengnsys >/dev/null
970        local i
971        for (( i = 0; i < ${#SOURCES[@]}; i++ )); do
972                if [ -d "$INSTALL_TARGET/${TARGETS[i]}" ]; then
973                        rsync -irplt "${SOURCES[i]}" $(dirname $(readlink -e "$INSTALL_TARGET/${TARGETS[i]}"))
974                else
975                        rsync -irplt "${SOURCES[i]}" $(readlink -m "$INSTALL_TARGET/${TARGETS[i]}")
976                fi
977        done
978        popd >/dev/null
979        NEWFILES=""             # Ficheros de configuración que han cambiado de formato.
980        if grep -q 'pxelinux.0' /etc/dhcp*/dhcpd*.conf; then
981                echoAndLog "${FUNCNAME}(): updating DHCP files"
982                perl -pi -e 's/pxelinux.0/grldr/' /etc/dhcp*/dhcpd*.conf
983                service=$DHCPSERV; $STARTSERVICE
984                NEWFILES="/etc/dhcp*/dhcpd*.conf"
985        fi
986        if ! grep -q 'shimx64.efi.signed' /etc/dhcp*/dhcpd*.conf; then
987                echoAndLog "${FUNCNAME}(): updating DHCP files for UEFI computers"
988                UEFICFG="    # 0007 == x64 EFI boot\n"\
989"    if option arch = 00:07 {\n"\
990"        filename \"shimx64.efi.signed\";\n"\
991"    } else {\n"\
992"        filename \"grldr\";\n"\
993"    }"
994                sed -i -e 1i"option arch code 93 = unsigned integer 16;" -e s@"^.*grldr\"\;"@"$UEFICFG"@g /etc/dhcp*/dhcpd*.conf
995                service=$DHCPSERV; $STARTSERVICE
996                NEWFILES="/etc/dhcp*/dhcpd*.conf"
997        fi
998        if ! diff -q $WORKDIR/opengnsys/admin/Sources/Services/opengnsys.init /etc/init.d/opengnsys 2>/dev/null; then
999                echoAndLog "${FUNCNAME}(): updating new init file"
1000                backupFile /etc/init.d/opengnsys
1001                service="opengnsys"
1002                $STOPSERVICE
1003                cp -a $WORKDIR/opengnsys/admin/Sources/Services/opengnsys.init /etc/init.d/opengnsys
1004                systemctl daemon-reload
1005                $STARTSERVICE
1006                NEWFILES="$NEWFILES /etc/init.d/opengnsys"
1007        fi
1008        if ! diff -q \
1009             $WORKDIR/opengnsys/admin/Sources/Services/opengnsys.service \
1010             /lib/systemd/system/opengnsys.service 2>/dev/null; then
1011                echoAndLog "${FUNCNAME}(): updating new service file"
1012                backupFile /lib/systemd/system/opengnsys.service
1013                service="opengnsys"
1014                $STOPSERVICE
1015                cp -a \
1016                   $WORKDIR/opengnsys/admin/Sources/Services/opengnsys.service \
1017                   /lib/systemd/system/opengnsys.service
1018                systemctl daemon-reload
1019                $STARTSERVICE
1020                NEWFILES="$NEWFILES /lib/systemd/system/opengnsys.service"
1021        fi
1022        if ! diff -q $WORKDIR/opengnsys/admin/Sources/Services/opengnsys.default /etc/default/opengnsys >/dev/null; then
1023                echoAndLog "${FUNCNAME}(): updating new default file"
1024                backupFile /etc/default/opengnsys
1025                # Buscar si hay nuevos parámetros.
1026                local var valor
1027                while IFS="=" read -e var valor; do
1028                        [[ $var =~ ^# ]] || \
1029                                grep -q "^$var=" /etc/default/opengnsys || \
1030                                echo "$var=$valor" >> /etc/default/opengnsys
1031                done < $WORKDIR/opengnsys/admin/Sources/Services/opengnsys.default
1032                NEWFILES="$NEWFILES /etc/default/opengnsys"
1033        fi
1034
1035        echoAndLog "${FUNCNAME}(): updating cron files"
1036        [ ! -f /etc/cron.d/torrentcreator ] && echo "* * * * *   root   [ -x $INSTALL_TARGET/bin/torrent-creator ] && $INSTALL_TARGET/bin/torrent-creator" > /etc/cron.d/torrentcreator
1037        [ ! -f /etc/cron.d/torrenttracker ] && echo "5 * * * *   root   [ -x $INSTALL_TARGET/bin/torrent-tracker ] && $INSTALL_TARGET/bin/torrent-tracker" > /etc/cron.d/torrenttracker
1038        [ ! -f /etc/cron.d/imagedelete ] && echo "* * * * *   root   [ -x $INSTALL_TARGET/bin/deletepreimage ] && $INSTALL_TARGET/bin/deletepreimage" > /etc/cron.d/imagedelete
1039        [ ! -f /etc/cron.d/ogagentqueue ] && echo "* * * * *   root   [ -x $INSTALL_TARGET/bin/ogagentqueue.cron ] && $INSTALL_TARGET/bin/ogagentqueue.cron" > /etc/cron.d/ogagentqueue
1040
1041        echoAndLog "${FUNCNAME}(): deleting deprecated cron file"
1042        [ -e /etc/cron.d/opengnsys ] && rm -f /etc/cron.d/opengnsys \
1043                                              $INSTALL_TARGET/bin/opengnsys.cron
1044
1045        # Se modifican los nombres de las plantilla PXE por compatibilidad con los equipos UEFI.
1046        if [ -f $INSTALL_TARGET/tftpboot/menu.lst/templates/01 ]; then
1047            BIOSPXEDIR="$INSTALL_TARGET/tftpboot/menu.lst/templates"
1048            mv $BIOSPXEDIR/01 $BIOSPXEDIR/10
1049            sed -i "s/\bMBR\b/1hd/" $BIOSPXEDIR/10
1050        fi
1051        echoAndLog "${FUNCNAME}(): server files successfully updated"
1052}
1053
1054####################################################################
1055### Funciones de compilación de código fuente de servicios
1056####################################################################
1057
1058# Mueve el fichero del nuevo servicio si es distinto al del directorio destino.
1059function moveNewService()
1060{
1061        local service
1062
1063        # Recibe 2 parámetros: fichero origen y directorio destino.
1064        [ $# == 2 ] || return 1
1065        [ -f  $1 -a -d $2 ] || return 1
1066
1067        # Comparar los ficheros.
1068        if ! diff -q $1 $2/$(basename $1) &>/dev/null; then
1069                # Parar los servicios si fuese necesario.
1070                service="opengnsys"
1071                [ -z "$NEWSERVICES" ] && $STOPSERVICE
1072                # Nuevo servicio.
1073                NEWSERVICES="$NEWSERVICES $(basename $1)"
1074                # Mover el nuevo fichero de servicio
1075                mv $1 $2
1076                $STARTSERVICE
1077        fi
1078}
1079
1080
1081# Compiling and updating OpenGnsys Server service
1082function ogServerCompilation()
1083{
1084        local ogserverUrl="https://codeload.github.com/opengnsys/ogServer/zip/$BRANCH"
1085        local error=0 serv
1086
1087        echoAndLog "${FUNCNAME}(): downloading ogServer code..."
1088
1089        if ! (curl "${ogserverUrl}" -o ogserver.zip && \
1090              unzip -qo "ogserver.zip")
1091        then
1092                errorAndLog "${FUNCNAME}(): "\
1093                            "error getting ogServer code from ${ogserverUrl}"
1094                return 1
1095        fi
1096        rm -f ogserver.zip
1097        echoAndLog "${FUNCNAME}(): ogServer code was downloaded"
1098
1099        echoAndLog "${FUNCNAME}(): Recompiling OpenGnsys Admin Server"
1100        pushd "$WORKDIR/ogServer-${BRANCH#v}"
1101        autoreconf -fi && ./configure && make && moveNewService ogserver $INSTALL_TARGET/sbin
1102        if [ $? -ne 0 ]; then
1103                echoAndLog "${FUNCNAME}(): error while compiling OpenGnsys Server"
1104                error=1
1105        fi
1106        popd
1107        # Renaming OpenGnsys Server configuration file, if needed
1108        [ -e $INSTALL_TARGET/etc/ogAdmServer.cfg ] && \
1109            rm -f $INSTALL_TARGET/etc/ogAdmServer.cfg
1110        [ -e $INSTALL_TARGET/etc/ogserver.cfg ] && \
1111            rm -f $INSTALL_TARGET/etc/ogserver.cfg
1112        if [ ! -e $INSTALL_TARGET/etc/ogserver.json ]; then
1113                echo "{
1114                        \"rest\" : {
1115                                \"ip\" : \"$ServidorAdm\",
1116                                \"port\" : \"8888\",
1117                                \"api_token\": \"$APITOKEN\"
1118                        },
1119                        \"database\" : {
1120                                \"ip\": \"$datasource\",
1121                                \"port\": \"3306\",
1122                                \"name\" : \"$CATALOG\",
1123                                \"user\" : \"$USUARIO\",
1124                                \"pass\" : \"$PASSWORD\"
1125                        },
1126                        \"wol\" : {
1127                                \"interface\" : \"$INTERFACE\"
1128                        }
1129                }" | jq '.' > "$INSTALL_TARGET"/etc/ogserver.json
1130        fi
1131        # Remove old OpenGnsys services
1132        for serv in ogAdmAgent ogAdmRepo ogAdmServer; do
1133                pgrep $serv > /dev/null && pkill -9 $serv && \
1134                    echoAndLog "${FUNCNAME}(): removing deprecated $serv service"
1135                rm -f $INSTALL_TARGET/sbin/$serv
1136                if [ $serv != ogAdmRepo ]; then
1137                        rm -f $INSTALL_TARGET/etc/$serv.cfg
1138                fi
1139        done
1140        # Generating an ogServer API token, if it does not exist
1141        [ -z "$APITOKEN" ] && \
1142            $INSTALL_TARGET/bin/settoken -f
1143        # Updating service file, if needed
1144        if ! diff -q \
1145             "$WORKDIR"/ogServer-"${BRANCH#v}"/cfg/ogserver.service \
1146             /lib/systemd/system/ogserver.service 2>/dev/null; then
1147                service="opengnsys"
1148                $STOPSERVICE
1149                echoAndLog "${FUNCNAME}(): updating new service file"
1150                backupFile /lib/systemd/system/ogserver.service
1151                service="ogserver"
1152                $STOPSERVICE
1153                cp -a \
1154                   "$WORKDIR"/ogServer-"${BRANCH#v}"/cfg/ogserver.service \
1155                   /lib/systemd/system/ogserver.service
1156                systemctl daemon-reload
1157                $STARTSERVICE
1158                service="opengnsys"
1159                $STARTSERVICE
1160                NEWFILES="$NEWFILES /lib/systemd/system/ogserver.service"
1161        fi
1162
1163        return $error
1164}
1165
1166
1167####################################################################
1168### Funciones instalacion cliente OpenGnsys
1169####################################################################
1170
1171# Actualizar cliente OpenGnsys
1172function updateClient()
1173{
1174        local FILENAME=ogLive-bionic-5.4.0-40-generic-amd64-r20200629.85eceaf.iso       # 1.2 (64 bits)
1175        local SOURCEFILE=$DOWNLOADURL/$FILENAME
1176        local TARGETFILE=$(oglivecli config download-dir)/$FILENAME
1177        local SOURCELENGTH
1178        local TARGETLENGTH
1179        local OGINITRD
1180        local SAMBAPASS
1181
1182        # Comprobar si debe convertirse el antiguo cliente al nuevo formato ogLive.
1183        if oglivecli check | grep -q "oglivecli convert"; then
1184                echoAndLog "${FUNCNAME}(): Converting OpenGnsys Client to default ogLive"
1185                oglivecli convert
1186        fi
1187        # Comprobar si debe actualizarse el cliente.
1188        SOURCELENGTH=$(curl -sI $SOURCEFILE 2>&1 | awk '/Content-Length:/ {gsub("\r", ""); print $2}')
1189        TARGETLENGTH=$(stat -c "%s" $TARGETFILE 2>/dev/null)
1190        [ -z $TARGETLENGTH ] && TARGETLENGTH=0
1191        if [ "$SOURCELENGTH" != "$TARGETLENGTH" ]; then
1192                echoAndLog "${FUNCNAME}(): Downloading $FILENAME"
1193                oglivecli download $FILENAME
1194                if [ ! -s $TARGETFILE ]; then
1195                        errorAndLog "${FUNCNAME}(): Error downloading $FILENAME"
1196                        return 1
1197                fi
1198                # Actaulizar la imagen ISO del ogclient.
1199                echoAndLog "${FUNCNAME}(): Updatting ogLive client"
1200                oglivecli install $FILENAME
1201               
1202                INSTALLEDOGLIVE=${FILENAME%.*}
1203
1204                echoAndLog "${FUNCNAME}(): ogLive successfully updated"
1205        else
1206                # Si no existe, crear el fichero de claves de Rsync.
1207                if [ ! -f /etc/rsyncd.secrets ]; then
1208                        echoAndLog "${FUNCNAME}(): Restoring ogLive access key"
1209                        OGINITRD=$(oglivecli config install-dir)/$(jq -r ".oglive[.default].directory")/oginitrd.img
1210                        SAMBAPASS=$(gzip -dc $OGINITRD | \
1211                                    cpio -i --to-stdout scripts/ogfunctions 2>&1 | \
1212                                    grep "^[    ].*OPTIONS=" | \
1213                                    sed 's/\(.*\)pass=\(\w*\)\(.*\)/\2/')
1214                        echo -ne "$SAMBAPASS\n$SAMBAPASS\n" | setsmbpass
1215                else
1216                        echoAndLog "${FUNCNAME}(): ogLive is already updated"
1217                fi
1218                # Versión del ogLive instalado.
1219                echo "${FILENAME%.*}" > $INSTALL_TARGET/doc/veroglive.txt
1220        fi
1221}
1222
1223# Update ogClient
1224function updateOgClient()
1225{
1226        local ogclientUrl="https://codeload.github.com/opengnsys/ogClient/zip/$BRANCH"
1227        local CLIENTPASS
1228
1229        echoAndLog "${FUNCNAME}(): downloading ogClient code..."
1230
1231        if ! (curl "${ogclientUrl}" -o ogclient.zip && \
1232             unzip -qo ogclient.zip)
1233        then
1234                errorAndLog "${FUNCNAME}(): "\
1235                            "error getting ogClient code from ${ogclientUrl}"
1236                return 1
1237        fi
1238        if [ -e $INSTALL_TARGET/client/ogClient/cfg/ogclient.json ]; then
1239             rm -f ogClient-"${BRANCH#v}"/cfg/ogclient.json
1240        else
1241             CLIENTPASS=$(awk -F":" '{print $2}' /etc/rsyncd.secrets)
1242             sed -i -e 's/127.0.0.1/'$ServidorAdm'/' \
1243                -e 's/pass'.*$'/pass\": "'$CLIENTPASS'"/' \
1244                ogClient-"${BRANCH#v}"/cfg/ogclient.json
1245        fi
1246        rsync -irplt "ogClient-${BRANCH#v}/" $INSTALL_TARGET/client/ogClient
1247        rm -f ogclient.zip
1248        echoAndLog "${FUNCNAME}(): ogClient code was downloaded and updated"
1249
1250        return 0
1251}
1252
1253# Comprobar permisos y ficheros.
1254function checkFiles()
1255{
1256        local LOGROTATEDIR=/etc/logrotate.d
1257
1258        # Comprobar permisos adecuados.
1259        if [ -x $INSTALL_TARGET/bin/checkperms ]; then
1260                echoAndLog "${FUNCNAME}(): Checking permissions"
1261                OPENGNSYS_DIR="$INSTALL_TARGET" OPENGNSYS_USER="$OPENGNSYS_CLIENTUSER" APACHE_USER="$APACHE_RUN_USER" APACHE_GROUP="$APACHE_RUN_GROUP" $INSTALL_TARGET/bin/checkperms
1262        fi
1263        # Eliminamos el fichero de estado del tracker porque es incompatible entre los distintos paquetes
1264        if [ -f /tmp/dstate ]; then
1265                echoAndLog "${FUNCNAME}(): Deleting unused files"
1266                rm -f /tmp/dstate
1267        fi
1268        # Crear nuevos ficheros de logrotate y borrar el fichero antiguo.
1269        if [ -d $LOGROTATEDIR ]; then
1270                rm -f $LOGROTATEDIR/opengnsys
1271                if [ ! -f $LOGROTATEDIR/opengnsysServer ]; then
1272                        echoAndLog "${FUNCNAME}(): Creating logrotate configuration file for server"
1273                        sed -e "s/OPENGNSYSDIR/${INSTALL_TARGET//\//\\/}/g" \
1274                                $WORKDIR/opengnsys/server/etc/logrotate.tmpl > $LOGROTATEDIR/opengnsysServer
1275                fi
1276                if [ ! -f $LOGROTATEDIR/opengnsysRepo ]; then
1277                        echoAndLog "${FUNCNAME}(): Creating logrotate configuration file for repository"
1278                        sed -e "s/OPENGNSYSDIR/${INSTALL_TARGET//\//\\/}/g" \
1279                                $WORKDIR/opengnsys/server/etc/logrotate.tmpl > $LOGROTATEDIR/opengnsysRepo
1280                fi
1281        fi
1282}
1283
1284# Resumen de actualización.
1285function updateSummary()
1286{
1287        # Actualizar fichero de versión y revisión.
1288        local VERSIONFILE REVISION
1289        VERSIONFILE="$INSTALL_TARGET/doc/VERSION.json"
1290        # Obtener revisión.
1291        if [ $REMOTE -eq 1 ]; then
1292                # Revisión: rAñoMesDía.Gitcommit (8 caracteres de fecha y 7 primeros de commit).
1293                if [ "$BRANCH" = "master" ]; then
1294                        REVISION=$(curl -s "$API_URL" | jq '"r" + (.commit.commit.committer.date | split("-") | join("")[:8]) + "." + (.commit.sha[:7])')
1295                else
1296                        REVISION=$(curl -s "$API_URL" | jq '"r" + (.commit.committer.date | split("-") | join("")[:8]) + "." + (.sha[:7])')
1297                fi
1298        else
1299                # Parámetro "release" del fichero JSON.
1300                REVISION=$(jq -r '.release' $PROGRAMDIR/../doc/VERSION.json 2>/dev/null)
1301        fi
1302        [ -f $VERSIONFILE ] || echo '{ "project": "OpenGnsys" }' > $VERSIONFILE
1303        jq ".release=$REVISION" $VERSIONFILE | sponge $VERSIONFILE
1304        VERSION="$(jq -r '[.project, .version, .codename, .release] | join(" ")' $VERSIONFILE 2>/dev/null)"
1305        # Borrar antiguo fichero de versión.
1306        rm -f "${VERSIONFILE/json/txt}"
1307
1308        echo
1309        echoAndLog "OpenGnsys Update Summary"
1310        echo       "========================"
1311        echoAndLog "Project version:                  $VERSION"
1312        echoAndLog "Update log file:                  $LOG_FILE"
1313        [ "$NEWFILES" ] && echoAndLog "Check new config files:           $(echo $NEWFILES)"
1314        [ "$NEWSERVICES" ] && echoAndLog "New compiled services:            $(echo $NEWSERVICES)"
1315        echoAndLog "Warnings:"
1316        echoAndLog " - You must to clear web browser cache before loading OpenGnsys page"
1317        echoAndLog " - Run \"settoken\" script to update authentication tokens"
1318        [ "$INSTALLEDOGLIVE" ] && echoAndLog " - Installed new ogLive Client: $INSTALLEDOGLIVE"
1319        echoAndLog " - Review syslog configuration and logrotate by syslog,"
1320        echoAndLog "      in debug mode OpenGnsys log is very extensive."
1321
1322        echo
1323}
1324
1325
1326
1327#####################################################################
1328####### Proceso de actualización de OpenGnsys
1329#####################################################################
1330
1331
1332# Comprobar si hay conexión y detectar parámetros de red por defecto.
1333checkNetworkConnection
1334if [ $? -ne 0 ]; then
1335        errorAndLog "Error connecting to server. Causes:"
1336        errorAndLog " - Network is unreachable, check device parameters"
1337        errorAndLog " - You are inside a private network, configure the proxy service"
1338        errorAndLog " - Server is temporally down, try again later"
1339        exit 1
1340fi
1341getNetworkSettings
1342
1343# Elegir versión y comprobar si se intanta actualizar a una versión anterior.
1344chooseVersion
1345checkVersion
1346if [ $? -ne 0 ]; then
1347        errorAndLog "Cannot downgrade to an older version ($OLDVERSION to $NEWVERSION)"
1348        errorAndLog "You must to uninstall OpenGnsys and install desired release"
1349        exit 1
1350fi
1351
1352echoAndLog "OpenGnsys update begins at $(date)"
1353pushd $WORKDIR
1354
1355# Comprobar auto-actualización del programa.
1356if [ "$PROGRAMDIR" != "$INSTALL_TARGET/bin" ]; then
1357        checkAutoUpdate
1358        if [ $? -ne 0 ]; then
1359                echoAndLog "OpenGnsys updater has been overwritten"
1360                echoAndLog "Please, run this script again"
1361                exit
1362        fi
1363fi
1364
1365# Detectar datos de auto-configuración del instalador.
1366autoConfigure
1367
1368# Instalar dependencias.
1369installDependencies ${DEPENDENCIES[*]}
1370if [ $? -ne 0 ]; then
1371        errorAndLog "Error: you must to install all needed dependencies"
1372        exit 1
1373fi
1374
1375# Arbol de directorios de OpenGnsys.
1376createDirs ${INSTALL_TARGET}
1377if [ $? -ne 0 ]; then
1378        errorAndLog "Error while creating directory paths"
1379        exit 1
1380fi
1381
1382# Si es necesario, descarga el repositorio de código en directorio temporal
1383if [ $REMOTE -eq 1 ]; then
1384        downloadCode $CODE_URL
1385        if [ $? -ne 0 ]; then
1386                errorAndLog "Error while getting code from repository"
1387                exit 1
1388        fi
1389else
1390        ln -fs "$(dirname $PROGRAMDIR)" opengnsys
1391fi
1392
1393# Comprobar configuración de MySQL.
1394checkMysqlConfig $OPENGNSYS_DBUSER $OPENGNSYS_DBPASSWORD
1395
1396# Actualizar la BD.
1397updateDatabase
1398
1399# Actualizar ficheros complementarios del servidor
1400updateServerFiles
1401if [ $? -ne 0 ]; then
1402        errorAndLog "Error updating OpenGnsys Server files"
1403        exit 1
1404fi
1405
1406# Configurar Rsync.
1407rsyncConfigure
1408
1409# Actualizar ficheros del cliente.
1410updateClientFiles
1411createCerts
1412updateInterfaceAdm
1413
1414# Actualizar páqinas web.
1415apacheConfiguration
1416updateWebFiles
1417if [ $? -ne 0 ]; then
1418        errorAndLog "Error updating OpenGnsys Web Admin files"
1419        exit 1
1420fi
1421# Actaulizar ficheros descargables.
1422updateDownloadableFiles
1423# Generar páginas Doxygen para instalar en el web
1424makeDoxygenFiles
1425
1426# Recompilar y actualizar los servicios del sistema
1427if ogServerCompilation; then
1428        # Restart services, if necessary.
1429        if [ "$NEWSERVICES" ]; then
1430                echoAndLog "Restarting OpenGnsys services"
1431                service="opengnsys" $STARTSERVICE
1432                service="ogserver" $STARTSERVICE
1433        fi
1434else
1435        errorAndLog "Error compiling OpenGnsys services"
1436        exit 1
1437fi
1438
1439# Actaulizar ficheros auxiliares del cliente
1440updateClient
1441if [ $? -ne 0 ]; then
1442        errorAndLog "Error updating client files"
1443        exit 1
1444fi
1445
1446# Update ogClient
1447if ! updateOgClient; then
1448        errorAndLog "Error updating ogClient files"
1449        exit 1
1450fi
1451
1452# Comprobar permisos y ficheros.
1453checkFiles
1454
1455# Mostrar resumen de actualización.
1456updateSummary
1457
1458rm -rf $WORKDIR
1459echoAndLog "OpenGnsys update finished at $(date)"
1460
1461popd
1462
Note: See TracBrowser for help on using the repository browser.