[__package_apt] Mark already installed packages as manual
...if they were automatically installed as a dependency of another package. This prevents these pacakges from being uninstalled by `apt-get autoremove`. See: https://github.com/ungleich/cdist/pull/781
This commit is contained in:
parent
e2500248f2
commit
f3494e8a80
3 changed files with 74 additions and 34 deletions
|
@ -1,6 +1,7 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# 2011-2012 Nico Schottelius (nico-cdist at schottelius.org)
|
||||
# 2021 Dennis Camera (cdist at dtnr.ch)
|
||||
#
|
||||
# This file is part of cdist.
|
||||
#
|
||||
|
@ -21,19 +22,48 @@
|
|||
# Retrieve the status of a package - parsed dpkg output
|
||||
#
|
||||
|
||||
if [ -f "$__object/parameter/name" ]; then
|
||||
name="$(cat "$__object/parameter/name")"
|
||||
breify() {
|
||||
# Convert arguments to a POSIX BRE-compatible form, i.e. escape special
|
||||
# characters (incl. delimiter)
|
||||
printf '%s' "$*" | sed -e 's/[].^$*\[]/\\&/g' -e 's:/:\\/:g'
|
||||
}
|
||||
|
||||
|
||||
if test -f "${__object}/parameter/name"
|
||||
then
|
||||
name=$(cat "${__object:?}/parameter/name")
|
||||
else
|
||||
name="$__object_id"
|
||||
name=${__object_id:?}
|
||||
fi
|
||||
|
||||
# Except dpkg failing, if package is not known / installed
|
||||
packages="$(apt-cache showpkg "$name" | sed -e "1,/Reverse Provides:/d" | cut -d ' ' -f 1) $name"
|
||||
for p in $packages; do
|
||||
if dpkg -s "$p" 2>/dev/null | grep --quiet "^Status: install ok installed$" ; then
|
||||
version=$(dpkg -s "$p" 2>/dev/null | grep "^Version:" | cut -d ' ' -f 2)
|
||||
echo "present $p $version"
|
||||
exit 0
|
||||
fi
|
||||
state_dir=$(apt-config dump | sed -n -e 's/^Dir::State *"\(.*\)";$/\/\1/p')
|
||||
extended_states_file=${state_dir%/}/extended_states
|
||||
|
||||
# if $name is e.g. editor, check if any editor is installed instead
|
||||
rprovides=$(apt-cache showpkg "${name}" | sed -e '1,/^Reverse Provides:/d' -e 's/ .*$//')
|
||||
|
||||
for pkg in ${name} ${rprovides}
|
||||
do
|
||||
if dpkg -s "${pkg}" 2>/dev/null | grep -qxF 'Status: install ok installed'
|
||||
then
|
||||
version=$(dpkg -s "${pkg}" 2>/dev/null | sed -n -e 's/^Version: *//p')
|
||||
|
||||
if test -f "${extended_states_file}"
|
||||
then
|
||||
# On Debian >= 5 check if the package is auto installed
|
||||
|
||||
# NOTE: instead of using apt-mark(8) parse the extended_states file
|
||||
# directly. apt-mark is sloow and didn't have a stable
|
||||
# interface in older Debian versions.
|
||||
is_auto=$(sed -n -e '/^Package: '$(breify "${name}")'$/,/^$/!d' -e 's/^Auto-Installed: *//p' "${extended_states_file}")
|
||||
fi
|
||||
|
||||
# NOTE: older versions don't have apt-mark -> all packages are manual
|
||||
auto_word=$(test $((is_auto)) -ne 0 && echo auto || echo manual)
|
||||
|
||||
echo "present ${auto_word} ${pkg} ${version}"
|
||||
exit 0
|
||||
fi
|
||||
done
|
||||
|
||||
echo absent
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#!/bin/sh -e
|
||||
#
|
||||
# 2011-2013 Nico Schottelius (nico-cdist at schottelius.org)
|
||||
# 2021 Dennis Camera (cdist at dtnr.ch)
|
||||
#
|
||||
# This file is part of cdist.
|
||||
#
|
||||
|
@ -56,31 +57,36 @@ else
|
|||
fi
|
||||
|
||||
|
||||
# FIXME: use grep directly, state is a list, not a line!
|
||||
state_is="$(cat "$__object/explorer/state")"
|
||||
case "$state_is" in
|
||||
present*)
|
||||
name="$(echo "$state_is" | cut -d ' ' -f 2)"
|
||||
version_is="$(echo "$state_is" | cut -d ' ' -f 3)"
|
||||
state_is="present"
|
||||
;;
|
||||
*)
|
||||
version_is=""
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ "$state_is" = "$state_should" ]; then
|
||||
if [ -z "$version" ] || [ "$version" = "$version_is" ]; then
|
||||
exit 0;
|
||||
fi
|
||||
fi
|
||||
read -r state_is auto_state name version_is <"${__object:?}/explorer/state"
|
||||
|
||||
# Hint if we need to avoid questions at some point:
|
||||
# DEBIAN_PRIORITY=critical can reduce the number of questions
|
||||
aptget="DEBIAN_FRONTEND=noninteractive apt-get --quiet --yes -o Dpkg::Options::=\"--force-confdef\" -o Dpkg::Options::=\"--force-confold\""
|
||||
|
||||
case "$state_should" in
|
||||
case ${state_should}
|
||||
in
|
||||
present)
|
||||
if test "${state_is}" = 'present'
|
||||
then
|
||||
if test -z "${version}" || test "${version}" = "${version_is}"
|
||||
then
|
||||
if test "${auto_state}" = 'auto'
|
||||
then
|
||||
# package is installed, but marked auto -> mark it manual so
|
||||
# that it doesn't get removed by apt-get autoremove.
|
||||
|
||||
echo 'head -n1 "$(command -v apt-mark)" | grep -qvF python \'
|
||||
# new implementation (Debian >= 7)
|
||||
echo "&& apt-mark manual '${name}' \\"
|
||||
# old Python implementation (Debian 5-7)
|
||||
echo "|| apt-mark unmarkauto '${name}'"
|
||||
# NOTE: older versions don't need to be supported because
|
||||
# they will always be manual
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
# There are special arguments to apt(8) to prevent aborts if apt woudn't been
|
||||
# updated after the 19th April 2021 till the bullseye release. The additional
|
||||
# arguments acknoledge the happend suite change (the apt(8) update does the
|
||||
|
@ -104,12 +110,15 @@ EOF
|
|||
if [ -n "$version" ]; then
|
||||
name="${name}=${version}"
|
||||
fi
|
||||
echo "$aptget $recommendsparam install $target_release '$name'"
|
||||
echo "installed" >> "$__messages_out"
|
||||
|
||||
echo "${aptget} ${recommendsparam} install ${target_release} '${name}'"
|
||||
echo 'installed' >>"${__messages_out:?}"
|
||||
;;
|
||||
absent)
|
||||
echo "$aptget remove $purgeparam '$name'"
|
||||
echo "removed" >> "$__messages_out"
|
||||
test "${state_is}" != 'absent' || exit 0
|
||||
|
||||
echo "${aptget} remove ${purgeparam} '${name}'"
|
||||
echo 'removed' >>"${__messages_out:?}"
|
||||
;;
|
||||
*)
|
||||
echo "Unknown state: $state_should" >&2
|
||||
|
|
|
@ -11,6 +11,7 @@ next:
|
|||
* Type __package_apt: Fix complaint about suite change (Matthias Stecher)
|
||||
* Type __debconf_set_selections: Fix bug where --file was unsupported (Evilham)
|
||||
* Types __letsencrypt_cert, __grafana_dashboard: Improve bullseye support (Evilham)
|
||||
* Type __package_apt: Mark already installed packages as manual (Dennis Camera)
|
||||
|
||||
6.9.8: 2021-08-24
|
||||
* Type __rsync: Rewrite (Ander Punnar)
|
||||
|
|
Loading…
Reference in a new issue