From 036e65fffca6c06a463b0590463f4b019619fc14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gardais=20J=C3=A9r=C3=A9my?= Date: Wed, 30 Jun 2021 16:13:57 +0200 Subject: [PATCH] reprepro: Script to auto import .deb files from a directory --- app/reprepro.import.sh | 302 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 302 insertions(+) create mode 100755 app/reprepro.import.sh diff --git a/app/reprepro.import.sh b/app/reprepro.import.sh new file mode 100755 index 0000000..6255ab9 --- /dev/null +++ b/app/reprepro.import.sh @@ -0,0 +1,302 @@ +#!/bin/sh + +# Vars {{{ +readonly PROGNAME=$(basename "${0}") +readonly PROGDIR=$(readlink -m $(dirname "${0}")) +readonly ARGS="${*}" +readonly NBARGS="${#}" +## Test if DEBUG is already defined (by parent script,…) +[ -z "${DEBUG}" ] && DEBUG=1 + +## 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|-q|-r] [hostname] + +Try to import all .deb files from a given directory to Reprepro. + +EXAMPLES : + - Import .deb files from default directory (/tmp) + ${PROGNAME} + + - Import .deb files from a specific directory + ${PROGNAME} --dir /var/backups/my.deb.files/ + + - Import .deb files to Stretch and Buster releases + ${PROGNAME} --release "stretch buster" + +OPTIONS : + -d,--dir,--directory + Specify the directory to parse for .deb files (default: /tmp). + + --debug + Enable debug messages. + + -h,--help + Print this help message. + + -r,--release + Set the release(s) for which the packages should be added separated + by whitespaces (default: "buster bullseye"). + +EOF + +} +# }}} +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}" + + return 0 +} +# }}} +error_message() { # {{{ + + local_error_message="${1}" + local_error_code="${2}" + + ## Print message if DEBUG is enable (=0) + [ "${DEBUG}" -eq "0" ] && printf '%b\n' "ERROR − ${PROGNAME} : ${RED}${local_error_message}${RESET}" + + exit "${local_error_code:=66}" +} +# }}} +define_vars() { # {{{ + + ### If reprepro_dir wasn't defined (argument,...) {{{ + if [ -z "${reprepro_dir}" ]; then + ## Use /tmp as default value + reprepro_dir="/tmp" + fi + ### }}} + + ### If release_list wasn't defined (argument,...) {{{ + if [ -z "${release_list}" ]; then + ## Use current stable (buster) and testing release (bullseye) as default value + release_list="buster bullseye" + fi + ### }}} + + ### If packages_list_file wasn't defined (argument,...) {{{ + if [ -z "${packages_list_file}" ]; then + ## Store it in /tmp + packages_list_file="/tmp/${PROGNAME}.packages.list" + fi + ### }}} + +} +# }}} +is_directory_absent() { # {{{ + + local_directory="${1}" + + ## Directory doesn't exist by default + return_is_directory_absent="0" + + ### Check if the directory is absent from the system + if [ ! -d "${local_directory}" ]; then + return_is_directory_absent="0" + debug_message "is_directory_absent − \ +The directory ${RED}${local_directory}${COLOR_DEBUG} doesn't exists." + else + return_is_directory_absent="1" + debug_message "is_directory_absent − \ +The directory ${RED}${local_directory}${COLOR_DEBUG} exists." + fi + + return "${return_is_directory_absent}" + +} +# }}} +is_file_empty() { # {{{ + + local_file="${1}" + + ## File is empty by default + return_is_file_empty="0" + + ### Check if the file is empty + if [ ! -s "${local_file}" ]; then + return_is_file_empty="0" + debug_message "is_file_empty − \ +The file ${RED}${local_file}${COLOR_DEBUG} is empty or doesn't exists." + else + return_is_file_empty="1" + debug_message "is_file_empty − \ +The file ${RED}${local_file}${COLOR_DEBUG} exists and has a size greater than zero." + fi + + return "${return_is_file_empty}" + +} +# }}} +is_file_not_empty() { # {{{ + + local_file="${1}" + + ## File is empty by default + return_is_file_not_empty="1" + + ### Check if file exists and has a size greater than zero + if [ -s "${local_file}" ]; then + return_is_file_not_empty="0" + debug_message "is_file_not_empty − \ +The file ${RED}${local_file}${COLOR_DEBUG} exists and has a size greater than zero." + else + return_is_file_empty="1" + debug_message "is_file_not_empty − \ +The file ${RED}${local_file}${COLOR_DEBUG} is empty or doesn't exists." + fi + + return "${return_is_file_not_empty}" + +} +# }}} +main() { # {{{ + + ## Define all vars according the selected options + define_vars + + ## If the given directory doesn't exists {{{ + ### Exit with error + is_directory_absent "${reprepro_dir}" \ + && error_message "Please verify the directory ${reprepro_dir}." 3 + ## }}} + + ## Get the list of .deb files to manage {{{ + rm -f -- "${packages_list_file}" + debug_message "main − \ +Get the list of .deb files to manage from ${reprepro_dir} directory and store it to ${packages_list_file} file." + find "${reprepro_dir}" -maxdepth 1 -type f -iname "*.deb" > "${packages_list_file}" + ## }}} + + ## If the list of .deb files to manage is empty {{{ + ### Exit + is_file_empty "${packages_list_file}" \ + && exit 0 + ## }}} + + ## For each package in the list {{{ + while IFS= read -r package; do + ### Test if the package size is greater than zero + if is_file_not_empty "${package}" ; then + debug_message "while_package − \ +Manage ${package} file." + + ### For each release {{{ + for release in ${release_list}; do + debug_message "for_release − \ + Add it to ${release} release." + #### Add the package with reprepro for this release + #### Or exit with an error message and code + reprepro -b /var/lib/reprepro includedeb "${release:=/dev/null}" "${package:=/dev/null}" \ + || error_message "Error when adding ${package} to ${release}." 4 + done + ### }}} + ### Then finally remove the package {{{ + debug_message "while_package − \ +Remove ${package} file." + #rm -f -- "${package}" + ### }}} + else + ### If package is empty or doesn't exists, just skip it {{{ + debug_message "while_package − \ +Skip ${package} file." + ### }}} + fi + done < "${packages_list_file}" + ## }}} + + ## Regenerates index files for the managed codenames {{{ + for release in ${release_list}; do + debug_message "for_release2 − \ +Regenerate index files for ${release} codename." + reprepro -b /var/lib/reprepro export "${release:=/dev/null}" \ + || error_message "Error when export index files for ${release} codename." 5 + done + ## }}} + +} +# }}} + +# Manage arguments # {{{ +# This code can't be in a function due to arguments + +if [ ! "${NBARGS}" -eq "0" ]; then + + ## If the first argument is not an option + if ! printf -- '%s' "${1}" | grep -q -E -- "^-+"; + then + usage + error_message "Unknown argument (${1}), check the help." 2 + fi + + manage_arg="0" + + # Parse all options (start with a "-") one by one + while printf -- '%s' "${1}" | grep -q -E -- "^-+"; do + + case "${1}" in + -d|--dir|--directory ) ## Set directory + ## Move to the next argument + shift + ## Override previous definition of reprepro_dir + reprepro_dir="${1}" + ;; + --debug ) ## debug + DEBUG=0 + ;; + -h|--help ) ## help + usage + ## Exit after help informations + exit 0 + ;; + -r|--release ) ## Set release list + ## Move to the next argument + shift + ## Override previous definition of release_list + release_list="${1}" + ;; + -- ) ## End of options list + ## End the while loop + break + ;; + * ) ## 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 0