diff --git a/github/check.owncloud.update.sh b/github/check.owncloud.update.sh new file mode 100755 index 0000000..3ddf490 --- /dev/null +++ b/github/check.owncloud.update.sh @@ -0,0 +1,348 @@ +#!/bin/sh +# +# Purpose {{{ +## Create a temp file (to monitor) if an upgrade is available for Owncloud Core +## project on Github or one of it's application. +# 1. Get current version from APT repo (by default). +# 1.b Or use version from version.php file (with --file-mode option). +# 2. Get latest version from github repository. +# 3. Compare current and new versions. +# 4. … +# 5. Create a temp file (to monitor) if an upgrade is available. +# +# 2023-03-04 +# }}} +# How-to use {{{ +## 1. Needs releasetags script, in the same directory +## cf. https://git.ipr.univ-rennes.fr/cellinfo/scripts/src/master/github/releasetags +# wget https://git.ipr.univ-rennes.fr/cellinfo/scripts/raw/master/github/releasetags +## 2. Create a cron job, eg : +#00 20 * * * root /opt/repos/ipr.scripts/github/check.owncloud.update.sh +## 2-1 Create a cron job to compare the current version from version.php file (default to: /var/www/owncloud/version.php) +#00 20 * * * root /opt/repos/ipr.scripts/github/check.owncloud.update.sh --file-mode +## 2-2 Create a cron job to compare the current version from version.php file on a specific location +#00 20 * * * root /opt/repos/ipr.scripts/github/check.owncloud.update.sh --file /srv/www/owncloud/version.php +## 3. Monitor the temp file : /tmp/.github.owncloud.upgrade +# }}} +# 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 --canonicalize-missing $(dirname "${0}")); readonly PROGDIR +ARGS="${*}"; readonly ARGS +readonly NBARGS="${#}" +[ -z "${DEBUG-}" ] && DEBUG=1 +## Export DEBUG for sub-script +export DEBUG + +## Default values for some vars +readonly PACKAGE_NAME_DEFAULT="owncloud-complete-files" +readonly VERSION_PHP_FILE_DEFAULT="/var/www/owncloud/version.php" +readonly CHECK_MODE_DEFAULT="repository" + +## Colors +readonly PURPLE='\033[1;35m' +readonly RED='\033[0;31m' +readonly RESET='\033[0m' +readonly COLOR_DEBUG="${PURPLE}" +# }}} +usage() { # {{{ + + cat <<- HELP +usage: $PROGNAME [-d|-f|-h|-p|-r] + +Try to compare current version of installed Owncloud with latest version on Github. + +EXAMPLES : + - Default - Check current version from installed package with APT repository (default package name: ${PACKAGE_NAME_DEFAULT}) + ${PROGNAME} + ${PROGNAME} --repo-mode + + - Check current version from a specific .deb package name + ${PROGNAME} --package owncloud-server + + - Check current version from Owncloud's version.php file (default location: ${VERSION_PHP_FILE_DEFAULT}) + ${PROGNAME} --file-mode + + - Check current version from Owncloud's version.php file on specific location (auto set file-mode) + ${PROGNAME} --file /srv/www/owncloud/version.php + +OPTIONS : + -d,--debug + Enable debug messages. + + --file-mode + Get current Owncloud's version from version.php file. + + -f,--file + Define version.php file location. + Default: ${VERSION_PHP_FILE_DEFAULT} + + -h,--help + Print this help message. + + -p,--package + Define the .deb package name to parse. + Default: ${PACKAGE_NAME_DEFAULT} + + -r,--repo-mode,--repo,--repository + (default) Get current Owncloud's version of .deb package version from APT repository. +HELP +} +# }}} +debug_message() { # {{{ + + local_debug_message="${1}" + + ## Print message if DEBUG is enable (=0) + [ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6b\e[m\n' "DEBUG − ${PROGNAME} : ${local_debug_message}" + + unset local_debug_message + + return 0 +} +# }}} +error_message() { # {{{ + + local_error_message="${1}" + local_error_code="${2}" + + ## Print message + printf '%b\n' "ERROR − ${PROGNAME} : ${RED}${local_error_message}${RESET}" >&2 + + unset local_error_message + + exit "${local_error_code:=66}" +} +# }}} +is_var_empty() { # {{{ + + local_var_empty="${1}" + debug_prefix="${2:-}" + ## Return False by default + return_var_empty="1" + + debug_message "${debug_prefix}is_var_empty − Test var value (${1})." + [ -z "${local_var_empty}" ] && return_var_empty="0" + + 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/owncloud/core" \ + && 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 from application repository {{{ + new_version=$("${PROGDIR}"/releasetags "${repo_url}" | grep -vE -- '(dev|rc)' | head -n1 | sed 's/v//g') + if is_var_empty "${new_version-}" "|| "; then + error_message "define_vars − Invalid value for ${package_name} new version (${new_version})." 1 + else + debug_message "| define_vars − Get value (${RED}${new_version}${COLOR_DEBUG}) for new_version variable." + fi + ## }}} + ## 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 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 '/Installed:/ {print $2}' | sed 's/.:\(.*\)-.*/\1/') + ;; + "file" ) ## Check current version from installed .deb file + current_version=$(sed --silent "s/^\$OC_VersionString = '\(.*\)';/\1/p" "${version_php_file}") + ;; + * ) ## 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 + + ## Uncomment variable(s) to simulate different behaviour + #current_version="10.13.2" + #current_version="10.13.2-3+1.1" + #new_version="10.19.2" + + 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 current version is uptodate {{{ + else + 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}" + ### Exit + debug_message "-- Test version END" + debug_message "--- MAIN END" + exit 0 + fi + ## }}} + debug_message "-- Test version END" + + debug_message "--- MAIN END" + + # Exit + 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 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 --quiet --extended-regexp -- "^-+"; + 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 --quiet --extended-regexp -- "^-+"; do + + case "${1}" in + -d|--debug ) ## debug + DEBUG=0 + debug_message "--- Manage argument BEGIN" + ;; + -p|--package ) ## Define package_name + ## Move to the next argument + shift + ## Define var + readonly package_name="${1}" + ;; + -f|--file ) ## Define version_php_file + ## Move to the next argument + shift + ## Define var + readonly version_php_file="${1}" + ## AND set check_mode to file mode + readonly check_mode="file" + ;; + --file-mode ) ## Define check_mode to file mode + ## Define var + readonly check_mode="file" + ;; + -r|--repo-mode|--repo|--repository ) ## Define check_mode to repo mode + ## Define var + readonly check_mode="repo" + ;; + * ) ## unknow option + printf '%b\n' "${RED}Invalid option: ${1}${RESET}" + printf '%b\n' "---" + usage + exit 1 + ;; + esac + + debug_message "| ${RED}${1}${COLOR_DEBUG} option managed." + + ## Move to the next argument + shift + manage_arg=$((manage_arg+1)) + + done + + debug_message "| ${RED}${manage_arg}${COLOR_DEBUG} argument(s) successfully managed." +else + debug_message "| No arguments/options to manage." +fi + + debug_message "--- Manage argument END" +# }}} + +main + +# This should never be reach +exit 255