From 92afb7383039c95e7c867006b4e81b098a4ea9da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gardais=20J=C3=A9r=C3=A9my?= Date: Mon, 26 Jun 2023 14:02:54 +0200 Subject: [PATCH] Now download glpi-agent new package Also get REVISION number from installer script. Current version also get revision number (-1). --- github/check.glpi-agent.update | 338 ++++++++++++++++++++++----------- 1 file changed, 230 insertions(+), 108 deletions(-) diff --git a/github/check.glpi-agent.update b/github/check.glpi-agent.update index 6fe646e..64711ab 100755 --- a/github/check.glpi-agent.update +++ b/github/check.glpi-agent.update @@ -1,10 +1,15 @@ #!/bin/sh +# # Purpose {{{ -## Create a temp file (to monitor) if an upgrade is available for GLPI Agent -## project on Github − https://github.com/glpi-project/glpi-agent/releases -## It's based on .deb package installation to check the current version. -## It can also compare the current available version in APT repositories -## if "--repo" option is given. +# This script will try to get last version of glpi-agent .deb file +# https://github.com/glpi-project/glpi-agent/releases +# 1. Get current version from APT repo (by default). +# 1.b Or use version from manually installed package (with --file option). +# 2. Get latest version from github repository. +# 3. Compare current and new versions. +# 4. Download the .deb file for this new version. +# 5. Create a temp file (to monitor) if an upgrade is available. +# }}} ## How-to use {{{ ### 1. Needs releasetags script, in the same directory ### cf. https://git.ipr.univ-rennes1.fr/cellinfo/scripts/src/master/github/releasetags @@ -17,24 +22,32 @@ # Or enable MAILTO in cronjob and edit the script to print a message. # Or send a mail. # … -## }}} # }}} - +# Flags {{{ +## Exit on error +set -o errexit +## Exit on unset var +### Use "${VARNAME-}" to test a var that may not have been set +set -o nounset +## Pipeline command is treated as failed +### Not available in POSIX sh − https://github.com/koalaman/shellcheck/wiki/SC3040 +#set -o pipefail +## Help with debugging +### Call the script by prefixing it with "TRACE=1 ./script.sh" +if [ "${TRACE-0}" -eq 1 ]; then set -o xtrace; fi +# }}} # Vars {{{ PROGNAME=$(basename "${0}"); readonly PROGNAME -PROGDIR=$(readlink -m $(dirname "${0}")); readonly PROGDIR +PROGDIR=$(readlink --canonicalize-missing $(dirname "${0}")); readonly PROGDIR ARGS="${*}"; readonly ARGS readonly NBARGS="${#}" -[ -z "${DEBUG}" ] && DEBUG=1 +[ -z "${DEBUG-}" ] && DEBUG=1 ## Export DEBUG for sub-script export DEBUG ## Default values for some vars -### Don't use APT repository by default -readonly REPOSITORY_MODE_DEFAULT=1 - -readonly GLPI_AGENT_REPO_URL="https://github.com/glpi-project/glpi-agent" -readonly GLPI_AGENT_NEW_VERSION_FILE="/tmp/.github.glpi-agent.upgrade" +readonly PACKAGE_NAME_DEFAULT="glpi-agent" +readonly CHECK_MODE_DEFAULT="repository" ## Colors readonly PURPLE='\033[1;35m' @@ -45,17 +58,14 @@ readonly COLOR_DEBUG="${PURPLE}" usage() { # {{{ cat <<- HELP -usage: $PROGNAME [-d|-h|-r] +usage: $PROGNAME [-d|-h|-f|-r] -Compare GLPI Agent installed version and latest one. +Try to get last version of ${PACKAGE_NAME_DEFAULT} .deb file. EXAMPLES : - - Compare the current version installed from .deb file + - Check ${PACKAGE_NAME_DEFAULT} version (from APT repository or manually installed file). ${PROGNAME} - - Compare the current version from apt's repository - ${PROGNAME} --repo - OPTIONS : -d,--debug Enable debug messages. @@ -63,10 +73,12 @@ OPTIONS : -h,--help Print this help message. - -r,--repo,--repository - Use GLPI Agent version from APT repository. -HELP + -f,--file,--p,--package + Use manually installed package. + -r,--repo,--repository + Use ${PACKAGE_NAME_DEFAULT} version from APT repository. +HELP } # }}} debug_message() { # {{{ @@ -87,110 +99,212 @@ error_message() { # {{{ local_error_code="${2}" ## Print message - printf '%b\n' "ERROR − ${PROGNAME} : ${RED}${local_error_message}${RESET}" + printf '%b\n' "ERROR − ${PROGNAME} : ${RED}${local_error_message}${RESET}" >&2 unset local_error_message exit "${local_error_code:=66}" } # }}} -define_vars() { # {{{ - - ## If repository_mode wasn't defined (argument) {{{ - if [ -z "${repository_mode}" ]; then - ## Use default value - readonly repository_mode="${REPOSITORY_MODE_DEFAULT}" - fi - # }}} - -} -# }}} is_var_empty() { # {{{ + local_var_empty="${1}" + debug_prefix="${2:-}" ## Return False by default return_var_empty="1" - ## Total number of variables to test - local_total_var="${#}" - loop_count_var_empty="0" + debug_message "${debug_prefix}is_var_empty − Test var value (${1})." + [ -z "${local_var_empty}" ] && return_var_empty="0" - ## While it remains a variable to test - while [ "${local_total_var}" -gt "${loop_count_var_empty}" ]; do - debug_message "is_var_empty − \ -Test var: ${1}." - ### Test if this is empty and set return value to True - [ -z "${1}" ] && return_var_empty="0" - - ### Increase the number of tested variables - loop_count_var_empty=$((loop_count_var_empty+1)) - - ### Shift to the next variable - shift - done - - unset local_total_var - unset loop_count_var_empty + unset debug_prefix + unset local_var_empty return "${return_var_empty}" } # }}} +define_vars() { # {{{ + + debug_message "-- define_vars BEGIN" + ## If repo_url wasn't defined {{{ + is_var_empty "${repo_url-}" "|| " \ + && repo_url="https://github.com/glpi-project/glpi-agent" \ + && debug_message "| define_vars − Use value (${RED}${repo_url}${COLOR_DEBUG}) for repo_url variable." + ## }}} + ## If package_name wasn't defined (argument) {{{ + ## Use default value + is_var_empty "${package_name-}" "|| " \ + && debug_message "| define_vars − Use default value (${RED}${PACKAGE_NAME_DEFAULT}${COLOR_DEBUG}) for package_name variable." \ + && package_name="${PACKAGE_NAME_DEFAULT}" + ## }}} + ## Get new_version_major from application repository {{{ + new_version_major=$("${PROGDIR}"/releasetags "${repo_url}" | grep --invert-match --extended-regexp -- '(dev|rc)' | head --lines=1 | sed 's/v//g') + if is_var_empty "${new_version_major-}" "|| "; then + error_message "define_vars − Invalid value for ${package_name} new version (${new_version_major})." 1 + else + debug_message "| define_vars − Get value (${RED}${new_version_major}${COLOR_DEBUG}) for new_version_major variable." + fi + ## }}} + ## Get new_version_revision from official installer script {{{ + ## Because Github release version don't integer revision number… + ## Download installer script + installer_script_file="/tmp/glpi-agent-${new_version_major}-linux-installer.pl" + installer_script_url="https://github.com/glpi-project/glpi-agent/releases/download/${new_version_major}/glpi-agent-${new_version_major}-linux-installer.pl" + wget --quiet "${installer_script_url}" --output-document="${installer_script_file}" + ## Parse file to find any revision number + new_version_revision=$(grep --text "^my \$DEBREVISION" -- "${installer_script_file}" | cut --delimiter=\" --fields=2) + ## Define new_version according to revision number + if is_var_empty "${new_version_revision-}" "|| "; then + debug_message "| define_vars − No revision for this package." + new_version="${new_version_major}" + else + debug_message "| define_vars − There is a revision (${new_version_revision}) for this package." + new_version="${new_version_major}-${new_version_revision}" + fi + debug_message "| define_vars − Set (${RED}${new_version}${COLOR_DEBUG}) for new_version variable." + ## }}} + ## If new_package_filename wasn't defined {{{ + is_var_empty "${new_package_filename-}" "|| " \ + && new_package_filename="${package_name}_${new_version}_all.deb" \ + && debug_message "| define_vars − Use value (${RED}${new_package_filename}${COLOR_DEBUG}) for new_package_filename variable." + ## }}} + ## If new_package_url wasn't defined {{{ + is_var_empty "${new_package_url-}" "|| " \ + && new_package_url="${repo_url}/releases/download/${new_version_major}/${new_package_filename}" \ + && debug_message "| define_vars − Use value (${RED}${new_package_url}${COLOR_DEBUG}) for new_package_url variable." + ## }}} + ## If new_version_file wasn't defined {{{ + is_var_empty "${new_version_file-}" "|| " \ + && new_version_file="/tmp/.github.${package_name}.upgrade" \ + && debug_message "| define_vars − Use value (${RED}${new_version_file}${COLOR_DEBUG}) for new_version_file variable." + ## }}} + ## If tmp_package_path wasn't defined {{{ + is_var_empty "${tmp_package_path-}" "|| " \ + && tmp_package_path="/tmp/.${new_package_filename}" \ + && debug_message "| define_vars − Use value (${RED}${tmp_package_path}${COLOR_DEBUG}) for tmp_package_path variable." + ## }}} + ## If new_package_path wasn't defined {{{ + is_var_empty "${new_package_path-}" "|| " \ + && new_package_path="/tmp/${new_package_filename}" \ + && debug_message "| define_vars − Use value (${RED}${new_package_path}${COLOR_DEBUG}) for new_package_path variable." + ## }}} + ## If check_mode wasn't defined (argument) {{{ + ## Use default value + is_var_empty "${check_mode-}" "|| " \ + && debug_message "| define_vars − Use default value (${RED}${CHECK_MODE_DEFAULT}${COLOR_DEBUG}) for check_mode variable." \ + && check_mode="${CHECK_MODE_DEFAULT}" + ## }}} + + ## Get current_version according to the check_mode {{{ + case "${check_mode}" in + "repo"|"repository" ) ## Check current version from repository + current_version=$(apt-cache policy -- "${package_name}" | awk '/Candidate:/ {print $2}' | sed 's/.:\(.*\)/\1/') + ;; + "file" ) ## Check current version from installed .deb file + current_version=$(dpkg --list -- "${package_name}" | awk -v pattern="${package_name}" '$0~pattern {print $3}' | sed 's/.:\(.*\)-.*/\1/') + ;; + * ) ## unknow mode + error_message "define_vars − Invalid check mode: ${check_mode}. See help message with -h." 2 + ;; + esac + + ## If current_version is empty + is_var_empty "${current_version}" "|| " \ + && error_message "define_vars − Error with current_version variable (${current_version}) for package (${package_name})." 2 + ## }}} + debug_message "-- define_vars END" +} +# }}} +is_version_greater_than() { # {{{ + + first_value="${1}" + value_to_compare="${2}" + debug_prefix="${3:-}" + + ## Return False by default + return_is_version_greater_than="1" + + debug_message "${debug_prefix}is_version_greater_than − \ +Is first value (${first_value}) greater than the second value (${value_to_compare})." + + if printf '%s\n' "${first_value}" "${value_to_compare}" | sort --check=quiet --version-sort; then + debug_message "${debug_prefix}is_version_greater_than − ${first_value} <= ${value_to_compare} ." + return_is_version_greater_than="1" + else + debug_message "${debug_prefix}is_version_greater_than − ${first_value} > ${value_to_compare} ." + return_is_version_greater_than="0" + fi + + unset first_value + unset value_to_compare + unset debug_prefix + + return "${return_is_version_greater_than}" +} +# }}} main() { # {{{ + debug_message "--- MAIN BEGIN" + ## Define all vars define_vars - ## Get current version from APT repository or from .deb package {{{ + ## Uncomment variable(s) to simulate different behaviour + #current_version="14-1" + #new_version="22-1" - if [ "${repository_mode}" -eq "0" ]; then - debug_message "--- MAIN Check current version from ${RED}APT repositories${COLOR_DEBUG}." - glpi_agent_current_version=$(apt-cache policy glpi-agent \ - | awk '/Candidate:/ {print $2}' \ - | sed 's/.:\(.*\)-.*/\1/') + debug_message "-- Test version BEGIN" + ## If new_version is greater than current_version {{{ + if is_version_greater_than "${new_version}" "${current_version}" "|| "; then + debug_message "| Current version (${current_version}) is older than new one \ +(${new_version})." + ### If it doesn't already exists, download the new package {{{ + if [ ! -f "${new_package_path}" ]; then + debug_message "| Download .deb file from ${package_name} repository on Github to: ${new_package_path} ." + wget --quiet "${new_package_url}" --output-document="${new_package_path}" + fi + ### }}} + ## }}} + ## If current version is uptodate {{{ else - debug_message "--- MAIN Check current version from ${RED}manually installed .deb package${COLOR_DEBUG}." - glpi_agent_current_version=$(dpkg -l glpi-agent \ - | awk '/^ii.*glpi-agent/ {print $3}' \ - | sed 's/.:\(.*\)-.*/\1/') - fi - ## }}} - ## Get latest version from project repository {{{ - ### OR Exit with error message - debug_message "--- MAIN Check latest version from project repository (${RED}${GLPI_AGENT_REPO_URL}${COLOR_DEBUG})." - glpi_agent_latest_version=$("${PROGDIR}/releasetags" "${GLPI_AGENT_REPO_URL}" | head --lines=1 \ - || error_message "Can't get latest GLPI Agent version from repository (${GLPI_AGENT_REPO_URL})." 02 ) - ## }}} - - ## If any of the two variables is empty {{{ - ### OR Exit with error message - is_var_empty "${glpi_agent_current_version}" "${glpi_agent_latest_version}" \ - && error_message "At least one variable is empty (current version : ${glpi_agent_current_version}, latest version : ${glpi_agent_latest_version}) !" 04 - ## }}} - - # Check if the current version is the last one {{{ - ## If the two versions are the same {{{ - if [ "${glpi_agent_current_version}" = "${glpi_agent_latest_version}" ]; then - debug_message "Test version − \ -The current GLPI Agent version (${RED}${glpi_agent_current_version}${COLOR_DEBUG}) is up-to-date." - - ### Ensure to remove any temp file - rm --force -- "${GLPI_AGENT_NEW_VERSION_FILE}" - - exit 0 - ## }}} - ## If the versions are different {{{ - else - debug_message "Test version − \ -Current version (${RED}${glpi_agent_current_version}${COLOR_DEBUG}) and latest one (${RED}${glpi_agent_latest_version}${COLOR_DEBUG}) seems to be different." - - ## Create a temp file to monitor - touch -- "${GLPI_AGENT_NEW_VERSION_FILE}" - debug_message "An upgrade is available for GLPI Agent (current : ${glpi_agent_current_version}) : ${glpi_agent_latest_version}." >> "${GLPI_AGENT_NEW_VERSION_FILE}" - + debug_message "| Current version (${current_version}) seems uptodate \ +or newer than available version (${new_version})." + ### Ensure to remove any temp file and useless .deb files + rm --force -- "${new_version_file}" "${new_package_path}" "${tmp_package_path}" + ### Exit + debug_message "-- Test version END" + debug_message "--- MAIN END" exit 0 fi ## }}} + debug_message "-- Test version END" + + ## Verify downloaded package {{{ + debug_message "-- Verify downloaded package BEGIN" + ## If the downloaded package has a size greater than zero {{{ + if [ -s "${new_package_path}" ]; then + debug_message "| Downloaded package looks good." + ### Create a temp file to monitor + touch -- "${new_version_file}" + printf '\e[1;35m%-6s\e[m\n' "An upgrade is available for ${package_name} terminal (current : ${current_version}) : ${new_version}." >> "${new_version_file}" + ## }}} + ## If the size is null {{{ + else + debug_message "| Empty file, don't need to go further." + ### Ensure to remove the file to monitor + rm --force -- "${new_version_file}" + + ### Keep a record of the downloaded package because as a new release might come soon + mv --force -- "${new_package_path}" "${tmp_package_path}" + fi + ## }}} + debug_message "-- Verify downloaded package END" # }}} + + debug_message "--- MAIN END" + + # Exit + exit 0 } # }}} @@ -201,8 +315,15 @@ if [ ! "${NBARGS}" -eq "0" ]; then manage_arg="0" + ## If the first argument ask for help (h|help|-h|-help|-*h|-*help) {{{ + if printf -- '%s' "${1-}" | grep --quiet --extended-regexp -- "^-*h(elp)?$"; then + usage + exit 0 + fi + ## }}} + ## If the first argument is not an option - if ! printf -- '%s' "${1}" | grep -q -E -- "^-+"; + if ! printf -- '%s' "${1}" | grep --quiet --extended-regexp -- "^-+"; then ## Print help message and exit printf '%b\n' "${RED}Invalid option: ${1}${RESET}" @@ -213,20 +334,20 @@ if [ ! "${NBARGS}" -eq "0" ]; then fi # Parse all options (start with a "-") one by one - while printf -- '%s' "${1}" | grep -q -E -- "^-+"; do + while printf -- '%s' "${1-}" | grep --quiet --extended-regexp -- "^-+"; do case "${1}" in - --debug ) ## debug + -d|--debug ) ## debug DEBUG=0 debug_message "--- Manage argument BEGIN" ;; - -h|--help ) ## help - usage - ## Exit after help informations - exit 0 + -f|--file|--files|-p|--package ) ## Define check_mode to file mode + ## Define var + readonly check_mode="file" ;; - -r|--repo|--repository ) ## Set repository_mode - repository_mode=0 + --repo|--repository ) ## Define check_mode to repo mode + ## Define var + readonly check_mode="repo" ;; * ) ## unknow option printf '%b\n' "${RED}Invalid option: ${1}${RESET}" @@ -254,4 +375,5 @@ fi main +# This should never be reach exit 255