Skip to content

Commit a78d9da

Browse files
committed
2025-07-02 20:22:55
1 parent 289271b commit a78d9da

File tree

2 files changed

+105
-53
lines changed

2 files changed

+105
-53
lines changed

app.backup_fs.conf

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# -------------------------------------------------------------------------------------------------------------------- #
2+
# GENERAL
3+
# -------------------------------------------------------------------------------------------------------------------- #
4+
15
FS_SRC=(
26
'/etc'
37
'/opt'
@@ -6,18 +10,49 @@ FS_SRC=(
610
'/var/vmail'
711
)
812
FS_DST='/tmp/backup_fs'
9-
FS_TPL="$( date -u '+%m' )/$( date -u '+%d' )"
13+
FS_TPL="$( date -u '+%m' )/$( date -u '+%d' )-$( date -u '+%H' )"
14+
15+
# -------------------------------------------------------------------------------------------------------------------- #
16+
# ENCRYPTION
17+
# -------------------------------------------------------------------------------------------------------------------- #
18+
1019
ENC_ON=0
1120
ENC_APP='gpg'
1221
ENC_PASS='SECRET'
13-
SYNC_ON=0
14-
SYNC_HOST='192.168.1.1'
15-
SYNC_USER='root'
16-
SYNC_PASS='PASSWORD'
17-
SYNC_DST='/remote/directory'
22+
23+
# -------------------------------------------------------------------------------------------------------------------- #
24+
# SSH FS
25+
# -------------------------------------------------------------------------------------------------------------------- #
26+
27+
SSH_ON=0
28+
SSH_HOST='192.168.1.1'
29+
SSH_USER='root'
30+
SSH_PASS='PASSWORD'
31+
SSH_DST='/remote/directory'
32+
SSH_MNT='/mnt/backup'
33+
34+
# -------------------------------------------------------------------------------------------------------------------- #
35+
# RSYNC
36+
# -------------------------------------------------------------------------------------------------------------------- #
37+
38+
RSYNC_ON=0
39+
RSYNC_HOST='192.168.1.1'
40+
RSYNC_USER='root'
41+
RSYNC_PASS='PASSWORD'
42+
RSYNC_DST='/remote/directory'
43+
44+
# -------------------------------------------------------------------------------------------------------------------- #
45+
# MAIL
46+
# -------------------------------------------------------------------------------------------------------------------- #
47+
1848
MAIL_ON=0
1949
MAIL_FROM='postmaster@example.org'
2050
MAIL_TO=('mail@example.org')
51+
52+
# -------------------------------------------------------------------------------------------------------------------- #
53+
# GITLAB
54+
# -------------------------------------------------------------------------------------------------------------------- #
55+
2156
GITLAB_ON=0
2257
GITLAB_API='http://example.org/api/v4'
2358
GITLAB_PROJECT='0'

app.backup_fs.sh

Lines changed: 64 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,11 @@ FS_TPL="${FS_TPL:?}"; readonly FS_TPL
2929
ENC_ON="${ENC_ON:?}"; readonly ENC_ON
3030
ENC_APP="${ENC_APP:?}"; readonly ENC_APP
3131
ENC_PASS="${ENC_PASS:?}"; readonly ENC_PASS
32-
SYNC_ON="${SYNC_ON:?}"; readonly SYNC_ON
33-
SYNC_HOST="${SYNC_HOST:?}"; readonly SYNC_HOST
34-
SYNC_USER="${SYNC_USER:?}"; readonly SYNC_USER
35-
SYNC_PASS="${SYNC_PASS:?}"; readonly SYNC_PASS
36-
SYNC_DST="${SYNC_DST:?}"; readonly SYNC_DST
32+
RSYNC_ON="${RSYNC_ON:?}"; readonly RSYNC_ON
33+
RSYNC_HOST="${RSYNC_HOST:?}"; readonly RSYNC_HOST
34+
RSYNC_USER="${RSYNC_USER:?}"; readonly RSYNC_USER
35+
RSYNC_PASS="${RSYNC_PASS:?}"; readonly RSYNC_PASS
36+
RSYNC_DST="${RSYNC_DST:?}"; readonly RSYNC_DST
3737
MAIL_ON="${MAIL_ON:?}"; readonly MAIL_ON
3838
MAIL_FROM="${MAIL_FROM:?}"; readonly MAIL_FROM
3939
MAIL_TO=("${MAIL_TO[@]:?}"); readonly MAIL_TO
@@ -42,6 +42,13 @@ GITLAB_API="${GITLAB_API:?}"; readonly GITLAB_API
4242
GITLAB_PROJECT="${GITLAB_PROJECT:?}"; readonly GITLAB_PROJECT
4343
GITLAB_TOKEN="${GITLAB_TOKEN:?}"; readonly GITLAB_TOKEN
4444

45+
# Variables.
46+
LOG_MOUNT="${SRC_DIR}/log.fs_mount"
47+
LOG_CHECK="${SRC_DIR}/log.fs_check"
48+
LOG_BACKUP="${SRC_DIR}/log.fs_backup"
49+
LOG_SYNC="${SRC_DIR}/log.fs_sync"
50+
LOG_CLEAN="${SRC_DIR}/log.fs_clean"
51+
4552
# -------------------------------------------------------------------------------------------------------------------- #
4653
# -----------------------------------------------------< SCRIPT >----------------------------------------------------- #
4754
# -------------------------------------------------------------------------------------------------------------------- #
@@ -53,7 +60,7 @@ function _msg() {
5360
case "${type}" in
5461
'error') echo "${msg}" >&2; exit 1 ;;
5562
'success') echo "${msg}" ;;
56-
*) return 1 ;;
63+
*) exit 1 ;;
5764
esac
5865
}
5966

