summaryrefslogtreecommitdiffstats
path: root/server/bin/setclientmode
blob: e44684f35aa6cb4cf03e1f947609ebe654f39f3b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
#!/bin/bash

#/**
# 	  setclientmode NombrePlatilla { NombrePC | NombreAula } Modo_trabajo
#@file	  setclientmode
#@brief   Configura el archivo de arranque de PXE para los clientes, ya sea un equipo o un aula, generando enlaces a archivos usados como plantilla. 
#@warning El archivo PXE por defecto "default" se deja en modo de ejecución "user" y se eliminan los enlaces para equipos con la plantilla por defecto.
#@param   $1 NombrePlatilla
#@param   $2 Ámbito { NombrePC | NombreAula }
#@param   $3 Modo_trabajo = { 0, TEMP, 1, PERM } - 0 si es temporal y 1 si es permanente. 
#@param   $4 Fichero con los datos de acceso a la base de datos (USUARIO, PASSWORD, datasource y CATALOG).
#@version 1.0 - Versión inicial.
#@author  Irina Gomez y Ramon Gomez - Univ. Sevilla, noviembre 2010
#@version 1.0.1 - Identificacion de la plantilla por nombre en consola = en primera linea de la plantilla
#@author  Irina Gomez - Univ. Sevilla
#@date    2013-05-31
#@version 1.0.2 - Cambio en la funcionalidad del script: el cambio del archivo de arranque PXE puede hacerse de manera temporal (codigo 0) modificando solo el fichero de arranque PXE durante 60 sg. y sin tocar la base de datos o permanente (codigo 1), actualizando tanto el fichero PXE como la base de datos.
#@author  Juan Carlos Garcia - Univ. Zaragoza
#@date    2015-11-17
#@version 1.1.0 - Se incluye la unidad organizativa como parametro del kernel: ogunit=directorio_unidad (ticket #678).
#@author  Irina Gomez, ETSII Universidad de Sevilla
#@date    2015-12-16
#@version 1.1.0a - El server siempre es el servidor PXE. El segundo parámetro de la IP es el SERVER. La asignación del ogLive siempre es el server. (ticket #859).
#@author  Antonio J. Doblas Viso, Universidad de Malaga
#@date    2018-07-11
#@version 1.1.1 - Crea configuración PXE para BIOS y UEFI. Permite pasar datos de acceso a la base de datos en un fichero. (ticket #802)
#@author  Irina Gomez, ETSII Universidad de Sevilla
#@date    2019-02-13
#*/ ##

# Variables.
PROG=$(basename $0)
OPENGNSYS=${OPENGNSYS:-"/opt/opengnsys"}
SERVERCONF="$4"
SERVERCONF=${SERVERCONF:-$OPENGNSYS/etc/ogAdmServer.cfg}
PXEDIR[0]=$OPENGNSYS/tftpboot/menu.lst
PXEDIR[1]=$OPENGNSYS/tftpboot/grub
LOGFILE=$OPENGNSYS/log/opengnsys.log
MYCNF=/tmp/.my.cnf.$$

