diff --git a/dist/rpm/openQA.spec b/dist/rpm/openQA.spec index 1af37ecb2c5..fee67b41dc1 100644 --- a/dist/rpm/openQA.spec +++ b/dist/rpm/openQA.spec @@ -694,6 +694,7 @@ fi %{_localstatedir}/lib/openqa/script %{_localstatedir}/lib/openqa/tests %{_datadir}/openqa/script/openqa-check-devel-repo +%{_datadir}/openqa/script/openqa-clean-repo-cache %{_unitdir}/openqa-minion-restart.service %{_unitdir}/openqa-minion-restart.path diff --git a/docs/Installing.asciidoc b/docs/Installing.asciidoc index 4eb99814613..899e3452773 100644 --- a/docs/Installing.asciidoc +++ b/docs/Installing.asciidoc @@ -1234,7 +1234,9 @@ This triggers a nightly system upgrade which first looks into configured openQA repositories for stable packages, then conducts the upgrade and schedules reboots during the configured reboot maintenance windows using `rebootmgr`. As an alternative to the systemd timer the script -`/usr/share/openqa/script/openqa-auto-update` can be called when desired. +`/usr/share/openqa/script/openqa-auto-update` can be called when desired. The +script also supports cache cleanup preserving a certain number of versions per +package. Check its helptext for details. The distribution package `openQA-continuous-update` can be used to continuously upgrade the system. It will frequently check whether `devel:openQA` contains diff --git a/script/openqa-auto-update b/script/openqa-auto-update index 5efa2d3872c..c30e4f36ef4 100755 --- a/script/openqa-auto-update +++ b/script/openqa-auto-update @@ -2,11 +2,29 @@ set -e set -o pipefail +keep=${OPENQA_PACKAGE_CACHE_RETENTION_KEEP:-10} +min_mtime=${OPENQA_PACKAGE_CACHE_RETENTION_MIN_MTIME:-100} +glob=${OPENQA_PACKAGE_CACHE_REPO_GLOB:-*devel*openQA*} usage() { cat << EOF Usage: openqa-auto-update Trigger automatic system upgrade and reboot if devel:openQA packages are stable +Set OPENQA_PACKAGE_CACHE_RETENTION to also clean the zypper cache from packages +of the openQA development repository. This is useful in conjunction with the +zypper repository setting "keeppackages=1" to allow for a more fine-tuned +descicion on what packages to keep. This cleanup is influenced by further +environment variables: + ZYPPER_PACKAGES_CACHE_DIR: the zypper cache dir in case a non-standard + location is used + OPENQA_PACKAGE_CACHE_RETENTION_KEEP: the number of versions of the same + package to keep (default: $keep) + OPENQA_PACKAGE_CACHE_RETENTION_MIN_MTIME: the minimum age of packages in days + to be considered (default: $min_mtime) + OPENQA_PACKAGE_CACHE_REPO_GLOB: the glob to find relevant packages + (default: $glob) +Checkout "openqa-clean-repo-cache --help" for details. + Options: -h, --help display this help EOF @@ -30,5 +48,11 @@ done # call ref independently of dup to avoid unintended mass-removals in case ref fails (see poo#150845) zypper -n ref zypper -n --no-refresh dup --replacefiles --auto-agree-with-licenses --download-in-advance + +if [[ $OPENQA_PACKAGE_CACHE_RETENTION ]]; then + echo 'Cleaning repository cache' + "$(dirname "${BASH_SOURCE[0]}")"/openqa-clean-repo-cache --remove --keep "$keep" --min-mtime "$min_mtime" --glob "$glob" +fi + # shellcheck disable=SC2015 needs-restarting --reboothint > /dev/null || (command -v rebootmgrctl > /dev/null && rebootmgrctl reboot || :) diff --git a/script/openqa-clean-repo-cache b/script/openqa-clean-repo-cache new file mode 100755 index 00000000000..2e06cf6e971 --- /dev/null +++ b/script/openqa-clean-repo-cache @@ -0,0 +1,81 @@ +#!/bin/bash +set -e +set -o pipefail + +# define defaults for CLI arguments +dryrun='' remove='' keep=3 min_mtime='' glob='' +cache_dir=${ZYPPER_PACKAGES_CACHE_DIR:-/var/cache/zypp/packages} + +# parse CLI arguments +usage() { + cat << EOF +Cleans packages from the zypper cache directory. + +This script can be automatically invoked via openqa-auto-update by setting the +environment variable OPENQA_PACKAGE_CACHE_RETENTION. + +Usage: openqa-clean-repo-cache [options] + +Operations: + -d, --dryrun display what files are considered/kept/removed + -r, --remove remove files matching the criteria specified via options + -h, --help display this help + + Options: + -h, --help display this help + -k, --keep the number of versions to keep per package (default: $keep) + --min-mtime keep packages with an mtime that is not older than the + specified number of days, even if this means keeping more + than specified through the '--keep' option + -c, --cache-dir specifies the zypper cache directory + (default: $cache_dir) + -g, --glob specifies the glob used to filter relevant repos/packages +EOF + exit "$1" +} +opts=$(getopt -o drhk:c:g: --long dryrun,remove,help,keep:,min-mtime:,cache-dir:,glob: -n "$0" -- "$@") || usage 1 +eval set -- "$opts" +while true; do + case "$1" in + -d | --dryrun) dryrun=1; shift ;; + -r | --remove) remove=1; shift ;; + -h | --help) usage 0 ;; + -k | --keep) keep=$2; shift 2 ;; + --min-mtime) min_mtime=$2; shift 2 ;; + -c | --cache-dir) cache_dir=$2; shift 2 ;; + -g | --glob) glob=$2; shift 2 ;; + --) shift; break ;; + *) shift; break ;; + esac +done + +# make commands for on specified operation +[[ $dryrun && $remove ]] && echo 'Specify either --dryrun OR --remove.' && exit 1 +if [[ $dryrun ]]; then + remove_cmd=(echo 'remove') keep_cmd=(echo 'keep ') +elif [[ $remove ]]; then + remove_cmd=(rm --verbose --force) keep_cmd=() +else + echo 'No operation specified.' && exit 1 +fi + +# find relevant packages, sort them so newest are first +IFS=$'\n' +find_cmd=(find "$cache_dir" -type f -name '*.rpm') +[[ $glob ]] && find_cmd+=(-ipath "$glob") +[[ $min_mtime ]] && find_cmd+=(-mtime "+$min_mtime") +# shellcheck disable=SC2207 +package_files=($("${find_cmd[@]}" | sort --reverse --version-sort)) +previous_package_name='' package_count=0 + +# run commands for relevant packages considering specified number of versions to keep +for package_file in "${package_files[@]}"; do + package_name=$(rpm -q --qf "%{NAME}\n" "$package_file") + [[ $package_name != "$previous_package_name" ]] && previous_package_name=$package_name package_count=0 + package_count=$((package_count + 1)) + if [[ $package_count -gt "$keep" ]]; then + "${remove_cmd[@]}" "$package_file" + elif [[ ${#keep_cmd[@]} -gt 0 ]]; then + "${keep_cmd[@]}" "$package_file" + fi +done