@@ -100,35 +107,26 @@ EOF
100107
}
101108

102109
function _gpg() {
103-
local out; out="${1}.gpg"
104-
local pass; pass="${2}"
105-
106-
gpg --batch --passphrase "${pass}" --symmetric --output "${out}" \
110+
gpg --batch --passphrase "${2}" --symmetric --output "${1}.gpg" \
107111
--s2k-cipher-algo "${ENC_S2K_CIPHER:-AES256}" \
108112
--s2k-digest-algo "${ENC_S2K_DIGEST:-SHA512}" \
109113
--s2k-count "${ENC_S2K_COUNT:-65536}"
110114
}
111115

112116
function _ssl() {
113-
local out; out="${1}.ssl"
114-
local pass; pass="${2}"
115-
116-
openssl enc "-${ENC_SSL_CIPHER:-aes-256-cfb}" -out "${out}" -pass "pass:${pass}" \
117+
openssl enc "-${ENC_SSL_CIPHER:-aes-256-cfb}" -out "${1}.ssl" -pass "pass:${2}" \
117118
-salt -md "${ENC_SSL_DIGEST:-sha512}" -iter "${ENC_SSL_COUNT:-65536}" -pbkdf2
118119
}
119120

120121
function _enc() {
121-
local out; out="${1}"
122-
local pass; pass="${ENC_PASS}"
123-
124122
if (( "${ENC_ON}" )); then
125123
case "${ENC_APP}" in
126-
'gpg') _gpg "${out}" "${pass}" ;;
127-
'ssl') _ssl "${out}" "${pass}" ;;
124+
'gpg') _gpg "${1}" "${ENC_PASS}" ;;
125+
'ssl') _ssl "${1}" "${ENC_PASS}" ;;
128126
*) _msg 'error' 'ENC_APP does not exist!' ;;
129127
esac
130128
else
131-
cat < '/dev/stdin' > "${out}"
129+
cat < '/dev/stdin' > "${1}"
132130
fi
133131
}
134132

@@ -139,6 +137,33 @@ function _sum() {
139137
sha256sum "${in}" | sed 's| .*/| |g' | tee "${out}" > '/dev/null'
140138
}
141139