# Control básico de errores.
if [ $# -ne 3 -a $# -ne 4 ]; then
	echo "$PROG: Error de ejecución"
	echo "Formato: $PROG PLANTILLA [NOMBRE_PC|NOMBRE_AULA] MODO [ BD_CONF ]"
	exit 1
fi
if [ ! -r $SERVERCONF ]; then
	echo "$PROG: Sin acceso a fichero de configuración"
	exit 2
fi
TEMPLATE[0]=$(grep -l "^#.* $1 *$" ${PXEDIR[0]}/templates/*)
TEMPLATE[1]=$(grep -l "^#.* $1 *$" ${PXEDIR[1]}/templates/*)
if [ -z "${TEMPLATE[0]}" -a -z "${TEMPLATE[1]}" ]; then
	echo "No existe archivo platilla: $1"
	exit
fi

case "$3" in
	0|TEMP)	MODE="TEMP" ;;
	1|PERM)	MODE="PERM" ;;
	*)	echo "$PROG: Modo desconodido: 0, TEMP (temporal), 1, PERM (permanente)"
		exit 1 ;;
esac

# Obtener datos de acceso a la Base de datos.
source $SERVERCONF
# Sustituir caracteres ' por \' para evitar inyección SQL.
BOOTMODE="${1//\'/\'}"
RESOURCE="${2//\'/\'}"
# Componer fichero con credenciales de conexión. 
touch $MYCNF 
chmod 600 $MYCNF 
cat << EOT > $MYCNF 
[client] 
user=$USUARIO 
password=$PASSWORD 
EOT
# Borrar el fichero temporal si termina el proceso. 
trap "rm -f $MYCNF" 0 1 2 3 6 9 15 
# Buscar ordenador individual o todos los de una aula.
ETHERNET=$(mysql --defaults-extra-file=$MYCNF -D "$CATALOG" -s -N -e \
		"SELECT mac FROM ordenadores 
 		   JOIN aulas USING (idaula) 
 		  WHERE aulas.nombreaula='$RESOURCE' 
 		     OR nombreordenador='$RESOURCE';")
if [ -z "$ETHERNET" ]; then
	date +"%b %d %T $PROG: No existe aula o equipo con el nombre \"$2\"" | tee -a $LOGFILE
	exit 1
fi

# Copiar fichero de configuración y actualizar base de datos.
date +"%b %d %T $PROG: Configurando \"$1\" en \"$2\" en modo \"$MODE\"" | tee -a $LOGFILE
NPC=0
for MAC in $ETHERNET; do
	date +"%b %d %T $PROG: Detectada ethernet \"$MAC\" en \"$2\"" | tee -a $LOGFILE
	MACFILE="${MAC^^}"
	PXEFILE=01-${MACFILE:0:2}-${MACFILE:2:2}-${MACFILE:4:2}-${MACFILE:6:2}-${MACFILE:8:2}-${MACFILE:10:2}
	if [ "$1" != "default" ]; then
		# Si no está definida la variable LANG, usar idioma inglés por defecto.
		[ -z "$LANG" -o "$LANG" == "C" ] && LANG="en"
		# Obtener de la BD los parámetros de arranque asociados (separador es TAB).
		DATOS=$(mysql --defaults-extra-file=$MYCNF -D "$CATALOG" -s -N -e \
			"SELECT ' LANG=$LANG',
				' ip=', CONCAT_WS(':', ordenadores.ip,
				(SELECT (@serverip:=ipserveradm) FROM entornos LIMIT 1),
				aulas.router, aulas.netmask,
				ordenadores.nombreordenador, ordenadores.netiface, 'none'),
				' group=', REPLACE(TRIM(aulas.nombreaula), ' ', '_'),
				' ogrepo=', (@repoip:=IFNULL(repositorios.ip, '')),
				' oglive=', @serverip,
				' oglog=', @serverip,
				' ogshare=', @serverip,
				' oglivedir=', ordenadores.oglivedir,
				IF(perfileshard.descripcion<>'', CONCAT(' hardprofile=', REPLACE(TRIM(perfileshard.descripcion), ' ', '_')), ''),
				IF(aulas.ntp<>'', CONCAT(' ogntp=', aulas.ntp), ''),
				IF(aulas.dns<>'', CONCAT(' ogdns=', aulas.dns), ''),
				IF(aulas.proxy<>'', CONCAT(' ogproxy=', aulas.proxy), ''),
				IF(entidades.ogunit=1 AND NOT centros.directorio='', CONCAT(' ogunit=', centros.directorio), ''),
				CASE
				    WHEN menus.resolucion IS NULL THEN ''
				    WHEN menus.resolucion <= '999' THEN CONCAT(' vga=', menus.resolucion)
				    WHEN menus.resolucion LIKE '%:%' THEN CONCAT(' video=', menus.resolucion)
				    ELSE menus.resolucion
				END
				FROM ordenadores 
				JOIN aulas USING(idaula)
				JOIN centros USING(idcentro)
				JOIN entidades USING(identidad)
				LEFT JOIN repositorios USING(idrepositorio)
				LEFT JOIN perfileshard USING(idperfilhard)
				LEFT JOIN menus USING(idmenu)
				WHERE ordenadores.mac='$MAC';")
		# Quitar tabuladores, sustituir acentos y dejar resolución por defecto.
		DATOS=$(echo ${DATOS//	/} | tr 'áéíóúñçÁÉÍÓÚÑÇ' 'aeiouncAEIOUNC')
		[[ "$DATOS" =~ (vga|video) ]] || DATOS="$DATOS vga=788"
		# Obtener directorio ogLive a partir de los datos.
		OGLIVEDIR=$(echo "$DATOS" | awk -F= 'BEGIN {RS=" "} $1=="oglivedir" {print $2}')

		# Pondremos como propietario al usuario y grupo de Apache para que se pueda cambiar desde la consola web.
		PERMS=$(ps axho user,group,comm|awk '!/root/ && /httpd|apache/ {u=$1; g=$2} END {if (g) printf "%s:%s",u,g}')

		for BOOTTYPE in 0 1; do
			# Si no existe la plantilla borramos el archivo PXE anterior continuamos
			if [ -z "${TEMPLATE[$BOOTTYPE]}" ]; then
				rm ${PXEDIR[$BOOTTYPE]}/$PXEFILE
				continue
			fi
			# Comprobar si existe "oglivedir" en la plantilla para evitar duplicados.
			if grep -q "oglivedir=" ${TEMPLATE[$BOOTTYPE]} 2>/dev/null; then
				DATOSAUX="${DATOS/oglivedir=$OGLIVEDIR/}"
			fi
			# Renombra el fichero PXE original
			[ -e ${PXEDIR[$BOOTTYPE]}/$PXEFILE ] && mv ${PXEDIR[$BOOTTYPE]}/$PXEFILE ${PXEDIR[$BOOTTYPE]}/$PXEFILE.netboot

			# Crear fichero PXE a partir de la plantilla con los datos obtenidos en la BD.
			sed -e "s,vga=[0-9]*,,g; s,INFOHOST,${DATOSAUX//,/\\,},g; s,set ISODIR=.*,set ISODIR=$OGLIVEDIR,g" ${TEMPLATE[$BOOTTYPE]} >${PXEDIR[$BOOTTYPE]}/$PXEFILE
			[ -n "$PERMS" ] && chown $PERMS ${PXEDIR[$BOOTTYPE]}/$PXEFILE
		done


		# Si el modo de trabajo es temporal (0) mete un retardo, restaura el fichero PXE a su estado original y no toca la base de datos
		if [ "$MODE" == "TEMP" ]; then
			sleep 60
			for BOOTTYPE in 0 1; do
				[ -e ${PXEDIR[$BOOTTYPE]}/$PXEFILE ] && rm ${PXEDIR[$BOOTTYPE]}/$PXEFILE
				[ -e ${PXEDIR[$BOOTTYPE]}/$PXEFILE.netboot ] && mv ${PXEDIR[$BOOTTYPE]}/$PXEFILE.netboot ${PXEDIR[$BOOTTYPE]}/$PXEFILE
			done
		fi


		# Si el modo de trabajo es permanente (1)  borra el fichero PXE.netboot si existe y graba los datos en la base de datos
		if [ "$MODE" == "PERM" ]; then
			[ -e ${PXEDIR[0]}/$PXEFILE.netboot ] && rm ${PXEDIR[0]}/$PXEFILE.netboot
			[ -e ${PXEDIR[1]}/$PXEFILE.netboot ] && rm ${PXEDIR[1]}/$PXEFILE.netboot
			# Si no existe la plantilla de tipo BIOS tomo el nombre de la UEFI
			[ -z "${TEMPLATE[0]}" ] && TEMPLATE[0]=${TEMPLATE[1]}

			mysql --defaults-extra-file=$MYCNF -D "$CATALOG" -e \
				"UPDATE ordenadores SET arranque='$(basename ${TEMPLATE[0]})' WHERE mac='$MAC';"
		fi
	fi
	let NPC=NPC+1
done
date +"%b %d %T $PROG: $NPC equipo(s) configurado(s)" | tee -a $LOGFILE