169 lines
4.5 KiB
Bash
Executable file
169 lines
4.5 KiB
Bash
Executable file
#!/bin/bash
|
|
|
|
# Script to backup git repo(s) to Backblaze B2
|
|
|
|
# Usage
|
|
read -r -d '' __usage <<-'EOF' || true
|
|
Options:
|
|
-b --b2-bucket [arg] Backblaze B2 bucket name.
|
|
-i --b2-id [arg] Backblaze B2 account ID.
|
|
-k --b2-key [arg] Backblaze B2 application key.
|
|
-g --github-account [arg] GitHub account name.
|
|
-p --https-password [arg] GitHub account password (for private repos)
|
|
-t --temp-dir [arg] Dir to use for temp files.
|
|
-s --use-https Use HTTPS to clone instead of SSH
|
|
|
|
-h --help This page.
|
|
EOF
|
|
__helptext='NOTE: --temp-dir defaults to "$(mktemp -d)" if not specified.'
|
|
|
|
# Load BASH3 Boilerplate functions
|
|
source bash3boilerplate/main.sh
|
|
|
|
# Color fix for rxvt-unicode (tell b3bp we're xterm)
|
|
if [[ "${TERM}" =~ rxvt-unicode-.*color ]]; then
|
|
TERM="xterm"
|
|
fi
|
|
|
|
# Functions
|
|
function clone_repository() {
|
|
# Clone the repo using either HTTPS or SSH
|
|
local repo="${1:-}"
|
|
local repo_url=""
|
|
if [[ "${arg_s}" == "1" ]]; then
|
|
# Use HTTPS
|
|
repo_url="github.com/${__github_account}/${repo}.git"
|
|
if [[ "${arg_p:-}" != "" ]]; then
|
|
repo_url="https://${__github_account}:${arg_p}@${repo_url}"
|
|
else
|
|
repo_url="https://${repo_url}"
|
|
fi
|
|
else
|
|
# Use SSH
|
|
repo_url="git@github.com:${__github_account}/${repo}.git"
|
|
fi
|
|
git clone --mirror \
|
|
"${repo_url}" \
|
|
"${__temp_dir}/${repo}-${__date}.git"
|
|
}
|
|
function compress_repository() {
|
|
# Move to repository dir so relative paths are used in the archive
|
|
local repo_source="${1:-}"
|
|
local archive_dest="${2:-}"
|
|
local repo_path="$(dirname "$(realpath "${repo_source}")")"
|
|
local repo_source="$(basename "$(realpath "${repo_source}")")"
|
|
local archive_dest="$(realpath "${archive_dest}")"
|
|
pushd "${repo_path}" >/dev/null
|
|
|
|
# Create archive
|
|
tar cpzf "${archive_dest}" "${repo_source}"
|
|
|
|
# Done
|
|
popd >/dev/null
|
|
}
|
|
function find_b2_cmd() {
|
|
if which backblaze-b2 >/dev/null 2>&1; then
|
|
# Arch Linux uses this name
|
|
echo "backblaze-b2"
|
|
elif which b2 > /dev/null 2>&1; then
|
|
echo "b2"
|
|
else
|
|
__b3bp_log error "B2 command-line tool not found"
|
|
exit 1
|
|
fi
|
|
}
|
|
function fix_repository_name() {
|
|
# Remove '.git' from the name (if present)
|
|
local repository="${1:-}"
|
|
if [[ "${repository: -4:4}" == ".git" ]]; then
|
|
repository="${repository:0: -4}"
|
|
fi
|
|
echo "${repository}"
|
|
}
|
|
function main() {
|
|
# Create the __temp_dir
|
|
mkdir -p "${__temp_dir}"
|
|
|
|
# Authorize B2 account
|
|
"${__b2_cmd}" authorize-account "${__b2_id}" "${__b2_key}"
|
|
|
|
# Loop over repos
|
|
for repo in "${@}"; do
|
|
repo="$(fix_repository_name "${repo}")"
|
|
|
|
echo "Backing up ${repo}"
|
|
|
|
# Clone repo
|
|
echo "Cloning ${repo}"
|
|
clone_repository "${repo}"
|
|
|
|
# Compress repo
|
|
echo "Compressing ${repo}"
|
|
compress_repository "${__temp_dir}/${repo}-${__date}.git" \
|
|
"${__temp_dir}/${repo}-${__date}.git.tgz"
|
|
|
|
# Upload repo
|
|
echo "Uploading ${repo}"
|
|
"${__b2_cmd}" upload-file "${__b2_bucket}" \
|
|
"${__temp_dir}/${repo}-${__date}.git.tgz" \
|
|
"${__github_account}/${repo}-${__date}.git.tgz"
|
|
|
|
# Cleanup
|
|
/bin/rm "${__temp_dir}/${repo}-${__date}.git.tgz"
|
|
/bin/rm -rf "${__temp_dir}/${repo}-${__date}.git"
|
|
|
|
# Done
|
|
echo "Successfully backed up ${repo}"
|
|
done
|
|
|
|
# Remove __temp_dir (if empty)
|
|
/bin/rmdir --ignore-fail-on-non-empty "${__temp_dir}"
|
|
}
|
|
|
|
# Set env
|
|
__b2_bucket="${arg_b}"
|
|
__b2_cmd="$(find_b2_cmd)"
|
|
__b2_id="${arg_i}"
|
|
__b2_key="${arg_k}"
|
|
__date="$(date '+%F_%H%M%z')"
|
|
__github_account="${arg_g}"
|
|
__temp_dir="${arg_t:-}"
|
|
if [[ "$__temp_dir" == "" ]]; then
|
|
__temp_dir="$(mktemp -d)"
|
|
fi
|
|
|
|
# Check args
|
|
__run="yes"
|
|
if [[ "${arg_h}" == "0" ]]; then
|
|
# Show missing arg warnings only if help arg isn't specified
|
|
[[ -z "${arg_b:-}" ]] && echo "B2 bucket not specified" && __run="no"
|
|
[[ -z "${arg_i:-}" ]] && echo "B2 ID not specified" && __run="no"
|
|
[[ -z "${arg_k:-}" ]] && echo "B2 Key not specified" && __run="no"
|
|
[[ -z "${arg_g:-}" ]] && echo "GitHub account not specified" && __run="no"
|
|
[[ "${#}" == "0" ]] && echo "No repos specified" && __run="no"
|
|
fi
|
|
|
|
# Debug
|
|
#echo "== Debug =="
|
|
#echo "b: [${arg_b}]"
|
|
#echo "i: [${arg_i}]"
|
|
#echo "k: [${arg_k}]"
|
|
#echo "g: [${arg_g}]"
|
|
#echo "t: [${arg_t}]"
|
|
#echo "p: [${arg_p}]"
|
|
#echo ""
|
|
#echo "s: [${arg_s}]"
|
|
#echo "h: [${arg_h}]"
|
|
#echo ""
|
|
#echo "r: [${@}]"
|
|
#echo "== Debug =="
|
|
|
|
# Show help or run backups
|
|
if [[ "${arg_h}" = 1 ]] || [[ "${__run}" == "no" ]]; then
|
|
# -h or --help used or missing argument(s), show usage and exit
|
|
help "Usage: ${__base} [options] repo(s)..."
|
|
else
|
|
# Backup repo(s)
|
|
main "${@}"
|
|
fi
|
|
exit 0
|