scripts/proxmox/proxmox.template.debian.upgrade.sh

352 lines
9.3 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/sh
#
# This script will try to upgrade an LXC Debian template
# 1. Start the LXC container if available
# 2. Run some script to upgrade the container
# 3. Stop the container
# This script can be call by a cronjob (eg. daily, weekly,…)
# Vars {{{
readonly PROGNAME=$(basename "${0}")
readonly PROGDIR=$(readlink -m $(dirname "${0}"))
readonly ARGS="${*}"
readonly NBARGS="${#}"
[ -z "${DEBUG}" ] && DEBUG=1
## Export DEBUG for sub-script
export DEBUG
readonly CT_ID_DEFAULT="199124"
readonly SLEEP_DELAY_DEFAULT="20"
## Colors
readonly PURPLE='\033[1;35m'
readonly RED='\033[0;31m'
readonly RESET='\033[0m'
readonly COLOR_DEBUG="${PURPLE}"
# }}}
usage() { # {{{
cat <<- EOF
usage: $PROGNAME [-d|-h|-i|-s]
Start and upgrade an LXC container for Debian template
EXAMPLES:
- Upgrade default LXC container (${CT_ID_DEFAULT}) :
${PROGNAME}
- Specify the container ID :
${PROGNAME} --id 666
OPTIONS:
-d,--debug
Enable debug messages.
-h,--help
Print this help message.
-i,--id
Choose a different LXC container ID (default ${CT_ID_DEFAULT}).
-s,--sleep
Set a different delay to test container between each
different state (default: ${SLEEP_DELAY_DEFAULT}).
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}"
return 0
}
# }}}
error_message() { # {{{
local_error_message="${1}"
local_error_code="${2}"
## Print error message
printf '%b\n' "ERROR ${PROGNAME}: ${RED}${local_error_message}${RESET}"
exit "${local_error_code:=66}"
}
# }}}
define_vars() { # {{{
## If ct_id wasn't defined (argument) {{{
if [ -z "${ct_id}" ]; then
## Use default value
readonly ct_id="${CT_ID_DEFAULT}"
fi
## }}}
## If sleep_delay wasn't defined (argument) {{{
if [ -z "${sleep_delay}" ]; then
## Use default value
readonly sleep_delay="${SLEEP_DELAY_DEFAULT}"
fi
## }}}
}
# }}}
is_proxmox_absent() { # {{{
## By default, Proxmox is absent on an host
return_is_proxmox_absent="0"
## Check if the system runs on a PVE kernel
if ! uname --kernel-release -- | grep --quiet -- "pve";
then
return_is_proxmox_absent="0"
debug_message "is_proxmox_absent \
Proxmox is ${RED}absent${COLOR_DEBUG} on this host."
else
return_is_proxmox_absent="1"
debug_message "is_proxmox_absent \
Proxmox seems ${RED}present${COLOR_DEBUG} on this host."
fi
return "${return_is_proxmox_absent}"
}
# }}}
is_lxc_container_absent() { # {{{
local_ct_id="${1}"
## By default, the LXC container is absent from the current host
return_is_lxc_container_absent="0"
## Check if the system runs on a PVE kernel
if ! /usr/sbin/pct list -- | grep --quiet "${local_ct_id}";
then
return_is_lxc_container_absent="0"
debug_message "is_lxc_container_absent \
The LXC container (${RED}${local_ct_id}${COLOR_DEBUG}) is ${RED}absent${COLOR_DEBUG} from this host."
else
return_is_lxc_container_absent="1"
debug_message "is_lxc_container_absent \
The LXC container (${RED}${local_ct_id}${COLOR_DEBUG}) is ${RED}present${COLOR_DEBUG} on this host."
fi
return "${return_is_lxc_container_absent}"
}
# }}}
is_lxc_container_state() { # {{{
local_ct_id="${1}"
local_ct_state="${2}"
## Compare the status of the LXC container with argument
if /usr/sbin/pct status "${local_ct_id}" -- | grep --quiet --word-regexp "${local_ct_state}";
then
return_is_lxc_container_state="0"
debug_message "is_lxc_container_state \
The LXC container (${RED}${local_ct_id}${COLOR_DEBUG}) is in ${RED}${local_ct_state}${COLOR_DEBUG} state."
else
return_is_lxc_container_state="1"
debug_message "is_lxc_container_state \
The LXC container (${RED}${local_ct_id}${COLOR_DEBUG}) is not in ${RED}${local_ct_state}${COLOR_DEBUG} state."
fi
return "${return_is_lxc_container_state}"
}
# }}}
start_lxc_container() { # {{{
local_ct_id="${1}"
## By default, the container is not running
return_start_lxc_container="1"
## Start LXC container state
/usr/sbin/pct start "${local_ct_id}" || exit 1
## Wait a little for the container to start
sleep "${sleep_delay}"
## Verify LXC container status
if is_lxc_container_state "${local_ct_id}" "running";
then
return_start_lxc_container="0"
debug_message "start_lxc_container \
LXC container ${RED}${local_ct_id}${COLOR_DEBUG} is now ${RED}running${COLOR_DEBUG}."
else
return_start_lxc_container="1"
debug_message "start_lxc_container \
LXC container ${RED}${local_ct_id}${COLOR_DEBUG} is still ${RED}stopped${COLOR_DEBUG}."
fi
return "${return_start_lxc_container}"
}
# }}}
stop_lxc_container() { # {{{
local_ct_id="${1}"
## By default, the container is running
return_stop_lxc_container="1"
## Stop LXC container state
/usr/sbin/pct stop "${local_ct_id}" || exit 1
## Wait a little for the container to stop
sleep "${sleep_delay}"
## Verify LXC container status
if is_lxc_container_state "${local_ct_id}" "stopped";
then
return_stop_lxc_container="0"
debug_message "stop_lxc_container \
LXC container ${RED}${local_ct_id}${COLOR_DEBUG} is now ${RED}stopped${COLOR_DEBUG}."
else
return_stop_lxc_container="1"
debug_message "stop_lxc_container \
LXC container ${RED}${local_ct_id}${COLOR_DEBUG} is still ${RED}running${COLOR_DEBUG}."
fi
return "${return_stop_lxc_container}"
}
# }}}
upgrade_container() { # {{{
local_ct_id="${1}"
## Keep output if DEBUG mode is activated
if [ "${DEBUG}" -eq "0" ]; then
/usr/sbin/pct exec "${local_ct_id:-/dev/null}" -- bash -c "wget https://git.ipr.univ-rennes.fr/cellinfo/scripts/raw/master/proxmox/proxmox.template.debian.sh --output-document=/tmp/proxmox.template.debian.sh" || exit 2
/usr/sbin/pct exec "${local_ct_id:-/dev/null}" -- bash -c "chmod +x /tmp/proxmox.template.debian.sh" || exit 2
/usr/sbin/pct exec "${local_ct_id:-/dev/null}" -- bash -c "/tmp/proxmox.template.debian.sh" || exit 2
else
/usr/sbin/pct exec "${local_ct_id:-/dev/null}" -- bash -c "wget --quiet https://git.ipr.univ-rennes.fr/cellinfo/scripts/raw/master/proxmox/proxmox.template.debian.sh --output-document=/tmp/proxmox.template.debian.sh" || exit 2
/usr/sbin/pct exec "${local_ct_id:-/dev/null}" -- bash -c "chmod +x /tmp/proxmox.template.debian.sh" || exit 2
/usr/sbin/pct exec "${local_ct_id:-/dev/null}" -- bash -c "/tmp/proxmox.template.debian.sh" > /dev/null 2>&1 || exit 2
fi
}
# }}}
main() { # {{{
## If Proxmox is not yet available on this host {{{
### Exit
is_proxmox_absent \
&& exit 0
## }}}
## Define all vars
define_vars
## If the LXC container ID is absent from this host {{{
### Exit
is_lxc_container_absent "${ct_id}" \
&& exit 0
## }}}
## If the LXC container ID is already running {{{
### Exit with error message
is_lxc_container_state "${ct_id}" "running" \
&& error_message "LXC container (${ct_id}) is already running. \
Please power it off if you don't have any work in progress." "3"
## }}}
## If the LXC container ID is stopped {{{
### Try to start the container
is_lxc_container_state "${ct_id}" "stopped" \
&& start_lxc_container "${ct_id}"
## }}}
## Try to upgrade the container {{{
### And re-stop the container
### Then exit with success the script
upgrade_container "${ct_id}" \
&& stop_lxc_container "${ct_id}" \
&& exit 0
## }}}
}
# }}}
# Manage arguments # {{{
# This code can't be in a function due to argument management
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
;;
-i|--id ) ## Use given CT ID
## Move to the next argument
shift
## Define ct_id
readonly ct_id="${1}"
;;
-s|--sleep ) ## Use given sleeping delay
## Move to the next argument
shift
## Define sleep_delay
readonly sleep_delay="${1}"
;;
* ) ## 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
# }}}
main
exit 255