From e79b26a61f790108b90c3625d554f6df4086d616 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Sun, 21 Jun 2020 13:15:38 +0200 Subject: [PATCH] [type/__package_opkg] Also lock execution of code-remote --- .../type/__package_opkg/explorer/pkg_status | 11 ++- cdist/conf/type/__package_opkg/gencode-remote | 94 +++++++++++++------ 2 files changed, 73 insertions(+), 32 deletions(-) diff --git a/cdist/conf/type/__package_opkg/explorer/pkg_status b/cdist/conf/type/__package_opkg/explorer/pkg_status index 1ba88e81..f5a6f098 100755 --- a/cdist/conf/type/__package_opkg/explorer/pkg_status +++ b/cdist/conf/type/__package_opkg/explorer/pkg_status @@ -23,7 +23,9 @@ # Retrieve the status of a package - parses opkg output # -LOCKFILE="${__type_explorer}/cdist_opkg.lock" +__type_path=${__object%%${__object_id}*} + +LOCKFILE="${__type_path}/cdist_opkg.lock" _lock() ( set -o noclobber until echo $$>"${LOCKFILE}" @@ -48,9 +50,10 @@ else fi -# NOTE: We need to lock parallel execution of this explorer because opkg will -# try to acquire the OPKG lock (usually /var/lock/opkg.lock) using lockf(2) for -# every operation. It will not wait for the lock but terminate with an error. +# NOTE: We need to lock parallel execution of type explorers and code-remote +# because opkg will try to acquire the OPKG lock (usually /var/lock/opkg.lock) +# using lockf(2) for every operation. +# It will not wait for the lock but terminate with an error. # This leads to incorrect 'absent notpresent' statuses when parallel execution # is enabled. trap _unlock EXIT diff --git a/cdist/conf/type/__package_opkg/gencode-remote b/cdist/conf/type/__package_opkg/gencode-remote index 269d5f49..ad90dc24 100755 --- a/cdist/conf/type/__package_opkg/gencode-remote +++ b/cdist/conf/type/__package_opkg/gencode-remote @@ -2,6 +2,7 @@ # # 2011,2013 Nico Schottelius (nico-cdist at schottelius.org) # 2012 Giel van Schijndel (giel plus cdist at mortis dot eu) +# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) # # This file is part of cdist. # @@ -19,41 +20,78 @@ # along with cdist. If not, see . # # -# Manage packages on OpenWRT and co. +# Manage packages on OpenWrt, optware, and co. # -if [ -f "$__object/parameter/name" ]; then - name="$(cat "$__object/parameter/name")" +if test -f "${__object}/parameter/name" +then + name=$(cat "${__object}/parameter/name") else - name="$__object_id" + name=$__object_id fi -state_should="$(cat "$__object/parameter/state")" +state_should=$(cat "${__object}/parameter/state") +state_is=$(cat "${__object}/explorer/pkg_status") -state_is="$(cat "$__object/explorer/pkg_status")" -case "$state_is" in - absent*) - present="$(echo "$state_is" | cut -d ' ' -f 2)" - state_is="absent" - ;; +case $state_is +in + (absent*) + presence=$(echo "${state_is}" | cut -d ' ' -f 2) + state_is='absent' + ;; esac -[ "$state_is" = "$state_should" ] && exit 0 +if test "${state_is}" = "${state_should}" +then + exit 0 +fi -case "$state_should" in - present) - if [ "$present" = "notpresent" ]; then - echo "opkg --verbosity=0 update" - fi - echo "opkg --verbosity=0 install '$name'" - echo "installed" >> "$__messages_out" - ;; - absent) - echo "opkg --verbosity=0 remove '$name'" - echo "removed" >> "$__messages_out" - ;; - *) - echo "Unknown state: ${state_should}" >&2 - exit 1 - ;; +cat <<'EOF' +__type_path=${__object%%${__object_id}*} + +LOCKFILE="${__type_path}/cdist_opkg.lock" +_lock() ( + set -o noclobber + until echo $$>"${LOCKFILE}" + do + while test -f "${LOCKFILE}"; do sleep 1; done + done + +) 2>/dev/null +_unlock() { + if test -s "${LOCKFILE}" && test "$(cat "${LOCKFILE}")" = $$ + then + rm "${LOCKFILE}" + fi +} +EOF + +# NOTE: We need to lock parallel execution of code-remote to ensure that it is +# not executed concurrently with a type explorer. +# opkg will try to acquire the OPKG lock (usually /var/lock/opkg.lock) using +# lockf(2) for every operation. +# It will not wait for the lock but terminate with an error leading to an +# incorrect outcome. +echo 'trap _unlock EXIT' +echo '_lock' + +case $state_should +in + (present) + if test "${presence}" = 'notpresent' + then + echo 'opkg --verbosity=0 update' + fi + + printf "opkg --verbosity=0 install '%s'\n" "${name}" + echo 'installed' >>"${__messages_out}" + ;; + (absent) + printf "opkg --verbosity=0 remove '%s'" "${name}" + echo 'removed' >>"${__messages_out}" + ;; + (*) + printf 'Unknown state: %s\n' "${state_should}" >&2 + exit 1 + ;; esac