bkctld: new inc-lock and inc-unlock command

This commit is contained in:
Jérémy Lecour 2020-11-28 10:46:57 +01:00 committed by Jérémy Lecour
parent fd6c5e4a12
commit 1a52f012a6
4 changed files with 186 additions and 2 deletions

View File

@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
* bkctld: new inc-lock and inc-unlock command
### Changed
### Deprecated

32
bkctld
View File

@ -124,6 +124,38 @@ case "${subcommand}" in
"${LIBDIR}/bkctld-${subcommand}" "${jail_name}"
fi
;;
"inc-lock" | "inc-unlock")
if [ "${subcommand}" = "inc-lock" ]; then
lock_status=on
elif [ "${subcommand}" = "inc-unlock" ]; then
lock_status=off
else
show_help
exit 1
fi
pattern="${2:-}"
if [ "${pattern}" = "all" ]; then
target_path_pattern=$(incs_path "*/*")
elif [ -n "${pattern}" ]; then
# Check if pattern is a jail name
if jails_with_incs_list | grep --silent --fixed-strings --line-regexp "${pattern}"; then
debug "${pattern} is a jail, change pattern to ${pattern}/*"
# then change attern to all subdirectories
target_path_pattern=$(incs_path "${pattern}/*")
else
# or use it as is
target_path_pattern=$(incs_path "${pattern}")
fi
else
show_help
exit 1
fi
for target_path in ${target_path_pattern}; do
"${LIBDIR}/bkctld-inc-lock" "${lock_status}" "${target_path}"
done
echo "finish"
;;
*)
show_help
exit 1

45
lib/bkctld-inc-lock Executable file
View File

@ -0,0 +1,45 @@
#!/bin/sh
#
# Description: Lock or unlock dated copies (incs) on BTRFS formatted volumes
# Usage: inc-<lock|unlock> <all|jailname[/inc]>
#
# shellcheck source=./includes
LIBDIR="$(dirname $0)" && . "${LIBDIR}/includes"
lock_status="${1:?}"
target_path="${2:?}"
lock_target() {
target="${1:?}"
if is_btrfs "${target}"; then
btrfs property set -ts "${target}" ro true
info "Lock ${target}: done".
else
info "Lock ${target}: not BTRFS, nothing done".
fi
}
unlock_target() {
target="${1:?}"
if is_btrfs "${target}"; then
btrfs property set -ts "${target}" ro false
info "Unlock ${target}: done."
else
info "Unlock ${target}: not BTRFS, nothing done."
fi
}
# this directory test must be quoted,beacause of the probable globbing
if [ -d ${target_path} ]; then
if [ "${lock_status}" = "on" ]; then
lock_target "${target_path}"
elif [ "${lock_status}" = "off" ]; then
unlock_target "${target_path}"
else
error "Unknown lock status \`${lock_status}'."
exit 1
fi
else
error "\`${target_path}': no such file or directory."
exit 1
fi

View File

@ -122,4 +122,109 @@ load test_helper
assert_failure
}
@test "BTRFS based inc can be unlock with complex pattern" {
if is_btrfs "/backup"; then
# Prepare an inc older than the policy
recent_inc_path="${INCSPATH}/${INC_NAME}"
older_inc_name=$(date -d -1month +"%Y-%m-%d-%H")
older_inc_path="${INCSPATH}/${older_inc_name}"
# Create the inc, rename it to make it older, then run 'rm'
/usr/lib/bkctld/bkctld-inc
mv "${recent_inc_path}" "${older_inc_path}"
# run 'inc' again to remake today's inc
/usr/lib/bkctld/bkctld-inc
# inc should be locked
run touch "${older_inc_path}/var/log/lastlog"
assert_failure
# unlock inc
pattern="${JAILNAME}/$(date -d -1month +"%Y-%m-*")"
bkctld inc-unlock "${pattern}"
# inc should be unlocked
run touch "${older_inc_path}/var/log/lastlog"
assert_success
# other inc should still be locked
run touch "${recent_inc_path}/var/log/lastlog"
assert_failure
else
# On an ext4 filesystem it's always true
run true
assert_success
fi
}
@test "BTRFS based inc can be unlock with jail name" {
if is_btrfs "/backup"; then
# Prepare an inc older than the policy
recent_inc_path="${INCSPATH}/${INC_NAME}"
older_inc_name=$(date -d -1month +"%Y-%m-%d-%H")
older_inc_path="${INCSPATH}/${older_inc_name}"
# Create the inc, rename it to make it older, then run 'rm'
/usr/lib/bkctld/bkctld-inc
mv "${recent_inc_path}" "${older_inc_path}"
# run 'inc' again to remake today's inc
/usr/lib/bkctld/bkctld-inc
# incs should be locked
run touch "${recent_inc_path}/var/log/lastlog"
assert_failure
run touch "${older_inc_path}/var/log/lastlog"
assert_failure
# unlock incs
pattern="${JAILNAME}"
bkctld inc-unlock "${pattern}"
# incs should be unlocked
run touch "${recent_inc_path}/var/log/lastlog"
assert_success
run touch "${older_inc_path}/var/log/lastlog"
assert_success
else
# On an ext4 filesystem it's always true
run true
assert_success
fi
}
@test "BTRFS based inc can be unlock with 'all' pattern" {
if is_btrfs "/backup"; then
# Prepare an inc older than the policy
recent_inc_path="${INCSPATH}/${INC_NAME}"
older_inc_name=$(date -d -1month +"%Y-%m-%d-%H")
older_inc_path="${INCSPATH}/${older_inc_name}"
# Create the inc, rename it to make it older, then run 'rm'
/usr/lib/bkctld/bkctld-inc
mv "${recent_inc_path}" "${older_inc_path}"
# run 'inc' again to remake today's inc
/usr/lib/bkctld/bkctld-inc
# incs should be locked
run touch "${recent_inc_path}/var/log/lastlog"
assert_failure
run touch "${older_inc_path}/var/log/lastlog"
assert_failure
# unlock incs
pattern="all"
bkctld inc-unlock "${pattern}"
# incs should be unlocked
run touch "${recent_inc_path}/var/log/lastlog"
assert_success
run touch "${older_inc_path}/var/log/lastlog"
assert_success
else
# On an ext4 filesystem it's always true
run true
assert_success
fi
}
# TODO: add many tests for incs (creation and removal)