#!/bin/bash

#####################################################################
####### Script instalador OpenGnsys
####### Autor: Luis Guillén <lguillen@unizar.es>
#####################################################################

#####################################################################
####### Funciones de configuración
#####################################################################

# Si la distribución no es la recomendada mostramos mensaje informativo.
function checkDistribution()
{
	local ADVISED VERSION

	ADVISED="18"
	[ -r /etc/os-release ] && eval $(grep VERSION /etc/os-release)

	[[ "$VERSION" == "$ADVISED."* ]] && return

	echoAndLog "The OpenGnsys version 1.2.0 installation was tested with full functionality on Ubuntu 18.04 with PHP 7.2."
	echo -n "Do you want to continue? [y/N]: "
	read -r GO_ON
	if [ "${GO_ON^^}" != "Y" ]; then
		echoAndLog "We left the installation." && exit
	fi
}

# Recoge los datos de configuración introducidos por el usuario.
function userData ()
{

	DEFAULT_OGLIVE="ogLive-bionic-5.4.0-40-generic-amd64-r20200629.85eceaf.iso "	# Cliente ogLive

	echo -e "\\nOpenGnsys Installation"

	if [[ $- =~ s ]]; then
		echo -e "\\nNot interactive mode: setting default configuration values.\\n"
		OGLIVE="$DEFAULT_OGLIVE"
		return
	fi

	#while : ; do
	#	echo -e "\\n\\nChoose ogLive client to install."
	#	echo -e "1) Kernel 5.4, 64-bit, EFI-compatible"
	#	echo -e "2) Kernel 3.2, 32-bit"
	#	echo -e "3) Both"
	#	echo -n -e "Please, type a valid number (1): "
	#	read -r OPT
	#	case "$OPT" in
	#		1|"")	OGLIVE="$DEFAULT_OGLIVE"
	#			break ;;
	#		2)	OGLIVE="ogLive-precise-3.2.0-23-generic-r5159.iso"
	#			break ;;
	#		3)	OGLIVE=" $DEFAULT_OGLIVE ogLive-precise-3.2.0-23-generic-r5159.iso";
	#			break ;;
	#		*)	echo -e "\\aERROR: unknown option, try again."
	#	esac
	#done
	OGLIVE="$DEFAULT_OGLIVE"

}

# Asigna valores globales de configuración para el script.
function globalSetup ()
{
	PROGRAMDIR=$(readlink -e "$(dirname "$0")")
	PROGRAMNAME=$(basename "$0")

	# Comprobar si se ha descargado el paquete comprimido (REMOTE=0) o sólo el instalador (REMOTE=1).
	OPENGNSYS_SERVER="opengnsys.es"
	DOWNLOADURL="https://$OPENGNSYS_SERVER/trac/downloads"
	if [ -d "$PROGRAMDIR/../installer" ]; then
		REMOTE=0
	else
		REMOTE=1
	fi
	BRANCH="master"
	CODE_URL="https://codeload.github.com/opengnsys/OpenGnsys/zip/$BRANCH"
	API_URL="https://api.github.com/repos/opengnsys/OpenGnsys"

	# Directorios de instalación y destino de OpenGnsys.
	WORKDIR=/tmp/ogboot_installer
	INSTALL_OGBOOT_TARGET=/opt/ogboot
	PATH=$PATH:$INSTALL_OGBOOT_TARGET/bin

	# Registro de incidencias.
	OGLOGFILE=$INSTALL_OGBOOT_TARGET/log/${PROGRAMNAME%.sh}.log
	LOG_FILE=/tmp/$(basename $OGLOGFILE)

	# Usuario del cliente para acceso remoto.
	OPENGNSYS_CLIENT_USER="opengnsys"
}

