evolinux-base: add dir-check script

This commit is contained in:
Jérémy Lecour 2022-06-01 17:23:56 +02:00 committed by Jérémy Lecour
parent e9bc035fb9
commit 249e53fc21
3 changed files with 313 additions and 4 deletions

View file

@ -12,8 +12,9 @@ The **patch** part changes is incremented if multiple releases happen the same m
### Added
certbot: add hapee (HAProxy Enterprise Edition) deploy hook
evolinux-base: add update-evobackup-canary script
* certbot: add hapee (HAProxy Enterprise Edition) deploy hook
* evolinux-base: add dir-check script
* evolinux-base: add update-evobackup-canary script
### Changed

View file

@ -0,0 +1,299 @@
#!/bin/sh
PROGNAME="dir-check"
REPOSITORY="https://gitea.evolix.org/evolix/ansible-roles"
VERSION="22.06"
readonly VERSION
show_version() {
cat <<END
${PROGNAME} version ${VERSION}
Copyright 2022 Evolix <info@evolix.fr>,
Jérémy Lecour <jlecour@evolix.fr>
${REPOSITORY}
${PROGNAME} comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to redistribute it under certain conditions.
See the GNU Affero General Public License v3.0 for details.
END
}
show_help() {
cat <<EOF
Usage: ${PROGNAME} [OPTIONS] --dir /path/to/directory-to-check
Without --check, it creates the metadata files
With --check, it checks the data against the metadata previously stored
Options
-h|--help|-? Display help
-V|--version Display version, authors and license
EOF
}
log_date() {
date +"%Y-%m-%d %H:%M:%S"
}
is_log_file() {
test -n "${log_file}"
}
is_verbose() {
test "${verbose}" = "1"
}
is_quiet() {
test "${quiet}" = "1"
}
is_check() {
test "${check}" = "1"
}
log_line() {
level=$1
msg=$2
# printf "[%s] %s: %s\n" "$(log_date)" "${level}" "${msg}"
printf "%s: %s\n" "${level}" "${msg}"
}
log_debug() {
level="DEBUG"
msg=$1
if ! is_quiet && is_verbose; then
if is_log_file; then
log_line "${level}" "${msg}" >> "${log_file}"
else
log_line "${level}" "${msg}" >&2
fi
fi
}
log_info() {
level="INFO"
msg=$1
if ! is_quiet; then
if is_log_file; then
log_line "${level}" "${msg}" >> "${log_file}"
else
log_line "${level}" "${msg}" >&2
fi
fi
}
log_warning() {
level="WARNING"
msg=$1
if ! is_quiet; then
if is_log_file; then
log_line "${level}" "${msg}" >> "${log_file}"
else
log_line "${level}" "${msg}" >&2
fi
fi
}
log_error() {
level="ERROR"
msg=$1
if ! is_quiet; then
if is_log_file; then
log_line "${level}" "${msg}" >> "${log_file}"
if tty -s; then
printf "%s\n" "${msg}" >&2
fi
else
log_line "${level}" "${msg}" >&2
fi
fi
}
log_fatal() {
level="FATAL"
msg=$1
if is_log_file; then
log_line "${level}" "${msg}" >> "${log_file}"
if tty -s; then
printf "%s\n" "${msg}" >&2
fi
else
log_line "${level}" "${msg}" >&2
fi
}
metadata_algorithm() {
echo "du --bytes"
}
list_files_with_size() {
path=$1
find "${path}" -type f -exec $(metadata_algorithm) {} \; | sort -k2
}
prepare_metadata() {
list_files_with_size "${final_dir}" > "${metadata_file}"
"${checksum_bin}" "${metadata_file}" > "${checksum_file}"
}
check_metadata() {
if [ -f "${checksum_file}" ]; then
# subshell to scope the commands to "parent_dir"
"${checksum_bin}" --status --check "${checksum_file}"
last_rc=$?
if [ ${last_rc} -ne 0 ]; then
log_error "Verification failed with checksum file ${checksum_file}."
exit 1
fi
else
log_warning "Couldn't find checksum file ${checksum_file}. Skip verification."
fi
if [ -f "${metadata_file}" ]; then
while read metadata_line; do
expected_size=$(echo "${metadata_line}" | cut -f1)
file=$(echo "${metadata_line}" | cut -f2)
if [ -f "${file}" ]; then
actual_size=$($(metadata_algorithm) "${file}" | cut -f1)
if [ "${actual_size}" != "${expected_size}" ]; then
log_error "File ${file} has actual size of ${actual_size} instead of ${expected_size}."
rc=1
fi
else
log_error "Couldn't find file ${file}."
rc=1
fi
done < "${metadata_file}"
if [ ${rc} -eq 0 ]; then
log_info "Directory is consistent with metadata stored in metadata file ${metadata_file}."
fi
else
log_fatal "Couldn't find metadata file ${metadata_file}."
exit 1
fi
}
main() {
if [ -z "${dir}" ]; then
log_fatal "dir option is empty"
exit 1
elif [ -e "${dir}" ] && [ ! -d "${dir}" ]; then
log_fatal "directory '${dir}' exists but is not a directory"
exit 1
fi
checksum_cmd="sha256sum"
checksum_bin=$(command -v ${checksum_cmd})
if [ -z "${checksum_bin}" ]; then
log_fatal "Couldn't find ${checksum_cmd}.\nUse 'apt install ${checksum_cmd}'."
exit 1
fi
parent_dir=$(dirname "${dir}")
final_dir=$(basename "${dir}")
metadata_file="${final_dir}.metadata"
checksum_file="${metadata_file}.${checksum_cmd}"
cwd=${PWD}
cd "${parent_dir}" || log_error "Impossible to change to ${parent_dir}"
case ${action} in
check)
check_metadata
;;
prepare)
prepare_metadata
;;
*)
log_fatal "Unknown action ${action}."
rc=1
;;
esac
cd "${cwd}" || log_error "Impossible to change back to ${cwd}"
}
# Declare variables
verbose=""
quiet=""
action=""
dir=""
rc=0
# Parse options
# based on https://gist.github.com/deshion/10d3cb5f88a21671e17a
while :; do
case $1 in
-h|-\?|--help)
show_help
exit 0
;;
-V|--version)
show_version
exit 0
;;
--dir)
# with value separated by space
if [ -n "$2" ]; then
dir="$2"
shift
else
log_fatal 'ERROR: "--dir" requires a non-empty option argument.'
fi
;;
--dir=?*)
# with value speparated by =
dir=${1#*=}
;;
--dir=)
# without value
log_fatal '"--dir" requires a non-empty option argument.'
;;
--prepare)
action="prepare"
;;
--check)
action="check"
;;
-v|--verbose)
verbose=1
;;
--quiet)
quiet=1
verbose=0
;;
--)
# End of all options.
shift
break
;;
-?*|[[:alnum:]]*)
# ignore unknown options
if tty -s; then
printf 'Unknown option : %s\n' "$1" >&2
echo "" >&2
show_usage >&2
exit 1
else
log_fatal "Unknown option : $1"
fi
;;
*)
# Default case: If no more options then break out of the loop.
break
;;
esac
shift
done
# Default values
verbose=${verbose:-0}
quiet=${quiet:-0}
action=${action:-}
log_file=${log_file:-}
set -u
main
exit ${rc}

View file

@ -35,10 +35,19 @@
force: True
owner: root
group: root
mode: "0750"
mode: "0755"
# TODO: delete when this has been run once on all our servers
- name: update-evobackup-canary is removed from sbin
file:
path: /usr/local/sbin/update-evobackup-canary
state: absent
state: absent
- name: dir-check script is present
copy:
src: "dir-check.sh"
dest: /usr/local/bin/dir-check
force: True
owner: root
group: root
mode: "0755"