Merge branch 'unstable' into stable
This commit is contained in:
commit
78ef69bb6e
|
@ -20,6 +20,15 @@ The **patch** part changes is incremented if multiple releases happen the same m
|
||||||
|
|
||||||
### Security
|
### Security
|
||||||
|
|
||||||
|
## [22.06.1] 2022-06-06
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
* evocheck: upstream release 22.06.1
|
||||||
|
* minifirewall: upstream release 22.06
|
||||||
|
* mysql: evomariabackup release 22.06.1
|
||||||
|
* mysql: reorganize evomariabackup to use mtree instead of our own dir-check
|
||||||
|
|
||||||
## [22.06] 2022-06-03
|
## [22.06] 2022-06-03
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
# Script to verify compliance of a Debian/OpenBSD server
|
# Script to verify compliance of a Debian/OpenBSD server
|
||||||
# powered by Evolix
|
# powered by Evolix
|
||||||
|
|
||||||
VERSION="22.06"
|
VERSION="22.06.1"
|
||||||
readonly VERSION
|
readonly VERSION
|
||||||
|
|
||||||
# base functions
|
# base functions
|
||||||
|
@ -236,11 +236,11 @@ check_debiansecurity() {
|
||||||
if is_debian_bullseye; then
|
if is_debian_bullseye; then
|
||||||
# https://www.debian.org/releases/bullseye/amd64/release-notes/ch-information.html#security-archive
|
# https://www.debian.org/releases/bullseye/amd64/release-notes/ch-information.html#security-archive
|
||||||
# https://www.debian.org/security/
|
# https://www.debian.org/security/
|
||||||
pattern="^deb http://security\.debian\.org/debian-security/? bullseye-security main"
|
pattern="^deb ?(\[.*\])? ?http://security\.debian\.org/debian-security/? bullseye-security main"
|
||||||
elif is_debian_buster; then
|
elif is_debian_buster; then
|
||||||
pattern="^deb http://security\.debian\.org/debian-security/? buster/updates main"
|
pattern="^deb ?(\[.*\])? ?http://security\.debian\.org/debian-security/? buster/updates main"
|
||||||
elif is_debian_stretch; then
|
elif is_debian_stretch; then
|
||||||
pattern="^deb http://security\.debian\.org/debian-security/? stretch/updates main"
|
pattern="^deb ?(\[.*\])? ?http://security\.debian\.org/debian-security/? stretch/updates main"
|
||||||
else
|
else
|
||||||
pattern="^deb.*security"
|
pattern="^deb.*security"
|
||||||
fi
|
fi
|
||||||
|
@ -363,7 +363,7 @@ check_alert5minifw() {
|
||||||
}
|
}
|
||||||
check_minifw() {
|
check_minifw() {
|
||||||
/sbin/iptables -L -n | grep -q -E "^ACCEPT\s*all\s*--\s*31\.170\.8\.4\s*0\.0\.0\.0/0\s*$" \
|
/sbin/iptables -L -n | grep -q -E "^ACCEPT\s*all\s*--\s*31\.170\.8\.4\s*0\.0\.0\.0/0\s*$" \
|
||||||
|| failed "IS_MINIFW" "minifirewall seems not starded"
|
|| failed "IS_MINIFW" "minifirewall seems not started"
|
||||||
}
|
}
|
||||||
check_minifw_includes() {
|
check_minifw_includes() {
|
||||||
if is_debian_bullseye; then
|
if is_debian_bullseye; then
|
||||||
|
@ -742,12 +742,13 @@ check_backupuptodate() {
|
||||||
backup_dir="/home/backup"
|
backup_dir="/home/backup"
|
||||||
if [ -d "${backup_dir}" ]; then
|
if [ -d "${backup_dir}" ]; then
|
||||||
if [ -n "$(ls -A ${backup_dir})" ]; then
|
if [ -n "$(ls -A ${backup_dir})" ]; then
|
||||||
# shellcheck disable=SC2231
|
# Look for all files, including subdirectories.
|
||||||
for file in ${backup_dir}/*; do
|
# If this turns out to be problematic, we can go back to first level only, with --max-depth=1
|
||||||
|
find "${backup_dir}" -type f | while read -r file; do
|
||||||
limit=$(date +"%s" -d "now - 2 day")
|
limit=$(date +"%s" -d "now - 2 day")
|
||||||
updated_at=$(stat -c "%Y" "$file")
|
updated_at=$(stat -c "%Y" "$file")
|
||||||
|
|
||||||
if [ -f "$file" ] && [ "$limit" -gt "$updated_at" ]; then
|
if [ "$limit" -gt "$updated_at" ]; then
|
||||||
failed "IS_BACKUPUPTODATE" "$file has not been backed up"
|
failed "IS_BACKUPUPTODATE" "$file has not been backed up"
|
||||||
test "${VERBOSE}" = 1 || break;
|
test "${VERBOSE}" = 1 || break;
|
||||||
fi
|
fi
|
||||||
|
@ -1217,14 +1218,20 @@ check_usrsharescripts() {
|
||||||
test "$expected" = "$actual" || failed "IS_USRSHARESCRIPTS" "/usr/share/scripts must be $expected"
|
test "$expected" = "$actual" || failed "IS_USRSHARESCRIPTS" "/usr/share/scripts must be $expected"
|
||||||
}
|
}
|
||||||
check_sshpermitrootno() {
|
check_sshpermitrootno() {
|
||||||
if is_debian_stretch || is_debian_buster || is_debian_bullseye; then
|
sshd_args="-C addr=,user=,host=,laddr=,lport=0"
|
||||||
if grep -q "^PermitRoot" /etc/ssh/sshd_config; then
|
if is_debian_jessie || is_debian_stretch; then
|
||||||
grep -E -qi "PermitRoot.*no" /etc/ssh/sshd_config \
|
# Noop, we'll use the default $sshd_args
|
||||||
|| failed "IS_SSHPERMITROOTNO" "PermitRoot should be set at no"
|
:
|
||||||
fi
|
elif is_debian_buster; then
|
||||||
|
sshd_args="${sshd_args},rdomain="
|
||||||
else
|
else
|
||||||
grep -E -qi "PermitRoot.*no" /etc/ssh/sshd_config \
|
# NOTE: From Debian Bullseye 11 onward, with OpenSSH 8.1, the argument
|
||||||
|| failed "IS_SSHPERMITROOTNO" "PermitRoot should be set at no"
|
# -T doesn't require the additional -C.
|
||||||
|
sshd_args=
|
||||||
|
fi
|
||||||
|
# XXX: We want parameter expension here
|
||||||
|
if ! (sshd -T $sshd_args | grep -q 'permitrootlogin no'); then
|
||||||
|
failed "IS_SSHPERMITROOTNO" "PermitRoot should be set to no"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
check_evomaintenanceusers() {
|
check_evomaintenanceusers() {
|
||||||
|
|
|
@ -77,7 +77,6 @@ evolinux_packages_include: True
|
||||||
|
|
||||||
evolinux_packages_system: True
|
evolinux_packages_system: True
|
||||||
evolinux_packages_diagnostic: True
|
evolinux_packages_diagnostic: True
|
||||||
evolinux_packages_hardware: True
|
|
||||||
evolinux_packages_hardware_raid: True
|
evolinux_packages_hardware_raid: True
|
||||||
evolinux_packages_common: True
|
evolinux_packages_common: True
|
||||||
evolinux_packages_stretch: True
|
evolinux_packages_stretch: True
|
||||||
|
@ -223,4 +222,4 @@ evolinux_generateldif_include: True
|
||||||
evolinux_cron_checkhpraid_frequency: daily
|
evolinux_cron_checkhpraid_frequency: daily
|
||||||
|
|
||||||
# Motd
|
# Motd
|
||||||
evolinux_motd_include: True
|
evolinux_motd_include: True
|
||||||
|
|
|
@ -131,7 +131,9 @@ check_data() {
|
||||||
# subshell to scope the commands to "parent_dir"
|
# subshell to scope the commands to "parent_dir"
|
||||||
"${checksum_bin}" --status --check "${checksum_file}"
|
"${checksum_bin}" --status --check "${checksum_file}"
|
||||||
last_rc=$?
|
last_rc=$?
|
||||||
if [ ${last_rc} -ne 0 ]; then
|
if [ ${last_rc} -eq 0 ]; then
|
||||||
|
log_debug "Verification succeeded with checksum file \`${checksum_file}' (inside \`${parent_dir}')."
|
||||||
|
else
|
||||||
log_error "Verification failed with checksum file \`${checksum_file}' (inside \`${parent_dir}')."
|
log_error "Verification failed with checksum file \`${checksum_file}' (inside \`${parent_dir}')."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
@ -146,8 +148,10 @@ check_data() {
|
||||||
if [ -f "${file}" ]; then
|
if [ -f "${file}" ]; then
|
||||||
actual_size=$($(data_command) "${file}" | cut -f1)
|
actual_size=$($(data_command) "${file}" | cut -f1)
|
||||||
|
|
||||||
if [ "${actual_size}" != "${expected_size}" ]; then
|
if [ "${actual_size}" = "${expected_size}" ]; then
|
||||||
log_error "File \`${file}' has actual size of ${actual_size} instead of ${expected_size}."
|
log_debug "File \`${file}' has a consistent size of ${actual_size}."
|
||||||
|
else
|
||||||
|
log_error "File \`${file}' has an actual size of ${actual_size} instead of ${expected_size}."
|
||||||
rc=1
|
rc=1
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
|
@ -157,6 +161,8 @@ check_data() {
|
||||||
done < "${data_file}"
|
done < "${data_file}"
|
||||||
if [ ${rc} -eq 0 ]; then
|
if [ ${rc} -eq 0 ]; then
|
||||||
log_info "Directory \`${final_dir}' is consistent with data stored in \`${data_file}' (inside \`${parent_dir}')."
|
log_info "Directory \`${final_dir}' is consistent with data stored in \`${data_file}' (inside \`${parent_dir}')."
|
||||||
|
else
|
||||||
|
log_error "Directory \`${final_dir}' is not consistent with data stored in \`${data_file}' (inside \`${parent_dir}')."
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
log_fatal "Couldn't find data file \`${data_file}' (inside \`${parent_dir}')."
|
log_fatal "Couldn't find data file \`${data_file}' (inside \`${parent_dir}')."
|
||||||
|
@ -183,7 +189,7 @@ main() {
|
||||||
parent_dir=$(dirname "${dir}")
|
parent_dir=$(dirname "${dir}")
|
||||||
final_dir=$(basename "${dir}")
|
final_dir=$(basename "${dir}")
|
||||||
|
|
||||||
data_file="${PROGNAME}.db"
|
data_file="${final_dir}.${PROGNAME}.db"
|
||||||
checksum_file="${data_file}.${checksum_cmd}"
|
checksum_file="${data_file}.${checksum_cmd}"
|
||||||
|
|
||||||
cwd=${PWD}
|
cwd=${PWD}
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
- hdparm
|
- hdparm
|
||||||
- smartmontools
|
- smartmontools
|
||||||
- lm-sensors
|
- lm-sensors
|
||||||
when: evolinux_packages_hardware | bool
|
when: ansible_virtualization_role == "host"
|
||||||
|
|
||||||
- name: Install/Update common tools
|
- name: Install/Update common tools
|
||||||
apt:
|
apt:
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
# Description: Firewall designed for standalone server
|
# Description: Firewall designed for standalone server
|
||||||
### END INIT INFO
|
### END INIT INFO
|
||||||
|
|
||||||
VERSION="22.05"
|
VERSION="22.06"
|
||||||
|
|
||||||
NAME="minifirewall"
|
NAME="minifirewall"
|
||||||
# shellcheck disable=SC2034
|
# shellcheck disable=SC2034
|
||||||
|
@ -121,6 +121,7 @@ if [ -t 1 ]; then
|
||||||
# see if it supports colors...
|
# see if it supports colors...
|
||||||
ncolors=$(tput colors)
|
ncolors=$(tput colors)
|
||||||
|
|
||||||
|
# shellcheck disable=SC2086
|
||||||
if [ -n "${ncolors}" ] && [ ${ncolors} -ge 8 ]; then
|
if [ -n "${ncolors}" ] && [ ${ncolors} -ge 8 ]; then
|
||||||
RED=$(tput setaf 1)
|
RED=$(tput setaf 1)
|
||||||
GREEN=$(tput setaf 2)
|
GREEN=$(tput setaf 2)
|
||||||
|
@ -363,6 +364,7 @@ start() {
|
||||||
|
|
||||||
if [ "${SYSCTL_ICMP_ECHO_IGNORE_BROADCASTS}" = "1" ] || [ "${SYSCTL_ICMP_ECHO_IGNORE_BROADCASTS}" = "0" ]; then
|
if [ "${SYSCTL_ICMP_ECHO_IGNORE_BROADCASTS}" = "1" ] || [ "${SYSCTL_ICMP_ECHO_IGNORE_BROADCASTS}" = "0" ]; then
|
||||||
echo "${SYSCTL_ICMP_ECHO_IGNORE_BROADCASTS}" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
|
echo "${SYSCTL_ICMP_ECHO_IGNORE_BROADCASTS}" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
|
||||||
|
# Apparently not applicable to IPv6
|
||||||
else
|
else
|
||||||
printf "${RED}ERROR: invalid %s value '%s', must be '0' or '1'.\n" "SYSCTL_ICMP_ECHO_IGNORE_BROADCASTS" "${SYSCTL_ICMP_ECHO_IGNORE_BROADCASTS}" >&2
|
printf "${RED}ERROR: invalid %s value '%s', must be '0' or '1'.\n" "SYSCTL_ICMP_ECHO_IGNORE_BROADCASTS" "${SYSCTL_ICMP_ECHO_IGNORE_BROADCASTS}" >&2
|
||||||
exit 1
|
exit 1
|
||||||
|
@ -370,6 +372,7 @@ start() {
|
||||||
|
|
||||||
if [ "${SYSCTL_ICMP_IGNORE_BOGUS_ERROR_RESPONSES}" = "1" ] || [ "${SYSCTL_ICMP_IGNORE_BOGUS_ERROR_RESPONSES}" = "0" ]; then
|
if [ "${SYSCTL_ICMP_IGNORE_BOGUS_ERROR_RESPONSES}" = "1" ] || [ "${SYSCTL_ICMP_IGNORE_BOGUS_ERROR_RESPONSES}" = "0" ]; then
|
||||||
echo "${SYSCTL_ICMP_IGNORE_BOGUS_ERROR_RESPONSES}" > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses
|
echo "${SYSCTL_ICMP_IGNORE_BOGUS_ERROR_RESPONSES}" > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses
|
||||||
|
# Apparently not applicable to IPv6
|
||||||
else
|
else
|
||||||
printf "${RED}ERROR: invalid %s value '%s', must be '0' or '1'.\n" "SYSCTL_ICMP_IGNORE_BOGUS_ERROR_RESPONSES" "${SYSCTL_ICMP_IGNORE_BOGUS_ERROR_RESPONSES}" >&2
|
printf "${RED}ERROR: invalid %s value '%s', must be '0' or '1'.\n" "SYSCTL_ICMP_IGNORE_BOGUS_ERROR_RESPONSES" "${SYSCTL_ICMP_IGNORE_BOGUS_ERROR_RESPONSES}" >&2
|
||||||
exit 1
|
exit 1
|
||||||
|
@ -379,6 +382,11 @@ start() {
|
||||||
for proc_sys_file in /proc/sys/net/ipv4/conf/*/accept_source_route; do
|
for proc_sys_file in /proc/sys/net/ipv4/conf/*/accept_source_route; do
|
||||||
echo "${SYSCTL_ACCEPT_SOURCE_ROUTE}" > "${proc_sys_file}"
|
echo "${SYSCTL_ACCEPT_SOURCE_ROUTE}" > "${proc_sys_file}"
|
||||||
done
|
done
|
||||||
|
if is_ipv6_enabled; then
|
||||||
|
for proc_sys_file in /proc/sys/net/ipv6/conf/*/accept_source_route; do
|
||||||
|
echo "${SYSCTL_ACCEPT_SOURCE_ROUTE}" > "${proc_sys_file}"
|
||||||
|
done
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
printf "${RED}ERROR: invalid %s value '%s', must be '0' or '1'.\n" "SYSCTL_ACCEPT_SOURCE_ROUTE" "${SYSCTL_ACCEPT_SOURCE_ROUTE}" >&2
|
printf "${RED}ERROR: invalid %s value '%s', must be '0' or '1'.\n" "SYSCTL_ACCEPT_SOURCE_ROUTE" "${SYSCTL_ACCEPT_SOURCE_ROUTE}" >&2
|
||||||
exit 1
|
exit 1
|
||||||
|
@ -386,6 +394,7 @@ start() {
|
||||||
|
|
||||||
if [ "${SYSCTL_TCP_SYNCOOKIES}" = "1" ] || [ "${SYSCTL_TCP_SYNCOOKIES}" = "0" ]; then
|
if [ "${SYSCTL_TCP_SYNCOOKIES}" = "1" ] || [ "${SYSCTL_TCP_SYNCOOKIES}" = "0" ]; then
|
||||||
echo "${SYSCTL_TCP_SYNCOOKIES}" > /proc/sys/net/ipv4/tcp_syncookies
|
echo "${SYSCTL_TCP_SYNCOOKIES}" > /proc/sys/net/ipv4/tcp_syncookies
|
||||||
|
# Apparently not applicable to IPv6
|
||||||
else
|
else
|
||||||
printf "${RED}ERROR: invalid %s value '%s', must be '0' or '1'.\n" "SYSCTL_TCP_SYNCOOKIES" "${SYSCTL_TCP_SYNCOOKIES}" >&2
|
printf "${RED}ERROR: invalid %s value '%s', must be '0' or '1'.\n" "SYSCTL_TCP_SYNCOOKIES" "${SYSCTL_TCP_SYNCOOKIES}" >&2
|
||||||
exit 1
|
exit 1
|
||||||
|
@ -398,6 +407,11 @@ start() {
|
||||||
for proc_sys_file in /proc/sys/net/ipv4/conf/*/send_redirects; do
|
for proc_sys_file in /proc/sys/net/ipv4/conf/*/send_redirects; do
|
||||||
echo "${SYSCTL_ICMP_REDIRECTS}" > "${proc_sys_file}"
|
echo "${SYSCTL_ICMP_REDIRECTS}" > "${proc_sys_file}"
|
||||||
done
|
done
|
||||||
|
if is_ipv6_enabled; then
|
||||||
|
for proc_sys_file in /proc/sys/net/ipv6/conf/*/accept_redirects; do
|
||||||
|
echo "${SYSCTL_ICMP_REDIRECTS}" > "${proc_sys_file}"
|
||||||
|
done
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
printf "${RED}ERROR: invalid %s value '%s', must be '0' or '1'.\n" "SYSCTL_ICMP_REDIRECTS" "${SYSCTL_ICMP_REDIRECTS}" >&2
|
printf "${RED}ERROR: invalid %s value '%s', must be '0' or '1'.\n" "SYSCTL_ICMP_REDIRECTS" "${SYSCTL_ICMP_REDIRECTS}" >&2
|
||||||
exit 1
|
exit 1
|
||||||
|
@ -407,6 +421,7 @@ start() {
|
||||||
for proc_sys_file in /proc/sys/net/ipv4/conf/*/rp_filter; do
|
for proc_sys_file in /proc/sys/net/ipv4/conf/*/rp_filter; do
|
||||||
echo "${SYSCTL_RP_FILTER}" > "${proc_sys_file}"
|
echo "${SYSCTL_RP_FILTER}" > "${proc_sys_file}"
|
||||||
done
|
done
|
||||||
|
# Apparently not applicable to IPv6
|
||||||
else
|
else
|
||||||
printf "${RED}ERROR: invalid %s value '%s', must be '0' or '1'.\n" "SYSCTL_RP_FILTER" "${SYSCTL_RP_FILTER}" >&2
|
printf "${RED}ERROR: invalid %s value '%s', must be '0' or '1'.\n" "SYSCTL_RP_FILTER" "${SYSCTL_RP_FILTER}" >&2
|
||||||
exit 1
|
exit 1
|
||||||
|
@ -416,6 +431,7 @@ start() {
|
||||||
for proc_sys_file in /proc/sys/net/ipv4/conf/*/log_martians; do
|
for proc_sys_file in /proc/sys/net/ipv4/conf/*/log_martians; do
|
||||||
echo "${SYSCTL_LOG_MARTIANS}" > "${proc_sys_file}"
|
echo "${SYSCTL_LOG_MARTIANS}" > "${proc_sys_file}"
|
||||||
done
|
done
|
||||||
|
# Apparently not applicable to IPv6
|
||||||
else
|
else
|
||||||
printf "${RED}ERROR: invalid %s value '%s', must be '0' or '1'.\n" "SYSCTL_LOG_MARTIANS" "${SYSCTL_LOG_MARTIANS}" >&2
|
printf "${RED}ERROR: invalid %s value '%s', must be '0' or '1'.\n" "SYSCTL_LOG_MARTIANS" "${SYSCTL_LOG_MARTIANS}" >&2
|
||||||
exit 1
|
exit 1
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
VERSION="22.06"
|
VERSION="22.06.1"
|
||||||
|
|
||||||
show_version() {
|
show_version() {
|
||||||
cat <<END
|
cat <<END
|
||||||
|
@ -20,25 +20,33 @@ show_help() {
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
Usage: evomariabackup --backup-dir /path/to/mariabackup-target --compress-file /path/to/compressed.tgz
|
Usage: evomariabackup --backup-dir /path/to/mariabackup-target --compress-file /path/to/compressed.tgz
|
||||||
Options
|
Options
|
||||||
--backup-dir mariabackup target directory
|
|
||||||
--compress-file File name for the compressed version
|
|
||||||
--backup Force backup phase
|
--backup Force backup phase
|
||||||
--no-backup Skip backup phase
|
--no-backup Skip backup phase
|
||||||
|
--backup-dir mariabackup target directory
|
||||||
|
it enables backup phase if not explicitly disabled
|
||||||
--compress Force compress phase
|
--compress Force compress phase
|
||||||
--no-compress Skip compress phase
|
--no-compress Skip compress phase
|
||||||
|
--compress-file File name for the compressed version
|
||||||
|
it enables backup phase if not explicitly disabled
|
||||||
|
--mtree Force mtree phase
|
||||||
|
--no-mtree Skip mtree phase
|
||||||
|
--mtree-file File name for the mtree specification
|
||||||
|
it enables mtree phase if not explicitly disabled
|
||||||
--log-file Log file to send messages
|
--log-file Log file to send messages
|
||||||
--post-backup-hook Script to execute after other tasks
|
--post-backup-hook Script to execute after other tasks
|
||||||
--verbose Output much more information (to stdout/stderr or the log file)
|
--verbose Output much more information (to stdout/stderr or the log file)
|
||||||
--quiet Ouput only the most critical information
|
--quiet Ouput only the most critical information
|
||||||
--lock-file Specify which lock file to use (default: /run/lock/mariabackup.lock)
|
--lock-file Specify which lock file to use (default: /run/lock/mariabackup.lock)
|
||||||
--max-age Lock file is ignored if older than this (default: 1d)
|
--max-age Lock file is ignored if older than this (default: 1d)
|
||||||
|
--force-unlock If a lock is present, do as if it has expired
|
||||||
-h|--help|-? Display help
|
-h|--help|-? Display help
|
||||||
-V|--version Display version, authors and license
|
-V|--version Display version, authors and license
|
||||||
|
|
||||||
Example usage for a backup then compress :
|
Example usage for a backup, mtree then compress :
|
||||||
# /usr/local/bin/evomariabackup --verbose \
|
# /usr/local/bin/evomariabackup --verbose \
|
||||||
--backup-dir /backup/mariabackup/current \
|
--backup --backup-dir /backup/mariabackup/current \
|
||||||
--compress-file /backup/mariabackup/compressed/$(date +%H).tgz \
|
--mtree --mtree-file /backup/mariabackup/current.mtree \
|
||||||
|
--compress --compress-file /backup/mariabackup/compressed/$(date +\%H).tgz \
|
||||||
--log-file /var/log/evomariabackup.log
|
--log-file /var/log/evomariabackup.log
|
||||||
|
|
||||||
max-age possible values:
|
max-age possible values:
|
||||||
|
@ -139,7 +147,7 @@ duration_in_seconds() {
|
||||||
}
|
}
|
||||||
lock_file_created_at() {
|
lock_file_created_at() {
|
||||||
created_at=$(stat -c %Z "${lock_file}")
|
created_at=$(stat -c %Z "${lock_file}")
|
||||||
log_debug "Lock file ${lock_file} created at ${created_at}"
|
log_debug "Lock file \`${lock_file}' created at ${created_at}"
|
||||||
|
|
||||||
echo "${created_at}"
|
echo "${created_at}"
|
||||||
}
|
}
|
||||||
|
@ -148,10 +156,13 @@ lock_file_age() {
|
||||||
now=$(date +"%s")
|
now=$(date +"%s")
|
||||||
|
|
||||||
age=$(( now - last_change ))
|
age=$(( now - last_change ))
|
||||||
log_debug "Lock file ${lock_file} is ${age} seconds old"
|
log_debug "Lock file \`${lock_file}' is ${age} seconds old"
|
||||||
|
|
||||||
echo "${created_at}"
|
echo "${created_at}"
|
||||||
}
|
}
|
||||||
|
is_force_unlock() {
|
||||||
|
test "${force_unlock}" = "1"
|
||||||
|
}
|
||||||
is_lock_file_too_old() {
|
is_lock_file_too_old() {
|
||||||
test "$(lock_file_age)" -ge "${max_age}"
|
test "$(lock_file_age)" -ge "${max_age}"
|
||||||
}
|
}
|
||||||
|
@ -168,13 +179,20 @@ kill_or_clean_lockfile() {
|
||||||
log_debug "Found process with pid ${pid}"
|
log_debug "Found process with pid ${pid}"
|
||||||
|
|
||||||
lock_file_created_at_human=$(date --date "@$(lock_file_created_at)" +"%Y-%m-%d %H:%M:%S")
|
lock_file_created_at_human=$(date --date "@$(lock_file_created_at)" +"%Y-%m-%d %H:%M:%S")
|
||||||
if is_lock_file_too_old ; then
|
if is_lock_file_too_old || is_force_unlock ; then
|
||||||
# Kill the children
|
# Kill the children
|
||||||
pkill -9 --parent "${pid}"
|
pkill -9 --parent "${pid}"
|
||||||
# Kill the parent
|
# Kill the parent
|
||||||
kill -9 "${pid}"
|
kill -9 "${pid}"
|
||||||
# Only one process can run in parallel
|
# Only one process can run in parallel
|
||||||
log_warning "Process \`${pid}' (started at ${lock_file_created_at_human}) has been killed by \`$$'"
|
if is_lock_file_too_old; then
|
||||||
|
unlock_reason="lock is older than ${max_age}"
|
||||||
|
elif is_force_unlock; then
|
||||||
|
unlock_reason="--force-unlock was used"
|
||||||
|
else
|
||||||
|
unlock_reason="unknown reason"
|
||||||
|
fi
|
||||||
|
log_warning "Process \`${pid}' (started at ${lock_file_created_at_human}) has been killed by \`$$' (${unlock_reason})."
|
||||||
else
|
else
|
||||||
log_info "Process \`${pid}' (started at ${lock_file_created_at_human}) has precedence. Let's leave it work."
|
log_info "Process \`${pid}' (started at ${lock_file_created_at_human}) has precedence. Let's leave it work."
|
||||||
# make sure that this exit doesn't remove the existing lockfile !!
|
# make sure that this exit doesn't remove the existing lockfile !!
|
||||||
|
@ -188,7 +206,7 @@ kill_or_clean_lockfile() {
|
||||||
fi
|
fi
|
||||||
# Remove the lock file
|
# Remove the lock file
|
||||||
rm -f "${lock_file}"
|
rm -f "${lock_file}"
|
||||||
log_debug "Lock file ${lock_file} has been removed"
|
log_debug "Lock file \`${lock_file}' has been removed"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
new_lock_file() {
|
new_lock_file() {
|
||||||
|
@ -197,9 +215,9 @@ new_lock_file() {
|
||||||
|
|
||||||
if mkdir --parents "${lock_dir}"; then
|
if mkdir --parents "${lock_dir}"; then
|
||||||
echo $$ > "${lock_file}"
|
echo $$ > "${lock_file}"
|
||||||
log_debug "Lock file '${lock_file}' has been created"
|
log_debug "Lock file \`${lock_file}' has been created"
|
||||||
else
|
else
|
||||||
log_fatal "Failed to acquire lock file '${lock_file}'. Abort."
|
log_fatal "Failed to acquire lock file \`${lock_file}'. Abort."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
@ -211,30 +229,30 @@ check_backup_dir() {
|
||||||
if [ -d "${backup_dir:?}" ]; then
|
if [ -d "${backup_dir:?}" ]; then
|
||||||
if [ "$(ls -A "${backup_dir:?}")" ]; then
|
if [ "$(ls -A "${backup_dir:?}")" ]; then
|
||||||
if is_mariabackup_directory "${backup_dir:?}"; then
|
if is_mariabackup_directory "${backup_dir:?}"; then
|
||||||
log_debug "The backup directory ${backup_dir:?} is not empty but looks like a mariabackup target. Let's clear it."
|
log_debug "The backup directory \`${backup_dir:?}' is not empty but looks like a mariabackup target. Let's clear it."
|
||||||
rm -rf "${backup_dir:?}"
|
rm -rf "${backup_dir:?}"
|
||||||
else
|
else
|
||||||
log_fatal "The backup directory ${backup_dir:?} is not empty and doesn't look like a mariabackup target. Please verify and clear the directory if you are sure."
|
log_fatal "The backup directory \`${backup_dir:?}' is not empty and doesn't look like a mariabackup target. Please verify and clear the directory if you are sure."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
log_debug "The backup directory ${backup_dir:?} exists but is empty. Let's proceed."
|
log_debug "The backup directory \`${backup_dir:?}' exists but is empty. Let's proceed."
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
log_debug "The backup directory ${backup_dir:?} doesn't exist. Let's proceed."
|
log_debug "The backup directory \`${backup_dir:?}' doesn't exist. Let's proceed."
|
||||||
fi
|
fi
|
||||||
mkdir -p "${backup_dir:?}"
|
mkdir -p "${backup_dir:?}"
|
||||||
}
|
}
|
||||||
check_compress_dir() {
|
check_compress_dir() {
|
||||||
if [ -d "${compress_dir:?}" ]; then
|
if [ -d "${compress_dir:?}" ]; then
|
||||||
log_debug "The compress_dir directory ${compress_dir:?} exists. Let's proceed."
|
log_debug "The compress_dir directory \`${compress_dir:?}' exists. Let's proceed."
|
||||||
else
|
else
|
||||||
log_debug "The compress_dir directory ${compress_dir:?} doesn't exist. Let's proceed."
|
log_debug "The compress_dir directory \`${compress_dir:?}' doesn't exist. Let's proceed."
|
||||||
fi
|
fi
|
||||||
mkdir -p "${compress_dir:?}"
|
mkdir -p "${compress_dir:?}"
|
||||||
}
|
}
|
||||||
|
|
||||||
backup() {
|
backup_phase() {
|
||||||
if [ -z "${backup_dir}" ]; then
|
if [ -z "${backup_dir}" ]; then
|
||||||
log_fatal "backup-dir option is empty"
|
log_fatal "backup-dir option is empty"
|
||||||
else
|
else
|
||||||
|
@ -243,7 +261,7 @@ backup() {
|
||||||
|
|
||||||
mariabackup_bin=$(command -v mariabackup)
|
mariabackup_bin=$(command -v mariabackup)
|
||||||
if [ -z "${mariabackup_bin}" ]; then
|
if [ -z "${mariabackup_bin}" ]; then
|
||||||
log_fatal "Couldn't find mariabackup.\nUse 'apt install mariadb-backup'."
|
log_fatal "Couldn't find mariabackup.\nYou can install it with 'apt install mariadb-backup'."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -301,46 +319,44 @@ backup() {
|
||||||
log_info "END mariabackup prepare phase"
|
log_info "END mariabackup prepare phase"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
list_files_with_size() {
|
mtree_phase() {
|
||||||
path=$1
|
|
||||||
find "${path}" -type f -exec du --bytes {} \; | sort -k2
|
|
||||||
}
|
|
||||||
dircheck_prepare() {
|
|
||||||
if [ -z "${backup_dir}" ]; then
|
if [ -z "${backup_dir}" ]; then
|
||||||
log_fatal "backup-dir option is empty"
|
log_fatal "backup-dir option is empty"
|
||||||
exit 1
|
exit 1
|
||||||
elif [ -e "${backup_dir}" ] && [ ! -d "${backup_dir}" ]; then
|
elif [ -e "${backup_dir}" ] && [ ! -d "${backup_dir}" ]; then
|
||||||
log_fatal "backup directory '${backup_dir}' exists but is not a directory"
|
log_fatal "backup directory \`${backup_dir}' exists but is not a directory"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
dircheck_cmd="dir-check"
|
if [ -z "${mtree_file}" ]; then
|
||||||
dircheck_bin=$(command -v ${dircheck_cmd})
|
mtree_file="${backup_dir}.mtree"
|
||||||
if [ -z "${dircheck_bin}" ]; then
|
fi
|
||||||
log_fatal "Couldn't find ${dircheck_cmd}."
|
|
||||||
|
mtree_cmd="mtree"
|
||||||
|
mtree_bin=$(command -v ${mtree_cmd})
|
||||||
|
if [ -z "${mtree_bin}" ]; then
|
||||||
|
log_fatal "Couldn't find ${mtree_cmd}.\nYou can install it with 'apt install mtree-netbsd'."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
backup_parent_dir=$(dirname "${backup_dir}")
|
backup_parent_dir=$(dirname "${backup_dir}")
|
||||||
backup_final_dir=$(basename "${backup_dir}")
|
backup_final_dir=$(basename "${backup_dir}")
|
||||||
|
|
||||||
log_info "BEGIN dir-check phase"
|
log_info "BEGIN mtree phase"
|
||||||
cwd=${PWD}
|
log_debug "Store mtree specification of \`${backup_dir}' to \`${mtree_file}' using \`${mtree_bin}'"
|
||||||
cd "${backup_parent_dir}" || log_fatal "Impossible to change to ${backup_parent_dir}"
|
|
||||||
|
|
||||||
"${dircheck_bin}" --prepare --dir "${backup_final_dir}"
|
"${mtree_bin}" -x -c -p "${backup_dir}" > "${mtree_file}"
|
||||||
|
|
||||||
cd ${cwd} || log_fatal "Impossible to change back to ${cwd}"
|
log_info "END mtree phase"
|
||||||
log_info "END dir-check phase"
|
|
||||||
}
|
}
|
||||||
compress() {
|
compress_phase() {
|
||||||
compress_dir=$(dirname "${compress_file}")
|
compress_dir=$(dirname "${compress_file}")
|
||||||
|
|
||||||
if [ -z "${backup_dir}" ]; then
|
if [ -z "${backup_dir}" ]; then
|
||||||
log_fatal "backup-dir option is empty"
|
log_fatal "backup-dir option is empty"
|
||||||
exit 1
|
exit 1
|
||||||
elif [ -e "${backup_dir}" ] && [ ! -d "${backup_dir}" ]; then
|
elif [ -e "${backup_dir}" ] && [ ! -d "${backup_dir}" ]; then
|
||||||
log_fatal "backup directory '${backup_dir}' exists but is not a directory"
|
log_fatal "backup directory \`${backup_dir}' exists but is not a directory"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
if [ -z "${compress_file}" ]; then
|
if [ -z "${compress_file}" ]; then
|
||||||
|
@ -359,13 +375,13 @@ compress() {
|
||||||
elif [ -n "${gzip_bin}" ]; then
|
elif [ -n "${gzip_bin}" ]; then
|
||||||
compress_program="${gzip_bin} -6"
|
compress_program="${gzip_bin} -6"
|
||||||
else
|
else
|
||||||
log_fatal "Couldn't find pigz nor gzip.\nUse 'apt install pigz' or 'apt install gzip'."
|
log_fatal "Couldn't find pigz nor gzip.\nYou can install it with 'apt install pigz' or 'apt install gzip'."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! is_quiet; then
|
if ! is_quiet; then
|
||||||
log_info "BEGIN compression phase"
|
log_info "BEGIN compression phase"
|
||||||
log_debug "Compression of ${backup_dir} to ${compress_file} using \`${compress_program}'"
|
log_debug "Compression of \`${backup_dir}' to \`${compress_file}' using \`${compress_program}'"
|
||||||
fi
|
fi
|
||||||
if is_quiet || ! is_verbose ; then
|
if is_quiet || ! is_verbose ; then
|
||||||
tar --use-compress-program="${compress_program}" -cf "${compress_file}" "${backup_dir}" >/dev/null 2>&1
|
tar --use-compress-program="${compress_program}" -cf "${compress_file}" "${backup_dir}" >/dev/null 2>&1
|
||||||
|
@ -381,13 +397,13 @@ compress() {
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ${tar_rc} -ne 0 ]; then
|
if [ ${tar_rc} -ne 0 ]; then
|
||||||
log_fatal "An error occured while compressing ${backup_dir} to ${compress_file}"
|
log_fatal "An error occured while compressing \`${backup_dir}' to \`${compress_file}'"
|
||||||
exit 1
|
exit 1
|
||||||
elif ! is_quiet; then
|
elif ! is_quiet; then
|
||||||
log_info "END compression phase"
|
log_info "END compression phase"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
post_backup_hook() {
|
post_backup_hook_phase() {
|
||||||
if [ -x "${post_backup_hook}" ]; then
|
if [ -x "${post_backup_hook}" ]; then
|
||||||
|
|
||||||
if ! is_quiet; then
|
if ! is_quiet; then
|
||||||
|
@ -417,25 +433,33 @@ post_backup_hook() {
|
||||||
}
|
}
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
|
if ! is_quiet; then
|
||||||
|
log_info "BEGIN evomariabackup"
|
||||||
|
fi
|
||||||
|
|
||||||
kill_or_clean_lockfile "${lock_file}"
|
kill_or_clean_lockfile "${lock_file}"
|
||||||
# shellcheck disable=SC2064
|
# shellcheck disable=SC2064
|
||||||
trap "rm -f ${lock_file};" 0
|
trap "rm -f ${lock_file};" 0
|
||||||
new_lock_file "${lock_file}"
|
new_lock_file "${lock_file}"
|
||||||
|
|
||||||
if [ "${do_backup}" = "1" ] && [ -n "${backup_dir}" ]; then
|
if [ "${do_backup}" = "1" ] && [ -n "${backup_dir}" ]; then
|
||||||
backup
|
backup_phase
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "${do_dircheck}" = "1" ] && [ -n "${backup_dir}" ]; then
|
if [ "${do_mtree}" = "1" ] && [ -n "${backup_dir}" ]; then
|
||||||
dircheck_prepare
|
mtree_phase
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "${do_compress}" = "1" ] && [ -n "${compress_file}" ]; then
|
if [ "${do_compress}" = "1" ] && [ -n "${compress_file}" ]; then
|
||||||
compress
|
compress_phase
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -n "${post_backup_hook}" ]; then
|
if [ -n "${post_backup_hook}" ]; then
|
||||||
post_backup_hook
|
post_backup_hook_phase
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! is_quiet; then
|
||||||
|
log_info "END evomariabackup"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -446,9 +470,11 @@ log_file=""
|
||||||
verbose=""
|
verbose=""
|
||||||
quiet=""
|
quiet=""
|
||||||
max_age=""
|
max_age=""
|
||||||
|
force_unlock=""
|
||||||
do_backup=""
|
do_backup=""
|
||||||
backup_dir=""
|
backup_dir=""
|
||||||
do_dircheck=""
|
do_mtree=""
|
||||||
|
mtree_file=""
|
||||||
do_compress=""
|
do_compress=""
|
||||||
compress_file=""
|
compress_file=""
|
||||||
post_backup_hook=""
|
post_backup_hook=""
|
||||||
|
@ -510,14 +536,6 @@ while :; do
|
||||||
log_fatal '"--backup-dir" requires a non-empty option argument.'
|
log_fatal '"--backup-dir" requires a non-empty option argument.'
|
||||||
;;
|
;;
|
||||||
|
|
||||||
--dir-check)
|
|
||||||
do_dircheck=1
|
|
||||||
;;
|
|
||||||
|
|
||||||
--no-dir-check)
|
|
||||||
do_dircheck=0
|
|
||||||
;;
|
|
||||||
|
|
||||||
--compress)
|
--compress)
|
||||||
do_compress=1
|
do_compress=1
|
||||||
;;
|
;;
|
||||||
|
@ -550,6 +568,38 @@ while :; do
|
||||||
log_fatal '"--compress-file" requires a non-empty option argument.'
|
log_fatal '"--compress-file" requires a non-empty option argument.'
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
--mtree)
|
||||||
|
do_mtree=1
|
||||||
|
;;
|
||||||
|
|
||||||
|
--no-mtree)
|
||||||
|
do_mtree=0
|
||||||
|
;;
|
||||||
|
|
||||||
|
--mtree-file)
|
||||||
|
# with value separated by space
|
||||||
|
if [ -n "$2" ]; then
|
||||||
|
mtree_file="$2"
|
||||||
|
if [ -z "${do_mtree}" ]; then
|
||||||
|
do_mtree=1
|
||||||
|
fi
|
||||||
|
shift
|
||||||
|
else
|
||||||
|
log_fatal '"--mtree-file" requires a non-empty option argument.'
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
--mtree-file=?*)
|
||||||
|
# with value speparated by =
|
||||||
|
mtree_file=${1#*=}
|
||||||
|
if [ -z "${do_mtree}" ]; then
|
||||||
|
do_mtree=1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
--mtree-file=)
|
||||||
|
# without value
|
||||||
|
log_fatal '"--mtree-file" requires a non-empty option argument.'
|
||||||
|
;;
|
||||||
|
|
||||||
--lock-file)
|
--lock-file)
|
||||||
# with value separated by space
|
# with value separated by space
|
||||||
if [ -n "$2" ]; then
|
if [ -n "$2" ]; then
|
||||||
|
@ -568,6 +618,10 @@ while :; do
|
||||||
log_fatal '"--lock-file" requires a non-empty option argument.'
|
log_fatal '"--lock-file" requires a non-empty option argument.'
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
--force-unlock)
|
||||||
|
force_unlock=1
|
||||||
|
;;
|
||||||
|
|
||||||
--log-file)
|
--log-file)
|
||||||
# with value separated by space
|
# with value separated by space
|
||||||
if [ -n "$2" ]; then
|
if [ -n "$2" ]; then
|
||||||
|
@ -623,7 +677,7 @@ while :; do
|
||||||
if tty -s; then
|
if tty -s; then
|
||||||
printf 'Unknown option : %s\n' "$1" >&2
|
printf 'Unknown option : %s\n' "$1" >&2
|
||||||
echo "" >&2
|
echo "" >&2
|
||||||
show_usage >&2
|
show_help >&2
|
||||||
exit 1
|
exit 1
|
||||||
else
|
else
|
||||||
log_fatal 'Unknown option : %s\n' "$1" >&2
|
log_fatal 'Unknown option : %s\n' "$1" >&2
|
||||||
|
@ -643,9 +697,19 @@ done
|
||||||
lock_file="${lock_file:-/run/lock/evomariabackup.lock}"
|
lock_file="${lock_file:-/run/lock/evomariabackup.lock}"
|
||||||
verbose=${verbose:-0}
|
verbose=${verbose:-0}
|
||||||
quiet=${quiet:-0}
|
quiet=${quiet:-0}
|
||||||
max_age="${max_age:-86400}"
|
max_age="${max_age:-1d}"
|
||||||
do_backup="${do_backup:-1}"
|
force_unlock=${force_unlock:-0}
|
||||||
do_dircheck="${do_dircheck:-0}"
|
# Enable backup phase if not disabled and backup_dir is set
|
||||||
do_compress="${do_compress:-0}"
|
if [ -z "${do_backup}" ] && [ -n "${backup_dir}" ]; then
|
||||||
|
do_backup="1"
|
||||||
|
fi
|
||||||
|
# Enable mtree phase if not disabled and mtree_file is set
|
||||||
|
if [ -z "${do_mtree}" ] && [ -n "${mtree_file}" ]; then
|
||||||
|
do_mtree="1"
|
||||||
|
fi
|
||||||
|
# Enable compress phase if not disabled and compress_file is set
|
||||||
|
if [ -z "${do_compress}" ] && [ -n "${compress_file}" ]; then
|
||||||
|
do_compress="1"
|
||||||
|
fi
|
||||||
|
|
||||||
main
|
main
|
Loading…
Reference in a new issue