140+
function _ssh() {
141+
echo "${SSH_PASS}" | sshfs "${SSH_USER:-root}@${SSH_HOST}:/${1}" "${2}" -o 'password_stdin'
142+
}
143+
144+
function _rsync() {
145+
local opts; opts=('--archive' '--quiet')
146+
(( "${RSYNC_DEL:-0}" )) && opts+=('--delete')
147+
(( "${RSYNC_RSF:-0}" )) && opts+=('--remove-source-files')
148+
(( "${RSYNC_PED:-0}" )) && opts+=('--prune-empty-dirs')
149+
(( "${RSYNC_CVS:-0}" )) && opts+=('--cvs-exclude')
150+
151+
rsync "${opts[@]}" -e "sshpass -p '${RSYNC_PASS}' ssh -p ${RSYNC_PORT:-22}" \
152+
"${1}/" "${RSYNC_USER:-root}@${RSYNC_HOST}:${2}/"
153+
}
154+
155+
function fs_mount() {
156+
(( ! "${SSH_ON}" )) && return 0
157+
158+
local msg; msg=(
159+
'error'
160+
'Error mounting SSH FS!'
161+
"Error mounting SSH FS to '${SSH_MNT}'!"
162+
)
163+
164+
_ssh "${SSH_DST}" "${SSH_MNT}" || { _mail "${msg[@]}"; _gitlab "${msg[@]}"; _msg 'error' "${msg[2]}"; }
165+
}
166+
142167
function fs_check() {
143168
local file; file="${FS_DST}/.backup_fs"; [[ -f "${file}" ]] && return 0
144169
local msg; msg=(
@@ -149,50 +174,38 @@ function fs_check() {
149174
}
150175

151176
function fs_backup() {
152-
local ts; ts="$( date -u '+%F.%H-%M-%S' )"
153-
local dirs; dirs="${FS_DST}/${FS_TPL}"
177+
local ts; ts="$( date -u '+%m.%d-%H' )"
178+
local tpl; tpl="${FS_DST}/${FS_TPL}"
154179
local file; file="$( hostname -f ).${ts}.tar.xz"
180+
local msg; msg=()
155181

156182
for i in "${!FS_SRC[@]}"; do [[ -e "${FS_SRC[i]}" ]] || unset 'FS_SRC[i]'; done
157-
[[ ! -d "${dirs}" ]] && mkdir -p "${dirs}"; cd "${dirs}" || _msg 'error' "Directory '${dirs}' not found!"
158-
if tar -cf - "${FS_SRC[@]}" | xz | _enc "${dirs}/${file}" && _sum "${dirs}/${file}"; then
183+
[[ ! -d "${tpl}" ]] && mkdir -p "${tpl}"; cd "${tpl}" || _msg 'error' "Directory '${tpl}' not found!"
184+
if tar -cf - "${FS_SRC[@]}" | xz | _enc "${tpl}/${file}" && _sum "${tpl}/${file}"; then
159185
msg=(
160186
'success'
161187
"Backup of files ('${file}') completed successfully"
162-
"Backup of files ('${file}') completed successfully. File '${dirs}/${file}' received."
188+
"Backup of files ('${file}') completed successfully. File '${tpl}/${file}' received."
163189
); _mail "${msg[@]}"; _gitlab "${msg[@]}"; _msg 'success' "${msg[2]}"
164190
else
165191
msg=(
166192
'error'
167193
"Error backing up files ('${file}')"
168-
"Error backing up files ('${file}')! File '${dirs}/${file}' not received or corrupted!"
194+
"Error backing up files ('${file}')! File '${tpl}/${file}' not received or corrupted!"
169195
); _mail "${msg[@]}"; _gitlab "${msg[@]}"; _msg 'error' "${msg[2]}"
170196
fi
171197
}
172198

173199
function fs_sync() {
174-
(( ! "${SYNC_ON}" )) && return 0
200+
(( ! "${RSYNC_ON}" )) && return 0
175201

176-
local opts; opts=('--archive' '--quiet')
177-
(( "${SYNC_DEL:-0}" )) && opts+=('--delete')
178-
(( "${SYNC_RSF:-0}" )) && opts+=('--remove-source-files')
179-
(( "${SYNC_PED:-0}" )) && opts+=('--prune-empty-dirs')
180-
(( "${SYNC_CVS:-0}" )) && opts+=('--cvs-exclude')
202+
local msg; msg=(
203+
'error'
204+
'Error synchronizing with remote storage'
205+
'Error synchronizing with remote storage!'
206+
)
181207

182-
if rsync "${opts[@]}" -e "sshpass -p '${SYNC_PASS}' ssh -p ${SYNC_PORT:-22}" \
183-
"${FS_DST}/" "${SYNC_USER:-root}@${SYNC_HOST}:${SYNC_DST}/"; then
184-
msg=(
185-
'success'
186-
'Synchronization with remote storage completed successfully'
187-
'Synchronization with remote storage completed successfully.'
188-
); _mail "${msg[@]}"; _msg 'success' "${msg[2]}"
189-
else
190-
msg=(
191-
'error'
192-
'Error synchronizing with remote storage'
193-
'Error synchronizing with remote storage!'
194-
); _mail "${msg[@]}"; _msg 'error' "${msg[2]}"
195-
fi
208+
_rsync "${FS_DST}" "${RSYNC_DST}" || { _mail "${msg[@]}"; _gitlab "${msg[@]}"; _msg 'error' "${msg[2]}"; }
196209
}
197210

198211
function fs_clean() {
@@ -201,5 +214,9 @@ function fs_clean() {
201214
}
202215

203216
function main() {
204-
fs_check && fs_backup && fs_sync && fs_clean
217+
{ fs_mount 2>&1 | tee "${LOG_MOUNT}"; } \
218+
&& { fs_check 2>&1 | tee "${LOG_CHECK}"; } \
219+
&& { fs_backup 2>&1 | tee "${LOG_BACKUP}"; } \
220+
&& { fs_sync 2>&1 | tee "${LOG_SYNC}"; } \
221+
&& { fs_clean 2>&1 | tee "${LOG_CLEAN}"; }
205222
}; main "$@"

0 commit comments

Comments
 (0)