diff --git a/src/functions.sh b/src/functions.sh index 6124175..2cd3666 100644 --- a/src/functions.sh +++ b/src/functions.sh @@ -15,17 +15,6 @@ scriptPath="$(dirname "$(readlink -f "$0")")" configPath="$(readlink -f "${scriptPath}/../config")" debug=false -if [[ ! -r "${configPath}/srb.cfg" ]]; then - # Start searching for common configuration paths - if [[ -r "$HOME/.config/systemrescue-backup/srb.cfg" ]]; then - configPath="$HOME/.config/systemrescue-backup" - elif [[ -r "/etc/systemrescue-backup/srb.cfg" ]]; then - configPath="/etc/systemrescue-backup" - else - echoerr "Warning: No configuration file path found. Defaults will be used." - fi -fi - ########################################################### ### Utility & Common Functions @@ -35,6 +24,23 @@ is_bin_in_path() { builtin type -P "$1" &>/dev/null } +# Check if argument is number. +is_num() { + [[ -n "$1" && "$1" -eq "$1" ]] 2>/dev/null +} + +# Convert signal name to signal number. +to_sig_num() { + if is_num "$1"; then + # Signal is already number. + kill -l "$1" >/dev/null # Check that signal number is valid. + echo "$1" # Return result. + else + # Convert to signal number. + kill -l "$1" + fi +} + echoreg() { if [[ "$1" == "-d" ]]; then shift @@ -187,6 +193,79 @@ run_modules() { done } +init_squashfs() { + truncate -s0 "${systemrescue_data_dir}/sysrescue/build_into_srm/.squashfs-pseudo" +} + +add_to_squashfs() { + local input="$1" + + if $debug; then + echo "Adding to SquashFS: $1" + fi + echo "$1" >> "${systemrescue_data_dir}/sysrescue/build_into_srm/.squashfs-pseudo" +} + +add_path_to_squashfs() { + local path="$1" + local dir_perm="$2" + local file_perm="$3" + local file_owner="$4" + local file_group="$5" + local perm + + [[ -z "$dir_perm" ]] && dir_perm="755" + [[ -z "$file_perm" ]] && file_perm="644" + [[ -z "$file_owner" ]] && file_owner="root" + [[ -z "$file_group" ]] && file_group="root" + + while read -r file; do + if [[ -d "$file" ]]; then + [[ "$dir_perm" == "match" ]] && perm="$(stat -c "%a" "$file")" || perm="$dir_perm" + #add_to_squashfs "${file/${systemrescue_data_dir}\/sysrescue\/build_into_srm\///} m $dir_perm root root" + elif [[ -f "$file" ]]; then + [[ "$file_perm" == "match" ]] && perm="$(stat -c "%a" "$file")" || perm="$file_perm" + #add_to_squashfs "${file/${systemrescue_data_dir}\/sysrescue\/build_into_srm\///} m $file_perm root root" + fi + add_to_squashfs "${file/${systemrescue_data_dir}\/sysrescue\/build_into_srm\///} m $perm root root" + done < <(find "$path") +} + +trap_add() { + local handler="${1:?Handler required}" + #local signal="${2:?Signal required}" + local signals=("${@:2}") + local hdls + local signal + + if [[ "${#signals[@]}" -lt 1 ]]; then + echo_fail 1 "Signal required" + fi + + if $debug; then + echo "=====================================================" + fi + + for signal in "${signals[@]}"; do + hdls="$( trap -p "${signal}" | cut -f2 -d \' )" + trap "${hdls}${hdls:+;}${handler}" "${signal}" + if $debug; then + echo "Adding Trap: $handler (${signal})" + echo "Old Traps: $hdls" + fi + done + + if $debug; then + echo "Current Traps:" + trap -p "${signals[@]}" + fi + + if $debug; then + echo "=====================================================" + fi +} + + ########################################################### ### BACKUP and RESTORE FUNCTIONS ########################################################### @@ -243,7 +322,7 @@ restore_btrfs_subvolumes() { done < "${restoreDir}/btrfs.dump" } -restore_btfs_mounts() { +restore_btrfs_mounts() { local rootBase mountSource mountDest rootBase="$1" @@ -257,3 +336,19 @@ restore_btfs_mounts() { mount "$mountSource" "${rootBase}/${mountDest}" done < "$restoreDir/mounts.dump" } + + +########################################################### +### Initialization +########################################################### + +if [[ ! -r "${configPath}/srb.cfg" ]]; then + # Start searching for common configuration paths + if [[ -r "$HOME/.config/systemrescue-backup/srb.cfg" ]]; then + configPath="$HOME/.config/systemrescue-backup" + elif [[ -r "/etc/systemrescue-backup/srb.cfg" ]]; then + configPath="/etc/systemrescue-backup" + else + echoerr "Warning: No configuration file path found. Defaults will be used." + fi +fi diff --git a/src/recovery/execute/100_build b/src/recovery/execute/100_build new file mode 100644 index 0000000..b5cb353 --- /dev/null +++ b/src/recovery/execute/100_build @@ -0,0 +1,7 @@ +#!/bin/bash + +"${systemrescue_data_dir}/systemrescue-customize" --auto --overwrite \ + --source="${systemrescue_cache_dir}/systemrescue-${systemrescue_cd_version}-amd64.iso" \ + --dest="${systemrescue_data_dir}/systemrescue-backup-${systemrescue_cd_version}-amd64.iso" \ + --recipe-dir="${systemrescue_data_dir}/sysrescue" \ + --work-dir="${systemrescue_temp_dir}/customize" diff --git a/src/recovery/finalize/100_cleanup b/src/recovery/finalize/100_cleanup index fe941e1..cf118b4 100644 --- a/src/recovery/finalize/100_cleanup +++ b/src/recovery/finalize/100_cleanup @@ -1,8 +1,12 @@ #!/bin/bash -umount "${systemrescue_data_dir}/build/build_into_srm/var/backups/systemrescue-backup/backupdb" &>/dev/null -umount "${systemrescue_data_dir}/build/build_into_srm/etc/resticprofile" &>/dev/null +umount "${systemrescue_data_dir}/sysrescue/build_into_srm/var/backups/systemrescue-backup/backupdb" &>/dev/null +umount "${systemrescue_data_dir}/sysrescue/build_into_srm/etc/resticprofile" &>/dev/null -if [[ -d "${systemrescue_data_dir}/build/build_into_srm" ]]; then - rm -rf "${systemrescue_data_dir}/build/build_into_srm" || exit 1 +if [[ -d "${systemrescue_data_dir}/sysrescue/build_into_srm" ]]; then + rm -rf "${systemrescue_data_dir}/sysrescue/build_into_srm" || exit 1 +fi + +if [[ -d "${systemrescue_temp_dir}/customize" ]]; then + rm -rf "${systemrescue_temp_dir}/customize" || exit_fail 100 "Failed to clean up directory: ${systemrescue_temp_dir}/customize" fi diff --git a/src/recovery/prepare/050_preprocess b/src/recovery/prepare/050_preprocess new file mode 100644 index 0000000..d2da226 --- /dev/null +++ b/src/recovery/prepare/050_preprocess @@ -0,0 +1,5 @@ +#!/bin/bash + +if [[ -n "$systemrescue_cd_iso_url" ]]; then + systemrescue_cd_iso_url="${systemrescue_cd_iso_url//\{SYSRESCUECD_VERSION\}/$systemrescue_cd_version}" +fi diff --git a/src/recovery/prepare/100_prepare b/src/recovery/prepare/100_prepare index e729eea..68d408a 100644 --- a/src/recovery/prepare/100_prepare +++ b/src/recovery/prepare/100_prepare @@ -1,21 +1,64 @@ #!/bin/bash -mkdir -p "$systemrescue_data_dir" || return 1 -mkdir -p "$systemrescue_temp_dir" || return 1 -mkdir -p "$systemrescue_cache_dir" || return 1 +# Ensure initial required directories exist +mkdir -p "$systemrescue_data_dir" || exit_fail 10 "FATAL: Failed to create systemrescue_data_dir" +mkdir -p "$systemrescue_cache_dir" || exit_fail 10 "FATAL: Failed to create systemrescue_cache_dir" +if [[ -d "$systemrescue_temp_dir" ]]; then + # Clean out Temporary Directory + rm -rf "$systemrescue_temp_dir" || exit_fail 10 "FATAL: Failed to clean systemrescue_temp_dir" +fi +mkdir -p "$systemrescue_temp_dir" || exit_fail 10 "FATAL: Failed to create systemrescue_temp_dir" +trap_add "rm -rf \"$systemrescue_temp_dir\"" EXIT -mkdir -p "${systemrescue_data_dir}/build/build_into_srm/var/backups/systemrescue-backup/backupdb" || return 1 -#mount --bind "${systemrescue_data_dir}/backupdb" "${systemrescue_data_dir}/build/build_into_srm/var/backups/systemrescue-backup/backupdb" || exit 1 -if ! mount --bind "${systemrescue_data_dir}/backupdb" "${systemrescue_data_dir}/build/build_into_srm/var/backups/systemrescue-backup/backupdb"; then - if ! cp -a "${systemrescue_data_dir}/backupdb/" "${systemrescue_data_dir}/build/build_into_srm/var/backups/systemrescue-backup/backupdb/"; then - exit_fail 205 "FATAL: Failed to copy backupdb files over to recovery image build" - fi +# Download SystemRescueCD ISO and Customize script +curl -C - -Lso \ + "${systemrescue_cache_dir}/systemrescue-${systemrescue_cd_version}-amd64.iso" \ + "$systemrescue_cd_iso_url" +curl -C - -Lso \ + "${systemrescue_data_dir}/systemrescue-customize" \ + "$systemrescue_cd_customize_url" +chmod 755 "${systemrescue_data_dir}/systemrescue-customize" +mkdir "${systemrescue_temp_dir}/customize" || exit_fail 10 "FATAL: Failed to create customize directory in systemrescue_temp_dir" + +# Copy SysRescue Skeleton configuration over to Disc staging directory +mkdir -p "${systemrescue_data_dir}/sysrescue" || exit_fail 10 "FATAL: Could not create sysrescue directory in systemrescue_data_dir" +if ! cp -a "${configPath}/sysrescue/." "${systemrescue_data_dir}/sysrecue/"; then + exit_fail 205 "FATAL: Failed to copy sysrescue config files over to recovery image build" +fi +trap_add "rm -rf \"${systemrescue_data_dir}/sysrescue\"" EXIT + +# Copy SystemRescue-Backup Configuration to Disc staging directory +mkdir -p "${systemrescue_data_dir}/sysrescue/build_into_srm/etc/systemrescue-backup" || exit_fail 10 "FATAL: Could not create sysrescue config directory in systemrescue_data_dir" +if ! cp -a "${configPath}/." "${systemrescue_data_dir}/sysrescue/build_into_srm/etc/systemrescue-backup/"; then + exit_fail 205 "FATAL: Failed to copy SRB config files over to recovery image build" fi -# mkdir -p "${systemrescue_data_dir}/build/build_into_srm/etc/resticprofile" -# if ! mount --bind "${resticprofile_config_dir}" "${systemrescue_data_dir}/build/build_into_srm/etc/resticprofile"; then -# if ! cp -a "${resticprofile_config_dir}" "${systemrescue_data_dir}/build/build_into_srm/etc/resticprofile"; then -# exit_fail 205 "FATAL: Failed to copy resticprofile config files over to recovery image build" -# fi -# fi -#mount --bind "/etc/resticprofile" "${systemrescue_data_dir}/build/build_into_srm/etc/resticprofile" || return 1 +# Copy backupdb to Disc staging directory +mkdir -p "${systemrescue_data_dir}/sysrescue/build_into_srm/var/backups/systemrescue-backup/backupdb" || exit_fail 10 "FATAL: Could not create backupdb directory in systemrescue_data_dir" +if ! cp -a "${systemrescue_data_dir}/backupdb/." "${systemrescue_data_dir}/sysrescue/build_into_srm/var/backups/systemrescue-backup/backupdb/"; then + exit_fail 205 "FATAL: Failed to copy backupdb files over to recovery image build" +fi + +# Copy SystemRescue-Backup to Disc staging directory +mkdir -p "${systemrescue_data_dir}/sysrescue/build_into_srm/usr/lib/systemrescue-backup" || exit_fail 10 "FATAL: Could not create SystemRescueBackup Script directory in systemrescue_data_dir" +if ! cp -a "${scriptPath}/." "${systemrescue_data_dir}/sysrescue/build_into_srm/usr/lib/systemrescue-backup/"; then + exit_fail 205 "FATAL: Failed to copy SystemRescue-Backup Scripts over to recovery image build" +fi +mkdir -p "${systemrescue_data_dir}/sysrescue/build_into_srm/usr/local/bin" || exit_fail 10 "FATAL: Could not create usr/local/bin directory in systemrescue_data_dir" +if ! ln -srf "${systemrescue_data_dir}/sysrescue/build_into_srm/usr/lib/systemrescue-backup/srb" "${systemrescue_data_dir}/sysrescue/build_into_srm/usr/local/bin/srb"; then + exit_fail 205 "FATAL: Failed to create srb symlink in usr/local/bin in recovery image build directory" +fi + +# Setup SquashFS-Pseudo Permissions on files & directories. +init_squashfs +add_to_squashfs "/etc m 755 root root" +add_to_squashfs "/var m 755 root root" +add_to_squashfs "/usr m 755 root root" +add_to_squashfs "/usr/lib m 755 root root" +add_to_squashfs "/usr/local m 755 root root" +add_to_squashfs "/usr/local/bin m 755 root root" + +add_path_to_squashfs "${systemrescue_data_dir}/sysrescue/build_into_srm/etc/systemrescue-backup" 700 600 +add_path_to_squashfs "${systemrescue_data_dir}/sysrescue/build_into_srm/var/backups" 700 600 +add_path_to_squashfs "${systemrescue_data_dir}/sysrescue/build_into_srm/root" 700 600 +add_path_to_squashfs "${systemrescue_data_dir}/sysrescue/build_into_srm/usr/lib/systemrescue-backup" match match diff --git a/src/resticprofile/execute/100_null b/src/resticprofile/execute/100_null new file mode 100644 index 0000000..057bbe1 --- /dev/null +++ b/src/resticprofile/execute/100_null @@ -0,0 +1,3 @@ +#!/bin/bash + +# Placemat for doing nothing. diff --git a/src/resticprofile/finalize/100_cleanup b/src/resticprofile/finalize/100_cleanup index f1e4915..98d6e02 100644 --- a/src/resticprofile/finalize/100_cleanup +++ b/src/resticprofile/finalize/100_cleanup @@ -1,5 +1,5 @@ #!/bin/bash -if [[ -d "${systemrescue_data_dir}/build/build_into_srm/usr/local/bin" ]]; then - rm -rf "${systemrescue_data_dir}/build/build_into_srm/usr/local/bin" || return 1 +if [[ -d "${systemrescue_data_dir}/sysrescue/build_into_srm/usr/local/bin" ]]; then + rm -rf "${systemrescue_data_dir}/sysrescue/build_into_srm/usr/local/bin" || return 1 fi diff --git a/src/resticprofile/init/001_default b/src/resticprofile/init/001_default index ba7c804..c9a9fdd 100644 --- a/src/resticprofile/init/001_default +++ b/src/resticprofile/init/001_default @@ -5,6 +5,8 @@ echoreg -d "Loaded resticprofile Recovery Module Initialization" # Setup Defaults according to what's been develeoped and tested restic_version="0.17.0" resticprofile_version="0.28.0" +restic_url="https://github.com/restic/restic/releases/download/v{RESTIC_VERSION}/restic_{RESTIC_VERSION}_linux_amd64.bz2" +resticprofile_url="https://github.com/creativeprojects/resticprofile/releases/download/v{RESTICPROFILE_VERSION}/resticprofile_{RESTICPROFILE_VERSION}_linux_amd64.tar.gz" resticprofile_config_dir="/etc/resticprofile" resticprofile_init_find_config() { diff --git a/src/resticprofile/prepare/050_preprocess b/src/resticprofile/prepare/050_preprocess new file mode 100644 index 0000000..8307341 --- /dev/null +++ b/src/resticprofile/prepare/050_preprocess @@ -0,0 +1,9 @@ +#!/bin/bash + +if [[ -n "$restic_url" ]]; then + restic_url="${restic_url//\{RESTIC_VERSION\}/$restic_version}" +fi + +if [[ -n "$resticprofile_url" ]]; then + resticprofile_url="${resticprofile_url//\{RESTICPROFILE_VERSION\}/$resticprofile_version}" +fi diff --git a/src/resticprofile/prepare/100_prepare b/src/resticprofile/prepare/100_prepare index 7c9b763..18a5dd7 100644 --- a/src/resticprofile/prepare/100_prepare +++ b/src/resticprofile/prepare/100_prepare @@ -4,47 +4,63 @@ echoreg "Using SystemRescueCD Version: $systemrescue_cd_version" echoreg "Using Restic Version: $restic_version" echoreg "Using ResticProfile Version: $resticprofile_version" -mkdir -p "${systemrescue_cache_dir}" || return 1 -mkdir -p "${systemrescue_data_dir}/build/build_into_srm/usr/local/bin" || return 1 -mkdir -p "${systemrescue_temp_dir}/restic-install" || return 1 +# Create iniital required staging directories +mkdir -p "${systemrescue_cache_dir}" || exit_fail 100 "FATAL: Could not create systemrescue_cache_dir" +mkdir -p "${systemrescue_data_dir}/sysrescue/build_into_srm/usr/local/bin" || exit_fail 100 "FATAL: Could not create directory: ${systemrescue_data_dir}/sysrescue/build_into_srm/usr/local/bin" +mkdir -p "${systemrescue_temp_dir}/restic-install" || exit_fail 100 "FATAL: Could not create directory: ${systemrescue_temp_dir}/restic-install" +# Download, Extract, and Install if it's not cached already: restic if [[ ! -f "${systemrescue_cache_dir}/restic_${restic_version}_linux_amd64.bz2" ]]; then - curl -C - -Lso "${systemrescue_cache_dir}/restic_${restic_version}_linux_amd64.bz2" "https://github.com/restic/restic/releases/download/v${restic_version}/restic_${restic_version}_linux_amd64.bz2" || return 1 + curl -C - -Lso \ + "${systemrescue_cache_dir}/restic_${restic_version}_linux_amd64.bz2" \ + "$restic_url" fi -bunzip2 -k "${systemrescue_cache_dir}/restic_${restic_version}_linux_amd64.bz2" || return 1 +bunzip2 -kf "${systemrescue_cache_dir}/restic_${restic_version}_linux_amd64.bz2" || exit_fail 101 "FATAL: Failed to extract restic binary" chmod 755 "${systemrescue_cache_dir}/restic_${restic_version}_linux_amd64" chown root:root "${systemrescue_cache_dir}/restic_${restic_version}_linux_amd64" -mv "${systemrescue_cache_dir}/restic_${restic_version}_linux_amd64" "${systemrescue_data_dir}/build/build_into_srm/usr/local/bin/restic" || return 1 +mv "${systemrescue_cache_dir}/restic_${restic_version}_linux_amd64" "${systemrescue_data_dir}/sysrescue/build_into_srm/usr/local/bin/restic" || exit_fail 102 "FATAL: Failed to move restic binary to sysrescue build directory" +# Download, Extract, and Install if it's not cached already: resticprofile if [[ ! -f "${systemrescue_cache_dir}/resticprofile_${resticprofile_version}_linux_amd64.tar.gz" ]]; then - curl -C - -Lso "${systemrescue_cache_dir}/resticprofile_${resticprofile_version}_linux_amd64.tar.gz" "https://github.com/creativeprojects/resticprofile/releases/download/v${resticprofile_version}/resticprofile_${resticprofile_version}_linux_amd64.tar.gz" || return 1 + curl -C - -Lso \ + "${systemrescue_cache_dir}/resticprofile_${resticprofile_version}_linux_amd64.tar.gz" \ + "$resticprofile_url" + #"https://github.com/creativeprojects/resticprofile/releases/download/v${resticprofile_version}/resticprofile_${resticprofile_version}_linux_amd64.tar.gz" || return 1 fi -tar -xzf "${systemrescue_cache_dir}/resticprofile_${resticprofile_version}_linux_amd64.tar.gz" -C "${systemrescue_temp_dir}/restic-install" || return 1 +tar -xzf "${systemrescue_cache_dir}/resticprofile_${resticprofile_version}_linux_amd64.tar.gz" -C "${systemrescue_temp_dir}/restic-install" || exit_fail 101 "FATAL: Failed to extract resticprofile archive" chmod 755 "${systemrescue_temp_dir}/restic-install/resticprofile" chown root:root "${systemrescue_temp_dir}/restic-install/resticprofile" -mv "${systemrescue_temp_dir}/restic-install/resticprofile" "${systemrescue_data_dir}/build/build_into_srm/usr/local/bin/resticprofile" || return 1 -rm -rf "${systemrescue_temp_dir}/restic-install" || return 1 +mv "${systemrescue_temp_dir}/restic-install/resticprofile" "${systemrescue_data_dir}/sysrescue/build_into_srm/usr/local/bin/resticprofile" || exit_fail 102 "FATAL: Failed to move resticprofile binary to sysrescue build directory" +rm -rf "${systemrescue_temp_dir}/restic-install" || exit_fail 100 "FATAL: Failed to remove temporary restic-install directory" -mkdir -p "${systemrescue_data_dir}/build/build_into_srm/etc/resticprofile" -if ! mount --bind "${resticprofile_config_dir}" "${systemrescue_data_dir}/build/build_into_srm/etc/resticprofile"; then - if ! cp -a "${resticprofile_config_dir}" "${systemrescue_data_dir}/build/build_into_srm/etc/"; then - exit_fail 205 "FATAL: Failed to copy resticprofile config files over to recovery image build" - fi +# Copy resticprofile configuration to Disc staging directory +mkdir -p "${systemrescue_data_dir}/sysrescue/build_into_srm/etc/resticprofile" +if ! cp -a "${resticprofile_config_dir}/." "${systemrescue_data_dir}/sysrescue/build_into_srm/etc/resticprofile/"; then + exit_fail 205 "FATAL: Failed to copy resticprofile config files over to recovery image build" fi -if $debug; then - echo "===========================================================================" - echo "Cache Dir: $systemrescue_cache_dir" - ls -lR "$systemrescue_cache_dir" - echo "=====" - echo +add_to_squashfs "/usr/local/bin/restic m 755 root root" +add_to_squashfs "/usr/local/bin/resticprofile m 755 root root" +add_path_to_squashfs "${systemrescue_data_dir}/sysrescue/build_into_srm/etc/resticprofile" 700 600 - echo "Data Dir: $systemrescue_data_dir" - ls -lR "$systemrescue_data_dir" - echo "=====" - echo +# if $debug; then +# echo "===========================================================================" +# echo "Cache Dir: $systemrescue_cache_dir" +# ls -lR "$systemrescue_cache_dir" +# echo "=====" +# echo - echo "Temp Dir: $systemrescue_temp_dir" - ls -lR "$systemrescue_temp_dir" - echo "===========================================================================" -fi +# echo "Data Dir: $systemrescue_data_dir" +# ls -lR "$systemrescue_data_dir" +# echo "=====" +# echo + +# echo "Temp Dir: $systemrescue_temp_dir" +# ls -lR "$systemrescue_temp_dir" +# echo "===========================================================================" + +# echo "SquashFS Definitions:" +# echo +# cat "${systemrescue_data_dir}/sysrescue/build_into_srm/.squashfs-pseudo" +# echo "===========================================================================" +# fi