captaincore/app/backup/download
2026-03-05 18:56:33 -05:00

124 lines
3.8 KiB
Bash
Executable file

#!/usr/bin/env bash
#
# Runs custom bash script or WP-CLI commands on a site.
#
# `captaincore site backup download <site> <backup_id> <payload_id>`
#
# [<email>]
# Sent email with downloadable link
#
if [ ${#@} -ne 3 ]; then
echo -e "${COLOR_RED}Error:${COLOR_NORMAL} Please specify <site> <backup-id> and <payload-id>."
fi
while read config; do
if [[ "$config" == "Error:"* ]]; then
continue
fi
declare "$config"
done <<< "$(captaincore config fetch --captain-id=$CAPTAIN_ID)"
site=$1
backup_id=$2
payload_id=$3
# Extract environment
if [[ "$site" == *"-staging"* ]]; then
environment=staging
fi
if [[ "$site" == *"-production"* ]]; then
environment=production
fi
if [[ "$site" != *"-"* ]]; then
environment=production
fi
mkdir -p "${CAPTAINCORE_PATH}/data/payload/"
payload_file="${CAPTAINCORE_PATH}/data/payload/${payload_id}.txt"
# Load site configs
IFS=$'\n'$'\r'; for line in $(captaincore site get $site --bash --captain-id=$CAPTAIN_ID); do declare "$line"; done; unset IFS
timestamp=$( date +'%Y-%m-%d_%H-%M-%S' )
restore_path="$path/${site}_${site_id}/${environment}/restores/${timestamp}-${backup_id:0:8}"
zip_name="${site}_${environment}_${backup_id:0:8}_at_$timestamp.zip"
mkdir -p "$restore_path"
if [[ -n "$payload_id" && -f "$payload_file" ]]; then
read -r -d '' php_code << heredoc
\$data = json_decode( base64_decode( file_get_contents ( "$payload_file" ) ) );
\$files = \$data->files;
\$directories = \$data->directories;
if ( ! empty( \$directories ) ) {
file_put_contents ( "$restore_path/directories_to_restore.txt", implode( PHP_EOL, \$directories ) );
}
file_put_contents ( "$restore_path/files_to_restore.txt", implode( PHP_EOL, \$files ) );
heredoc
php -r "$php_code"
fi
restic_repo="rclone:$rclone_backup/${site}_${site_id}/${environment}/restic-repo"
restic_args=(--repo "$restic_repo" --password-file "${CAPTAINCORE_PATH}/data/restic.key")
# Get snapshot timestamp
read -r -d '' php_code << heredoc
\$snapshots = json_decode( file_get_contents( "php://stdin" ) );
\$dt = new DateTime( \$snapshots[0]->time );
echo \$dt->format( "Y-m-d g:i:s a" );
heredoc
timestamp=$( restic snapshots ${backup_id:0:8} --json "${restic_args[@]}" | php -r "$php_code" )
# Build --include flags from files and directories
include_args=()
if [ -f "${restore_path}/files_to_restore.txt" ]; then
while IFS= read -r file || [ -n "$file" ]; do
include_args+=(--include "$file")
done < "${restore_path}/files_to_restore.txt"
fi
if [ -f "${restore_path}/directories_to_restore.txt" ]; then
while IFS= read -r dir || [ -n "$dir" ]; do
include_args+=(--include "${dir}/**")
done < "${restore_path}/directories_to_restore.txt"
fi
# Restore files directly from restic (no FUSE mount needed)
echo "Restoring from Restic repo"
restic restore ${backup_id:0:8} --target "${restore_path}/restore/" "${restic_args[@]}" "${include_args[@]}"
cd $restore_path
zip -qr ${zip_name} restore/
rm -rf ${restore_path}/restore/
# Moves snapshot to Backblaze archive folder
rclone move $zip_name $rclone_snapshot/${site}_${site_id}/
backup_url=$( captaincore backup fetch-link --zip-name="$zip_name" --site=$site --site-id=$site_id --captain-id=$CAPTAIN_ID )
echo $backup_url
if [[ $FLAG_EMAIL != "" ]]; then
count=$(( $( wc -l "$restore_path/files_to_restore.txt" | awk '{ print $1 }' ) + 1 ))
if [[ $captaincore_dev == true ]]; then
curl_argument="-k"
fi
curl ${curl_argument} --silent --request POST "$captaincore_api" --header "Content-Type: application/json" --data @- << EOF
{
"command": "backup-download-notify",
"token": "$token",
"site_id": "$site_id",
"data": {
"email": "$FLAG_EMAIL",
"environment": "$environment",
"file_count": $count,
"timestamp": "$timestamp",
"download_url": "$backup_url"
}
}
EOF
fi