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() { read_variable() {
var_name=$1 var_name=$1
file=$2 file=$2
pattern="^\s*${var_name}=-?[0-9]+" pattern="^\s*${var_name}=-?[0-9]+"
grep --extended-regexp --only-matching "${pattern}" "${file}" | cut -d= -f2 grep --extended-regexp --only-matching "${pattern}" "${file}" | cut -d= -f2
} }
check_jail() { check_jail() {
jail=$1 jail_name=$1
jail_path=$(jail_path "${jail_name}")
cur_time=$(date "+%s") 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) )) date_diff=$(( (cur_time - last_conn) / (60*60) ))
if [ -f "${CONFDIR}/${jail}.d/check_policy" ]; then check_policy_file=$(jail_check_policy_file "${jail_name}")
# 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
if [ -f "${check_policy_file}" ]; then if [ -f "${check_policy_file}" ]; then
local_critical=$(read_variable "CRITICAL" "${check_policy_file}") 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 if [ "${local_critical}" -gt "0" ] && [ "${date_diff}" -gt "${local_critical}" ]; then
nb_crit=$((nb_crit + 1)) 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 [ "${return}" -le 2 ] && return=2
elif [ "${local_warning}" -gt "0" ] && [ "${date_diff}" -gt "${local_warning}" ]; then elif [ "${local_warning}" -gt "0" ] && [ "${date_diff}" -gt "${local_warning}" ]; then
nb_warn=$((nb_warn + 1)) 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 [ "${return}" -le 1 ] && return=1
else else
nb_ok=$((nb_ok + 1)) 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 fi
} }
for jail in $("${LIBDIR}/bkctld-list"); do for jail_name in $(jails_list); do
if [ -f "${JAILDIR}/${jail}/var/log/lastlog" ]; then jail_path=$(jail_path "${jail_name}")
check_jail "${jail}"
if [ -f "${jail_path}/var/log/lastlog" ]; then
check_jail "${jail_name}"
else else
nb_unkn=$((nb_unkn + 1)) 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 [ "${return}" -le 3 ] && return=3
fi fi
done done

View file

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

View file

@ -17,58 +17,77 @@ relative_date() {
echo ${past_date} echo ${past_date}
} }
remove_inc() { delete_inc_btrfs() {
jail=$1 jail_name=$1
inc=$2 inc_name=$2
start=$(date +"%H:%M:%S") inc_path=$(inc_path "${jail_name}" "${inc_name}")
inc_inode=$(stat --format=%i "${INCDIR}/${jail}/${inc}")
if [ "${inc_inode}" -eq 256 ]; then start=$(current_time)
/bin/btrfs subvolume delete "${INCDIR}/${jail}/${inc}" | debug
end=$(date +"%H:%M:%S") if dry_run; then
notice "${jail} : deleted ${inc} inc [${start}/${end}]" echo "[dry-run] delete btrfs subvolume ${inc_path}"
else else
lock="/run/lock/bkctld/rm-${jail}.lock" /bin/btrfs subvolume delete "${inc_path}" | debug
if [ -f "${lock}" ]; then fi
warning "${jail} : trying to run already running rm"
else end=$(current_time)
( notice "${jail_name} : ${inc_name} inc deleted [${start}/${end}]"
empty="/tmp/bkctld-${$}-$(date +%N)" }
mkdir -p /run/lock/bkctld && touch "${lock}" && mkdir -p "${empty}" delete_inc_ext() {
trap "rm -f ${lock} && rmdir ${empty}" 0 jail_name=$1
rsync -a --delete "${empty}/" "${INCDIR}/${jail}/${inc}/" inc_name=$2
rmdir "${INCDIR}/${jail}/${inc}/"
end=$(date +"%H:%M:%S") inc_path=$(inc_path "${jail_name}" "${inc_name}")
notice "${jail} : deleted ${inc} inc [${start}/${end}]"
) lock_file="${LOCKDIR}/rm-${jail_name}.lock"
fi 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 fi
} }
for jail in $("${LIBDIR}/bkctld-list"); do for jail_name in $(jails_list); do
incs=$(ls "${INCDIR}/${jail}") incs_policy_file=$(jail_incs_policy_file ${jail_name})
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
# If not incs policy if found, we don't remove incs
if [ -n "${incs_policy_file}" ]; then if [ -n "${incs_policy_file}" ]; then
incs_policy_keep_file="$(mktemp)" incs_policy_keep_file="$(mktemp)"
# shellcheck disable=SC2064
trap "rm ${incs_policy_keep_file}" 0
# loop for each line in jail configuration # 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 # inc date in ISO format
incs_policy_date=$(relative_date ${incs_policy_line}) incs_policy_date=$(relative_date ${incs_policy_line})
echo ${incs_policy_date} >> "${incs_policy_keep_file}" echo ${incs_policy_date} >> "${incs_policy_keep_file}"
done 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 for inc_name in ${incs_to_delete}; do
remove_inc "${jail}" "${inc}" 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 done
rm "${incs_policy_keep_file}"
fi fi
done done

View file

@ -10,6 +10,7 @@ BACKUP_DISK="${BACKUP_DISK:-}"
JAILDIR="${JAILDIR:-/backup/jails}" JAILDIR="${JAILDIR:-/backup/jails}"
INCDIR="${INCDIR:-/backup/incs}" INCDIR="${INCDIR:-/backup/incs}"
TPLDIR="${TPLDIR:-/usr/share/bkctld}" TPLDIR="${TPLDIR:-/usr/share/bkctld}"
LOCKDIR="${LOCKDIR:-/run/lock/bkctld}"
INDEX_DIR="${INDEX_DIR:-/backup/index}" INDEX_DIR="${INDEX_DIR:-/backup/index}"
IDX_FILE="${IDX_FILE:-${INDEX_DIR}/bkctld-jails.idx}" IDX_FILE="${IDX_FILE:-${INDEX_DIR}/bkctld-jails.idx}"
LOCALTPLDIR="${LOCALTPLDIR:-/usr/local/share/bkctld}" LOCALTPLDIR="${LOCALTPLDIR:-/usr/local/share/bkctld}"
@ -62,3 +63,79 @@ error() {
fi fi
exit 1 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
}