forked from ungleich-public/cdist
134 lines
4.8 KiB
Bash
Executable File
134 lines
4.8 KiB
Bash
Executable File
#!/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.
|
|
#
|
|
# cdist is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# cdist is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
|
|
#
|
|
#
|
|
# Manage packages on Debian and co.
|
|
#
|
|
|
|
if [ -f "$__object/parameter/name" ]; then
|
|
name="$(cat "$__object/parameter/name")"
|
|
else
|
|
name="$__object_id"
|
|
fi
|
|
|
|
state_should=$(cat "${__object:?}/parameter/state")
|
|
version_should=$(cat "${__object:?}/parameter/version" 2>/dev/null) || true
|
|
|
|
if [ -f "$__object/parameter/target-release" ]; then
|
|
target_release="--target-release $(cat "$__object/parameter/target-release")"
|
|
else
|
|
target_release=""
|
|
fi
|
|
|
|
if [ -f "$__object/parameter/install-recommends" ]; then
|
|
# required if __apt_norecommends is used
|
|
recommendsparam="-o APT::Install-Recommends=1"
|
|
else
|
|
recommendsparam="-o APT::Install-Recommends=0"
|
|
fi
|
|
|
|
if [ -f "$__object/parameter/purge-if-absent" ]; then
|
|
purgeparam="--purge"
|
|
else
|
|
purgeparam=""
|
|
fi
|
|
|
|
|
|
read -r state_is auto_state name_is 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
|
|
present)
|
|
if test -n "${version_should}" -a "${version_should}" != "${version_is}"
|
|
then
|
|
# other version should be installed
|
|
name="${name}=${version_should}"
|
|
aptget="${aptget:?} -o APT::Get::allow-downgrades=true"
|
|
elif test "${state_is}" = 'present'
|
|
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.
|
|
|
|
# NOTE: There are two implementations of apt-mark(8) with a
|
|
# different API. Although the new implementation (C++) still
|
|
# supports the API of the old implementation (Python), it is
|
|
# marked as deprecated:
|
|
# https://salsa.debian.org/apt-team/apt/-/blob/0.8.15/cmdline/apt-mark.cc#L105
|
|
#
|
|
# Debian < 5 (without apt-mark) don't need to be supported,
|
|
# because the state explorer will report all packages as manual
|
|
# for those.
|
|
echo 'if ! head -n1 "$(command -v apt-mark)" | grep -qF python'
|
|
|
|
# new C++ implementation (Debian >= 7)
|
|
echo "then apt-mark manual '${name_is}' >/dev/null"
|
|
|
|
# old Python implementation (Debian 5-6)
|
|
echo "else apt-mark unmarkauto '${name_is}'"
|
|
|
|
echo 'fi'
|
|
fi
|
|
|
|
# package already installed -> exit
|
|
exit 0
|
|
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
|
|
# same by itself).
|
|
#
|
|
# Using '-o $config' instead of the --allow-releaseinfo-change-* parameter
|
|
# allows backward compatablility to pre-buster Debian versions.
|
|
#
|
|
# See more: ticket #861
|
|
# https://code.ungleich.ch/ungleich-public/cdist/-/issues/861
|
|
apt_opts="-o Acquire::AllowReleaseInfoChange::Suite=true -o Acquire::AllowReleaseInfoChange::Version=true"
|
|
|
|
# following is bit ugly, but important hack.
|
|
# due to how cdist config run works, there isn't
|
|
# currently better way to do it :(
|
|
cat << EOF
|
|
if [ ! -f /var/cache/apt/pkgcache.bin ] || [ "\$( stat --format %Y /var/cache/apt/pkgcache.bin )" -lt "\$( date +%s -d '-1 day' )" ]
|
|
then echo apt-get $apt_opts update > /dev/null 2>&1 || true
|
|
fi
|
|
EOF
|
|
|
|
echo "${aptget} ${recommendsparam} install ${target_release} '${name}'"
|
|
echo 'installed' >>"${__messages_out:?}"
|
|
;;
|
|
absent)
|
|
test "${state_is}" != 'absent' || exit 0
|
|
|
|
echo "${aptget} remove ${purgeparam} '${name_is}'"
|
|
echo 'removed' >>"${__messages_out:?}"
|
|
;;
|
|
*)
|
|
echo "Unknown state: $state_should" >&2
|
|
exit 1
|
|
;;
|
|
esac
|