flatcar-scripts/pkg_auto/impl/cleanups.sh
Krzesimir Nowak 4c5e550055 pkg-auto: Add package automation scripts
This adds some scripts I have been using for over a year to deal with
the weekly package updates.

It comes with a `README.md` which describes a workflow similar to my
own.

The `sync_packages.sh` and `update_packages.sh` scripts are currently
not used anywhere. The idea behind them was to use them for Github
Action, but that will come as a follow-up PR.
2024-11-27 16:00:57 +01:00

154 lines
3.6 KiB
Bash

#!/bin/bash
#
# Cleanups
#
# This is basically a command stack to be executed in some deferred
# time. So last command added will be the first to be executed at
# cleanup time.
#
# Cleanups are implemented through two functions, setup_cleanups and
# add_cleanup, prefixed with _${type}_. So for type "foo" the
# functions would be _foo_setup_cleanups and _foo_add_cleanup.
#
# setup_cleanup may take some extra parameters that are specific to
# the type. For example file type takes a path where the commands will
# be stored.
#
# add_cleanup takes one or more command to add to the cleanup stack.
#
if [[ -z ${__CLEANUPS_SH_INCLUDED__:-} ]]; then
__CLEANUPS_SH_INCLUDED__=x
source "$(dirname "${BASH_SOURCE[0]}")/util.sh"
# Sets up cleanup stack of a given type. A type may need some extra
# parameter, which comes after a comma. Possible types are:
#
# - file: requires extra argument about cleanup file location; an
# example could be "file,/path/to/cleanups-file"
# - trap: executed on shell exit
# - ignore: noop
#
# Params:
#
# 1 - type of cleanup
function setup_cleanups() {
local kind
kind=${1}; shift
if [[ -n ${_cleanups_sh_cleanup_kind_:-} ]]; then
fail "cannot set cleanups to '${kind}', they are already set up to '${_cleanups_sh_cleanup_kind_}'"
fi
declare -g _cleanups_sh_cleanup_kind_
_ensure_valid_cleanups_sh_cleanup_kind_ "${kind}"
_cleanups_sh_cleanup_kind_=${kind}
_call_cleanup_func setup_cleanups "${@}"
}
# Adds commands to the cleanup stack.
#
# Params:
#
# @ - commands, one per parameter
function add_cleanup() {
_call_cleanup_func add_cleanup "${@}"
}
#
# Implementation details.
#
# "file" cleanups
function _file_setup_cleanups() {
if [[ ${#} -ne 1 ]]; then
fail 'missing cleanup file location argument for file cleanups'
fi
declare -g _file_cleanup_file
_file_cleanup_file=$(realpath "${1}"); shift
add_cleanup "rm -f ${_file_cleanup_file@Q}"
}
function _file_add_cleanup() {
local fac_cleanup_dir tmpfile
dirname_out "${_file_cleanup_file}" fac_cleanup_dir
tmpfile=$(mktemp -p "${fac_cleanup_dir}")
printf '%s\n' "${@}" >"${tmpfile}"
if [[ -f "${_file_cleanup_file}" ]]; then
cat "${_file_cleanup_file}" >>"${tmpfile}"
fi
mv -f "${tmpfile}" "${_file_cleanup_file}"
}
# "trap" cleanups
function _trap_update_trap() {
# shellcheck disable=SC2064 # using double quotes on purpose instead of single quotes
trap "${_trap_cleanup_actions}" EXIT
}
function _trap_setup_cleanups() {
declare -g _trap_cleanup_actions
_trap_cleanup_actions=':'
declare -g -A _trap_cleanup_snapshots
_trap_cleanup_snapshots=()
_trap_update_trap
}
function _trap_add_cleanup() {
local tac_joined
join_by tac_joined ' ; ' "${@/%/' || :'}"
_trap_cleanup_actions="${tac_joined} ; ${_trap_cleanup_actions}"
_trap_update_trap
}
# "ignore" cleanups
function _ignore_setup_cleanups() {
:
}
function _ignore_add_cleanup() {
:
}
function _ensure_valid_cleanups_sh_cleanup_kind_() {
local kind
kind=${1}; shift
local -a functions=(
setup_cleanups
add_cleanup
)
local func
for func in "${functions[@]/#/_${kind}_}"; do
if ! declare -pF "${func}" >/dev/null 2>/dev/null; then
fail "kind '${kind}' is not a valid cleanup kind, function '${func}' is not defined"
fi
done
}
function _call_cleanup_func() {
local func_name
func_name=${1}; shift
if [[ -z "${_cleanups_sh_cleanup_kind_}" ]]; then
_cleanups_sh_cleanup_kind_='trap'
fi
local func
func="_${_cleanups_sh_cleanup_kind_}_${func_name}"
"${func}" "${@}"
}
fi