diff --git a/CHANGELOG b/CHANGELOG index 9c23b4d..a4c6d8a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - base: set the title of the terminal when connecting to a server +- base: import dump-server-state.sh script - post-install: add a version number to motd-carp-state.sh - nagios-nrpe : add a check dhcp_pool diff --git a/roles/base/files/dump-server-state.sh b/roles/base/files/dump-server-state.sh new file mode 100644 index 0000000..841c5ef --- /dev/null +++ b/roles/base/files/dump-server-state.sh @@ -0,0 +1,754 @@ +#!/bin/sh + +PROGNAME="dump-server-state" +REPOSITORY="https://gitea.evolix.org/evolix/dump-server-state" + +VERSION="22.03" +readonly VERSION + +dump_dir= +rc=0 + +# base functions + +show_version() { + cat <, + Jérémy Lecour , + Éric Morino , + Brice Waegeneire , + Jérémy Dubois + and others. + +${REPOSITORY} + +${PROGNAME} comes with ABSOLUTELY NO WARRANTY.This is free software, +and you are welcome to redistribute it under certain conditions. +See the GNU General Public License v3.0 for details. +END +} +show_help() { + cat < "${dump_dir}/packages.txt") + last_rc=$? + + if [ ${last_rc} -eq 0 ]; then + debug "* pkg_info OK" + else + debug "* pkg_info ERROR :" + debug "${last_result}" + rc=10 + fi + + last_result=$(pkg_info -m > "${dump_dir}/packages_manual.txt") + last_rc=$? + + if [ ${last_rc} -eq 0 ]; then + debug "* pkg_info -m OK" + else + debug "* pkg_info -m ERROR :" + debug "${last_result}" + rc=10 + fi +} + +task_uname() { + debug "Task: uname" + + last_result=$(uname -a > "${dump_dir}/uname.txt") + last_rc=$? + + if [ ${last_rc} -eq 0 ]; then + debug "* uname OK" + else + debug "* uname ERROR" + debug "${last_result}" + rc=10 + fi +} + +task_uptime() { + debug "Task: uptime" + + last_result=$(uptime > "${dump_dir}/uptime.txt") + last_rc=$? + + if [ ${last_rc} -eq 0 ]; then + debug "* uptime OK" + else + debug "* uptime ERROR" + debug "${last_result}" + rc=10 + fi +} + +task_processes() { + debug "Task: Process list" + + last_result=$(ps auwwx > "${dump_dir}/ps.txt") + last_rc=$? + + if [ ${last_rc} -eq 0 ]; then + debug "* ps OK" + else + debug "* ps ERROR" + debug "${last_result}" + rc=10 + fi + + pstree_bin=$(command -v pstree) + + if [ -n "${pstree_bin}" ]; then + last_result=$(${pstree_bin} -w > "${dump_dir}/pstree.txt") + last_rc=$? + + if [ ${last_rc} -eq 0 ]; then + debug "* pstree OK" + else + debug "* pstree ERROR" + debug "${last_result}" + rc=10 + fi + fi +} + +task_fstat() { + debug "Task: Network status" + + last_result=$({ fstat | head -1 ; fstat | grep internet ; } > "${dump_dir}/fstat.txt") + last_rc=$? + + if [ ${last_rc} -eq 0 ]; then + debug "* fstat OK" + else + debug "* fstat ERROR" + debug "${last_result}" + rc=10 + fi +} + +task_netcfg() { + debug "Task: Network configuration" + + last_result=$(ifconfig -A > "${dump_dir}/ifconfig.txt") + last_rc=$? + + if [ ${last_rc} -eq 0 ]; then + debug "* ifconfig OK" + else + debug "* ifconfig ERROR" + debug "${last_result}" + rc=10 + fi + + last_result=$(netstat -nr > "${dump_dir}/routes.txt") + last_rc=$? + + if [ ${last_rc} -eq 0 ]; then + debug "* netstat OK" + else + debug "* netstat ERROR" + debug "${last_result}" + rc=10 + fi +} + +task_pfctl() { + debug "Task : PacketFilter" + + last_result=$(pfctl -sa > "${dump_dir}/pfctl.txt") + last_rc=$? + + if [ ${last_rc} -eq 0 ]; then + debug "* pfctl OK" + else + debug "* pfctl ERROR" + debug "${last_result}" + rc=10 + fi +} + +task_sysctl() { + debug "Task: sysctl values" + + sysctl_bin=$(command -v sysctl) + + if [ -n "${sysctl_bin}" ]; then + last_result=$(${sysctl_bin} -a 2>/dev/null | sort -h > "${dump_dir}/sysctl.txt") + last_rc=$? + + if [ ${last_rc} -eq 0 ]; then + debug "* sysctl OK" + else + debug "* sysctl ERROR" + debug "${last_result}" + rc=10 + fi + else + debug "* sysctl not found" + fi +} + +task_disks() { + debug "Task: Disks" + + sysctl_bin=$(command -v sysctl) + + if [ -n "${sysctl_bin}" ]; then + disks=$(${sysctl_bin} hw.disknames | grep -Eo "(wd|sd)[0-9]*") + for disk in ${disks}; do + disklabel_bin=$(command -v disklabel) + if [ -n "${disklabel_bin}" ]; then + last_result=$(${disklabel_bin} "${disk}" > "${dump_dir}/partitions-${disk}") + last_rc=$? + + if [ ${last_rc} -eq 0 ]; then + debug "* disklabel ${disk} OK" + else + debug "* disklabel ${disk} ERROR" + debug "${last_result}" + rc=10 + fi + else + debug "* disklabel not found" + fi + + bioctl_bin=$(command -v bioctl) + if [ -n "${bioctl_bin}" ]; then + last_result=$(${bioctl_bin} "${disk}" 2>/dev/null > "${dump_dir}/bioctl-${disk}") + last_rc=$? + + if [ ${last_rc} -eq 0 ]; then + debug "* bioctl ${disk} OK" + else + debug "* bioctl ${disk} ERROR" + debug "${last_result}" + rc=10 + fi + else + debug "* bioctl not found" + fi + + atactl_bin=$(command -v atactl) + if [ -n "${atactl_bin}" ]; then + last_result=$(${atactl_bin} "${disk}" 2>/dev/null > "${dump_dir}/atactl-${disk}") + last_rc=$? + + if [ ${last_rc} -eq 0 ]; then + debug "* atactl ${disk} OK" + else + debug "* atactl ${disk} ERROR" + debug "${last_result}" + rc=10 + fi + else + debug "* atactl not found" + fi + + done + cat "${dump_dir}"/partitions-* > "${dump_dir}/partitions" + cat "${dump_dir}"/bioctl-* > "${dump_dir}/bioctl" + cat "${dump_dir}"/atactl-* > "${dump_dir}/atactl" + else + debug "* sysctl not found" + fi +} + +task_mount() { + debug "Task: Mount points" + + mount_bin=$(command -v mount) + + if [ -n "${mount_bin}" ]; then + last_result=$(${mount_bin} > "${dump_dir}/mount.txt") + last_rc=$? + + if [ ${last_rc} -eq 0 ]; then + debug "* mount points OK" + else + debug "* mount points ERROR" + debug "${last_result}" + rc=10 + fi + else + debug "* mount not found" + fi +} + +task_df() { + debug "Task: df" + + df_bin=$(command -v df) + + if [ -n "${df_bin}" ]; then + last_result=$(${df_bin} > "${dump_dir}/df.txt") + last_rc=$? + + if [ ${last_rc} -eq 0 ]; then + debug "* df OK" + else + debug "* df ERROR" + debug "${last_result}" + rc=10 + fi + else + debug "* df not found" + fi +} + +task_dmesg() { + debug "Task: dmesg" + + dmesg_bin=$(command -v dmesg) + + if [ -n "${dmesg_bin}" ]; then + last_result=$(${dmesg_bin} > "${dump_dir}/dmesg.txt") + last_rc=$? + + if [ ${last_rc} -eq 0 ]; then + debug "* dmesg OK" + else + debug "* dmesg ERROR" + debug "${last_result}" + rc=10 + fi + + last_result=$(${dmesg_bin} -s > "${dump_dir}/dmesg-console.txt") + last_rc=$? + + if [ ${last_rc} -eq 0 ]; then + debug "* dmesg console buffer OK" + else + debug "* dmesg console buffer ERROR" + debug "${last_result}" + rc=10 + fi + + else + debug "* dmesg not found" + fi +} + +task_rcctl() { + debug "Task: Services" + + rcctl_bin=$(command -v rcctl) + + if [ -n "${rcctl_bin}" ]; then + last_result=$(${rcctl_bin} ls failed > "${dump_dir}/rcctl-failed-services.txt") + last_rc=$? + + if [ ${last_rc} -eq 0 ]; then + debug "* failed services OK" + else + debug "* failed services ERROR" + debug "${last_result}" + rc=10 + fi + + last_result=$(${rcctl_bin} ls on > "${dump_dir}/rcctl-on-services.txt") + last_rc=$? + + if [ ${last_rc} -eq 0 ]; then + debug "* on services OK" + else + debug "* on services ERROR" + debug "${last_result}" + rc=10 + fi + + last_result=$(${rcctl_bin} ls started > "${dump_dir}/rcctl-started-services.txt") + last_rc=$? + + if [ ${last_rc} -eq 0 ]; then + debug "* started services OK" + else + debug "* started services ERROR" + debug "${last_result}" + rc=10 + fi + + else + debug "* rcctl not found" + fi +} + + +main() { + if [ -z "${dump_dir}" ]; then + echo "ERROR: You must provide the --dump-dir argument" >&2 + exit 1 + fi + + if [ -d "${dump_dir}" ]; then + if [ "${FORCE}" != "1" ]; then + echo "ERROR: The dump directory ${dump_dir} already exists. Delete it first." >&2 + exit 2 + fi + else + create_dump_dir + fi + + if [ "${TASK_ETC}" -eq 1 ]; then + task_etc + fi + if [ "${TASK_PACKAGES}" -eq 1 ]; then + task_packages + fi + if [ "${TASK_UNAME}" -eq 1 ]; then + task_uname + fi + if [ "${TASK_UPTIME}" -eq 1 ]; then + task_uptime + fi + if [ "${TASK_PROCESSES}" -eq 1 ]; then + task_processes + fi + if [ "${TASK_FSTAT}" -eq 1 ]; then + task_fstat + fi + if [ "${TASK_NETCFG}" -eq 1 ]; then + task_netcfg + fi + if [ "${TASK_PFCTL}" -eq 1 ]; then + task_pfctl + fi + if [ "${TASK_SYSCTL}" -eq 1 ]; then + task_sysctl + fi + if [ "${TASK_DISKS}" -eq 1 ]; then + task_disks + fi + if [ "${TASK_MOUNT}" -eq 1 ]; then + task_mount + fi + if [ "${TASK_DF}" -eq 1 ]; then + task_df + fi + if [ "${TASK_DMESG}" -eq 1 ]; then + task_dmesg + fi + if [ "${TASK_RCCTL}" -eq 1 ]; then + task_rcctl + fi + + + debug "=> Your dump is available at ${dump_dir}" + exit ${rc} +} + +# 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 + ;; + -v|--verbose) + VERBOSE=1 + ;; + + -f|--force) + FORCE=1 + ;; + + -d|--dump-dir) + # with value separated by space + if [ -n "$2" ]; then + dump_dir=$2 + shift + else + printf 'ERROR: "-d|--dump-dir" requires a non-empty option argument.\n' >&2 + exit 1 + fi + ;; + --dump-dir=?*) + # with value speparated by = + dump_dir=${1#*=} + ;; + --dump-dir=) + # without value + printf 'ERROR: "--dump-dir" requires a non-empty option argument.\n' >&2 + exit 1 + ;; + + --all) + for option in \ + TASK_ETC \ + TASK_PACKAGES \ + TASK_UNAME \ + TASK_UPTIME \ + TASK_PROCESSES \ + TASK_FSTAT \ + TASK_NETCFG \ + TASK_PFCTL \ + TASK_SYSCTL \ + TASK_DISKS \ + TASK_MOUNT \ + TASK_DF \ + TASK_DMESG \ + TASK_RCCTL + do + eval "${option}=1" + done + ;; + + --none) + for option in \ + TASK_ETC \ + TASK_PACKAGES \ + TASK_UNAME \ + TASK_UPTIME \ + TASK_PROCESSES \ + TASK_FSTAT \ + TASK_NETCFG \ + TASK_PFCTL \ + TASK_SYSCTL \ + TASK_DISKS \ + TASK_MOUNT \ + TASK_DF \ + TASK_DMESG \ + TASK_RCCTL + do + eval "${option}=0" + done + ;; + + --etc) + TASK_ETC=1 + ;; + --no-etc) + TASK_ETC=0 + ;; + + --packages) + TASK_PACKAGES=1 + ;; + --no-packages) + TASK_PACKAGES=0 + ;; + + --uname) + TASK_UNAME=1 + ;; + --no-uname) + TASK_UNAME=0 + ;; + + --uptime) + TASK_UPTIME=1 + ;; + --no-uptime) + TASK_UPTIME=0 + ;; + + --processes) + TASK_PROCESSES=1 + ;; + --no-processes) + TASK_PROCESSES=0 + ;; + + --fstat) + TASK_FSTAT=1 + ;; + --no-fstat) + TASK_FSTAT=0 + ;; + + --netcfg) + TASK_NETCFG=1 + ;; + --no-netcfg) + TASK_NETCFG=0 + ;; + + --pfctl) + TASK_PFCTL=1 + ;; + --no-pfctl) + TASK_PFCTL=0 + ;; + + --sysctl) + TASK_SYSCTL=1 + ;; + --no-sysctl) + TASK_SYSCTL=0 + ;; + + --disks) + TASK_DISKS=1 + ;; + --no-disks) + TASK_DISKS=0 + ;; + + --mount) + TASK_MOUNT=1 + ;; + --no-mount) + TASK_MOUNT=0 + ;; + + --df) + TASK_DF=1 + ;; + --no-df) + TASK_DF=0 + ;; + + --dmesg) + TASK_DMESG=1 + ;; + --no-dmesg) + TASK_DMESG=0 + ;; + + --rcctl) + TASK_RCCTL=1 + ;; + --no-rcctl) + TASK_RCCTL=0 + ;; + + --) + # End of all options. + shift + break + ;; + -?*) + # ignore unknown options + printf 'WARN: Unknown option : %s\n' "$1" >&2 + exit 1 + ;; + *) + # Default case: If no more options then break out of the loop. + break + ;; + esac + + shift +done + +# Default values +: "${VERBOSE:=0}" +: "${FORCE:=0}" +: "${TASK_ETC:=0}" +: "${TASK_PACKAGES:=1}" +: "${TASK_UNAME:=1}" +: "${TASK_UPTIME:=1}" +: "${TASK_PROCESSES:=1}" +: "${TASK_FSTAT:=1}" +: "${TASK_NETCFG:=1}" +: "${TASK_PFCTL:=1}" +: "${TASK_SYSCTL:=1}" +: "${TASK_DISKS:=1}" +: "${TASK_MOUNT:=1}" +: "${TASK_DF:=1}" +: "${TASK_DMESG:=1}" +: "${TASK_RCCTL:=1}" + +export LC_ALL=C + +set -u + +main diff --git a/roles/base/files/zzz_evobackup b/roles/base/files/zzz_evobackup index e7fc3dc..20b619c 100755 --- a/roles/base/files/zzz_evobackup +++ b/roles/base/files/zzz_evobackup @@ -324,11 +324,11 @@ if [ "${LOCAL_TASKS}" = "1" ]; then server_state_dir="${LOCAL_BACKUP_DIR}/server-state" - backup_server_state_bin=$(command -v backup-server-state) + dump_server_state_bin=$(command -v dump-server-state) if [ "${SYSTEM}" = "linux" ]; then - if [ -n "${backup_server_state_bin}" ]; then - ${backup_server_state_bin} --etc --dpkg-full --force --backup-dir "${server_state_dir}" + if [ -n "${dump_server_state_bin}" ]; then + ${dump_server_state_bin} --all --force --backup-dir "${server_state_dir}" else mkdir -p "${server_state_dir}" @@ -366,8 +366,8 @@ if [ "${LOCAL_TASKS}" = "1" ]; then cat ${server_state_dir}/partitions-* > ${server_state_dir}/partitions fi else - if [ -n "${backup_server_state_bin}" ]; then - ${backup_server_state_bin} --etc --force --backup-dir "${server_state_dir}" + if [ -n "${dump_server_state_bin}" ]; then + ${dump_server_state_bin} --all --force --backup-dir "${server_state_dir}" else mkdir -p "${server_state_dir}" diff --git a/roles/base/tasks/main.yml b/roles/base/tasks/main.yml index a7bb5f8..c536ee0 100644 --- a/roles/base/tasks/main.yml +++ b/roles/base/tasks/main.yml @@ -11,3 +11,4 @@ - include: cron.yml - include: fstab.yml - include: ntp.yml +- include: utils.yml diff --git a/roles/base/tasks/utils.yml b/roles/base/tasks/utils.yml new file mode 100644 index 0000000..f1ed300 --- /dev/null +++ b/roles/base/tasks/utils.yml @@ -0,0 +1,9 @@ +--- +- name: dump-server-state script is present + copy: + src: "dump-server-state.sh" + dest: /usr/local/sbin/dump-server-state + force: True + owner: root + group: wheel + mode: "0750"