2020-06-04 14:37:01 +02:00
#!/bin/sh
# This script will check if any APT upgrade is available and
# will prepare the host in order to apply upgrade with another script
2020-06-18 08:45:28 +02:00
# 1. Create a temp file
# 2. Disable SGE queue
2020-06-04 14:37:01 +02:00
# This script can be call by a cronjob (eg. weekly)
# Another script should try to apply upgrades also with cron (eg. hourly)
# Vars {{{
readonly PROGNAME = $( basename " ${ 0 } " )
readonly PROGDIR = $( readlink -m $( dirname " ${ 0 } " ) )
readonly ARGS = " ${ * } "
readonly NBARGS = " ${# } "
2020-09-24 15:18:09 +02:00
[ -z " ${ DEBUG } " ] && DEBUG = 1
2020-06-04 14:37:01 +02:00
## Export DEBUG for sub-script
export DEBUG
2020-06-18 08:45:28 +02:00
readonly APT_TMP_FILE = "/tmp/.apt.upgrade"
2020-06-04 14:37:01 +02:00
## Colors
readonly PURPLE = '\033[1;35m'
readonly RED = '\033[0;31m'
readonly RESET = '\033[0m'
readonly COLOR_DEBUG = " ${ PURPLE } "
# }}}
usage( ) { # {{{
cat <<- EOF
usage: $PROGNAME
Verify if any APT package upgrade is available and
try to prepare the host by :
* Disabling SGE queue
EXAMPLES :
- Verify upgrade and prepare the current host
${ PROGNAME }
2020-09-24 15:18:09 +02:00
OPTIONS :
-d,--debug
Enable debug messages.
-h,--help
Print this help message.
2020-06-04 14:37:01 +02:00
EOF
}
# }}}
debug_message( ) { # {{{
local_message = " ${ 1 } "
## Print message if DEBUG is enable (=0)
[ " ${ DEBUG } " -eq "0" ] && printf '\e[1;35m%-6b\e[m\n' " DEBUG − ${ PROGNAME } : ${ local_message } "
2020-08-20 10:02:11 +02:00
return 0
2020-06-04 14:37:01 +02:00
}
# }}}
2020-09-24 15:44:01 +02:00
define_vars( ) { # {{{
## If sge_hostname wasn't defined
if [ -z " ${ sge_hostname } " ] ; then
## Use local host for sge_hostname
sge_hostname = " $( hostname -f) "
fi
}
# }}}
2020-06-15 13:49:25 +02:00
is_apt_upgrade_absent( ) { # {{{
2020-06-04 14:37:01 +02:00
## Count the number of upgradable packages and substract 1 for the header
2020-06-25 08:50:17 +02:00
local_apt_upgrade_number = " $( apt list --upgradable 2>/dev/null \
2020-06-04 16:52:10 +02:00
| wc -l \
| awk '{print $1-1}' ) "
2020-06-04 14:37:01 +02:00
case " ${ local_apt_upgrade_number } " in
0 ) ## No available upgrade
return_apt_upgrade_absent = "0"
; ;
* ) ## Upgrade seems available
return_apt_upgrade_absent = "1"
; ;
esac
## Simple debug message to valid current variable
debug_message " is_apt_upgrade_absent − \
APT upgrade available for this system: ${ RED } ${ local_apt_upgrade_number : =/dev/null } ${ COLOR_DEBUG } ."
return " ${ return_apt_upgrade_absent } "
}
# }}}
2020-06-15 13:49:25 +02:00
is_apt_upgrade_present( ) { # {{{
2020-06-04 14:37:01 +02:00
## Count the number of upgradable packages and substract 1 for the header
2020-06-25 08:50:17 +02:00
local_apt_upgrade_number = " $( apt list --upgradable 2>/dev/null \
2020-06-04 16:52:10 +02:00
| wc -l \
| awk '{print $1-1}' ) "
2020-06-04 14:37:01 +02:00
case " ${ local_apt_upgrade_number } " in
0 ) ## No available upgrade
return_apt_upgrade_present = "1"
; ;
* ) ## Upgrade seems available
return_apt_upgrade_present = "0"
; ;
esac
## Simple debug message to valid current variable
debug_message " is_apt_upgrade_present − \
APT upgrade available for this system: ${ RED } ${ local_apt_upgrade_number : =/dev/null } ${ COLOR_DEBUG } ."
return " ${ return_apt_upgrade_present } "
2020-09-24 15:44:01 +02:00
}
# }}}
is_sge_slots_more_than_percentage( ) { # {{{
local_percentage = " ${ 1 } "
## Get the number of total SGE slots
local_sge_slots = $( qhost -h " ${ sge_hostname : =/dev/null } " -q -xml \
| grep --max-count= 1 -- "'slots'" \
| sed 's;.*<queuevalue.*>\(.*\)</queuevalue>;\1;' )
## Get the expected percentage of total SGE slots
local_sge_slots_percentage = $( echo " ${ local_sge_slots } " \
| awk -v percentage = " 0. ${ local_percentage } " '{ print int($1 * percentage) }' )
## Get the number of SGE used slots
local_sge_slots_used = $( qhost -h " ${ sge_hostname : =/dev/null } " -q -xml \
| grep --max-count= 1 -- "'slots_used'" \
| sed 's;.*<queuevalue.*>\(.*\)</queuevalue>;\1;' )
if [ " ${ local_sge_slots_used } " -ge " ${ local_sge_slots_percentage } " ] ; then
## Used slots is greater or equal than expected percentage
return_sge_slots_percentage = "0"
## Simple debug message to valid current variable
2020-09-25 13:24:20 +02:00
debug_message " is_sge_slots_more_than_percentage − \
Used slots has reached ${ RED } ${ local_percentage } %${ COLOR_DEBUG } of total slots: ${ RED } ${ local_sge_slots_used : =/dev/null } ${ COLOR_DEBUG } /${ local_sge_slots } ."
2020-09-24 15:44:01 +02:00
else
return_sge_slots_percentage = "1"
## Simple debug message to valid current variable
2020-09-25 13:24:20 +02:00
debug_message " is_sge_slots_more_than_percentage − \
Used slots did not reach ${ RED } ${ local_percentage } %${ COLOR_DEBUG } of total slots: ${ RED } ${ local_sge_slots_used : =/dev/null } ${ COLOR_DEBUG } /${ local_sge_slots } ."
2020-09-24 15:44:01 +02:00
fi
return " ${ return_sge_slots_percentage } "
2020-09-25 13:24:20 +02:00
}
# }}}
is_pending_upgrade_more_than_days( ) { # {{{
local_days = " ${ 1 } "
local_line_size = "24"
local_max_file_size = " $(( ${ local_days } * ${ local_line_size } )) "
debug_message " is_pending_upgrade_more_than_days ( ${ local_days } ) − \
Check if ${ APT_TMP_FILE } has a size bigger than ${ RED } ${ local_max_file_size : =/dev/null } ${ COLOR_DEBUG } bytes ( ${ local_days } days * ${ local_line_size } bytes size for one line) ."
if [ $( find " ${ APT_TMP_FILE } " -type f -size +" ${ local_max_file_size } " c 2>/dev/null) ] ; then
## Temp file seems to exist for more than the maximum days
return_pending_upgrade_more_than_days = "0"
debug_message " is_pending_upgrade_more_than_days − \
There is pending upgrade( s) for more than ${ RED } ${ local_days : =/dev/null } ${ COLOR_DEBUG } days."
else
return_pending_upgrade_more_than_days = "1"
debug_message " is_pending_upgrade_more_than_days − \
NO pending upgrades for more than ${ RED } ${ local_days : =/dev/null } ${ COLOR_DEBUG } days."
fi
return " ${ return_pending_upgrade_more_than_days } "
2020-09-25 11:36:12 +02:00
}
# }}}
is_sge_slots_empty( ) { # {{{
## Get the number of SGE used slots
local_sge_slots_used = $( qhost -h " ${ sge_hostname : =/dev/null } " -q -xml \
| grep --max-count= 1 -- "'slots_used'" \
| sed 's;.*<queuevalue.*>\(.*\)</queuevalue>;\1;' )
if [ " ${ local_sge_slots_used } " -eq "0" ] ; then
## Used slots is null
return_sge_slots_empty = "0"
else
return_sge_slots_empty = "1"
fi
## Simple debug message to valid current variable
debug_message " is_sge_slots_empty − \
SGE slots currently in use: ${ RED } ${ local_sge_slots_used : =/dev/null } ${ COLOR_DEBUG } ."
return " ${ return_sge_slots_empty } "
2020-09-24 14:56:27 +02:00
}
# }}}
is_pending_job_empty( ) { # {{{
## Count the number of pending jobs (qw state only)
## Excluding root's jobs
local_pending_jobs = " $( qstat -s p -u '*' \
| grep --count --perl-regexp -- " (?=.*?\bqw\b)((?!root).)* $" ) "
case " ${ local_pending_jobs } " in
0 ) ## Pending jobs list is empty
return_pending_job_empty = "0"
; ;
* ) ## Some jobs are waiting
return_pending_job_empty = "1"
; ;
esac
## Simple debug message to valid current variable
debug_message " is_pending_job_empty − \
Pending jobs for the compute cluster: ${ RED } ${ local_pending_jobs : =/dev/null } ${ COLOR_DEBUG } ."
return " ${ return_pending_job_empty } "
2020-06-04 14:37:01 +02:00
}
# }}}
main( ) { # {{{
2020-09-24 15:44:01 +02:00
## Define all vars
define_vars
2020-06-22 11:25:11 +02:00
sge_disable_host_queue_script = " ${ PROGDIR } /sge.disable.host.queue.sh "
2020-06-04 14:37:01 +02:00
2020-09-24 14:56:27 +02:00
## If NO APT package upgrade is available {{{
2020-06-18 08:45:28 +02:00
### Ensure to remove any temp file related to APT upgrades
2020-06-04 14:37:01 +02:00
### Exit
is_apt_upgrade_absent \
2020-06-18 08:45:28 +02:00
&& rm -f -- " ${ APT_TMP_FILE } " \
2020-06-04 14:37:01 +02:00
&& exit 0
2020-09-24 14:56:27 +02:00
## }}}
2020-09-24 15:44:01 +02:00
## If SGE used slots is more than 75% of total slots AND {{{
## APT package upgrade is available
### Create a temp file
### Disable SGE queue
is_sge_slots_more_than_percentage "75" \
&& is_apt_upgrade_present \
&& touch " ${ APT_TMP_FILE } " && echo "APT upgrade is available." >> " ${ APT_TMP_FILE } " \
&& sh " ${ sge_disable_host_queue_script } " \
&& exit 0
## }}}
2020-09-25 13:24:20 +02:00
## If pending upgrade since 3~4 days AND {{{
## APT package upgrade is available
### Create a temp file
### Disable SGE queue
is_pending_upgrade_more_than_days "3" \
&& is_apt_upgrade_present \
&& touch " ${ APT_TMP_FILE } " && echo "APT upgrade is available." >> " ${ APT_TMP_FILE } " \
&& sh " ${ sge_disable_host_queue_script } " \
&& exit 0
## }}}
2020-09-25 11:36:12 +02:00
## If SGE used slots is NULL AND {{{
## APT package upgrade is available
### Create a temp file
### Disable SGE queue
is_sge_slots_empty \
&& is_apt_upgrade_present \
&& touch " ${ APT_TMP_FILE } " && echo "APT upgrade is available." >> " ${ APT_TMP_FILE } " \
&& sh " ${ sge_disable_host_queue_script } " \
&& exit 0
## }}}
2020-09-24 14:56:27 +02:00
## If pending job list is empty AND {{{
## APT package upgrade is available
### Create a temp file
### Disable SGE queue
is_pending_job_empty \
&& is_apt_upgrade_present \
&& touch " ${ APT_TMP_FILE } " && echo "APT upgrade is available." >> " ${ APT_TMP_FILE } " \
&& sh " ${ sge_disable_host_queue_script } " \
&& exit 0
## }}}
2020-06-04 14:37:01 +02:00
2020-09-24 14:56:27 +02:00
## If APT package upgrade is available {{{
2020-06-18 08:45:28 +02:00
### Create a temp file
2020-06-04 14:37:01 +02:00
### Disable SGE queue
is_apt_upgrade_present \
2020-06-18 08:45:28 +02:00
&& touch " ${ APT_TMP_FILE } " && echo "APT upgrade is available." >> " ${ APT_TMP_FILE } " \
2020-06-22 11:25:11 +02:00
&& sh " ${ sge_disable_host_queue_script } " \
2020-06-15 13:49:25 +02:00
&& exit 0
2020-09-24 14:56:27 +02:00
## }}}
2020-06-04 14:37:01 +02:00
}
# }}}
2020-09-24 15:18:09 +02:00
# Manage arguments # {{{
# This code can't be in a function due to arguments
if [ ! " ${ NBARGS } " -eq "0" ] ; then
manage_arg = "0"
## If the first argument is not an option
if ! printf -- '%s' " ${ 1 } " | grep -q -E -- "^-+" ;
then
## Print help message and exit
printf '%b\n' " ${ RED } Invalid option: ${ 1 } ${ RESET } "
printf '%b\n' "---"
usage
exit 1
fi
# Parse all options (start with a "-") one by one
while printf -- '%s' " ${ 1 } " | grep -q -E -- "^-+" ; do
case " ${ 1 } " in
-d| --debug ) ## debug
DEBUG = 0
; ;
-h| --help ) ## help
usage
## Exit after help informations
exit 0
; ;
* ) ## unknow option
printf '%b\n' " ${ RED } Invalid option: ${ 1 } ${ RESET } "
printf '%b\n' "---"
usage
exit 1
; ;
esac
debug_message " Arguments management − \
${ RED } ${ 1 } ${ COLOR_DEBUG } option managed."
## Move to the next argument
shift
manage_arg = $(( manage_arg+1))
done
debug_message " Arguments management − \
${ RED } ${ manage_arg } ${ COLOR_DEBUG } argument( s) successfully managed."
else
debug_message " Arguments management − \
No arguments/options to manage."
fi
# }}}
2020-06-04 14:37:01 +02:00
main
2020-06-15 13:49:25 +02:00
exit 255