refactor check, inc, rm subcommands

function extractions
variables extractions
comments
This commit is contained in:
Jérémy Lecour 2020-04-01 18:39:56 +02:00 committed by Jérémy Lecour
parent e7e3683944
commit e9e8a790ba
4 changed files with 215 additions and 78 deletions

View file

@ -38,27 +38,21 @@ fi
read_variable() {
var_name=$1
file=$2
pattern="^\s*${var_name}=-?[0-9]+"
grep --extended-regexp --only-matching "${pattern}" "${file}" | cut -d= -f2
}
check_jail() {
jail=$1
jail_name=$1
jail_path=$(jail_path "${jail_name}")
cur_time=$(date "+%s")
last_conn=$(stat --format=%Y "${JAILDIR}/${jail}/var/log/lastlog")
last_conn=$(stat --format=%Y "${jail_path}/var/log/lastlog")
date_diff=$(( (cur_time - last_conn) / (60*60) ))
if [ -f "${CONFDIR}/${jail}.d/check_policy" ]; then
# canonical configuration file
check_policy_file="${CONFDIR}/${jail}.d/check_policy"
elif [ -f "${JAILDIR}/${jail}/etc/bkctld-check" ]; then
# backward compatible configuration file
check_policy_file="${CONFDIR}/${jail}/etc/bkctld-check"
else
check_policy_file=""
fi
check_policy_file=$(jail_check_policy_file "${jail_name}")
if [ -f "${check_policy_file}" ]; then
local_critical=$(read_variable "CRITICAL" "${check_policy_file}")
@ -73,24 +67,26 @@ check_jail() {
if [ "${local_critical}" -gt "0" ] && [ "${date_diff}" -gt "${local_critical}" ]; then
nb_crit=$((nb_crit + 1))
output="${output}CRITICAL - ${jail} - ${date_diff} hours (critical: ${local_critical})\n"
output="${output}CRITICAL - ${jail_name} - ${date_diff} hours (critical: ${local_critical})\n"
[ "${return}" -le 2 ] && return=2
elif [ "${local_warning}" -gt "0" ] && [ "${date_diff}" -gt "${local_warning}" ]; then
nb_warn=$((nb_warn + 1))
output="${output}WARNING - ${jail} - ${date_diff} hours (warning: ${local_warning})\n"
output="${output}WARNING - ${jail_name} - ${date_diff} hours (warning: ${local_warning})\n"
[ "${return}" -le 1 ] && return=1
else
nb_ok=$((nb_ok + 1))
output="${output}OK - ${jail} - ${date_diff} hours (critical: ${local_critical}, warning: ${local_warning})\n"
output="${output}OK - ${jail_name} - ${date_diff} hours (critical: ${local_critical}, warning: ${local_warning})\n"
fi
}
for jail in $("${LIBDIR}/bkctld-list"); do
if [ -f "${JAILDIR}/${jail}/var/log/lastlog" ]; then
check_jail "${jail}"
for jail_name in $(jails_list); do
jail_path=$(jail_path "${jail_name}")
if [ -f "${jail_path}/var/log/lastlog" ]; then
check_jail "${jail_name}"
else
nb_unkn=$((nb_unkn + 1))
output="${output}UNKNOWN - ${jail} doesn't have lastlog !\n"
output="${output}UNKNOWN - ${jail_name} doesn't have lastlog !\n"
[ "${return}" -le 3 ] && return=3
fi
done

View file

@ -7,32 +7,77 @@
# shellcheck source=./config
LIBDIR="$(dirname $0)" && . "${LIBDIR}/config"
date=$(date +"%Y-%m-%d-%H")
for jail in $("${LIBDIR}/bkctld-list"); do
inc="${INCDIR}/${jail}/${date}"
mkdir -p "${INCDIR}/${jail}"
if [ ! -d "${inc}" ]; then
start=$(date +"%H:%M:%S")
jail_inode=$(stat --format=%i "${JAILDIR}/${jail}")
if [ "$jail_inode" -eq 256 ]; then
/bin/btrfs subvolume snapshot -r "${JAILDIR}/${jail}" "${inc}" | debug
end=$(date +"%H:%M:%S")
notice "${jail} : made ${date} inc [${start}/${end}]"
else
lock="/run/lock/bkctld/inc-${jail}.lock"
if [ -f "${lock}" ]; then
warning "${jail} : trying to run already running inc"
create_inc_btrfs() {
jail_name=$1
inc_name=$2
jail_path=$(jail_path "${jail_name}")
inc_path=$(inc_path "${jail_name}" "${inc_name}")
start=$(current_time)
if dry_run; then
echo "[dry-run] btrfs subvolume snapshot of ${jail_path} to ${inc_path}"
else
mkdir --parents "$(dirname "${inc_path}")"
# create a btrfs readonly snapshot from the jail
/bin/btrfs subvolume snapshot -r "${jail_path}" "${inc_path}" | debug
fi
end=$(current_time)
notice "${jail_name} : ${inc_name} inc created [${start}/${end}]"
}
create_inc_ext() {
jail_name=$1
inc_name=$2
jail_path=$(jail_path "${jail_name}")
inc_path=$(inc_path "${jail_name}" "${inc_name}")
lock="${LOCKDIR}/inc-${jail_name}.lock"
if [ -f "${lock}" ]; then
warning "${jail_name} : skipping ${inc_name}, it is already being created."
else
(
start=$(current_time)
mkdir --parents "${LOCKDIR}" && touch "${lock}"
# shellcheck disable=SC2064
trap "rm -f ${lock}" 0
if dry_run; then
echo "[dry-run] copy of ${jail_path} to ${inc_path}"
else
(
mkdir -p /run/lock/bkctld && touch "${lock}"
trap "rm -f ${lock}" 0
cp -alx "${JAILDIR}/${jail}/" "${inc}"
end=$(date +"%H:%M:%S")
notice "${jail} : made ${date} inc [${start}/${end}]"
)
mkdir --parents "$(dirname "${inc_path}")"
# create a copy of the jail with hard links
cp --archive --link --one-file-system "${jail_path}/" "${inc_path}"
fi
end=$(current_time)
notice "${jail_name} : ${inc_name} inc created [${start}/${end}]"
)
fi
}
inc_name=$(date +"%Y-%m-%d-%H")
for jail_name in $(jails_list); do
jail_path=$(jail_path "${jail_name}")
inc_path=$(inc_path "${jail_name}" "${inc_name}")
incs_policy_file=$(jail_incs_policy_file ${jail_name})
# If not incs policy is found, we don't create incs
if [ -n "${incs_policy_file}" ]; then
# If not incs directory is found, we don't create incs
if [ ! -d "${inc_path}" ]; then
if is_btrfs "${jail_path}"; then
create_inc_btrfs "${jail_name}" "${inc_name}"
else
create_inc_ext "${jail_name}" "${inc_name}"
fi
else
warning "${jail_name} : skipping ${inc_name}, it already exists."
fi
else
warning "${jail} : trying to made already existant inc"
warning "${jail_name} : skipping ${inc_name}, incs policy not found."
fi
done

View file

@ -17,58 +17,77 @@ relative_date() {
echo ${past_date}
}
remove_inc() {
jail=$1
inc=$2
delete_inc_btrfs() {
jail_name=$1
inc_name=$2
start=$(date +"%H:%M:%S")
inc_inode=$(stat --format=%i "${INCDIR}/${jail}/${inc}")
if [ "${inc_inode}" -eq 256 ]; then
/bin/btrfs subvolume delete "${INCDIR}/${jail}/${inc}" | debug
end=$(date +"%H:%M:%S")
notice "${jail} : deleted ${inc} inc [${start}/${end}]"
inc_path=$(inc_path "${jail_name}" "${inc_name}")
start=$(current_time)
if dry_run; then
echo "[dry-run] delete btrfs subvolume ${inc_path}"
else
lock="/run/lock/bkctld/rm-${jail}.lock"
if [ -f "${lock}" ]; then
warning "${jail} : trying to run already running rm"
else
(
empty="/tmp/bkctld-${$}-$(date +%N)"
mkdir -p /run/lock/bkctld && touch "${lock}" && mkdir -p "${empty}"
trap "rm -f ${lock} && rmdir ${empty}" 0
rsync -a --delete "${empty}/" "${INCDIR}/${jail}/${inc}/"
rmdir "${INCDIR}/${jail}/${inc}/"
end=$(date +"%H:%M:%S")
notice "${jail} : deleted ${inc} inc [${start}/${end}]"
)
fi
/bin/btrfs subvolume delete "${inc_path}" | debug
fi
end=$(current_time)
notice "${jail_name} : ${inc_name} inc deleted [${start}/${end}]"
}
delete_inc_ext() {
jail_name=$1
inc_name=$2
inc_path=$(inc_path "${jail_name}" "${inc_name}")
lock_file="${LOCKDIR}/rm-${jail_name}.lock"
if [ -f "${lock_file}" ]; then
warning "${jail_name} : skipping ${inc_name}, it is already being deleted."
else
(
mkdir --parents "${LOCKDIR}" && touch "${lock_file}" || error "Failed to acquire lock file '${lock_file}'"
empty=$(mktemp -d --suffix ".${$}" bkctld.XXXXX)
# shellcheck disable=SC2064
trap "rm -f ${lock_file}; rmdir ${empty}" 0
if dry_run; then
echo "[dry-run] delete ${inc_path} with rsync from ${empty}"
else
rsync --archive --delete "${empty}/" "${inc_path}/"
fi
rmdir "${inc_path}/"
end=$(current_time)
notice "${jail_name} : ${inc_name} inc deleted [${start}/${end}]"
)
fi
}
for jail in $("${LIBDIR}/bkctld-list"); do
incs=$(ls "${INCDIR}/${jail}")
if [ -f "${CONFDIR}/${jail}.d/incs_policy" ]; then
incs_policy_file="${CONFDIR}/${jail}.d/incs_policy"
elif [ -f "${CONFDIR}/${jail}" ]; then
incs_policy_file="${CONFDIR}/${jail}"
else
incs_policy_file=""
fi
for jail_name in $(jails_list); do
incs_policy_file=$(jail_incs_policy_file ${jail_name})
# If not incs policy if found, we don't remove incs
if [ -n "${incs_policy_file}" ]; then
incs_policy_keep_file="$(mktemp)"
# shellcheck disable=SC2064
trap "rm ${incs_policy_keep_file}" 0
# loop for each line in jail configuration
for incs_policy_line in $(cat ${incs_policy_file}); do
for incs_policy_line in $(cat ${incs_policy_file} | grep "^\+"); do
# inc date in ISO format
incs_policy_date=$(relative_date ${incs_policy_line})
echo ${incs_policy_date} >> "${incs_policy_keep_file}"
done
# shellcheck disable=SC2046
incs_to_delete=$(echo $(incs_list "${jail_name}") | grep -v -f "${incs_policy_keep_file}")
for inc in $(echo "${incs}" | grep -v -f "${incs_policy_keep_file}"); do
remove_inc "${jail}" "${inc}"
for inc_name in ${incs_to_delete}; do
inc_path=$(inc_path "${jail_name}" "${inc_name}")
if is_btrfs "${inc_path}"; then
delete_inc_btrfs "${jail_name}" "${inc_name}"
else
delete_inc_ext "${jail_name}" "${inc_name}"
fi
done
rm "${incs_policy_keep_file}"
fi
done

View file

@ -10,6 +10,7 @@ BACKUP_DISK="${BACKUP_DISK:-}"
JAILDIR="${JAILDIR:-/backup/jails}"
INCDIR="${INCDIR:-/backup/incs}"
TPLDIR="${TPLDIR:-/usr/share/bkctld}"
LOCKDIR="${LOCKDIR:-/run/lock/bkctld}"
INDEX_DIR="${INDEX_DIR:-/backup/index}"
IDX_FILE="${IDX_FILE:-${INDEX_DIR}/bkctld-jails.idx}"
LOCALTPLDIR="${LOCALTPLDIR:-/usr/local/share/bkctld}"
@ -62,3 +63,79 @@ error() {
fi
exit 1
}
dry_run() {
test "$DRY_RUN" = "1"
}
current_time() {
date +"%H:%M:%S"
}
# Returns true if the given path is on a btrfs filesystem
is_btrfs() {
path=$1
inode=$(stat --format=%i "${path}")
test $inode -eq 256
}
# Returns the list of all jails
jails_list() {
# shellcheck disable=SC2091
"${LIBDIR}/bkctld-list"
}
# Returns the list of all incs for a jail
incs_list() {
jail_name=$1
# shellcheck disable=SC2091
ls "$(incs_path "${jail_name}")/"
}
# Returns the complete path of a jail
jail_path() {
jail_name=$1
echo "${JAILDIR}/${jail_name}"
}
# Returns the path of incs for a jail
incs_path() {
jail_name=$1
echo "${INCDIR}/${jail_name}"
}
# Returns the path of a specific inc for a jail
inc_path() {
jail_name=$1
inc_name=$2
echo "${INCDIR}/${jail_name}/${inc_name}"
}
jail_incs_policy_file() {
jail_name=$1
new_file="${CONFDIR}/${jail_name}.d/incs_policy"
old_file="${CONFDIR}/${jail_name}"
if [ -f "${new_file}" ]; then
echo "${new_file}"
elif [ -f "${old_file}" ]; then
echo "${old_file}"
else
echo ""
fi
}
jail_check_policy_file() {
jail_name=$1
new_file="${CONFDIR}/${jail_name}.d/check_policy"
# old_file="${JAILDIR}/${jail_name}/etc/bkctld-check"
if [ -f "${new_file}" ]; then
echo "${new_file}"
# elif [ -f "${old_file}" ]; then
# echo "${old_file}"
else
echo ""
fi
}