source: epoptes/trunk/fuentes/epoptes-client/epoptes-client @ 6053

Last change on this file since 6053 was 6053, checked in by daduve, 2 years ago

Optimize epoptes-client to start control in slowly starting services

  • Property svn:executable set to *
File size: 16.1 KB
Line 
1#!/bin/bash
2
3###########################################################################
4# Connects to a remote server and offers it a local shell.
5# Usage: epoptes [server] [port]
6#
7# Copyright (C) 2010-2012 Alkis Georgopoulos <alkisg@gmail.com>
8#
9# This program is free software: you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation, either version 3 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program.  If not, see <http://www.gnu.org/licenses/>.
21#
22# On Debian GNU/Linux systems, the complete text of the GNU General
23# Public License can be found in `/usr/share/common-licenses/GPL'.
24###########################################################################
25
26# epoptes-client may be called either as root, to control the client, or as a
27# user, to control the user session.
28# As root, epoptes-client starts from if-up.d on standalone clients.
29# Unfortunately, thin and fat clients don't get if-up.d events, so just for
30# this case we're using a helper sysvinit script.
31# As a user, epoptes-client runs from /etc/xdg/autostart.
32# Users can cancel that from their System > Preferences > Services gnome menu.
33log_file="/tmp/.epoptes_log"
34VERSION=$(lliurex-version)
35download_certificate=False
36
37if [ ! -f $log_file ]; then
38        touch $log_file
39        chmod 777 $log_file
40else
41        chmod 777 $log_file
42fi
43
44
45discover() {
46        echo "  - Dentro de funcion discover -  " >> $log_file
47        echo >> $log_file
48        MATCH=""
49        if [[ "$VERSION" == *server* ]]
50        then
51                LIGHT=` echo "$DISPLAY" | cut -d ":" -f1`
52                if [[ -z "$LIGHT" ]]; then 
53                        MATCH="servidor"
54                else
55                        MATCH="ligero"
56                fi
57        else
58                if grep "client" $log_file > /dev/nul
59                then
60                        if [[ -z "$LTSP_FATCLIENT" ]]; then
61                                MATCH="Pesado"
62                                download_certificate=True
63                        else
64                                MATCH="Semiligero"
65                                download_certificate=True
66                        fi
67                fi
68        fi
69        echo >> $log_file
70        echo "** Soy un $MATCH **" >> $log_file
71        echo >> $log_file
72} 
73
74
75
76die() {
77    echo "epoptes-client ERROR: $@" >&2
78    echo "epoptes-client ERROR: $@" >> $log_file
79    exit 1
80}
81
82# The "boolean_is_true" name is used as a sentinel that prevents ltsp_config
83# from sourcing ltsp_common_functions. So we're using a different name.
84my_boolean_is_true() {
85    case "$1" in
86       # match all cases of true|y|yes
87       [Tt][Rr][Uu][Ee]|[Yy]|[Yy][Ee][Ss]) return 0 ;;
88       *) return 1 ;;
89    esac
90}
91
92# Return true if we're in a chroot.
93chrooted() {
94    # The result is cached in a variable with the same name as the function :P
95    test -n "$chrooted" && return "$chrooted"
96    test -n "$UID" || UID=$(id -u)
97    if [ "$UID" -gt 0 ]; then
98        chrooted=1
99    elif [ "$(stat -c %d/%i /)" = "$(stat -Lc %d/%i /proc/1/root 2>/dev/null)" ]
100    then
101        # the devicenumber/inode pair of / is the same as that of /sbin/init's
102        # root, so we're *not* in a chroot and hence return false.
103        chrooted=1
104    else
105        chrooted=0
106    fi
107    return "$chrooted"
108}
109
110# Get $UID and $TYPE of the client, and the default $SERVER and $PORT.
111basic_info() {
112    test -n "$UID" || UID=$(id -u)
113
114    # We temporarily need LTSP_CLIENT and LTSP_FATCLIENT to decide TYPE.
115    # Unfortunately, when epoptes-client is ran as a system service, they're
116    # not in our environment, and we need to source ltsp_config.
117    # But we don't want to pollute the environment with any of its other vars.
118    if [ "$UID" -eq 0 ] && [ -f /usr/share/ltsp/ltsp_config ] && ! chrooted &&
119        egrep -qs 'ltsp|nfs|nbd' /proc/cmdline
120    then
121        export $(
122            . /usr/share/ltsp/ltsp_config >/dev/null
123            echo "LTSP_CLIENT=$LTSP_CLIENT"
124            echo "LTSP_FATCLIENT=$LTSP_FATCLIENT"
125            echo "EPOPTES_CLIENT_VERIFY_CERTIFICATE=$EPOPTES_CLIENT_VERIFY_CERTIFICATE")
126        # LTSP_CLIENT may not be available in system sesssions, if so fake it
127        LTSP_CLIENT=${LTSP_CLIENT:-127.0.0.1}
128    fi
129
130    # LTSP_FATCLIENT may not be available in user sessions, autodetect it
131    if [ -n "$LTSP_CLIENT" ] && [ -z "$LTSP_FATCLIENT" ] &&
132        [ "$UID" -gt 0 ] && [ -x /usr/bin/getltscfg ] &&
133        egrep -qs 'ltsp|nfs|nbd' /proc/cmdline
134    then
135        LTSP_FATCLIENT=True
136    fi
137
138    if my_boolean_is_true "$LTSP_FATCLIENT"; then
139        TYPE="fat"
140    elif [ -n "$LTSP_CLIENT" ]; then
141        TYPE="thin"
142    else
143        TYPE="standalone"
144    fi
145
146    if ( [ "$TYPE" = "thin" ] && [ "$UID" -gt 0 ] ) || chrooted; then
147        SERVER=localhost
148    else
149        SERVER=server
150    fi
151    PORT=789
152
153    export UID TYPE SERVER PORT
154}
155
156fetch_certificate()
157{
158    echo "[fetch_certificate] Comprobando el certificado: epoptes-client -c">> $log_file
159    echo "[fetch_certificate]Debe ser 0 sino muere, UID : $UID" >> $log_file
160    test "$UID" -eq 0 || die "[fetch_certificate] Need to be root to fetch the certificate" >> $log_file
161    mkdir -p /etc/epoptes
162    openssl s_client -connect $SERVER:$PORT < /dev/null \
163        | sed '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/!d' \
164        > /etc/epoptes/server.crt
165    if [ -s /etc/epoptes/server.crt ]; then
166        echo "[fetch_certificate] Successfully fetched certificate from $SERVER:$PORT" >> $log_file
167        echo "[fetch_certificate] Successfully fetched certificate from $SERVER:$PORT"
168        exit 0
169    else
170        echo  "[fetch_certificate] FIRST Failed to fetch certificate from $SERVER:$PORT" >> $log_file
171        sleep 10
172        openssl s_client -connect $SERVER:$PORT < /dev/null \
173        | sed '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/!d' \
174        > /etc/epoptes/server.crt
175         if [ -s /etc/epoptes/server.crt ]; then
176                echo "[fetch_certificate] Successfully fetched certificate from $SERVER:$PORT" >> $log_file
177                echo "[fetch_certificate] Successfully fetched certificate from $SERVER:$PORT"
178                exit 0
179        else
180                die "[fetch_certificate] SECOND Failed to fetch certificate from $SERVER:$PORT"
181        fi
182       
183    fi
184}
185
186fetch_certificate_download()
187{
188    echo "[fetch_certificate_download] FORZANDO EL DOWNLOAD DEL CERTIFICADO">> $log_file
189    echo "[fetch_certificate_download] Comprobando el certificado">> $log_file
190    echo "[fetch_certificate_download] Debe ser 0 sino muere, UID : $UID" >> $log_file
191    test "$UID" -eq 0 || die "[fetch_certificate_download] Need to be root to fetch the certificate" >> $log_file
192    mkdir -p /etc/epoptes
193    openssl s_client -connect $SERVER:$PORT < /dev/null \
194        | sed '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/!d' \
195        > /etc/epoptes/server.crt
196    if [ -s /etc/epoptes/server.crt ]; then
197        echo "[fetch_certificate_download] Successfully fetched certificate from $SERVER:$PORT" >> $log_file
198        echo "[fetch_certificate_download] Successfully fetched certificate from $SERVER:$PORT"
199    else
200        echo  "[fetch_certificate_download] FIRST Failed to fetch certificate from $SERVER:$PORT" >> $log_file
201        sleep 10
202        openssl s_client -connect $SERVER:$PORT < /dev/null \
203        | sed '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/!d' \
204        > /etc/epoptes/server.crt
205         if [ -s /etc/epoptes/server.crt ]; then
206                echo "[fetch_certificate_download] Successfully fetched certificate from $SERVER:$PORT" >> $log_file
207                echo "[fetch_certificate_download] Successfully fetched certificate from $SERVER:$PORT"
208        else
209                die "[fetch_certificate_download] SECOND Failed to fetch certificate from $SERVER:$PORT"
210        fi
211       
212    fi
213}
214
215
216# Main.############################################
217
218# Check the first parameter as it may turn out we don't need to run at all
219case "$1" in
220    -v|--version)
221        echo "$VERSION"
222        exit
223        ;;
224    -h|--help)
225        if [ -x /usr/bin/man ]; then
226            exec man epoptes-client
227        else
228            echo "Usage: $0 [-c|-h|-v] [SERVER] [PORT]"
229            exit 0
230        fi
231        ;;
232    -c|--certificate)
233        need_certificate=True
234        shift
235        ;;
236esac
237
238echo "">> $log_file
239echo "*******DEPURANDO SCRIPT /USR/SBIN/EPOPTES PARA EL *************    USUARIO : $USER      ******">> $log_file
240echo "">> $log_file
241date >> $log_file
242echo "">> $log_file
243echo "$VERSION" >> $log_file
244echo "">> $log_file
245echo "_________MAIN_____________">> $log_file
246discover
247echo "Presesion Lightdm.........."  >> $log_file
248echo "">> $log_file
249name_aux=$(date | awk '{print $4}')
250file_socat="/tmp/.epoptes_socat_$name_aux"
251file_socat_post="/tmp/.epoptes_socat_post_$name_aux"
252ps aux | grep /usr/sbin/epoptes | grep -v root | grep -v "grep" >> $log_file
253ps aux | grep /usr/sbin/epoptes | grep -v root | grep -v "grep"  | awk '{print $2}' | uniq > $file_socat
254cat $file_socat >> $log_file
255USERS_SOCAT=$(wc -l < $file_socat)
256#USERS_SOCAT=$(ps aux | grep /usr/sbin/epoptes | grep -v "root" | grep -v "grep" | awk '{print $2}' | uniq | wc -l)
257echo "USERS_SOCAT = $USERS_SOCAT">> $log_file;
258if [[ "$MATCH" != ligero  ]]; then
259        if (("$USERS_SOCAT" > 2 )); then
260                echo "Estoy dentro del if matando procesos.......">> $log_file
261                for i in $(ps aux | grep /usr/sbin/epoptes | grep -v "root" | grep -v "grep" | awk '{print $2}' | uniq); do
262                        echo "Dentro del FOR para .......">> $log_file
263                        ps -aux | grep $i >> $log_file
264                        echo "Matando el proceso $i"  >> $log_file
265                        kill -9 $i >> $log_file
266                done
267        fi
268fi
269
270
271export VERSION="0.5.7" # Automatically updated by mkdst
272
273
274
275# When called from /etc/xdg/autostart, /sbin is not in the system path.
276PATH="$PATH:/sbin:/usr/sbin"
277
278# When launched as a service, LANG might not be set.
279if [ -z "$LANG" ] && [ -r /etc/default/locale ]; then
280    . /etc/default/locale
281    export LANG
282fi
283
284basic_info
285echo "Capturo basic info UID:$UID TYPE:$TYPE SERVER:$SERVER PORT:$PORT">> $log_file
286# The configuration file overrides the default values
287if [ -f /etc/default/epoptes-client ]; then
288    . /etc/default/epoptes-client
289fi
290# And the command line parameters override the configuration file
291export SERVER=${1:-$SERVER}
292export PORT=${2:-$PORT}
293
294# Provide an easy way to fetch the server certificate
295test -n "$need_certificate" && fetch_certificate
296
297#Nos aseguramos de tener el certificado del server
298echo "Necesito el certificado -> $download_certificate" >> $log_file
299BAJAR_CERT=True
300if [ $download_certificate  =  $BAJAR_CERT ];then
301        echo "Compruebo si el certificado existe..... ">> $log_file
302        if [ ! -s /etc/epoptes/server.crt ]; then
303               echo "FORZADO -> No tengo el certificado debo adquirirlo del server" >> $log_file
304               fetch_certificate_download
305        else
306                echo "Tengo el certificado continua la ejecucion....." >> $log_file
307        fi
308fi
309
310# We don't want the epoptes-client system service running on the epoptes server
311if ( [ $UID -eq 0 ] && [ $TYPE = "standalone" ] && [ -x /usr/bin/epoptes ] ) ||
312    chrooted
313then
314   echo "--Parte del chrooted--" >> $log_file
315   if lliurex-version -t client; then
316        echo "Compruebo como TRUE --> lliurex-version -t client" >> $log_file
317   else
318        echo "FIN compruebo como FALSE --> lliurex-version -t client" >> $log_file
319        exit 0
320   fi
321fi
322
323# Go to the scripts directory, so that we can run them with ./xxx
324cd $(dirname "$0")
325if [ -d ../epoptes-client ]; then
326    cd ../epoptes-client
327else
328    cd /usr/share/epoptes-client
329fi
330
331# Source the lsb init functions, for log_begin_msg.
332# Unfortunately it seems that Centos and Fedora don't have that file.
333if [ -f /lib/lsb/init-functions ]; then
334    . /lib/lsb/init-functions
335else
336    alias log_begin_msg="echo -n"
337fi
338log_begin_msg "Epoptes-client connecting to $SERVER:$PORT..."
339echo "Epoptes-client connecting to $SERVER:$PORT..."
340echo "Epoptes-client connecting to $SERVER:$PORT...">>$log_file
341# Call chain:
342#  * if-up.d executes /usr/sbin/epoptes-client
343#  * then socat is called
344#  * after a successful connection, socat exec's /bin/sh
345#  * and the daemon sends /usr/share/epoptes/client-functions to that shell
346
347# Kill all ghost instances of epoptes-client of the same user.
348# That may happen if network connectivity is lost for a while.
349# Standalone workstations don't hang if the network is down, and nbd might cope
350# with that for LTSP clients, but epoptes kills disconnected epoptes-clients.
351# The current epoptes-client is excluded because it starts with /bin/sh.
352echo "pkill de $UID"
353echo "pkill de $UID">>$lof_file
354pkill -U $UID -f '^epoptes-client$'
355
356# Remember the stdout descriptor to use it in the second phase.
357# stdio will be redirected to the server, but stderr will be kept in the
358# local console, to avoid possible noise from applications started in the
359# background.
360# If the callee needs to grab stderr, it can use `cmd 2>&1`.
361exec 5>&1
362
363# Bash supports launching a program with a different zeroth argument,
364# this makes pgrep'ing for epoptes-client easier.
365cmdline='bash -c \"exec -a epoptes-client sh\"'
366
367# Offer an lts.conf (or environment) variable to disable cert verification.
368if my_boolean_is_true "${EPOPTES_CLIENT_VERIFY_CERTIFICATE:-True}"; then
369    cert_param="cafile=/etc/epoptes/server.crt"
370else
371    cert_param="verify=0"
372fi
373
374# Connect to the server, or keep retrying until the server gets online
375# (for standalone workstations booted before the server).
376RUN=1
377salida(){
378        RUN=0
379        echo "Estoy en la funcion de SALIDA de $USER" >> $log_file
380        date >> $log_file
381        echo "Quiero matar el proceso $BASHPID" >> $log_file
382        #kill -9 $BASHPID
383}
384echo "RUN = $RUN"
385test_conn(){
386    echo "Testeando la funcion CONN $USER">> $log_file
387    if [ -z ${LTSP_CLIENT} ]; then
388        echo "No es cliente LTSP">> $log_file
389        #exit 0
390        #RUN=0
391        return 0
392    fi
393    ping -c 2 ${LTSP_CLIENT}
394    if [ $? -eq 0 ]; then
395        echo "Estamos en if del ping -c">> $log_file
396        #exit 0
397        return 0
398    fi
399    echo "Vamos a salida -- No detecte nada en funcion CONN">> $log_file
400    salida
401}
402
403trap salida KILL TERM QUIT INT STOP EXIT
404echo "__________________________________________________">>$log_file
405echo "">>$log_file
406echo "-- Funcion Principal para abrir el SOCAT --" >> $log_file
407if [ -s /etc/epoptes/server.crt ] || [ "$cert_param" = "verify=0" ]; then
408   echo "Dentro del if antes del while 1 del usuario $USER" >> $log_file
409   while [ ${RUN} -eq 1 ] && sleep 1; do
410        ALIVE=$(ps ax|grep $PPID|grep -v grep|wc -l)
411        echo "Dentro del While porque el RUN es $RUN para usuario $USER">> $log_file
412        ps aux | grep /usr/sbin/epoptes | grep -v root | grep -v "grep"  | awk '{print $2}' | uniq > $file_socat_post
413        echo "   - USERS_SOCAT_POST - ">>$log_file
414        cat $file_socat_post >> $log_file
415        USERS_SOCAT_POST=$(wc -l < $file_socat_post)
416        #USERS_SOCAT_POST=`ps aux | grep /usr/sbin/epoptes | grep -v root | grep -v "grep" | awk '{print $2}' | uniq | wc -l `
417        echo "Calculando el USERS_SOCAT_POST: $USERS_SOCAT_POST" >> $log_file
418        if (( $USERS_SOCAT_POST < 3 )) || [[ "$MATCH" == "ligero" ]]; then
419                echo "-----SOCAT se va a ejecutar para el usuario: $USER -----">> $log_file
420                sleep 20
421                date_create=$(date)
422                echo 'socat openssl-connect:$SERVER:$PORT,$cert_param,interval=60,forever EXEC:"$cmdline",sigint,sigquit,sigterm' >> $log_file
423                socat openssl-connect:$SERVER:$PORT,$cert_param,interval=60,forever EXEC:"$cmdline",sigint,sigquit
424                echo "-------------------------------------" $log_file
425                echo "Muere el SOCAT del usuario: $USER creado: $date_create">> $log_file
426                date >> $log_file
427                echo "-------------------------------------" $log_file
428        fi
429       
430        if [ "x${ALIVE}" != "x1" ]; then 
431                echo "Se aborta el script para el usuario $USER debido al AlIVE">> $log_file
432                exit 1
433        fi
434        echo "Paso del ALIVE y continuo porque RUN: $RUN del usuario $USER">> $log_file
435        test_conn
436        SESSION_GNOME=`ps aux | grep mate-session | wc -l `
437        if (( $SESSION_GNOME < 2 )); then
438                date >> $log_file
439                echo "La sesion no esta activa me quedo en la sesion MATE-SESSION: $SESSION_GNOME modifico el RUN" >> $log_file
440                RUN=0
441        fi
442    done;
443elif [ -f /etc/epoptes/server.crt ]; then
444        echo "Antes del while2 del user: $USER" >> $log_file
445    while [ ${RUN} -eq 1 ] && sleep 1; do
446        ALIVE=$(ps ax|grep $PPID|grep -v grep|wc -l)
447        socat tcp:$SERVER:$PORT,interval=60,forever EXEC:"$cmdline",nofork
448        if [ "x${ALIVE}" != "x1" ]; then 
449            exit 1
450        fi
451        echo "RUN en ELIF es $RUN del usuario $USER">> $log_file
452        test_conn
453    done;
454else
455        echo "en el else del usuario $USER">> $log_file
456    $0 -c
457    exec $0
458fi
459echo "____________FIN_______SCRIPT____________">> $log_file
Note: See TracBrowser for help on using the repository browser.