-
Notifications
You must be signed in to change notification settings - Fork 2
/
github-to-b2
executable file
·169 lines (148 loc) · 4.49 KB
/
github-to-b2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#!/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