From 73f1e7566e94e60ac01aefce172b74396ee500fe Mon Sep 17 00:00:00 2001 From: Robert August Vincent II Date: Wed, 7 Dec 2022 16:36:56 -0500 Subject: [PATCH 1/2] MODULES-10763 Do not report apt-get update as a change --- manifests/update.pp | 16 +++++++-- templates/update_had_no_effect.sh.epp | 51 +++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 templates/update_had_no_effect.sh.epp diff --git a/manifests/update.pp b/manifests/update.pp index a9f2486b16..1b3735eedb 100644 --- a/manifests/update.pp +++ b/manifests/update.pp @@ -56,13 +56,25 @@ } else { $_refresh = true } + # We perform the update in an `unless` clause of the exec, and + # return true only if the package cache file changed. + # This ensures that Puppet does not report a change if the + # update command had no effect. See MODULES-10763 for discussion. + $apt_update_had_no_effect = epp( + 'apt/update_had_no_effect.sh.epp', + 'provider' => $apt::provider, + 'timeout' => $apt::_update['timeout'], + 'tries' => $apt::_update['tries'], + ) exec { 'apt_update': - command => "${apt::provider} update", + command => "echo ${apt::provider} successfully updated the package cache.", loglevel => $apt::_update['loglevel'], - logoutput => 'on_failure', + logoutput => true, + provider => shell, refreshonly => $_refresh, timeout => $apt::_update['timeout'], tries => $apt::_update['tries'], try_sleep => 1, + unless => $apt_update_had_no_effect, } } diff --git a/templates/update_had_no_effect.sh.epp b/templates/update_had_no_effect.sh.epp new file mode 100644 index 0000000000..59790f6928 --- /dev/null +++ b/templates/update_had_no_effect.sh.epp @@ -0,0 +1,51 @@ +<%- | + String $provider = 'apt', + Integer $timeout = 300, + Integer $tries = 1, +| -%> +export PATH=/usr/bin:/bin:/usr/sbin:/sbin +<%# Since `mktemp` might not be available, we choose a reasonable default. -%> +TMPFILE="$(mktemp)" || TMPFILE=/tmp/.puppetlabs.apt.update_had_no_effect.sh +<%# Try to prevent command injection by truncating immediately before using. -%> +cat /dev/null > "$TMPFILE" +<%# Retrieve the configured apt-cache directory. -%> +apt-config shell DIR Dir::Cache > "$TMPFILE" && . "$TMPFILE" +<%# Set a reasonable default in case `apt-config shell` didn't work. -%> +[ "$DIR" ] || DIR='var/cache/apt' +<%# Early exit if the cache directory doesn't exist. -%> +cd "/$DIR" || exit 0 +<%# Try to prevent command injection by truncating immediately before using. -%> +cat /dev/null > "$TMPFILE" +<%# Retrieve the configured cache filename. -%> +apt-config shell CUR DIR::Cache::pkgcache >"$TMPFILE" && . "$TMPFILE" +<%# Set a reasonable default in case `apt-config shell` didn't work. -%> +[ "$CUR" ] || CUR=pkgcache.bin +<%# If the cache file doesn't exist, create it as an empty file. -%> +[ -e "$CUR" ] || cat /dev/null > "$CUR" +<%# Copy the cache file contents so we can detect changes. -%> +cat "$CUR" > "$TMPFILE" +<%# Loop for the configured number of tries. -%> +TRIES=<%= $tries %> +while true; do +<%# Use the `timeout` command from GNU coretools if available. -%> + if timeout 1 true; then + timeout <%= $timeout %> <%= $provider %> update && break + else + <%= $provider %> update && break + fi +<%# Exit if the number of configured tries has been reached. -%> + [ $TRIES -le 1 ] && break +<%# Emulate `try_sleep => 1` from the original `exec` resource -%> + sleep 1 +<%# Decrement the loop count -%> + TRIES=$(( TRIES - 1 )) +done +<%# Set the exit code to failure (1) presuming a change occurred. -%> +EXITCODE=1 +<%# Guard against a missing package cache file. -%> +[ -e "$CUR" ] || cat /dev/null > "$CUR" +<%# Set the exit code to success (0) if no change occurred. -%> +cmp "$CUR" "$TMPFILE" && EXITCODE=0 +<%# Clean up -%> +rm -f "$TMPFILE" +exit $EXITCODE From b030a17e9b1968950eeea424979fb62237b2d0c2 Mon Sep 17 00:00:00 2001 From: "Robert A. Vincent II (Bob-Vee)" Date: Wed, 27 Sep 2023 16:40:08 -0400 Subject: [PATCH 2/2] Changes suggested by @kenyon --- manifests/update.pp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/manifests/update.pp b/manifests/update.pp index 1b3735eedb..9a265ac29a 100644 --- a/manifests/update.pp +++ b/manifests/update.pp @@ -61,10 +61,12 @@ # This ensures that Puppet does not report a change if the # update command had no effect. See MODULES-10763 for discussion. $apt_update_had_no_effect = epp( - 'apt/update_had_no_effect.sh.epp', - 'provider' => $apt::provider, - 'timeout' => $apt::_update['timeout'], - 'tries' => $apt::_update['tries'], + "${module_name}/update_had_no_effect.sh.epp", + { + 'provider' => $apt::provider, + 'timeout' => $apt::_update['timeout'], + 'tries' => $apt::_update['tries'], + } ) exec { 'apt_update': command => "echo ${apt::provider} successfully updated the package cache.",