# Generar variables de configuración del instalador
# Variables globales:
# - OSDISTRIB, OSVERSION - tipo y versión de la distribución GNU/Linux
# - DEPENDENCIES - array de dependencias que deben estar instaladas
# - UPDATEPKGLIST, INSTALLPKGS, CHECKPKGS - comandos para gestión de paquetes
# - INSTALLEXTRADEPS - instalar dependencias no incluidas en la distribución
# - STARTSERVICE, ENABLESERVICE - iniciar y habilitar un servicio
# - STOPSERVICE, DISABLESERVICE - parar y deshabilitar un servicio
# - APACHESERV, APACHECFGDIR, APACHESITESDIR, APACHEUSER, APACHEGROUP - servicio y configuración de Apache
# - APACHEENABLEMODS, APACHEENABLESSL, APACHEMAKECERT - habilitar módulos y certificado SSL
# - APACHEENABLEOG, APACHEOGSITE, - habilitar sitio web de OpenGnsys
# - PHPFPMSERV - servicio PHP FastCGI Process Manager para Apache
# - INETDSERV - servicio Inetd
# - DHCPSERV, DHCPCFGDIR - servicio y configuración de DHCP
# - RSYNCSERV, RSYNCCFGDIR - servicio y configuración de Rsync
# - SAMBASERV, SAMBACFGDIR - servicio y configuración de Samba
# - TFTPSERV, TFTPCFGDIR - servicio y configuración de TFTP/PXE
function autoConfigure()
{
# Detectar sistema operativo del servidor (compatible con fichero os-release y con LSB).
if [ -f /etc/os-release ]; then
	source /etc/os-release
	OSDISTRIB="$ID"
	OSVERSION="$VERSION_ID"
else
	OSDISTRIB=$(lsb_release -is 2>/dev/null)
	OSVERSION=$(lsb_release -rs 2>/dev/null)
fi
# Convertir distribución a minúsculas y obtener solo el 1er número de versión.
OSDISTRIB="${OSDISTRIB,,}"
OSVERSION="${OSVERSION%%.*}"

# Configuración según la distribución GNU/Linux (usar minúsculas).
case "$OSDISTRIB" in
	ubuntu|debian|linuxmint)
		DEPENDENCIES=( subversion apache2 php php-ldap php-fpm isc-dhcp-server bittorrent tftp-hpa tftpd-hpa xinetd build-essential g++-multilib wget curl graphviz bittornado ctorrent samba rsync unzip netpipes debootstrap schroot squashfs-tools 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 gawk libdbi-dev libdbi1 automake liblz4-tool )
		UPDATEPKGLIST="apt-get update"
		INSTALLPKG="apt-get -y install --force-yes"
		CHECKPKG="dpkg -s \$package 2>/dev/null | grep Status | grep -qw install"
		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 systemctl enable \$service.service"
		DISABLESERVICE="eval systemctl disable \$service.service"
		APACHESERV=apache2
		APACHECFGDIR=/etc/apache2
		APACHESITESDIR=sites-available
		APACHEOGSITE=ogboot
		APACHEUSER="www-data"
		APACHEGROUP="www-data"
		APACHEENABLEMODS="a2enmod ssl rewrite proxy_fcgi fastcgi actions alias"
		APACHEENABLESSL="a2ensite default-ssl"
		APACHEENABLEOG="a2ensite $APACHEOGSITE"
		APACHEMAKECERT="make-ssl-cert generate-default-snakeoil --force-overwrite"
		DHCPSERV=isc-dhcp-server
		DHCPCFGDIR=/etc/dhcp
		INETDSERV=xinetd
		INETDCFGDIR=/etc/xinetd.d
		PHPFPMSERV=php-fpm
		RSYNCSERV=rsync
		RSYNCCFGDIR=/etc
		SAMBASERV=smbd
		SAMBACFGDIR=/etc/samba
		TFTPCFGDIR=/var/lib/tftpboot
		;;
	fedora|centos)
		DEPENDENCIES=( subversion httpd mod_ssl php-ldap php-fpm dhcp tftp-server tftp xinetd binutils gcc gcc-c++ glibc-devel glibc-devel.i686 glibc-static glibc-static.i686 libstdc++-devel.i686 make wget curl doxygen graphviz ctorrent samba samba-client rsync unzip debootstrap schroot squashfs-tools python-crypto arp-scan procps-ng 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 automake http://ftp.altlinux.org/pub/distributions/ALTLinux/5.1/branch/$(arch)/RPMS.classic/netpipes-4.2-alt1.$(arch).rpm )
		[ "$OSDISTRIB" == "centos" ] && UPDATEPKGLIST="yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-$OSVERSION.noarch.rpm http://rpms.remirepo.net/enterprise/remi-release-$OSVERSION.rpm"
		INSTALLEXTRADEPS=( 'pushd /tmp; wget -t3 http://ftp.acc.umu.se/mirror/bittornado/BitTornado-0.3.18.tar.gz && tar xvzf BitTornado-0.3.18.tar.gz && cd BitTornado-CVS && python setup.py install && ln -fs btlaunchmany.py /usr/bin/btlaunchmany && ln -fs bttrack.py /usr/bin/bttrack; popd' )
		INSTALLPKG="yum install -y libstdc++ libstdc++.i686"
		CHECKPKG="rpm -q --quiet \$package"
		SYSTEMD=$(which systemctl 2>/dev/null)
		if [ -n "$SYSTEMD" ]; then
			STARTSERVICE="eval systemctl start \$service.service"
			STOPSERVICE="eval systemctl stop \$service.service"
			ENABLESERVICE="eval systemctl enable \$service.service"
			DISABLESERVICE="eval systemctl disable \$service.service"
		else
			STARTSERVICE="eval service \$service start"
			STOPSERVICE="eval service \$service stop"
			ENABLESERVICE="eval chkconfig \$service on"
			DISABLESERVICE="eval chkconfig \$service off"
		fi
		APACHESERV=httpd
		APACHECFGDIR=/etc/httpd/conf.d
		APACHEOGSITE=ogboot.conf
		APACHEUSER="apache"
		APACHEGROUP="apache"
		APACHEREWRITEMOD="sed -i '/rewrite/s/^#//' $APACHECFGDIR/../*.conf"
		DHCPSERV=dhcpd
		DHCPCFGDIR=/etc/dhcp
		INETDSERV=xinetd
		INETDCFGDIR=/etc/xinetd.d
		PHPFPMSERV=php-fpm
		RSYNCSERV=rsync
		RSYNCCFGDIR=/etc
		SAMBASERV=smb
		SAMBACFGDIR=/etc/samba
		TFTPSERV=tftp
		TFTPCFGDIR=/var/lib/tftpboot
		;;
	"") 	echo "ERROR: Unknown Linux distribution, please install \"lsb_release\" command."
		exit 1 ;;
	*) 	echo "ERROR: Distribution not supported by OpenGnsys."
		exit 1 ;;
esac
}
# Modificar variables de configuración tras instalar paquetes del sistema.
function autoConfigurePost()
{
local f MKNETDIR

# Configuraciones específicas para Samba y TFTP en Debian 6.
[ -z "$SYSTEMD" -a ! -e /etc/init.d/$SAMBASERV ] && SAMBASERV=samba
[ ! -e $TFTPCFGDIR ] && TFTPCFGDIR=/srv/tftp

# Preparar arranque en red con Grub.
for f in grub-mknetdir grub2-mknetdir; do
	if which $f &>/dev/null; then MKNETDIR=$f; fi
done
$MKNETDIR --net-directory=$TFTPCFGDIR --subdir=grub
}


