dropshell/source/agent-remote/datacommands.sh
Your Name f7294e01e4
Some checks failed
Dropshell Test / Build_and_Test (push) Failing after 2m40s
:-'Generic Commit'
2025-05-28 20:40:24 +12:00

219 lines
7.2 KiB
Bash
Executable File

#!/bin/bash
# This script contains the common code for the autocommands.
MYID=$(id -u)
MYGRP=$(id -g)
_autocommandrun_volume() {
local command="$1"
local volume_name="$2"
local backup_folder="$3"
case "$command" in
create)
if docker volume ls | grep -q "${volume_name}"; then
echo "Volume ${volume_name} already exists - leaving unchanged"
return
fi
echo "Creating volume ${volume_name}"
docker volume create "${volume_name}"
;;
destroy)
echo "Destroying volume ${volume_name}"
docker volume rm "${volume_name}"
;;
backup)
echo "Backing up volume ${volume_name}"
docker run --rm -v "${volume_name}":/volume -v "${backup_folder}":/backup debian bash -c "tar -czvf /backup/backup.tgz -C /volume . && chown -R $MYID:$MYGRP /backup"
;;
restore)
echo "Restoring volume ${volume_name}"
docker volume rm "${volume_name}"
docker volume create "${volume_name}"
docker run --rm -v "${volume_name}":/volume -v "${backup_folder}":/backup debian bash -c "tar -xzvf /backup/backup.tgz -C /volume --strip-components=1"
;;
esac
}
_autocommandrun_path() {
local command="$1"
local path="$2"
local backup_folder="$3"
case "$command" in
create)
if [ -d "${path}" ]; then
echo "Path ${path} already exists - unchanged"
return
fi
echo "Creating path ${path}"
mkdir -p "${path}"
;;
destroy)
echo "Destroying path ${path}"
local path_parent;
path_parent=$(dirname "${path}")
local path_child;
path_child=$(basename "${path}")
if [ -d "${path_parent}/${path_child}" ]; then
docker run --rm -v "${path_parent}":/volume debian bash -c "rm -rfv /volume/${path_child}" || echo "Failed to destroy path ${path}"
else
echo "Path ${path} does not exist - nothing to destroy"
fi
;;
backup)
echo "Backing up path ${path}"
if [ -d "${path}" ]; then
docker run --rm -v "${path}":/path -v "${backup_folder}":/backup debian bash -c "tar -czvf /backup/backup.tgz -C /path . && chown -R $MYID:$MYGRP /backup"
else
echo "Path ${path} does not exist - nothing to backup"
fi
;;
restore)
if [ ! -f "${backup_folder}/backup.tgz" ]; then
echo "Backup file ${backup_folder}/backup.tgz does not exist - nothing to restore"
else
echo "Clearing existing data in path ${path}"
docker run --rm -v "${path}":/path debian bash -c "rm -rfv /path/{*,.*}"
echo "Restoring path ${path} from backup file ${backup_folder}/backup.tgz"
tar -xzvf "${backup_folder}/backup.tgz" -C "${path}" --strip-components=1
fi
;;
esac
}
_autocommandrun_file() {
local command="$1"
local filepath="$2"
local backup_folder="$3"
case "$command" in
create)
local file_parent;
file_parent=$(dirname "${filepath}")
local file_name;
file_name=$(basename "${filepath}")
if [ ! -d "${file_parent}" ]; then
echo "Parent directory ${file_parent} of ${file_name} does not exist - creating"
mkdir -p "${file_parent}"
fi
;;
destroy)
rm -f "${filepath}"
;;
backup)
echo "Backing up file ${filepath}"
local file_parent;
file_parent=$(dirname "${filepath}")
local file_name;
file_name=$(basename "${filepath}")
if [ -f "${file_parent}/${file_name}" ]; then
docker run --rm -v "${file_parent}":/volume -v "${backup_folder}":/backup debian bash -c "cp /volume/${file_name} /backup/${file_name} && chown -R $MYID:$MYGRP /backup"
else
echo "File ${filepath} does not exist - nothing to backup"
fi
;;
restore)
echo "Restoring file ${filepath}"
local file_name;
file_name=$(basename "${filepath}")
rm -f "${filepath}" || die "Unable to remove existing file ${filepath}, restore failed."
cp "${backup_folder}/${file_name}" "${filepath}" || die "Unable to copy file ${backup_folder}/${file_name} to ${filepath}, restore failed."
;;
esac
}
_autocommandparse() {
# first argument is the command
# if the command is backup or restore, then the last two arguments are the backup file and the temporary path
# all other arguments are of form:
# key=value
# where key can be one of volume, path or file.
# value is the path or volume name.
# we iterate over the key=value arguments, and for each we call:
# autorun <command> <backupfile> <key> <value>
local command="$1"
shift
local backup_temp_path="$1"
shift
echo "autocommandparse: command=$command backup_temp_path=$backup_temp_path"
# Extract the backup file and temp path (last two arguments)
local args=("$@")
local arg_count=${#args[@]}
# Process all key=value pairs
for ((i=0; i<$arg_count; i++)); do
local pair="${args[$i]}"
# Skip if not in key=value format
if [[ "$pair" != *"="* ]]; then
continue
fi
local key="${pair%%=*}"
local value="${pair#*=}"
# create backup folder unique to key/value.
local bfolder;
bfolder=$(echo "${key}_${value}" | tr -cd '[:alnum:]_-')
local targetpath="${backup_temp_path}/${bfolder}"
mkdir -p "${targetpath}"
# Key must be one of volume, path or file
case "$key" in
volume)
_autocommandrun_volume "$command" "$value" "$targetpath"
;;
path)
_autocommandrun_path "$command" "$value" "$targetpath"
;;
file)
_autocommandrun_file "$command" "$value" "$targetpath"
;;
*)
_die "Unknown key $key passed to auto${command}. We only support volume, path and file."
;;
esac
done
}
datacreate() {
_autocommandparse create none "$@"
}
datadestroy() {
_autocommandparse destroy none "$@"
}
databackup() {
_check_required_env_vars "BACKUP_FILE" "TEMP_DIR"
BACKUP_TEMP_PATH="$TEMP_DIR/backup"
mkdir -p "$BACKUP_TEMP_PATH"
echo "_autocommandparse [backup] [$BACKUP_TEMP_PATH]" "$@"
_autocommandparse backup "$BACKUP_TEMP_PATH" "$@"
tar zcvf "$BACKUP_FILE" -C "$BACKUP_TEMP_PATH" .
}
datarestore() {
_check_required_env_vars "BACKUP_FILE" "TEMP_DIR"
BACKUP_TEMP_PATH="$TEMP_DIR/restore"
echo "_autocommandparse [restore] [$BACKUP_TEMP_PATH]" "$@"
mkdir -p "$BACKUP_TEMP_PATH"
tar zxvf "$BACKUP_FILE" -C "$BACKUP_TEMP_PATH" --strip-components=1
_autocommandparse restore "$BACKUP_TEMP_PATH" "$@"
}