# Cargar lista de paquetes del sistema y actualizar algunas variables de configuración
# dependiendo de la versión instalada.
function updatePackageList()
{
local DHCPVERSION PHP7VERSION

# Si es necesario, actualizar la lista de paquetes disponibles.
[ -n "$UPDATEPKGLIST" ] && eval $UPDATEPKGLIST

# Configuración personallizada de algunos paquetes.
case "$OSDISTRIB" in
	ubuntu|linuxmint)	# Postconfiguación personalizada para Ubuntu.
		# Configuración para DHCP v3.
		DHCPVERSION=$(apt-cache show $(apt-cache pkgnames|egrep "dhcp.?-server$") | \
			      awk '/Version/ {print substr($2,1,1);}' | \
			      sort -n | tail -1)
		if [ $DHCPVERSION = 3 ]; then
			DEPENDENCIES=( ${DEPENDENCIES[@]/isc-dhcp-server/dhcp3-server} )
			DHCPSERV=dhcp3-server
			DHCPCFGDIR=/etc/dhcp3
		fi
		# Configuración para PHP 7 en Ubuntu.
		if [ -z "$(apt-cache pkgnames php7)" ]; then
			eval $INSTALLPKG software-properties-common
			add-apt-repository -y ppa:ondrej/php
			eval $UPDATEPKGLIST
			PHP7VERSION=$(apt-cache pkgnames php7 | sort | head -1)
			PHPFPMSERV="${PHP7VERSION}-fpm"
			DEPENDENCIES=( ${DEPENDENCIES[@]//php/$PHP7VERSION} )
		fi
		# Paquete correcto para realpath.
		[ -z "$(apt-cache pkgnames realpath)" ] && DEPENDENCIES=( ${DEPENDENCIES[@]//realpath/coreutils} )
		;;
	centos)	# Postconfiguación personalizada para CentOS.
		# Configuración para PHP 7.
		PHP7VERSION=$(yum list -q php7\* 2>/dev/null | awk -F. '/^php/ {print $1; exit;}')
		PHPFPMSERV="${PHP7VERSION}-${PHPFPMSERV}"
		DEPENDENCIES=( ${PHP7VERSION} ${DEPENDENCIES[@]//php/$PHP7VERSION-php} )
		# Cambios a aplicar a partir de CentOS 7.
		if [ $OSVERSION -ge 7 ]; then
			# Instalar ctorrent de EPEL para CentOS 6 (no disponible en CentOS 7).
			DEPENDENCIES=( ${DEPENDENCIES[*]/ctorrent/http://dl.fedoraproject.org/pub/epel/6/$(arch)/Packages/c/ctorrent-1.3.4-14.dnh3.3.2.el6.$(arch).rpm} )
		fi
		;;
	fedora)	# Postconfiguación personalizada para Fedora. 
		# Incluir paquetes específicos.
		DEPENDENCIES=( ${DEPENDENCIES[@]} btrfs-progs )
		;;
esac
}


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

# Comprueba si el elemento pasado en $2 está en el array $1
function isInArray()
{
	if [ $# -ne 2 ]; then
		errorAndLog "${FUNCNAME}(): invalid number of parameters"
		exit 1
	fi

	local deps
	local is_in_array=1
	local element="$2"

	echoAndLog "${FUNCNAME}(): checking if $2 is in $1"
	eval "deps=( \"\${$1[@]}\" )"

	# Copia local del array del parámetro 1.
	for (( i = 0 ; i < ${#deps[@]} ; i++ )); do
		if [ "${deps[$i]}" = "${element}" ]; then
			echoAndLog "isInArray(): $element found in array"
			is_in_array=0
		fi
	done

	if [ $is_in_array -ne 0 ]; then
		echoAndLog "${FUNCNAME}(): $element NOT found in array"
	fi

	return $is_in_array
}


#####################################################################
####### Funciones de manejo de paquetes Debian
#####################################################################

function checkPackage()
{
	package=$1
	if [ -z $package ]; then
		errorAndLog "${FUNCNAME}(): parameter required"
		exit 1
	fi
	echoAndLog "${FUNCNAME}(): checking if package $package exists"
	eval $CHECKPKG
	if [ $? -eq 0 ]; then
		echoAndLog "${FUNCNAME}(): package $package exists"
		return 0
	else
		echoAndLog "${FUNCNAME}(): package $package doesn't exists"
		return 1
	fi
}

# Recibe array con dependencias
# por referencia deja un array con las dependencias no resueltas
# devuelve 1 si hay alguna dependencia no resuelta
function checkDependencies()
{
	if [ $# -ne 2 ]; then
		errorAndLog "${FUNCNAME}(): invalid number of parameters"
		exit 1
	fi

	echoAndLog "${FUNCNAME}(): checking dependences"
	uncompletedeps=0

	# copia local del array del parametro 1
	local deps
	eval "deps=( \"\${$1[@]}\" )"

	declare -a local_notinstalled

	for (( i = 0 ; i < ${#deps[@]} ; i++ ))
	do
		checkPackage ${deps[$i]}
		if [ $? -ne 0 ]; then
			local_notinstalled[$uncompletedeps]=$package
			let uncompletedeps=uncompletedeps+1
		fi
	done

	# relleno el array especificado en $2 por referencia
	for (( i = 0 ; i < ${#local_notinstalled[@]} ; i++ ))
	do
		eval "${2}[$i]=${local_notinstalled[$i]}"
	done

	# retorna el numero de paquetes no resueltos
	echoAndLog "${FUNCNAME}(): dependencies uncompleted: $uncompletedeps"
	return $uncompletedeps
}

# Recibe un array con las dependencias y lo instala
function installDependencies()
{
	if [ $# -ne 1 ]; then
		errorAndLog "${FUNCNAME}(): invalid number of parameters"
		exit 1
	fi
	echoAndLog "${FUNCNAME}(): installing uncompleted dependencies"

	# copia local del array del parametro 1
	local deps
	eval "deps=( \"\${$1[@]}\" )"

	local string_deps=""
	for (( i = 0 ; i < ${#deps[@]} ; i++ ))
	do
		string_deps="$string_deps ${deps[$i]}"
	done

	if [ -z "${string_deps}" ]; then
		errorAndLog "${FUNCNAME}(): array of dependeces is empty"
		exit 1
	fi

	OLD_DEBIAN_FRONTEND=$DEBIAN_FRONTEND		# Debian/Ubuntu
	export DEBIAN_FRONTEND=noninteractive

	echoAndLog "${FUNCNAME}(): now $string_deps will be installed"
	eval $INSTALLPKG $string_deps
	if [ $? -ne 0 ]; then
		errorAndLog "${FUNCNAME}(): error installing dependencies"
		return 1
	fi

	DEBIAN_FRONTEND=$OLD_DEBIAN_FRONTEND		# Debian/Ubuntu
	test grep -q "EPEL temporal" /etc/yum.repos.d/epel.repo 2>/dev/null || mv -f /etc/yum.repos.d/epel.repo.rpmnew /etc/yum.repos.d/epel.repo 2>/dev/null	# CentOS/RedHat EPEL

	echoAndLog "${FUNCNAME}(): dependencies installed"
}

# Hace un backup del fichero pasado por parámetro
# deja un -last y uno para el día
function backupFile()
{
	if [ $# -ne 1 ]; then
		errorAndLog "${FUNCNAME}(): invalid number of parameters"
		exit 1
	fi

	local file="$1"
	local dateymd=`date +%Y%m%d`

	if [ ! -f "$file" ]; then
		warningAndLog "${FUNCNAME}(): file $file doesn't exists"
		return 1
	fi

	echoAndLog "${FUNCNAME}(): making $file backup"

	# realiza una copia de la última configuración como last
	cp -a "$file" "${file}-LAST"

	# si para el día no hay backup lo hace, sino no
	if [ ! -f "${file}-${dateymd}" ]; then
		cp -a "$file" "${file}-${dateymd}"
	fi

	echoAndLog "${FUNCNAME}(): $file backup success"
}

#####################################################################
####### Funciones para la descarga de código
#####################################################################

# 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..."
        echo "Current PATH: $(pwd)"
	curl "${url}" -o opengnsys.zip && unzip -q opengnsys.zip && mv "OpenGnsys-${BRANCH#v}" ogboot
	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
}


############################################################
###  Detectar red
############################################################

# Comprobar si existe conexión.
function checkNetworkConnection()
{
	echoAndLog "${FUNCNAME}(): Checking OpenGnsys server connectivity."
	echoAndLog "OPENGNSYS_SERVER: [[[$OPENGNSYS_SERVER]]]"
	OPENGNSYS_SERVER=${OPENGNSYS_SERVER:-"opengnsys.es"}
	if which curl &>/dev/null; then
		curl --connect-timeout 10 -s "https://$OPENGNSYS_SERVER/" -o /dev/null && \
			curl --connect-timeout 10 -s "http://$OPENGNSYS_SERVER/" -o /dev/null
	elif which wget &>/dev/null; then
		wget --spider -q "https://$OPENGNSYS_SERVER/" && \
			wget --spider -q "http://$OPENGNSYS_SERVER/"
	else
		echoAndLog "${FUNCNAME}(): Cannot execute \"wget\" nor \"curl\"."
		return 1
	fi
}

# Convierte nº de bits (notación CIDR) en máscara de red (gracias a FriedZombie en openwrt.org).
cidr2mask ()
{
	# Number of args to shift, 255..255, first non-255 byte, zeroes
	set -- $[ 5 - ($1 / 8) ] 255 255 255 255 $[ (255 << (8 - ($1 % 8))) & 255 ] 0 0 0
	[ $1 -gt 1 ] && shift $1 || shift
	echo ${1-0}.${2-0}.${3-0}.${4-0}
}

# Obtener los parámetros de red de la interfaz por defecto.
function getNetworkSettings()
{
	# Arrays globales definidas:
	# - DEVICE:     nombres de dispositivos de red activos.
	# - SERVERIP:   IPs locales del servidor.
	# - NETIP:      IPs de redes.
	# - NETMASK:    máscaras de red.
	# - NETBROAD:   IPs de difusión de redes.
	# - ROUTERIP:   IPs de routers.
	# Otras variables globales:
	# - DEFAULTDEV: dispositivo de red por defecto.
	# - DNSIP:      IP del servidor DNS principal.

	local i=0
	local dev=""

	echoAndLog "${FUNCNAME}(): Detecting network parameters."
	DEVICE=( $(ip -o link show up | awk '!/loopback/ {sub(/[:@].*/,"",$2); print $2}') )
	if [ -z "$DEVICE" ]; then
		errorAndLog "${FUNCNAME}(): Network devices not detected."
		exit 1
	fi
	for dev in ${DEVICE[*]}; do
		SERVERIP[i]=$(ip -o addr show dev "$dev" | awk '$3~/inet$/ {sub (/\/.*/, ""); print ($4); exit;}')
		if [ -n "${SERVERIP[i]}" ]; then
			NETMASK[i]=$( cidr2mask $(ip -o addr show dev "$dev" | awk '$3~/inet$/ {sub (/.*\//, "", $4); print ($4); exit;}') )
			NETBROAD[i]=$(ip -o addr show dev "$dev" | awk '$3~/inet$/ {print ($6); exit;}')
			NETIP[i]=$(ip route list proto kernel | awk -v d="$dev" '$3==d && /src/ {sub (/\/.*/,""); print $1; exit;}')
			ROUTERIP[i]=$(ip route list default | awk -v d="$dev" '$5==d {print $3; exit;}')
			DEFAULTDEV=${DEFAULTDEV:-"$dev"}
		fi
		let i++
	done
	DNSIP=$(systemd-resolve --status 2>/dev/null | awk '/DNS Servers:/ {print $3; exit;}')
	[ -z "$DNSIP" ] && DNSIP=$(awk '/nameserver/ {print $2; exit;}' /etc/resolv.conf)
	if [ -z "${NETIP[*]}" -o -z "${NETMASK[*]}" ]; then
		errorAndLog "${FUNCNAME}(): Network not detected."
		exit 1
	fi

	# Variables de ejecución de Apache
	# - APACHE_RUN_USER
	# - APACHE_RUN_GROUP
	if [ -f $APACHECFGDIR/envvars ]; then
		source $APACHECFGDIR/envvars
	fi
	APACHE_RUN_USER=${APACHE_RUN_USER:-"$APACHEUSER"}
	APACHE_RUN_GROUP=${APACHE_RUN_GROUP:-"$APACHEGROUP"}

	echoAndLog "${FUNCNAME}(): Default network device: $DEFAULTDEV."
}


############################################################
### Esqueleto para el Servicio pxe y contenedor tftpboot ###
############################################################

function tftpConfigure()
{
	echoAndLog "${FUNCNAME}(): Configuring TFTP service."
	# Habilitar TFTP y reiniciar Inetd.
	if [ -n "$TFTPSERV" ]; then
		if [ -f $INETDCFGDIR/$TFTPSERV ]; then
			perl -pi -e 's/disable.*/disable = no/' $INETDCFGDIR/$TFTPSERV
		else
			service=$TFTPSERV
			$ENABLESERVICE; $STARTSERVICE
		fi
	fi
	service=$INETDSERV
	$ENABLESERVICE; $STARTSERVICE

	# comprobamos el servicio tftp
	sleep 1
	testPxe
}

# Comprueba que haya conexión al servicio TFTP/PXE.
function testPxe ()
{
	echoAndLog "${FUNCNAME}(): Checking TFTP service... please wait."
	echo "test" >$TFTPCFGDIR/testpxe
	tftp -v 127.0.0.1 -c get testpxe /tmp/testpxe && echoAndLog "TFTP service is OK." || errorAndLog "TFTP service is down."
	rm -f $TFTPCFGDIR/testpxe /tmp/testpxe
}


########################################################################
## Configuración servicio Samba
########################################################################

# Configurar servicios Samba.
function smbConfigure()
{
	echoAndLog "${FUNCNAME}(): Configuring Samba service."

	backupFile $SAMBACFGDIR/smb.conf
	
	# Copiar plantailla de recursos para OpenGnsys
        sed -e "s/OGBOOTDIR/${INSTALL_OGBOOT_TARGET//\//\\/}/g" \
		$WORKDIR/ogboot/etc/smb-ogboot.conf.tmpl > $SAMBACFGDIR/smb-ogboot.conf
	# Configurar y recargar Samba"
	perl -pi -e "s/WORKGROUP/OPENGNSYS/; s/server string \=.*/server string \= ogBoot Samba Server/" $SAMBACFGDIR/smb.conf
	if ! grep -q "smb-ogboot" $SAMBACFGDIR/smb.conf; then
		echo "include = $SAMBACFGDIR/smb-ogboot.conf" >> $SAMBACFGDIR/smb.conf
	fi
	service=$SAMBASERV
	$ENABLESERVICE; $STARTSERVICE
	if [ $? -ne 0 ]; then
		errorAndLog "${FUNCNAME}(): error while configure Samba"
		return 1
	fi
	# Crear clave para usuario de acceso a los recursos.
	echo -ne "$OPENGNSYS_CLIENT_PASSWD\n$OPENGNSYS_CLIENT_PASSWD\n" | smbpasswd -a -s $OPENGNSYS_CLIENT_USER

	echoAndLog "${FUNCNAME}(): Added Samba configuration."
	return 0
}


########################################################################
## Configuración servicio Rsync
########################################################################

# Configurar servicio Rsync.
function rsyncConfigure()
{
	echoAndLog "${FUNCNAME}(): Configuring Rsync service."

	backupFile $RSYNCCFGDIR/rsyncd.conf

	# Configurar acceso a Rsync.
	sed -e "s/CLIENTUSER/$OPENGNSYS_CLIENT_USER/g" \
		$WORKDIR/ogboot/repoman/etc/rsyncd.conf.tmpl > $RSYNCCFGDIR/rsyncd.conf
	# Habilitar Rsync y reiniciar Inetd.
	if [ -n "$RSYNCSERV" ]; then
		if [ -f /etc/default/rsync ]; then
			perl -pi -e 's/RSYNC_ENABLE=.*/RSYNC_ENABLE=inetd/' /etc/default/rsync
		fi
		if [ -f $INETDCFGDIR/rsync ]; then
			perl -pi -e 's/disable.*/disable = no/' $INETDCFGDIR/rsync
		else
			cat << EOT > $INETDCFGDIR/rsync
service rsync
{
	disable = no
	socket_type = stream
	wait = no
	user = root
	server = $(which rsync)
	server_args = --daemon
	log_on_failure += USERID
	flags = IPv6
}
EOT
		fi
		service=$RSYNCSERV $ENABLESERVICE
		service=$INETDSERV $STARTSERVICE
	fi

	echoAndLog "${FUNCNAME}(): Added Rsync configuration."
	return 0
}

	
########################################################################
## Configuración servicio DHCP
########################################################################

# Configurar servicios DHCP.
function dhcpConfigure()
{
	echoAndLog "${FUNCNAME}(): Sample DHCP configuration."

	local errcode=0
	local i=0
	local dev=""

	backupFile $DHCPCFGDIR/dhcpd.conf
	for dev in ${DEVICE[*]}; do
		if [ -n "${SERVERIP[i]}" ]; then
			backupFile $DHCPCFGDIR/dhcpd-$dev.conf
			sed -e "s/SERVERIP/${SERVERIP[i]}/g" \
			    -e "s/NETIP/${NETIP[i]}/g" \
			    -e "s/NETMASK/${NETMASK[i]}/g" \
			    -e "s/NETBROAD/${NETBROAD[i]}/g" \
			    -e "s/ROUTERIP/${ROUTERIP[i]}/g" \
			    -e "s/DNSIP/$DNSIP/g" \
			    $WORKDIR/ogboot/server/etc/dhcpd.conf.tmpl > $DHCPCFGDIR/dhcpd-$dev.conf || errcode=1
			    echo "$WORKDIR/ogboot/server/etc/dhcpd.conf.tmpl"
		fi
		let i++
	done
	if [ $errcode -ne 0 ]; then
		errorAndLog "${FUNCNAME}(): error while configuring DHCP server"
		return 1
	fi
	ln -f $DHCPCFGDIR/dhcpd-$DEFAULTDEV.conf $DHCPCFGDIR/dhcpd.conf
	service=$DHCPSERV
	$ENABLESERVICE; $STARTSERVICE
	echoAndLog "${FUNCNAME}(): Sample DHCP configured in \"$DHCPCFGDIR\"."
	return 0
}


#####################################################################
####### Funciones específicas de la instalación de Opengnsys
#####################################################################

function installWebConsoleApacheConf()
{
	if [ $# -ne 2 ]; then
		errorAndLog "${FUNCNAME}(): invalid number of parameters"
		exit 1
	fi

	local path_ogboot_base="$1"
	local path_apache2_confd="$2"
	local CONSOLEDIR=${path_ogboot_base}/www
	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
	# Activar HTTPS.
	$APACHEENABLESSL
	$APACHEMAKECERT
	# Genera configuración de consola web a partir del fichero plantilla.
	if [ -n "$(apachectl -v | grep "2\.[0-2]")" ]; then
		# Configuración para versiones anteriores de Apache.
		sed -e "s,CONSOLEDIR,$CONSOLEDIR,g" \
			$WORKDIR/ogboot/server/etc/apache-prev2.4.conf.tmpl > $path_apache2_confd/$APACHESITESDIR/${APACHEOGSITE}
	else
		# Configuración específica a partir de Apache 2.4
		if [ -n "$sockfile" ]; then
			sed -e "s,CONSOLEDIR,$CONSOLEDIR,g" \
			    -e "s,proxy:fcgi:.*,proxy:unix:${sockfile%% *}|fcgi://localhost\",g" \
				$WORKDIR/ogboot/server/etc/apache.conf.tmpl > $path_apache2_confd/$APACHESITESDIR/${APACHEOGSITE}.conf
		else
			sed -e "s,CONSOLEDIR,$CONSOLEDIR,g" \
				$WORKDIR/ogboot/server/etc/apache.conf.tmpl > $path_apache2_confd/$APACHESITESDIR/${APACHEOGSITE}.conf
		fi
	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
}

# Crea la estructura base de la instalación de ogBoot
function createDirs()
{
	if [ $# -ne 1 ]; then
		errorAndLog "${FUNCNAME}(): invalid number of parameters"
		exit 1
	fi

	local path_ogboot_base="$1"

	# Crear estructura de directorios.
	echoAndLog "${FUNCNAME}(): creating directory paths in $path_ogboot_base"
	mkdir -p $path_ogboot_base
	mkdir -p $path_ogboot_base/bin
	mkdir -p $path_ogboot_base/client/{cache,images,log}
	mkdir -p $path_ogboot_base/doc
	mkdir -p $path_ogboot_base/etc
	mkdir -p $path_ogboot_base/lib
	mkdir -p $path_ogboot_base/log/clients
	ln -fs $path_ogboot_base/log /var/log/ogboot
	mkdir -p $path_ogboot_base/sbin
	mkdir -p $path_ogboot_base/www
	mkdir -p $path_ogboot_base/images/groups
	mkdir -p $TFTPCFGDIR
	ln -fs $TFTPCFGDIR $path_ogboot_base/tftpboot
	mkdir -p $path_ogboot_base/tftpboot/{menu.lst,grub}
	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 $OGLOGFILE && LOG_FILE=$OGLOGFILE
	chmod 600 $LOG_FILE

	echoAndLog "${FUNCNAME}(): directory paths created"
	return 0
}

# Copia ficheros de configuración y ejecutables genéricos del servidor.
function copyServerFiles ()
{
	if [ $# -ne 1 ]; then
		errorAndLog "${FUNCNAME}(): invalid number of parameters"
		exit 1
	fi

	local path_ogboot_base="$1"

	# Lista de ficheros y directorios origen y de directorios destino.
	local SOURCES=( tftpboot \
			/bin \
			doc )
	local TARGETS=( tftpboot \
			bin \
			doc )

	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/ogboot
	local i
	for (( i = 0; i < ${#SOURCES[@]}; i++ )); do
		if [ -f "${SOURCES[$i]}" ]; then
			echoAndLog "Copying ${SOURCES[$i]} to $path_ogboot_base/${TARGETS[$i]}"
			cp -a "${SOURCES[$i]}" "${path_ogboot_base}/${TARGETS[$i]}"
		elif [ -d "${SOURCES[$i]}" ]; then
			echoAndLog "Copying content of ${SOURCES[$i]} to $path_ogboot_base/${TARGETS[$i]}"
			cp -a "${SOURCES[$i]}"/* "${path_ogboot_base}/${TARGETS[$i]}"
		else
			warningAndLog "Unable to copy ${SOURCES[$i]} to $path_ogboot_base/${TARGETS[$i]}"
		fi
	done

	popd
}

####################################################################
### Funciones de compilación de código fuente de servicios
####################################################################

# Compilar los servicios de OpenGnsys
function ogServerCompilation ()
{
	local ogserverUrl="https://codeload.github.com/opengnsys/ogServer/zip/$BRANCH"
	local error=0

	echoAndLog "${FUNCNAME}(): downloading ogServer code..."

	if ! (curl "${ogserverUrl}" -o ogserver.zip && \
	      unzip -qo "ogserver.zip")
	then
		errorAndLog "${FUNCNAME}(): "\
			    "error getting ogServer code from ${ogserverUrl}"
		return 1
	fi
	rm -f ogserver.zip
	echoAndLog "${FUNCNAME}(): ogServer code was downloaded"

	echoAndLog "${FUNCNAME}(): Compiling OpenGnsys Server"
	pushd "$WORKDIR/ogServer-${BRANCH#v}"
	autoreconf -fi && ./configure && make && mv ogserver $INSTALL_OGBOOT_TARGET/sbin
	if [ $? -ne 0 ]; then
		echoAndLog "${FUNCNAME}(): error while compiling OpenGnsys Server"
		error=1
	fi
	popd

	return $error
}

####################################################################
### Funciones instalacion cliente opengnsys
####################################################################

function copyClientFiles()
{
	local errstatus=0

	echoAndLog "${FUNCNAME}(): Copying OpenGnsys Client files."
	cp -a $WORKDIR/ogboot/client/shared/* $INSTALL_OGBOOT_TARGET/client
	if [ $? -ne 0 ]; then
		errorAndLog "${FUNCNAME}(): error while copying client estructure"
		errstatus=1
	fi
	
	echoAndLog "${FUNCNAME}(): Copying OpenGnsys Cloning Engine files."
	mkdir -p $INSTALL_OGBOOT_TARGET/client/lib/engine/bin
	cp -a $WORKDIR/ogboot/client/engine/*.lib* $INSTALL_OGBOOT_TARGET/client/lib/engine/bin
	if [ $? -ne 0 ]; then
		errorAndLog "${FUNCNAME}(): error while copying engine files"
		errstatus=1
	fi
	
	if [ $errstatus -eq 0 ]; then
		echoAndLog "${FUNCNAME}(): client copy files success."
	else
		errorAndLog "${FUNCNAME}(): client copy files with errors"
	fi

	local ogclientUrl="https://codeload.github.com/opengnsys/ogClient/zip/$BRANCH"

	echoAndLog "${FUNCNAME}(): downloading ogClient code..."

	if ! (curl "${ogclientUrl}" -o ogclient.zip && \
	     unzip -qo ogclient.zip && \
	     mv "ogClient-${BRANCH#v}" $INSTALL_OGBOOT_TARGET/client/ogClient)
	then
		errorAndLog "${FUNCNAME}(): "\
			    "error getting ogClient code from ${ogclientUrl}"
		return 1
	fi
	rm -f ogclient.zip
	echoAndLog "${FUNCNAME}(): ogClient code was downloaded"

	return $errstatus
}


# Crear certificados para la firma de cargadores de arranque.
function createCerts ()
{
	local SSLCFGDIR=$INSTALL_OGBOOT_TARGET/client/etc/ssl
	echoAndLog "${FUNCNAME}(): creating certificate files"
	mkdir -p $SSLCFGDIR/{certs,private}
	openssl req -new -x509 -newkey rsa:2048 -keyout $SSLCFGDIR/private/opengnsys.key -out $SSLCFGDIR/certs/opengnsys.crt -nodes -days 3650 -subj "/CN=OpenGnsys/"
	openssl x509 -in $SSLCFGDIR/certs/opengnsys.crt -out $SSLCFGDIR/certs/opengnsys.cer -outform DER
	echoAndLog "${FUNCNAME}(): certificate successfully created"xmz8641	
}


# Crear cliente OpenGnsys.
function clientCreate()
{
	echo "-----------------------------2"
	if [ $# -ne 1 ]; then
		errorAndLog "${FUNCNAME}(): invalid number of parameters"
		exit 1
	fi

	echo "-----------------------------3"
	local FILENAME="$1"
	local TARGETFILE=$INSTALL_OGBOOT_TARGET/lib/$FILENAME
 
	# Descargar cliente, si es necesario.
	echo "PROGRAMDIR/FILENAME: $PROGRAMDIR/$FILENAME"
	if [ -s $PROGRAMDIR/$FILENAME ]; then
		echoAndLog "${FUNCNAME}(): Moving $PROGRAMDIR/$FILENAME file to $(dirname $TARGETFILE)"
		mv $PROGRAMDIR/$FILENAME $TARGETFILE
	else
		echoAndLog "${FUNCNAME}(): Downloading $FILENAME"
		oglivecli download $FILENAME
	fi
	echo "-----------------------------4"
	if [ ! -s $TARGETFILE ]; then
		errorAndLog "${FUNCNAME}(): Error loading $FILENAME"
		return 1
	fi

	echo "-----------------------------5"
	# Montar imagen, copiar cliente ogclient y desmontar.
	echoAndLog "${FUNCNAME}(): Installing ogLive Client"
	echo -ne "$OPENGNSYS_CLIENT_PASSWD\n$OPENGNSYS_CLIENT_PASSWD\n" | \
			oglivecli install $FILENAME

	echo "-----------------------------6"
	echoAndLog "${FUNCNAME}(): Client generation success"
}

#####################################################################
#######  Función de resumen informativo de la instalación
#####################################################################

function installationSummary()
{
	local VERSIONFILE REVISION

	# Crear fichero de versión y revisión, si no existe.
	VERSIONFILE="$INSTALL_OGBOOT_TARGET/doc/VERSION.json"
	[ -f $VERSIONFILE ] || echo '{ "project": "ogBoot" }' >$VERSIONFILE
	# Incluir datos de revisión, si se está instalando desde el repositorio
	# de código o si no está incluida en el fichero de versión.
	if [ $REMOTE -eq 1 ] || [ -z "$(jq -r '.release' $VERSIONFILE)" ]; then
		# Revisión: rAñoMesDía.Gitcommit (8 caracteres de fecha y 7 primeros de commit).
		RELEASE=$(curl -s "$API_URL/branches/$BRANCH" | jq -r '"r" + (.commit.commit.committer.date | split("-") | join("")[:8]) + "." + (.commit.sha[:7])' 2>/dev/null)
		# Obtener revisión para etiqueta de versión en vez de rama de código.
		[ -z "$RELEASE" ] && RELEASE=$(curl -s $(curl -s "$API_URL/tags" | jq -r ".[] | select(.name==\"$BRANCH\").commit.url" 2>/dev/null) | jq -r '"r" + (.commit.committer.date | split("-") | join("")[:8]) + "." + .sha[:7]' 2>/dev/null)
		jq ".release=\"$RELEASE\"" $VERSIONFILE | sponge $VERSIONFILE
	fi
	VERSION="$(jq -r '[.project, .version, .codename, .release] | join(" ")' $VERSIONFILE 2>/dev/null)"

	# Mostrar información.
	echo
	echoAndLog "ogBoot Installation Summary"
	echo       "=============================="
	echoAndLog "Project version:                  $VERSION"
	echoAndLog "Installation directory:           $INSTALL_OGBOOT_TARGET"
	echoAndLog "Installation log file:            $LOG_FILE"
	echoAndLog "Repository directory:             $INSTALL_OGBOOT_TARGET/images"
	echoAndLog "DHCP configuration directory:     $DHCPCFGDIR"
	echoAndLog "TFTP configuration directory:     $TFTPCFGDIR"
	echoAndLog "Installed ogLive client:          $(oglivecli list | awk '{print $2}')"
	echoAndLog "Samba configuration directory:    $SAMBACFGDIR"
	echoAndLog "Web Console URL:                  $OPENGNSYS_CONSOLEURL"
	echoAndLog "Web Console access data:          entered by the user"
	if grep -q "^RUN_BTTRACK.*no" /etc/default/opengnsys; then
		echoAndLog "BitTorrent service is disabled."
	fi
	echo
	echoAndLog "Post-Installation Instructions:"
	echo       "==============================="
	echoAndLog "You can improve server security by configuring firewall and SELinux,"
	echoAndLog "   running \"$INSTALL_OGBOOT_TARGET/lib/security-config\" script as root."
	echoAndLog "It's strongly recommended to synchronize this server with an NTP server."
	echoAndLog "Review or edit all configuration files."
	echoAndLog "Insert DHCP configuration data and restart service."
	echoAndLog "Review syslog configuration and logrotate by syslog,"
}

#####################################################################
#####################################################################
####### Proceso de instalación de ogBoot
#####################################################################
#####################################################################


# Sólo ejecutable por usuario root
if [ "$(whoami)" != 'root' ]; then
        echo "ERROR: this program must run under root privileges!!"
        exit 1
fi

globalSetup
# Comprobar instalación previa.
if cat $INSTALL_OGBOOT_TARGET/doc/VERSION.* &>/dev/null; then
	echo "ERROR: ogBoot is already installed. Run \"$INSTALL_OGBOOT_TARGET/lib/ogboot-update.sh\" as root to update."
	exit 2
fi

# Si la distribución no es la recomendada mostramos mensaje informativo.
checkDistribution

echoAndLog "ogBoot installation begins at $(date)"
# Introducir datos de configuración y establecer variables globales.
userData

echo "creando $WORKDIR"
mkdir -p $WORKDIR
pushd $WORKDIR

# Detectar datos iniciales de auto-configuración del instalador.

autoConfigure

# Detectar parámetros de red y comprobar si hay conexión.
getNetworkSettings
if [ $? -ne 0 ]; then
	errorAndLog "Error reading default network settings."
	exit 1
fi
checkNetworkConnection
if [ $? -ne 0 ]; then
	errorAndLog "Error connecting to server. Causes:"
	errorAndLog " - Network is unreachable, review devices parameters."
	errorAndLog " - You are inside a private network, configure the proxy service."
	errorAndLog " - Server is temporally down, try agian later."
	exit 1
fi

# Detener servicios de OpenGnsys, si están activos previamente.
[ -f /etc/init.d/opengnsys ] && /etc/init.d/opengnsys stop

# Actualizar repositorios
updatePackageList

# Instalación de dependencias (paquetes de sistema operativo).
declare -a notinstalled
checkDependencies DEPENDENCIES notinstalled
if [ $? -ne 0 ]; then
	installDependencies notinstalled
	if [ $? -ne 0 ]; then
		echoAndLog "Error while installing some dependeces, please verify your server installation before continue"
		exit 1
	fi
fi
if [ -n "$INSTALLEXTRADEPS" ]; then
	echoAndLog "Installing extra dependencies"
	for (( i=0; i<${#INSTALLEXTRADEPS[*]}; i++ )); do
		eval ${INSTALLEXTRADEPS[i]}
	done
fi	

# Detectar datos de auto-configuración después de instalar paquetes.
autoConfigurePost

# Arbol de directorios de OpenGnsys.
createDirs ${INSTALL_OGBOOT_TARGET}
if [ $? -ne 0 ]; then
	errorAndLog "Error while creating directory paths!"
	exit 1
fi

# Si es necesario, descarga el repositorio de código en directorio temporal
if [ $REMOTE -eq 1 ]; then
	downloadCode $CODE_URL
	if [ $? -ne 0 ]; then
		errorAndLog "Error while getting code from the repository"
		exit 1
	fi
else
	ln -fs "$(dirname $PROGRAMDIR)" ogboot
fi
# Configuración de TFTP.
tftpConfigure

# Configuración de Samba.
smbConfigure
if [ $? -ne 0 ]; then
	errorAndLog "Error while configuring Samba server!"
	exit 1
fi

# Configuración de Rsync.
rsyncConfigure

# Configuración ejemplo DHCP.
#dhcpConfigure
#if [ $? -ne 0 ]; then
#	errorAndLog "Error while copying your dhcp server files!"
#	exit 1
#fi

# Copiar ficheros de servicios OpenGnsys Server.
copyServerFiles ${INSTALL_OGBOOT_TARGET}
if [ $? -ne 0 ]; then
	errorAndLog "Error while copying the server files!"
	exit 1
fi
INSTVERSION=$(jq -r '.version' $INSTALL_OGBOOT_TARGET/doc/VERSION.json)

if [ $? -ne 0 ]; then
	errorAndLog "Error configuring Apache for OpenGnsys Admin"
	exit 1
fi

popd

# Crear la estructura de los accesos al servidor desde el cliente (shared)
copyClientFiles
if [ $? -ne 0 ]; then
	errorAndLog "Error creating client structure"
fi

# Crear certificado para firmar cargadores
createCerts

# Crear la estructura del cliente de OpenGnsys.
for i in $OGLIVE; do
	if ! clientCreate "$i"; then
		errorAndLog "Error creating client $i"
		exit 1
	fi
done

# Mostrar sumario de la instalación e instrucciones de post-instalación.
installationSummary

rm -rf $WORKDIR
echoAndLog "ogBoot installation finished at $(date)"
exit 0
