Various improvements
This commit is contained in:
parent
67c8d4715a
commit
9276d0f738
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,6 +1,6 @@
|
|||||||
*.txt
|
*.txt
|
||||||
build/
|
dist/
|
||||||
tests/helpers/*
|
tests/helpers/*
|
||||||
src/backups/
|
src/backups/
|
||||||
src/clean
|
src/clean
|
||||||
plan.sh
|
NOTE.todo
|
||||||
|
8
CHANGELOG
Normal file
8
CHANGELOG
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
CHANGELOG
|
||||||
|
|
||||||
|
All notable changes to this project will be documented in this file.
|
||||||
|
Version numbering uses Semantic Versioning 2.0.0 <https://semver.org/>
|
||||||
|
|
||||||
|
0.1.0
|
||||||
|
|
||||||
|
Initial release.
|
@ -1,9 +0,0 @@
|
|||||||
# Changelog
|
|
||||||
|
|
||||||
All notable changes to this project will be documented in this file.
|
|
||||||
|
|
||||||
Version numbering uses [Semantic Versioning 2.0.0](https://semver.org/).
|
|
||||||
|
|
||||||
# 0.1.0
|
|
||||||
|
|
||||||
Initial release.
|
|
81
Makefile
81
Makefile
@ -1,24 +1,28 @@
|
|||||||
SRC_DIR := ./src
|
SRC_DIR := ./src
|
||||||
DOCS_DIR := ./docs
|
DOCS_DIR := ./docs
|
||||||
TESTS_DIR := ./tests
|
TESTS_DIR := ./tests
|
||||||
BUILD_DIR := ./build
|
BUILD_DIR := ./dist
|
||||||
DOCS_BUILD_DIR := ./build/docs
|
|
||||||
|
|
||||||
.PHONY: help tests docs man install uninstall
|
.PHONY: help tests manpages install uninstall fixpath
|
||||||
|
|
||||||
all: man
|
all: manpages
|
||||||
|
|
||||||
help:
|
help:
|
||||||
@echo Usage: make TARGET
|
@echo 'Usage: make TARGET'
|
||||||
|
@echo ' make prefix=/path install'
|
||||||
|
@echo ' make prefix=/path uninstall'
|
||||||
@echo
|
@echo
|
||||||
@echo Available targets:
|
@echo Available targets:
|
||||||
@echo
|
@echo
|
||||||
@echo ' help print this help message'
|
@echo ' help print this help message'
|
||||||
@echo ' tests run tests from $(TESTS_DIR)'
|
@echo ' tests run tests from $(TESTS_DIR)'
|
||||||
@echo ' lint run shellcheck'
|
@echo ' lint run shellcheck'
|
||||||
@echo 'man build manual pages from $(DOCS_DIR)'
|
@echo ' manpages build manual pages from $(DOCS_DIR)'
|
||||||
|
@echo ' install install boring-backup with prefix'
|
||||||
|
@echo ' uninstall uninstall boring-backup with prefix'
|
||||||
@echo
|
@echo
|
||||||
@echo See README.md for more info.
|
@echo 'prefix examples: $$HOME/.local, /usr/local, /usr/bin'
|
||||||
|
@echo See README for more info.
|
||||||
|
|
||||||
tests:
|
tests:
|
||||||
# See bats(1), https://bats-core.readthedocs.io/en/latest/index.html
|
# See bats(1), https://bats-core.readthedocs.io/en/latest/index.html
|
||||||
@ -32,24 +36,63 @@ lint:
|
|||||||
shellcheck $(SRC_DIR)/lib/handlers/sources/*.sh
|
shellcheck $(SRC_DIR)/lib/handlers/sources/*.sh
|
||||||
shellcheck $(SRC_DIR)/lib/handlers/targets/*.sh
|
shellcheck $(SRC_DIR)/lib/handlers/targets/*.sh
|
||||||
|
|
||||||
man: build_dir
|
manpages:
|
||||||
# See rst2man(1), rst2html(1),
|
mkdir -pv $(BUILD_DIR)/share/man/ru/man1
|
||||||
|
# See rst2man(1)
|
||||||
# https://docutils.sourceforge.io/docs/index.html
|
# https://docutils.sourceforge.io/docs/index.html
|
||||||
rst2man $(DOCS_DIR)/boring-backup.ru.1.rst \
|
rst2man -v $(DOCS_DIR)/manpages/boring-backup.ru.1.rst \
|
||||||
> $(DOCS_BUILD_DIR)/boring-backup.ru.1
|
> $(BUILD_DIR)/share/man/ru/man1/boring-backup.1
|
||||||
sed -e 's/.SH NAME/.SH ИМЯ/' \
|
sed -e 's/.SH NAME/.SH ИМЯ/' \
|
||||||
-e 's/.SH AUTHOR/.SH АВТОРЫ/' \
|
-e 's/.SH AUTHOR/.SH АВТОРЫ/' \
|
||||||
-e 's/.SH COPYRIGHT/.SH АВТОРСКИЕ ПРАВА/' \
|
-e 's/.SH COPYRIGHT/.SH АВТОРСКИЕ ПРАВА/' \
|
||||||
-i $(DOCS_BUILD_DIR)/boring-backup.ru.1
|
-i $(BUILD_DIR)/share/man/ru/man1/boring-backup.1
|
||||||
gzip -9 $(DOCS_BUILD_DIR)/boring-backup.ru.1
|
gzip -vf9 $(BUILD_DIR)/share/man/ru/man1/boring-backup.1
|
||||||
|
|
||||||
build_dir:
|
html: manpages
|
||||||
mkdir -p $(BUILD_DIR)
|
mkdir -p $(BUILD_DIR)/share/doc/boring-backup
|
||||||
mkdir -p $(DOCS_BUILD_DIR)
|
zcat $(BUILD_DIR)/share/man/ru/man1/boring-backup.1.gz | \
|
||||||
|
groff -man -Kutf8 -Thtml \
|
||||||
|
> $(BUILD_DIR)/share/doc/boring-backup/boring-backup.1.html 2>/dev/null
|
||||||
|
rm -v grohtml-*.png
|
||||||
|
|
||||||
install:
|
install: manpages
|
||||||
# install
|
@echo prefix: $$prefix
|
||||||
|
install -Dm755 $(SRC_DIR)/boring-backup $$prefix/bin/boring-backup
|
||||||
|
install -Dm644 $(SRC_DIR)/lib/lib.sh $$prefix/share/boring-backup/lib.sh
|
||||||
|
install -Dm644 $(SRC_DIR)/lib/backup.sh $$prefix/share/boring-backup/backup.sh
|
||||||
|
install -Dm644 $(SRC_DIR)/lib/common.sh $$prefix/share/boring-backup/common.sh
|
||||||
|
install -Dm644 $(SRC_DIR)/lib/source.sh $$prefix/share/boring-backup/source.sh
|
||||||
|
install -Dm644 $(SRC_DIR)/lib/uri.sh $$prefix/share/boring-backup/uri.sh
|
||||||
|
install -Dm644 $(SRC_DIR)/lib/handlers/sources/tar.sh $$prefix/share/boring-backup/handlers/sources/tar.sh
|
||||||
|
install -Dm644 $(SRC_DIR)/lib/handlers/sources/mysqldump.sh $$prefix/share/boring-backup/handlers/sources/mysqldump.sh
|
||||||
|
install -Dm644 $(SRC_DIR)/lib/handlers/sources/pg_dump.sh $$prefix/share/boring-backup/handlers/sources/pg_dump.sh
|
||||||
|
install -Dm644 $(SRC_DIR)/lib/handlers/targets/cp.sh $$prefix/share/boring-backup/handlers/targets/cp.sh
|
||||||
|
install -Dm644 $(SRC_DIR)/lib/handlers/targets/s3cmd.sh $$prefix/share/boring-backup/handlers/targets/s3cmd.sh
|
||||||
|
sed -e "s%LIBRARY=\"\$${LIBRARY:-.\/lib}\"%LIBRARY=\"\$${LIBRARY:-$$prefix\/share\/boring-backup}\"%" \
|
||||||
|
-i $$prefix/share/boring-backup/lib.sh \
|
||||||
|
-i $$prefix/bin/boring-backup
|
||||||
|
install -Dm664 $(BUILD_DIR)/share/man/ru/man1/boring-backup.1.gz $$prefix/share/man/ru/man1/boring-backup.1.gz
|
||||||
|
|
||||||
uninstall:
|
uninstall:
|
||||||
# uninstall
|
@echo prefix: $$prefix
|
||||||
|
rm $$prefix/bin/boring-backup
|
||||||
|
rm $$prefix/share/boring-backup/lib.sh
|
||||||
|
rm $$prefix/share/boring-backup/backup.sh
|
||||||
|
rm $$prefix/share/boring-backup/common.sh
|
||||||
|
rm $$prefix/share/boring-backup/source.sh
|
||||||
|
rm $$prefix/share/boring-backup/uri.sh
|
||||||
|
rm $$prefix/share/boring-backup/handlers/sources/tar.sh
|
||||||
|
rm $$prefix/share/boring-backup/handlers/sources/mysqldump.sh
|
||||||
|
rm $$prefix/share/boring-backup/handlers/sources/pg_dump.sh
|
||||||
|
rm $$prefix/share/boring-backup/handlers/targets/cp.sh
|
||||||
|
rm $$prefix/share/boring-backup/handlers/targets/s3cmd.sh
|
||||||
|
rm -rv $$prefix/share/boring-backup
|
||||||
|
rm $$prefix/share/man/ru/man1/boring-backup.1.gz
|
||||||
|
|
||||||
|
fixpath:
|
||||||
|
# Set boring-backup library path
|
||||||
|
@echo prefix: $$prefix
|
||||||
|
@echo path: $$path
|
||||||
|
sed -e "s%LIBRARY=\"\$${LIBRARY:-.\/lib}\"%LIBRARY=\"\$${LIBRARY:-$$path}\"%" \
|
||||||
|
-i $$prefix/share/boring-backup/lib.sh \
|
||||||
|
-i $$prefix/bin/boring-backup
|
||||||
|
28
README
Normal file
28
README
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
BORING BACKUP
|
||||||
|
|
||||||
|
Bash powered backuping tool.
|
||||||
|
|
||||||
|
INSTALLATION
|
||||||
|
|
||||||
|
Install for user locally:
|
||||||
|
make prefix=$HOME/.local install
|
||||||
|
|
||||||
|
Uninstall:
|
||||||
|
make prefix=$HOME/.local uninstall
|
||||||
|
|
||||||
|
DEVELOPMENT
|
||||||
|
|
||||||
|
TESTING
|
||||||
|
|
||||||
|
BB uses amazing test suite: https://bats-core.readthedocs.io/
|
||||||
|
|
||||||
|
Install Bats:
|
||||||
|
git clone https://github.com/bats-core/bats-core.git
|
||||||
|
bash bats-core/install.sh ~/.local
|
||||||
|
|
||||||
|
Add some Bats extensions:
|
||||||
|
git clone https://github.com/bats-core/bats-assert.git tests/helpers/bats-assert
|
||||||
|
git clone https://github.com/bats-core/bats-support.git tests/helpers/bats-support
|
||||||
|
|
||||||
|
Run tests:
|
||||||
|
make test
|
33
README.md
33
README.md
@ -1,33 +0,0 @@
|
|||||||
# Boring Backup
|
|
||||||
|
|
||||||
Bash powered backup tool.
|
|
||||||
|
|
||||||
# Testing
|
|
||||||
|
|
||||||
BB uses amazing test suite: https://bats-core.readthedocs.io/
|
|
||||||
|
|
||||||
Install Bats:
|
|
||||||
|
|
||||||
git clone https://github.com/bats-core/bats-core.git
|
|
||||||
bash bats-core/install.sh ~/.local
|
|
||||||
|
|
||||||
Add some Bats extensions:
|
|
||||||
|
|
||||||
git clone https://github.com/bats-core/bats-assert.git tests/helpers/bats-assert
|
|
||||||
git clone https://github.com/bats-core/bats-support.git tests/helpers/bats-support
|
|
||||||
|
|
||||||
Run tests:
|
|
||||||
|
|
||||||
make test
|
|
||||||
|
|
||||||
# Linting
|
|
||||||
|
|
||||||
Run shellcheck:
|
|
||||||
|
|
||||||
make lint
|
|
||||||
|
|
||||||
# Building
|
|
||||||
|
|
||||||
Build manpages:
|
|
||||||
|
|
||||||
make man
|
|
@ -1,509 +0,0 @@
|
|||||||
:Title: boring-backup
|
|
||||||
:Title upper: BORING-BACKUP
|
|
||||||
:Subtitle: backup files and databases
|
|
||||||
:Author: ge
|
|
||||||
:Copyright: \(C) 2022, ge <https://nixhacks.net/>, GPLv3+
|
|
||||||
:Date: 2022 May 15
|
|
||||||
:Manual section: 1
|
|
||||||
:Version: boring-backup 0.1.0
|
|
||||||
|
|
||||||
Синопсис
|
|
||||||
--------
|
|
||||||
|
|
||||||
``boring-backup`` [-cvlphV] FILES..
|
|
||||||
|
|
||||||
Описание
|
|
||||||
--------
|
|
||||||
|
|
||||||
boring-backup - это расширяемая утилита для резервного копирования на основе
|
|
||||||
сценариев Bash.
|
|
||||||
|
|
||||||
Опции
|
|
||||||
-----
|
|
||||||
|
|
||||||
-c, --config config file.
|
|
||||||
-v, --verbose verbose output.
|
|
||||||
-l, --log-file log file.
|
|
||||||
-p, --pid-file PID file.
|
|
||||||
-h, --help print this help messagea and exit.
|
|
||||||
-V, --version print version and exit.
|
|
||||||
|
|
||||||
Быстрый старт
|
|
||||||
-------------
|
|
||||||
|
|
||||||
boring-backup можно рассматривать как фреймворк или библиотеку для создания
|
|
||||||
сценариев резервного копирования. Сценарии должны содержать валидный код на
|
|
||||||
Bash. Сценарий импортируется в основной скрипт с помощью команды ``source``
|
|
||||||
(см. ``bash``\(1) п. SHELL BUILTIN COMMANDS).
|
|
||||||
|
|
||||||
Простейший сценарий резервного копирования выглядит следующим образом::
|
|
||||||
|
|
||||||
sources=(file:/home/user)
|
|
||||||
targets=(file:/var/backup)
|
|
||||||
|
|
||||||
Здесь массивы `sources` и `targets` определяют точки, они же поинты (`points`)
|
|
||||||
резервного копирования: источники (`sources`) и назначения (`targets`). Это
|
|
||||||
основные сущности, с которыми работает boring-backup. Вот некоторые особенности
|
|
||||||
поинтов:
|
|
||||||
|
|
||||||
- Все поинты указываются в формате URI.
|
|
||||||
- Поинты могут указывать как на локальные (размещённые на текущей машине), так
|
|
||||||
и на удалённые (размещённые на удалённой машине) ресурсы.
|
|
||||||
- Можно указать как несколько источников, так и несколько назначений.
|
|
||||||
|
|
||||||
Для выполнения бэкапа директорий или отдельных файлов применяется схема URI
|
|
||||||
`file`. В схеме `file` нельзя указать директорию, размещённую на удалённом
|
|
||||||
хранилище (за исключением случая, когда удалённое хранилище примонтировано как
|
|
||||||
файловая система), для этого используйте другие схемы. В примере выше будет
|
|
||||||
выполнена резервная копия локальной директории /home/user в другую локальную
|
|
||||||
директорию /var/backup. Поскольку в сценарии из примера нет ничего, кроме
|
|
||||||
указания точек `sources` и `targets`, бэкап будет выполнен с параметрами по
|
|
||||||
умолчанию: директория /home/user будет заархивирована с помощью утилиты
|
|
||||||
``tar``\(1) и помещён в директорию /var/backup. Имя архива будет сложено по
|
|
||||||
шаблону::
|
|
||||||
|
|
||||||
${name_prefix}${name}${name_date_fmt}${name_suffix}${name_ext}
|
|
||||||
|
|
||||||
Описание переменных см. в разделе ПЕРЕМЕННЫЕ. Пример имени файла::
|
|
||||||
|
|
||||||
example.sh_example_2022.05.15-0953.tar
|
|
||||||
|
|
||||||
Обзор URI
|
|
||||||
---------
|
|
||||||
|
|
||||||
Источники (`sources`) и назначения (`targets`) должны быть указаны в виде
|
|
||||||
URI. Это позовляет наглядно в одной сроке видеть весь набор данных. Парсер
|
|
||||||
реализует поддержку следующего синтаксиса URI::
|
|
||||||
|
|
||||||
scheme:[//[username[:password]@]hostname[:port]]/[path]?[query]#[fragment]
|
|
||||||
|
|
||||||
Парсер URI соответствует RFC 3986 не полностью - разбиение на составные части
|
|
||||||
URI происходит верно, но интерпретация в отдельных ситуациях может отличаться.
|
|
||||||
См. примеры URI и реузультаты их интерпретации парсером в файле
|
|
||||||
`tests/parse_uri.bats`. На практике рекомендую придерживаться примеров, которые
|
|
||||||
приведены ниже и в файле `tests/parse_uri.bats`. В случае, если изменение
|
|
||||||
логики парсера необходимо, вы можете прислать правки в pull-реквесте или
|
|
||||||
завести feature-реквест в репозитории проекта. На текущий момент компоненты
|
|
||||||
`query` и `fragment` не используются.
|
|
||||||
|
|
||||||
Примеры URI для массива `sources`::
|
|
||||||
|
|
||||||
mysql://wordpress:1jobrRRjtLYs@localhost/wordpress
|
|
||||||
postgres://django:9%3F2%3D%40gHW@localhost:5432:/django
|
|
||||||
sqlite:///var/www/app/data/database.db
|
|
||||||
file:///var/www/html/
|
|
||||||
|
|
||||||
Примеры URI для `targets`::
|
|
||||||
|
|
||||||
file:/var/backup
|
|
||||||
ftp://jhon:%24t%D0%AFo%7C%5C%7C6@[fe80::5054:ff:fe24:382]:2021/backups/
|
|
||||||
rsync://backup_user@192.168.3.12:2022/backups
|
|
||||||
s3://my_bucket
|
|
||||||
|
|
||||||
Пароли содержащие специальные символы недопустимые в URI (включая пробелы)
|
|
||||||
необходимо закодировать в percent code. См. примеры кодирования строки на
|
|
||||||
разных языках программирования ниже.
|
|
||||||
|
|
||||||
Python 2::
|
|
||||||
|
|
||||||
python2 -c "import urllib, sys; \
|
|
||||||
print urllib.quote(sys.argv[1], safe='')" 'p@$$w0rd'
|
|
||||||
|
|
||||||
Python 3::
|
|
||||||
|
|
||||||
python3 -c "import urllib.parse, sys; \
|
|
||||||
print(urllib.parse.quote(sys.argv[1], safe=''))" 'p@$$w0rd'
|
|
||||||
|
|
||||||
Perl 5::
|
|
||||||
|
|
||||||
echo 'p@$$w0rd' | perl -MURI::Escape -wlne 'print uri_escape $_'
|
|
||||||
|
|
||||||
Поддерживаемые протоколы и схемы URI
|
|
||||||
------------------------------------
|
|
||||||
Схемы, которые могут быть использованы как sources
|
|
||||||
``````````````````````````````````````````````````
|
|
||||||
|
|
||||||
file
|
|
||||||
Может содержать путь к локальному файлу или директории. Файлы
|
|
||||||
архивируются при помощи ``tar`` и по умолчанию не сжимаются. Cжатие
|
|
||||||
архива может быть включено через переменную `compression`. Примеры::
|
|
||||||
|
|
||||||
/var/www/www-root/data
|
|
||||||
file:/var/www/html
|
|
||||||
file:///home/jhon/cool_stuff.txt
|
|
||||||
|
|
||||||
Не используйте двойной слэш для этой схемы, используйте один или три
|
|
||||||
слэша. Двойной слэш означает наличие компонента Authority, это приводит
|
|
||||||
к неверной интерпретации адреса.
|
|
||||||
|
|
||||||
См. также ``handler::tar``
|
|
||||||
|
|
||||||
mysql
|
|
||||||
URI содержит реквизиты для подключения к БД MySQL/MariaDB. Формат::
|
|
||||||
|
|
||||||
mysql://[username[:password]@]hostname[:port]/database
|
|
||||||
|
|
||||||
С помощью утилиты ``mysqldump``\(1) формируется дамп в формате SQL. Файл
|
|
||||||
по умолчанию не сжимается, но сжатие может быть включено через переменную
|
|
||||||
`compression`.
|
|
||||||
|
|
||||||
См. также ``handler::mysqldump``
|
|
||||||
|
|
||||||
postgres
|
|
||||||
Аналогично `mysql`, но для PostgreSQL. Для создания дампа используется
|
|
||||||
``pg_dump``\(1) с расширением .psql. Файл по умолчанию не сжимается, но
|
|
||||||
сжатие может быть включено через переменную `compression`.
|
|
||||||
|
|
||||||
См. также ``handler::pg_dump``
|
|
||||||
|
|
||||||
sqlite
|
|
||||||
Схема для баз данных SQLite. Мало отличается от `file`, добавлена для
|
|
||||||
наглядного обозначения, что источником является БД SQLite, а не иной файл.
|
|
||||||
|
|
||||||
См. также ``handler::sqlite``
|
|
||||||
|
|
||||||
Схемы, которые могут быть использованы как targets
|
|
||||||
``````````````````````````````````````````````````
|
|
||||||
|
|
||||||
file
|
|
||||||
В контексте `targets` указывает директорию для сохранения бэкапов. В
|
|
||||||
массиве `targets` обязательно должен быть хотя бы один поинт со схемой
|
|
||||||
`file`. Этот поинт будет использован как основной и сохранён в переменные
|
|
||||||
``__main_target`` (содержит URI) и ``__main_target_path`` (содержит
|
|
||||||
компонент URI path). Если в массиве присутствует несколько поинтов со
|
|
||||||
схемой `file`, то в качестве основного будет выбран первый по порядку
|
|
||||||
поинт. Все бэкапы первоначально будут сохраняться в директорию
|
|
||||||
``__main_target_path`` и затем копироваться в другой таргет с помощью
|
|
||||||
соответствующего обработчика. В случае копировани из одной директории в
|
|
||||||
другую используется утилита ``cp``\(1).
|
|
||||||
|
|
||||||
Избегайте указания в одном сценарии таргетов, которые ведут одновременно на
|
|
||||||
примонтированный к локальной машине сетевой диск и другое удалённое
|
|
||||||
хранилище. В таком случае архивы будут создаваться на сетевом диске и далее
|
|
||||||
снова копироваться по сети, что будет очень медленно.
|
|
||||||
|
|
||||||
См. также ``handler::cp``
|
|
||||||
|
|
||||||
ftp
|
|
||||||
Не реализовано.
|
|
||||||
|
|
||||||
sftp
|
|
||||||
Не реализовано.
|
|
||||||
|
|
||||||
rsync
|
|
||||||
Не реализовано.
|
|
||||||
|
|
||||||
s3
|
|
||||||
Не реализовано.
|
|
||||||
|
|
||||||
swift
|
|
||||||
Не реализовано.
|
|
||||||
|
|
||||||
sj
|
|
||||||
Не реализовано.
|
|
||||||
|
|
||||||
dav, davs
|
|
||||||
Не реализовано.
|
|
||||||
|
|
||||||
Создание резервных копий
|
|
||||||
------------------------
|
|
||||||
|
|
||||||
boring-backup предполагает, что для всех резервных копий необходимо создавать
|
|
||||||
архивы. Поэтому вам нужно следить за тем, чтобы в локальном хранилище всегда
|
|
||||||
хватало дискового пространства для создания новых архивов. boring-backup также
|
|
||||||
не удаляет старые архивы и вам также надо позаботиться об удалении устаревших
|
|
||||||
резервных копий. Изменить это поведение можно с помощью пользовательских
|
|
||||||
функций в сценариях. В этом разделе речь пойдёт о поведении, которое
|
|
||||||
установлено по умолчанию. См. функции ``builtin_backup``, ``process_sources``,
|
|
||||||
``process_targets``.
|
|
||||||
|
|
||||||
Базовая концепция строится на том, что существует несколько источников и
|
|
||||||
несколько точек назначения. Создаётся резервная копия источника и копируется в
|
|
||||||
точку назначения.
|
|
||||||
|
|
||||||
Для всех источников в сценарии выполняется локальная резервная копия. После
|
|
||||||
этого локальная копия переносится в удалённые точки назначения, если они
|
|
||||||
заданы. Копирование локального бэкапа будет осуществлёно столько раз, сколько
|
|
||||||
точек назначения задано. В каждом сценарии обязательно должен быть задан хотя
|
|
||||||
бы один источник и одна точка назначения. При этом в списке точек назначения
|
|
||||||
обязательно должна присутствовать точка со схемой `file`. Именно в неё будут
|
|
||||||
сохранены архивы.
|
|
||||||
|
|
||||||
Например, имеется следующий сценарий::
|
|
||||||
|
|
||||||
sources=(
|
|
||||||
mysql://wordpress:1jobrRRjtLYs@localhost/wordpress
|
|
||||||
file:///var/www/wordpress
|
|
||||||
)
|
|
||||||
targets=(
|
|
||||||
file:///var/backup
|
|
||||||
ftp://jhon:%24t%D0%AFo%7C%5C%7C6@[fe80::5054:ff:fe24:382]:2021/backups/
|
|
||||||
)
|
|
||||||
|
|
||||||
Здесь будут созданы архивы файлов и базы данных и сохранены в локальную
|
|
||||||
директорию /var/backup. Затем эти файлы будут переданы по протоколу FTP на
|
|
||||||
сервер fe80::5054:ff:fe24:382 в директорию /backups. Файлы из директории
|
|
||||||
/var/backup не будут удалены или перемещены. Если добавить дополнительную точку
|
|
||||||
назначения, то файлы из /var/backup будут скопированы и туда. Обратите
|
|
||||||
внимание, что boring-backup не выполняет повторного создания архивов для каждой
|
|
||||||
точки назначения — архивы создаются один раз и далее распространяются по всем
|
|
||||||
указанным назначениям. Если в массиве `targets` имеется несколько точек
|
|
||||||
назначения со схемой `file`, то архивы будут сохранены в первую по порядку
|
|
||||||
точку, а затем скопированы оттуда в остальные.
|
|
||||||
|
|
||||||
Резервное копирование на удалённое хранилище
|
|
||||||
--------------------------------------------
|
|
||||||
FTP
|
|
||||||
```
|
|
||||||
SFTP
|
|
||||||
````
|
|
||||||
Rsync over SSH
|
|
||||||
``````````````
|
|
||||||
Rsync with rsyncd
|
|
||||||
`````````````````
|
|
||||||
Amazon S3
|
|
||||||
`````````
|
|
||||||
S3 compatible storage
|
|
||||||
`````````````````````
|
|
||||||
OpenStack Swift
|
|
||||||
```````````````
|
|
||||||
Storj DCS
|
|
||||||
`````````
|
|
||||||
WebDAV
|
|
||||||
``````
|
|
||||||
Переменные
|
|
||||||
----------
|
|
||||||
|
|
||||||
``boring-backup`` условно разделяет переменные на "внутренние" ("защищённые") и
|
|
||||||
"обычные". К "защищённым" переменным относятся все перемеменные, имена которых
|
|
||||||
начинаются с двух знаков подчёркивания, например: ``__main_target``. Все
|
|
||||||
остальные переменные считаются "обычными".
|
|
||||||
|
|
||||||
Обычные переменные могут быть перезаписаны в пользовательском скрипте.
|
|
||||||
Защищённые переменные технически ничем от них не отличаются, однако не нужно
|
|
||||||
переопределять такие переменные в пользовательском скрипте, так как это может
|
|
||||||
привести к неожиданным ошибкам во время выполнения скрипта. Точно также очень
|
|
||||||
внимательно нужно относится к перезаписи обычных переменных — в обоих случаях
|
|
||||||
есть риск что-то поломать.
|
|
||||||
|
|
||||||
``backups``
|
|
||||||
Массив со списком созданных бэкапов. Содержит абсолютные пути к файлам.
|
|
||||||
Заполняется функциями-обработчиками `sources`.
|
|
||||||
|
|
||||||
| Тип: массив
|
|
||||||
| Умолчание: ()
|
|
||||||
|
|
||||||
``errors``
|
|
||||||
Массив с текстами ошибок. Заполняется функцией ``err`` с опцией ``-a``.
|
|
||||||
|
|
||||||
| Тип: массив
|
|
||||||
| Умолчание: ()
|
|
||||||
|
|
||||||
``log_date_fmt``
|
|
||||||
Формат даты в логе. См. ``date``\(1).
|
|
||||||
|
|
||||||
| Тип: строка
|
|
||||||
| Умолчание: %d/%b/%Y:%H:%M:%S %z
|
|
||||||
|
|
||||||
``name_prefix``
|
|
||||||
Префикс имени файла. Может быть задан в скрипте.
|
|
||||||
|
|
||||||
| Тип: строка
|
|
||||||
| Умолчание: имя_скрипта\_
|
|
||||||
|
|
||||||
``name``
|
|
||||||
Соответствует имени архивируемой директории/файла полученного из `path` с
|
|
||||||
помощью утилиты ``basename``\(1).
|
|
||||||
|
|
||||||
| Тип: строка
|
|
||||||
| Умолчание: нет
|
|
||||||
|
|
||||||
``name_date_fmt``
|
|
||||||
Дата, интерпретируемая утилитой ``date``\(1).
|
|
||||||
|
|
||||||
| Тип: строка
|
|
||||||
| Умолчание: _%Y%m%d
|
|
||||||
|
|
||||||
``name_suffix``
|
|
||||||
Суффикс, добавляемый к имени файла перед расширением. Строка
|
|
||||||
интерпретируется утилитой ``date``.
|
|
||||||
|
|
||||||
| Тип: строка
|
|
||||||
| Умолчание: -%H%M
|
|
||||||
|
|
||||||
``name_ext``
|
|
||||||
Расширение имени файла, соответствующее формату архива.
|
|
||||||
|
|
||||||
| Тип: строка
|
|
||||||
| Умолчание: .tar.gz
|
|
||||||
|
|
||||||
``tar_options``
|
|
||||||
Опции ``tar``. См. ``tar``\(1).
|
|
||||||
|
|
||||||
| Тип: строка
|
|
||||||
| Умолчание: -acf
|
|
||||||
|
|
||||||
``tar_exclude``
|
|
||||||
Список имён для опции ``tar`` ``--exclude``.
|
|
||||||
|
|
||||||
| Тип: массив
|
|
||||||
| Умолчание: нет
|
|
||||||
|
|
||||||
``compression``
|
|
||||||
В контексте ``tar`` работа этой фичи базируется на опции ``tar``
|
|
||||||
``--auto-compress``. Переменная может принимать значения, в соответствии с
|
|
||||||
табилцей ниже. Если переменная имеет значение, отличное от перечисленныых,
|
|
||||||
то будет использован ``gzip``. Если переменная пуста или не задана, то
|
|
||||||
сжатие будет отключено.
|
|
||||||
|
|
||||||
| Тип: строка
|
|
||||||
| Умолчание: нет
|
|
||||||
|
|
||||||
==================== ================ ========
|
|
||||||
Значение compression Расширение файла Утилита
|
|
||||||
==================== ================ ========
|
|
||||||
gzip, gz .tar.gz gzip
|
|
||||||
tgz .tgz gzip
|
|
||||||
taz .taz gzip
|
|
||||||
compress, Z .tar.Z compress
|
|
||||||
taZ .taZ compress
|
|
||||||
bzip2, bz2 .tar.bz2 bzip2
|
|
||||||
tz2 .tz2 bzip2
|
|
||||||
tbz2 .tbz2 bzip2
|
|
||||||
tbz .tbz bzip2
|
|
||||||
lzip, lz .tar.lz lzip
|
|
||||||
lzma .tar.lzma lzma
|
|
||||||
tlz .tlz lzma
|
|
||||||
lzop, lzo .tar.lzo lzop
|
|
||||||
xz .tar.xz xz
|
|
||||||
zstd, zst .tar.zst zstd
|
|
||||||
tzst .tzst zstd
|
|
||||||
==================== ================ ========
|
|
||||||
|
|
||||||
Функции
|
|
||||||
-------
|
|
||||||
|
|
||||||
``backup``
|
|
||||||
Пользовательская функция резервного копирования. Если она задана в скрипте,
|
|
||||||
то вызывается вместо ``builtin_backup``.
|
|
||||||
|
|
||||||
``builtin_backup``
|
|
||||||
Встроенная функция, запускает резервное копирвоание. Вызывает функции
|
|
||||||
``process_source`` и ``process_target``.
|
|
||||||
|
|
||||||
``err [-eao] MESSAGE``
|
|
||||||
Печатает сообщение об ошибке MESSAGE на экран и в лог и выполняет обработку
|
|
||||||
ошибок.
|
|
||||||
|
|
||||||
-e Выйти из скрипта с кодом выхода 1.
|
|
||||||
-a Добавить сообщение MESSAGE в массив ``errors``.
|
|
||||||
-o Вызвать функцию ``on_error``.
|
|
||||||
|
|
||||||
``finalise``
|
|
||||||
Пользовательская функция. Если задана, то запускается после функции
|
|
||||||
``backup`` или ``builtin_backup()``.
|
|
||||||
|
|
||||||
``gen_backup_name FILE_EXT``
|
|
||||||
Печатает полученное имя файла в STDOUT. Имя является выводом команды
|
|
||||||
``date`` и строки ``${prefix}${name}${date_fmt}${name_ext}``.
|
|
||||||
См. переменные ``name_prefix``, ``name``, ``name_date_fmt``, ``name_ext``.
|
|
||||||
|
|
||||||
``try COMMAND``
|
|
||||||
Функция выполняет команду COMMAND и в случае ненулевого кода выхода
|
|
||||||
вызывает ``err()`` с ключами ``-eao``. Ошибка при выполнении COMMAND
|
|
||||||
приведёт к вызову функции ``on_error``. Рекомендуется для использования в
|
|
||||||
качестве обёртки для команд правильное выполнение которых критично.
|
|
||||||
|
|
||||||
``handler::tar URI``
|
|
||||||
Архивация файлов с помощью ``tar``.
|
|
||||||
|
|
||||||
``handler::mysqldump URI``
|
|
||||||
Не реализовано.
|
|
||||||
|
|
||||||
``handler::pg_dump URI``
|
|
||||||
Не реализовано.
|
|
||||||
|
|
||||||
``handler::sqlite URI``
|
|
||||||
Не реализовано.
|
|
||||||
|
|
||||||
``handler::cp URI``
|
|
||||||
Копирует файлы в новое назначение с помощью ``cp``.
|
|
||||||
|
|
||||||
``handler::ftp URI``
|
|
||||||
Не реализовано.
|
|
||||||
|
|
||||||
``handler::sftp URI``
|
|
||||||
Не реализовано.
|
|
||||||
|
|
||||||
``handler::rsync URI``
|
|
||||||
Не реализовано.
|
|
||||||
|
|
||||||
``handler::s3 URI``
|
|
||||||
Не реализовано.
|
|
||||||
|
|
||||||
``handler::sj URI``
|
|
||||||
Не реализовано.
|
|
||||||
|
|
||||||
``handler::swift URI``
|
|
||||||
Не реализовано.
|
|
||||||
|
|
||||||
``handler::dav URI``
|
|
||||||
Не реализовано.
|
|
||||||
|
|
||||||
``handler::davs URI``
|
|
||||||
Не реализовано.
|
|
||||||
|
|
||||||
``is_installed COMMAND``
|
|
||||||
Проверяет установлена ли программа COMMAND.
|
|
||||||
|
|
||||||
``is_function_set FUNCTION``
|
|
||||||
Проверяет задана ли функция FUNCTION.
|
|
||||||
|
|
||||||
``log [-p] MESSAGE``
|
|
||||||
Печатает лог в файл ``__log_file`` (лог задаётся опцией --log-file) и на
|
|
||||||
экран, если указана опция ``-p``. Формат даты в логе можно изменить с
|
|
||||||
помощью переменной ``log_date_fmt``.
|
|
||||||
|
|
||||||
``on_error``
|
|
||||||
Пользовательская функция для обработки ошибок. Если задана, то запускается
|
|
||||||
при обработке ошибки в функции ``err`` с опцией ``-o``.
|
|
||||||
|
|
||||||
``parse_uri URI``
|
|
||||||
Парсер URI. Задаёт переменные ``scheme``, ``username``, ``password``,
|
|
||||||
``hostname``, ``port``, ``path``, ``query``, ``fragment`` и выполняет
|
|
||||||
декодинг пароля, если он закодирован в percent code.
|
|
||||||
|
|
||||||
``prepare``
|
|
||||||
Пользовательская функция. Если задана, то запускается до функции ``backup``
|
|
||||||
или ``builtin_backup``.
|
|
||||||
|
|
||||||
``process_source URI``
|
|
||||||
На основе схемы запускает соответсвующую функцию-обработчик.
|
|
||||||
|
|
||||||
``process_target URI``
|
|
||||||
На основе схемы запускает соответсвующую функцию-обработчик.
|
|
||||||
|
|
||||||
``source_script FILE``
|
|
||||||
Выполняет ``source`` пользовательского скрипта и проверяет его
|
|
||||||
корректность. Проверяется синтаксис Bash, наличие непустых массивов
|
|
||||||
`sources` и `targets`, наличие поинта `file` в `targets`. Во
|
|
||||||
вспомогательной функции ``validate_targets`` задаются значения переменных
|
|
||||||
``__main_target`` и ``__main_target_path``.
|
|
||||||
|
|
||||||
Использование функций в сценариях
|
|
||||||
---------------------------------
|
|
||||||
Переменные окружения
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
``LIBRARY``
|
|
||||||
Путь до библиотеки функций boring-backup.
|
|
||||||
|
|
||||||
Примеры
|
|
||||||
-------
|
|
||||||
См. также
|
|
||||||
---------
|
|
||||||
|
|
||||||
``bash``\(1), ``tar``\(1), ``cp``\(1), ``date``\(1), ``mysqldump``\(1),
|
|
||||||
``pg_dump``\(1)
|
|
||||||
|
|
||||||
RFC 3986 https://datatracker.ietf.org/doc/html/rfc3986
|
|
640
docs/manpages/boring-backup.ru.1.rst
Normal file
640
docs/manpages/boring-backup.ru.1.rst
Normal file
@ -0,0 +1,640 @@
|
|||||||
|
:Title: boring_backup
|
||||||
|
:Title upper: BORING_BACKUP
|
||||||
|
:Subtitle: бэкап файлов и баз данных
|
||||||
|
:Author: ge
|
||||||
|
:Copyright: \(C) 2022, ge <https://nixhacks.net/>, GPLv3+
|
||||||
|
:Date: 2022 May 15
|
||||||
|
:Manual section: 1
|
||||||
|
:Version: boring_backup 0.1.0
|
||||||
|
|
||||||
|
СИНТАКСИС
|
||||||
|
---------
|
||||||
|
|
||||||
|
**boring_backup** [-hVvs] [-c `файл`] [-l `файл`] [-p `файл`] файл ...
|
||||||
|
|
||||||
|
ОПИСАНИЕ
|
||||||
|
--------
|
||||||
|
|
||||||
|
boring_backup - это расширяемая утилита для резервного копирования на основе
|
||||||
|
сценариев Bash.
|
||||||
|
|
||||||
|
ОПЦИИ
|
||||||
|
-----
|
||||||
|
|
||||||
|
-h, --help
|
||||||
|
Показать справку и выйти.
|
||||||
|
|
||||||
|
-V, --version
|
||||||
|
Показать информацию о версии и выйти.
|
||||||
|
|
||||||
|
-v, --verbose
|
||||||
|
Печатать подробный вывод.
|
||||||
|
|
||||||
|
-c, --config=\ `файл`
|
||||||
|
Путь до файла конфигурации. См. **КОНФИГУРИРОВАНИЕ**.
|
||||||
|
|
||||||
|
-l, --log-file=\ `файл`
|
||||||
|
Путь до файла лога.
|
||||||
|
|
||||||
|
-s, --use-syslog
|
||||||
|
Записывать лог в syslog вместо файла. Эта опция несовместима с опцией
|
||||||
|
--log-file и переменной log_date_format.
|
||||||
|
|
||||||
|
-p, --pid-file=\ `файл`
|
||||||
|
Путь до PID-файла.
|
||||||
|
|
||||||
|
ОБЗОР
|
||||||
|
-----
|
||||||
|
|
||||||
|
**boring_backup** можно рассматривать как фреймворк или библиотеку для создания
|
||||||
|
сценариев резервного копирования. Сценарии (скрипты) должны содержать валидный
|
||||||
|
код на Bash.
|
||||||
|
|
||||||
|
Скрипты передаются в качестве аргументов **boring_backup** и исполняются в
|
||||||
|
цикле. Скрипты загружается с помощью команды ``source`` (см. ``bash``\(1)
|
||||||
|
п. SHELL BUILTIN COMMANDS).
|
||||||
|
|
||||||
|
Простейший сценарий резервного копирования выглядит следующим образом::
|
||||||
|
|
||||||
|
sources=(file:/home/john)
|
||||||
|
targets=(file:/var/backups)
|
||||||
|
|
||||||
|
Массивы `sources` и `targets` определяют источники и назначения соответственно.
|
||||||
|
Ресурсы из `sources` нужно сохранить в точку(и) назначения — `targets`. См.
|
||||||
|
больше примеров в разделе **ПРИМЕРЫ**.
|
||||||
|
|
||||||
|
Все ресурсы записываются в формате URI. См. подробности в разделе
|
||||||
|
**СХЕМЫ URI** и в описании функции ``parse_uri`` ниже.
|
||||||
|
|
||||||
|
Каждой схеме URI соответствует функция-обработчик, которая выполняет действие
|
||||||
|
с ресурсом. Например, URI со схемой `mysql` будет обработан функцией
|
||||||
|
``src_mysqldump``.
|
||||||
|
|
||||||
|
Обработчики ресурсов для массива `sources` имеют в имени префикс ``src_``, а
|
||||||
|
обработчики для массива `targets` префикс ``tgt_``. См. описания обработчиков в
|
||||||
|
разделе **ВСТРОЕННЫЕ ФУНКЦИИ**.
|
||||||
|
|
||||||
|
Поскольку скрипты резервного копирования это обычные скрипты Bash, то здесь
|
||||||
|
применимы все те же приёмы. В **boring_backup** предусмотрено несколько
|
||||||
|
специальных пользовательских функций и ряд специальных переменных. См. разделы
|
||||||
|
**ПЕРЕМЕННЫЕ** и **ПОЛЬЗОВАТЕЛЬСКИЕ ФУНКЦИИ**.
|
||||||
|
|
||||||
|
СХЕМЫ URI
|
||||||
|
---------
|
||||||
|
|
||||||
|
file
|
||||||
|
Схема для указания ресурсов в файловой системе. Примеры записи::
|
||||||
|
|
||||||
|
/var/www/www-root/data
|
||||||
|
file:/var/www/html
|
||||||
|
file:///home/jhon/cool_stuff.txt
|
||||||
|
|
||||||
|
Не используйте двойной слэш для этой схемы, используйте один или три
|
||||||
|
слэша. Двойной слэш означает наличие компонента Authority, который здесь
|
||||||
|
не обрабатывается, что приводит к неверной интерпретации адреса.
|
||||||
|
|
||||||
|
Схема `file` может быть указана как в массиве `sources`, так и `targets`.
|
||||||
|
|
||||||
|
В массиве `sources` схема обрабатывается функцией ``src_tar``. Файлы
|
||||||
|
архивируются и сжимаются согласно значению переменной $compression.
|
||||||
|
|
||||||
|
В контексте `targets` `file` указывает директорию для сохранения бэкапов.
|
||||||
|
В `targets` обязательно должен быть хотя бы один URI со схемой `file`.
|
||||||
|
Этот URI будет использован как основной и сохранён в переменные
|
||||||
|
$__main_target (содержит URI целиком) и $__main_target_path (содержит
|
||||||
|
компонент URI path).
|
||||||
|
|
||||||
|
Если в массиве `targets` присутствует несколько URI со схемой `file`, то в
|
||||||
|
качестве основного будет выбран первый по порядку URI. Все бэкапы
|
||||||
|
первоначально будут сохраняться туда и затем копироваться в другой таргет с
|
||||||
|
помощью соответствующего обработчика. В случае копирования бэкапов между
|
||||||
|
директориями будет использован обработчик ``tgt_cp``.
|
||||||
|
|
||||||
|
Избегайте указания в одном сценарии таргетов, которые ведут одновременно на
|
||||||
|
примонтированный к локальной машине сетевой диск и на другое удалённое
|
||||||
|
хранилище. В таком случае архивы будут создаваться на сетевом диске и далее
|
||||||
|
снова копироваться по сети. Это может быть очень медленно.
|
||||||
|
|
||||||
|
См. также ``src_tar``, ``tgt_cp``.
|
||||||
|
|
||||||
|
mysql, mariadb
|
||||||
|
URI содержит реквизиты для подключения к БД MySQL/MariaDB. Иногда такой
|
||||||
|
формат ещё называют DSN (data source name)::
|
||||||
|
|
||||||
|
mysql://[username[:password]@]hostname[:port]/database
|
||||||
|
|
||||||
|
См. также ``src_mysqldump``.
|
||||||
|
|
||||||
|
postgres
|
||||||
|
Аналогично `mysql`, но для PostgreSQL. Для создания дампа используется
|
||||||
|
``pg_dump``. Расширение несжатых файлов — .psql.
|
||||||
|
|
||||||
|
См. также ``src_pg_dump``
|
||||||
|
|
||||||
|
sqlite [НЕ РЕАЛИЗОВАН]
|
||||||
|
Схема для баз данных SQLite. Мало отличается от `file`, добавлена для
|
||||||
|
наглядного обозначения, что ресурсом является БД SQLite, а не иной файл.
|
||||||
|
|
||||||
|
См. также ``src_sqlite``
|
||||||
|
|
||||||
|
s3
|
||||||
|
Схема Simple Storage Service (S3). Пример использования::
|
||||||
|
|
||||||
|
s3://bucket
|
||||||
|
|
||||||
|
URI содержит только схему и путь. Все остальные реквизиты для подключения к
|
||||||
|
хранилищу задаются через конфигурационный файл или отдельные переменные.
|
||||||
|
См. ``tgt_s3cmd`` ниже.
|
||||||
|
|
||||||
|
В S3 важно наличие слэшей в конце URI. Пример::
|
||||||
|
|
||||||
|
s3://bucket/backups (1)
|
||||||
|
s3://bucket/backups/ (2)
|
||||||
|
|
||||||
|
В случае (1) при загрузке файла с именем dump.sql.gz файл будет сохранён
|
||||||
|
как, s3://bucket/backups, а не s3://bucket/backups/dump.sql.gz. Чтобы
|
||||||
|
такого не происходило следует добавлять слэш в конце (2), чтобы обозначить,
|
||||||
|
что backups в данном случае является директорией. Обработчик ``tgt_s3cmd``
|
||||||
|
сам добавляет слэш в конец URI, если его нет.
|
||||||
|
|
||||||
|
Ещё одной особенностью является то, что в URI можно записывать
|
||||||
|
несуществующие в хранилище директории. Они будут созданы при загрузке
|
||||||
|
файла. Таким образом можно делать следующее::
|
||||||
|
|
||||||
|
today="$(date +%d_%b_%Y)"
|
||||||
|
targets=(
|
||||||
|
file:///var/backups
|
||||||
|
s3://bucket/backups/$today
|
||||||
|
)
|
||||||
|
|
||||||
|
Бэкап будет сохранён как::
|
||||||
|
|
||||||
|
s3://bucket/backups/22_Aug_2022/dump.sql.gz
|
||||||
|
|
||||||
|
ПЕРЕМЕННЫЕ
|
||||||
|
----------
|
||||||
|
|
||||||
|
``sources``
|
||||||
|
| Тип: массив
|
||||||
|
| Умолчание: нет
|
||||||
|
|
||||||
|
Массив из строк с URI ресурсов, резервную копию которых нужно выполнить.
|
||||||
|
Массив обязатально должен быть непустой. Пример::
|
||||||
|
|
||||||
|
sources=(
|
||||||
|
file:///home/john
|
||||||
|
mysql://user:password@localhost:3306/database
|
||||||
|
)
|
||||||
|
|
||||||
|
См. **СХЕМЫ URI**.
|
||||||
|
|
||||||
|
``targets``
|
||||||
|
| Тип: массив
|
||||||
|
| Умолчание: нет
|
||||||
|
|
||||||
|
Массив из строк URI хранилищ, куда необходимо доставить резервные копии.
|
||||||
|
Обязательно должен содержать хотя бы один URI со схемой `file`. Пример::
|
||||||
|
|
||||||
|
targets=(
|
||||||
|
file:///var/backups
|
||||||
|
s3://bucket/backups/$today
|
||||||
|
)
|
||||||
|
|
||||||
|
См. **СХЕМЫ URI**.
|
||||||
|
|
||||||
|
``backups``
|
||||||
|
| Тип: массив
|
||||||
|
| Умолчание: нет
|
||||||
|
|
||||||
|
Массив со списком созданных бэкапов. Содержит абсолютные пути к файлам.
|
||||||
|
Заполняется функциями-обработчиками `sources` при успешном создании бэкапа.
|
||||||
|
|
||||||
|
При использовании пользовательской функции ``backup`` массив следует
|
||||||
|
заполнять вручную для корректного вызова функций-обработчиков для
|
||||||
|
`targets`. См. пример в разделе **ПРИМЕРЫ**.
|
||||||
|
|
||||||
|
``compression``
|
||||||
|
| Тип: строка
|
||||||
|
| Умолчание: нет
|
||||||
|
|
||||||
|
Тип компрессии для сжатия файлов.
|
||||||
|
|
||||||
|
В контексте ``tar`` работа этой фичи базируется на опции ``tar``
|
||||||
|
``--auto-compress``. Переменная может принимать значения, в соответствии с
|
||||||
|
табилцей ниже. Если переменная не задана, имеет пустое или отличное от
|
||||||
|
перечисленныых в таблице значение, то сжатие будет отключено.
|
||||||
|
|
||||||
|
Для файлов, которые не являются архивами tar (не созданы функцией
|
||||||
|
``src_tar``) расширение из таблицы будет добавлено к оригинальному
|
||||||
|
рассширению файла.
|
||||||
|
|
||||||
|
==================== ========== =================== =====================
|
||||||
|
Значение compression Утилита Расширение файла Расширение архива tar
|
||||||
|
==================== ========== =================== =====================
|
||||||
|
gzip, gz gzip .gz .tar.gz
|
||||||
|
tgz gzip .gz .tgz
|
||||||
|
taz gzip .gz .taz
|
||||||
|
bzip2, bz2 bzip2 .bz2 .tar.bz2
|
||||||
|
tz2 bzip2 .bz2 .tz2
|
||||||
|
tbz2 bzip2 .bz2 .tbz2
|
||||||
|
tbz bzip2 .bz2 .tbz
|
||||||
|
lzip, lz lzip .lz .tar.lz
|
||||||
|
lzma lzma .lzma .tar.lzma
|
||||||
|
tlz lzma .lzma .tlz
|
||||||
|
lzop, lzo lzop .lzo .tar.lzo
|
||||||
|
xz xz .xz .tar.xz
|
||||||
|
zstd, zst zstd .zst .tar.zst
|
||||||
|
tzst zstd .zst .tzst
|
||||||
|
==================== ========== =================== =====================
|
||||||
|
|
||||||
|
``log_date_format``
|
||||||
|
| Тип: строка
|
||||||
|
| Умолчание: %d/%b/%Y:%H:%M:%S %z
|
||||||
|
|
||||||
|
Формат даты в логе. См. ``date``. См. **КОНФИГУРИРОВАНИЕ**.
|
||||||
|
|
||||||
|
``name``
|
||||||
|
| Тип: строка
|
||||||
|
| Умолчание: нет
|
||||||
|
|
||||||
|
Соответствует имени архивируемой директории/файла полученного из `path` с
|
||||||
|
помощью утилиты ``basename``. Вычисляется автоматически, не может быть
|
||||||
|
задан в скрипте.
|
||||||
|
|
||||||
|
``name_date_format``
|
||||||
|
| Тип: строка
|
||||||
|
| Умолчание: _%Y%m%d
|
||||||
|
|
||||||
|
Дата, интерпретируемая утилитой ``date``. Полученная строка используется в
|
||||||
|
имени файла бэкапа.
|
||||||
|
|
||||||
|
``name_prefix``
|
||||||
|
| Тип: строка
|
||||||
|
| Умолчание: имя_скрипта\_
|
||||||
|
|
||||||
|
Префикс имени файла. Может быть задан в скрипте. Значение по-умолчанию
|
||||||
|
состоит из имени скрипта резервного копирования и знака "_".
|
||||||
|
|
||||||
|
``name_suffix``
|
||||||
|
| Тип: строка
|
||||||
|
| Умолчание: -%H%M
|
||||||
|
|
||||||
|
Суффикс, добавляемый к имени файла перед расширением. Строка
|
||||||
|
интерпретируется утилитой ``date``.
|
||||||
|
|
||||||
|
``name_ext``
|
||||||
|
| Тип: строка
|
||||||
|
| Умолчание: нет
|
||||||
|
|
||||||
|
Расширение имени файла соответствующее формату архива. Вычисляется
|
||||||
|
автоматически и не может быть задано в скрипте резервного копирования.
|
||||||
|
|
||||||
|
``mysqldump_options``
|
||||||
|
| Тип: строка
|
||||||
|
| Умолчание: нет
|
||||||
|
|
||||||
|
Опции для утилиты ``mysqldump``.
|
||||||
|
|
||||||
|
``pg_dump_options``
|
||||||
|
| Тип: строка
|
||||||
|
| Умолчание: нет
|
||||||
|
|
||||||
|
Опции для утилиты ``pg_dump``.
|
||||||
|
|
||||||
|
``s3cmd_config``
|
||||||
|
| Тип: строка
|
||||||
|
| Умолчание: нет
|
||||||
|
|
||||||
|
Путь к файлу конфигурации утилиты ``s3cmd``. См. соответствующую страницу
|
||||||
|
страницу справки ``s3cmd``\(1).
|
||||||
|
|
||||||
|
``s3cmd_options``
|
||||||
|
| Тип: строка
|
||||||
|
| Умолчание: --preserve --quiet --no-progress
|
||||||
|
|
||||||
|
Опции для утилиты ``s3cmd``.
|
||||||
|
|
||||||
|
``s3_access_key``
|
||||||
|
| Тип: строка
|
||||||
|
| Умолчание: нет
|
||||||
|
|
||||||
|
Значение для опции ``s3cmd`` ``--access_key``.
|
||||||
|
|
||||||
|
``s3_secret_key``
|
||||||
|
| Тип: строка
|
||||||
|
| Умолчание: нет
|
||||||
|
|
||||||
|
Значение для опции ``s3cmd`` ``--secret_key``.
|
||||||
|
|
||||||
|
``s3_host``
|
||||||
|
| Тип: строка
|
||||||
|
| Умолчание: нет
|
||||||
|
|
||||||
|
Значение для опции ``s3cmd`` ``--host``. Должен содержать адрес эндпоинта
|
||||||
|
для доступа к объектному хранилищу без схемы (только домен).
|
||||||
|
|
||||||
|
``s3_host_bucket``
|
||||||
|
| Тип: строка
|
||||||
|
| Умолчание: нет
|
||||||
|
|
||||||
|
Значение для опции ``s3cmd`` ``--host-bucket``. Шаблон для `virtual-hosted
|
||||||
|
style` адреса бакета. Для `path style` это значение должно совпадать с
|
||||||
|
`s3_host`.
|
||||||
|
|
||||||
|
``s3_region``
|
||||||
|
| Тип: строка
|
||||||
|
| Умолчание: na
|
||||||
|
|
||||||
|
Значение для опции ``s3cmd`` ``--region`` или ``--bucket_location``.
|
||||||
|
Переменная необязательна к заполнению, так как некоторые S3-совместимые
|
||||||
|
хранилища не используют регионы. В таком случае будет использован фиктивный
|
||||||
|
регион `na` (not available).
|
||||||
|
|
||||||
|
``tar_options``
|
||||||
|
| Тип: строка
|
||||||
|
| Умолчание: -acf
|
||||||
|
|
||||||
|
Опции ``tar``. См. ``tar``\(1).
|
||||||
|
|
||||||
|
``tar_exclude``
|
||||||
|
| Тип: массив
|
||||||
|
| Умолчание: нет
|
||||||
|
|
||||||
|
Список имён для опции ``tar`` ``--exclude``. Пример::
|
||||||
|
|
||||||
|
tar_exclude=( foo bar )
|
||||||
|
|
||||||
|
Массив разворачивается в строку вида '--exclude=foo --exclude=bar' и
|
||||||
|
подставляется в строку опций ``tar``.
|
||||||
|
|
||||||
|
ВСТРОЕННЫЕ ФУНКЦИИ
|
||||||
|
------------------
|
||||||
|
|
||||||
|
``set_compression``
|
||||||
|
Определить утилиту и расширение файла на основе строки.
|
||||||
|
|
||||||
|
При вызове этой функции в качестве аргумента ей передаётся значение
|
||||||
|
переменной $compression. На её основе функция задаёт переменные $cmpr_ext,
|
||||||
|
$tar_ext и $cmpr_cmd. $tar_ext используется только в функции ``src_tar``,
|
||||||
|
другие две в функции ``compress_file``.
|
||||||
|
|
||||||
|
См. таблицу в описании переменной $compression.
|
||||||
|
|
||||||
|
``compress_file``
|
||||||
|
Выполнить сжатие файла и напечатать имя сжатого файла. Удалить несжатый
|
||||||
|
файл.
|
||||||
|
|
||||||
|
Внутри себя вызывает функцию ``set_compression`` для определния утилиты и
|
||||||
|
расширения файла. Если переменная $compression не задана, то сжатие не
|
||||||
|
производится.
|
||||||
|
|
||||||
|
``gen_backup_name``
|
||||||
|
Функция печатает строку, содержащую имя файла. Имя генерируется с помощью
|
||||||
|
команды::
|
||||||
|
|
||||||
|
date +"${name_prefix}${name}${name_date_format}${name_suffix}${name_ext}"
|
||||||
|
|
||||||
|
$name_ext принимает значение, переданное в качестве аргумента. См. описания
|
||||||
|
переменных выше и также в исходном коде функции.
|
||||||
|
|
||||||
|
``handle_error``
|
||||||
|
Обработать ошибку. Делает проверку и вызывает пользовательскую функцию
|
||||||
|
``on_error``.
|
||||||
|
|
||||||
|
``is_function_set``
|
||||||
|
Проверить задана ли функция и вернуть код выхода. Применима в конструкции
|
||||||
|
**if**.
|
||||||
|
|
||||||
|
``is_installed``
|
||||||
|
Проверить установлена ли утилита и выйти из скрипта при неудаче.
|
||||||
|
|
||||||
|
``log``
|
||||||
|
Записать сообщение в лог.
|
||||||
|
|
||||||
|
Синтаксис: **log** [-pV] сообщение
|
||||||
|
|
||||||
|
| Опции:
|
||||||
|
| -p напечатать сообщение также на экран (STDOUT)
|
||||||
|
| -V игнорировать опцию **--verbose**
|
||||||
|
|
||||||
|
Функция записывает сообщения в лог-файл. Лог-файл может быть задан через
|
||||||
|
опцию **--log-file**, имя этого файла будет сохранено в переменную
|
||||||
|
$__log_file. **log** перед записью в файл удаляет из текста
|
||||||
|
escape-последовательности ANSI.
|
||||||
|
|
||||||
|
Формат лога '[%s] %s\\n', где первое вхождение %s заменяется на дату, а
|
||||||
|
второе на текст сообщения. Формат даты задаётся через переменную
|
||||||
|
$log_date_format (см. описание выше).
|
||||||
|
|
||||||
|
Все сообщения, отправляемые в **log** печатаются в терминал, если
|
||||||
|
**boring_backup** запущен с опцией **--verbose**. Избежать этого можно
|
||||||
|
вызвав логгер с опцией **-V**.
|
||||||
|
|
||||||
|
``parse_uri``
|
||||||
|
Разобрать строку URI на компоненты. Парсер соответствует RFC 3986.
|
||||||
|
|
||||||
|
Функция задаёт переменные: $scheme, $username, $password, $hostname,
|
||||||
|
$port, $path, $query, $fragment
|
||||||
|
|
||||||
|
Поддерживается работа с IPv6 адресами, если они заключены в квадратные
|
||||||
|
скобки.
|
||||||
|
|
||||||
|
Поддерживается работа с паролями, содержащими зарезервированные символы.
|
||||||
|
Такие пароли необходимо закодировать в так называемый percent code.
|
||||||
|
**parse_uri** возвращает в переменной $password уже раскодированный пароль.
|
||||||
|
Ниже представлены примеры кодирования паролей в командной строке.
|
||||||
|
|
||||||
|
Python 2::
|
||||||
|
|
||||||
|
python2 -c "import urllib, sys; \
|
||||||
|
print urllib.quote(sys.argv[1], safe='')" 'p@$$w0rd'
|
||||||
|
|
||||||
|
Python 3::
|
||||||
|
|
||||||
|
python3 -c "import urllib.parse, sys; \
|
||||||
|
print(urllib.parse.quote(sys.argv[1], safe=''))" 'p@$$w0rd'
|
||||||
|
|
||||||
|
Perl 5::
|
||||||
|
|
||||||
|
echo 'p@$$w0rd' | perl -MURI::Escape -wlne 'print uri_escape $_'
|
||||||
|
|
||||||
|
``remove_if_empty``
|
||||||
|
Удалить файл, если он пустой.
|
||||||
|
|
||||||
|
``src_mysqldump``
|
||||||
|
Получить SQL дамп базы данных MariaDB или MySQL.
|
||||||
|
|
||||||
|
Дамп выполняется с помощью утилиты ``mysqldump``. Ей можно передать
|
||||||
|
дополнительные опции через переменную $mysqldump_options (см. описание
|
||||||
|
выше).
|
||||||
|
|
||||||
|
``src_pg_dump``
|
||||||
|
Получить SQL дамп базы данных PostgreSQL.
|
||||||
|
|
||||||
|
Дамп выполняется с помощью утилиты ``pg_dump``. Ей можно передать
|
||||||
|
дополнительные опции через переменную $pg_dump_options (см. описание выше).
|
||||||
|
|
||||||
|
``src_tar``
|
||||||
|
Создать архив tar. Используемые переменные: $tar_options, $tar_exclude.
|
||||||
|
|
||||||
|
``tgt_cp``
|
||||||
|
Скопировать файлы в новое назначение.
|
||||||
|
|
||||||
|
Эта функция вызывается при каждом запуске резервного копирования и
|
||||||
|
обрабатывает схему `file` в массиве `targets`. Если в массиве есть
|
||||||
|
несколько URI со схемой `file`, то ``tgt_cp`` скопирует файлы из первой
|
||||||
|
директории во все остальные.
|
||||||
|
|
||||||
|
``tgt_s3cmd``
|
||||||
|
Загрузить файлы в S3-совместимое объектное хранилище с помощью ``s3cmd``.
|
||||||
|
|
||||||
|
Реквизиты для подключения к хранилищу можно передать в конфигурационном
|
||||||
|
файл ``s3cmd`` указав путь до него в переменной $s3cmd_config.
|
||||||
|
|
||||||
|
Помимо этого реквизиты можно записать прямо в скрипт резервного копирования
|
||||||
|
в переменные: $s3_access_key, $s3_secret_key, $s3_host, $s3_host_bucket,
|
||||||
|
$s3_region. Дополнительные опции для ``s3cmd`` можно задать через
|
||||||
|
$s3cmd_options. См. описание всех переменных в разделе **ПЕРЕМЕННЫЕ**.
|
||||||
|
|
||||||
|
``builtin_backup``
|
||||||
|
Запустить функции ``process_source`` и ``process_target`` для каждого URI
|
||||||
|
из соответствующих массивов.
|
||||||
|
|
||||||
|
``process_source``
|
||||||
|
Запустить соответствующую функцию-обработчик для массива `sources`.
|
||||||
|
|
||||||
|
``process_target``
|
||||||
|
Запустить соответствующую функцию-обработчик для массива `targets`.
|
||||||
|
|
||||||
|
``source_script``
|
||||||
|
Выполнить проверки и загрузить (``source``) пользовательский скрипт
|
||||||
|
резервного копирования.
|
||||||
|
|
||||||
|
``validate_sources``
|
||||||
|
Проверить массив `sources`. Выполняются проверки на пустой массив и на
|
||||||
|
использование правильного набора схем URI.
|
||||||
|
|
||||||
|
``validate_targets``
|
||||||
|
Проверить массив `targets`. Выполняются проверки на пустой массив и на
|
||||||
|
использование правильного набора схем URI. Для успешной проверки массив
|
||||||
|
должен содержать хотя бы одну строку URI со схемой `file`.
|
||||||
|
|
||||||
|
ПОЛЬЗОВАТЕЛЬСКИЕ ФУНКЦИИ
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
``prepare``
|
||||||
|
В этой функции можно запрограммировать действия, необходимые перед
|
||||||
|
выполнением бэкапа.
|
||||||
|
|
||||||
|
``backup``
|
||||||
|
Эта функция позволяет переопределить логику резервной копии.
|
||||||
|
|
||||||
|
Если функция **backup** объявлена, то она будет вызвана вместо встроенной
|
||||||
|
функции **builtin_backup**.
|
||||||
|
|
||||||
|
Используйте **backup**, когда вам необходимо использовать собственную
|
||||||
|
логику вместо заложенной разработчиком **boring_backup**.
|
||||||
|
|
||||||
|
``finalise``
|
||||||
|
В этой функции можно запрограммировать действия, выполнение которых
|
||||||
|
необходимо после выполнения бэкапа.
|
||||||
|
|
||||||
|
Пример использования: удаление локальных резервных копий после их загрузки
|
||||||
|
на удалённое хранилище.
|
||||||
|
|
||||||
|
``on_error``
|
||||||
|
В этой функции можно запрограммировать действия при возникновении ошибки.
|
||||||
|
В качестве аргумента для неё передаётся строка с текстом произошедшей
|
||||||
|
ошибки.
|
||||||
|
|
||||||
|
Пример использования: отправка отчёта об ошибке на имейл.
|
||||||
|
|
||||||
|
КОНФИГУРИРОВАНИЕ
|
||||||
|
----------------
|
||||||
|
|
||||||
|
По умолчанию **boring_backup** пытается прочитать файл по пути
|
||||||
|
~/.config/boring_backup. Также путь до конфигурационного файла можно
|
||||||
|
передать через опцию **--config**.
|
||||||
|
|
||||||
|
Конфиг имеет те же свойства, что и скрипт резервного копированиия, но
|
||||||
|
загружается всякий раз после загрузки скрипта резевного копирования. Таким
|
||||||
|
образом он может переопределять заданные в скриптах функции и переменные.
|
||||||
|
|
||||||
|
Параметры, которые нежелательно определять в скриптах резервного копирования:
|
||||||
|
|
||||||
|
* log_date_format
|
||||||
|
* name_date_format
|
||||||
|
|
||||||
|
Переопределять их следует через конфигурационный файл.
|
||||||
|
|
||||||
|
ПРИМЕРЫ
|
||||||
|
-------
|
||||||
|
|
||||||
|
Скрипт для бэкапа сайта со сжатием файлов с помощью ``xz``, загрузкой в S3 и
|
||||||
|
удалением локальных бэкапов после загрузки::
|
||||||
|
|
||||||
|
compression=xz
|
||||||
|
s3cmd_config=~/.s3cfg
|
||||||
|
sources=(
|
||||||
|
/var/www/www-data/example.com
|
||||||
|
mysql://example_user:Smk3mVH2@localhost/example_db
|
||||||
|
)
|
||||||
|
targets=(
|
||||||
|
/var/backups/example.com/
|
||||||
|
s3://mybucket/backups/example-com
|
||||||
|
)
|
||||||
|
finalise() {
|
||||||
|
log -p "\tClean up local backups"
|
||||||
|
log -p "\tFiles to delete: ${backups[@]}"
|
||||||
|
rm -- "${backups[@]}"
|
||||||
|
log -p "\tLocal backups deleted"
|
||||||
|
}
|
||||||
|
|
||||||
|
Бэкап домашней папки на примонтированный в /mnt/backups сетевой диск::
|
||||||
|
|
||||||
|
compression=xz
|
||||||
|
tar_exclude=(.cache)
|
||||||
|
sources=(/home/john)
|
||||||
|
targets=(/mnt/backups)
|
||||||
|
|
||||||
|
Бэкап приложения Gitea::
|
||||||
|
|
||||||
|
sources=(.) # just pass validation
|
||||||
|
targets=(.)
|
||||||
|
today="$(date +%d_%b_%Y)"
|
||||||
|
s3cmd_config=~/.s3cfg
|
||||||
|
prepare() {
|
||||||
|
systemctl stop gitea.service
|
||||||
|
sleep 5
|
||||||
|
}
|
||||||
|
backup() {
|
||||||
|
log -p "Dumping Gitea"
|
||||||
|
su -c "/usr/local/bin/gitea dump -c /etc/gitea/app.ini \
|
||||||
|
-f /home/git/.cache/gitea_dump.zip" - git 2>> "$__log_file"
|
||||||
|
backups+=(/home/git/.cache/gitea_dump.zip)
|
||||||
|
tgt_s3cmd s3://mybucket/backups/gitea-$today
|
||||||
|
}
|
||||||
|
finalise() {
|
||||||
|
systemctl start gitea.service
|
||||||
|
rm "${backups[@]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
ОКРУЖЕНИЕ
|
||||||
|
---------
|
||||||
|
|
||||||
|
LIBRARY
|
||||||
|
Если задана переменная окружения $LIBRARY, то её значение будет
|
||||||
|
использовано в качестве пути для поиска библиотеки **boring_backup**.
|
||||||
|
|
||||||
|
СМ. ТАКЖЕ
|
||||||
|
---------
|
||||||
|
|
||||||
|
``bash``\(1), ``date``\(1), ``cp``\(1), ``tar``\(1), ``mysqldump``\(1),
|
||||||
|
``pg_dump``\(1), ``s3cmd``\(1)
|
||||||
|
|
||||||
|
RFC 3986 https://datatracker.ietf.org/doc/html/rfc3986
|
||||||
|
|
||||||
|
ОШИБКИ
|
||||||
|
------
|
||||||
|
|
||||||
|
https://git.nxhs.cloud/ge/boring_backup/issues
|
@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
# boring-backup -- backup files and databases.
|
# boring_backup -- backup files and databases.
|
||||||
# Copyright (c) 2022 ge <https://nixhacks.net/>
|
# Copyright (c) 2022 ge <https://nixhacks.net/>
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# This program is free software: you can redistribute it and/or modify
|
||||||
@ -16,12 +16,7 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
__version='0.1.0'
|
VERSION='0.1.0'
|
||||||
__config=
|
|
||||||
__verbose=
|
|
||||||
__log_file='./log.txt'
|
|
||||||
__pid_file='/tmp/boring-backup.pid'
|
|
||||||
|
|
||||||
LIBRARY="${LIBRARY:-./lib}"
|
LIBRARY="${LIBRARY:-./lib}"
|
||||||
|
|
||||||
# Source library
|
# Source library
|
||||||
@ -30,24 +25,47 @@ if [ -f "$LIBRARY/lib.sh" ]; then
|
|||||||
. "$LIBRARY/lib.sh"
|
. "$LIBRARY/lib.sh"
|
||||||
else
|
else
|
||||||
echo "Error: Cannot source library $LIBRARY/lib.sh: No such file" >&2
|
echo "Error: Cannot source library $LIBRARY/lib.sh: No such file" >&2
|
||||||
|
__exit=1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
print_help() {
|
print_help() {
|
||||||
cat <<- EOF
|
printf << EOF \
|
||||||
Backup files and databases.
|
"USAGE:
|
||||||
|
|
||||||
Usage: $0 [-cvlphV] FILES..
|
$0 [-hVvs] [-c \033[4mfile\033[0m] [-l \033[4mfile\033[0m] \
|
||||||
|
[-p \033[4mfile\033[0m] file ...
|
||||||
|
|
||||||
Options:
|
OPTIONS:
|
||||||
-c, --config config file.
|
|
||||||
-v, --verbose verbose output.
|
|
||||||
-l, --log-file log file [default: $__log_file]
|
|
||||||
-p, --pid-file PID file [default: $__pid_file]
|
|
||||||
-h, --help print this help messagea and exit.
|
|
||||||
-V, --version print version and exit.
|
|
||||||
|
|
||||||
Environment:
|
-h, --help
|
||||||
LIBRARY path to bb library [current: $LIBRARY]
|
Print this help message and exit.
|
||||||
|
|
||||||
|
-V, --version
|
||||||
|
Print version and exit.
|
||||||
|
|
||||||
|
-v, --verbose
|
||||||
|
Enable verbose output.
|
||||||
|
|
||||||
|
-c, --config=\033[4mfile\033[0m
|
||||||
|
Path to configuration file. Default: ~/.config/boring_backup
|
||||||
|
Configuration file actually is Bash-script similar to backup
|
||||||
|
script. See boring_backup(1) CONFIGURATION.
|
||||||
|
|
||||||
|
-l, --log-file=\033[4mfile\033[0m
|
||||||
|
Log file.
|
||||||
|
|
||||||
|
-s, --use-syslog
|
||||||
|
Write log into syslog via logger instead of log file. This option
|
||||||
|
is incompatible with --log-file option and log_date_format variable.
|
||||||
|
|
||||||
|
-p, --pid-file=\033[4mfile\033[0m
|
||||||
|
PID file. Default: /tmp/boring_backup.pid
|
||||||
|
|
||||||
|
ENVIRONMENT:
|
||||||
|
|
||||||
|
LIBRARY Path to boring_backup library. Current path is
|
||||||
|
$LIBRARY
|
||||||
|
"
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,33 +106,70 @@ for args in "$@"; do
|
|||||||
shift
|
shift
|
||||||
case "$args" in
|
case "$args" in
|
||||||
--*)
|
--*)
|
||||||
set -- "$@" "$args";; # save long options
|
set -- "$@" "$args" # save long options
|
||||||
|
;;
|
||||||
-*)
|
-*)
|
||||||
args="$(echo "${args:1}" | grep -o . | xargs -I {} echo -n '-{} ')"
|
args="$(echo "${args:1}" |
|
||||||
|
grep -o . | xargs -I {} echo -n '-{} ')"
|
||||||
# shellcheck disable=SC2086
|
# shellcheck disable=SC2086
|
||||||
set -- "$@" $args;; # 'args' must be unquoted!
|
set -- "$@" $args # 'args' must be unquoted!
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
set -- "$@" "$args";; # save positional arguments
|
set -- "$@" "$args" # save positional arguments
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
# Final arguments parser
|
# Final arguments parser
|
||||||
while (( "$#" )); do
|
while (( "$#" )); do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
|
-h|--help)
|
||||||
|
print_help
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
-V|--version)
|
||||||
|
echo "$VERSION"
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
-v|--verbose)
|
||||||
|
verbose_output=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
-c|--config|--config=*)
|
-c|--config|--config=*)
|
||||||
optval "$1" "$2"; __config="$val"; shift "$sft";;
|
optval "$1" "$2"
|
||||||
-v|--verbose) __verbose=1; shift;;
|
bb_config="$val"
|
||||||
|
shift "$sft"
|
||||||
|
;;
|
||||||
-l|--log-file|--log-file=*)
|
-l|--log-file|--log-file=*)
|
||||||
optval "$1" "$2"; __log_file="$val"; shift "$sft";;
|
optval "$1" "$2"
|
||||||
|
log_file="$val"
|
||||||
|
shift "$sft"
|
||||||
|
;;
|
||||||
|
-s|--use-syslog)
|
||||||
|
use_syslog=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
-p|--pid-file|--pid-file=*)
|
-p|--pid-file|--pid-file=*)
|
||||||
optval "$1" "$2"; __pid_file="$val"; shift "$sft";;
|
optval "$1" "$2"
|
||||||
-h|--help) print_help; exit 0;;
|
pid_file="$val"
|
||||||
-V|--version) echo "$__version"; exit 0;;
|
shift "$sft"
|
||||||
-*) echo "Error: Unknown option: $1" >&2; exit 1;;
|
;;
|
||||||
*) __args+=("$1"); shift;; # Save positional args
|
-*)
|
||||||
|
echo "Error: Unknown option: $1" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
__args+=("$1") # Save positional args
|
||||||
|
shift
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# -- Set defaults -- #
|
||||||
|
log_file="${log_file:-./log.txt}"
|
||||||
|
bb_config="${bb_config:-$HOME/.config/boring_backup}"
|
||||||
|
pid_file="${pid_file:-/tmp/boring_backup.pid}"
|
||||||
|
|
||||||
# Exit if library is not loaded
|
# Exit if library is not loaded
|
||||||
if ! declare -F -- log > /dev/null 2>&1; then
|
if ! declare -F -- log > /dev/null 2>&1; then
|
||||||
exit 1
|
exit 1
|
||||||
@ -127,20 +182,20 @@ fi
|
|||||||
log -V "Backup STARTED"
|
log -V "Backup STARTED"
|
||||||
|
|
||||||
# Check PID file
|
# Check PID file
|
||||||
if [ -e "$__pid_file" ]; then
|
if [ -e "$pid_file" ]; then
|
||||||
# shellcheck disable=SC2009
|
# shellcheck disable=SC2009
|
||||||
# shellcheck disable=SC2143
|
# shellcheck disable=SC2143
|
||||||
if [ -z "$(ps ax -o pid | grep "$(cat "$__pid_file")")" ]; then
|
if [ -z "$(ps ax -o pid | grep "$(cat "$pid_file")")" ]; then
|
||||||
log -p "Process $(cat "$__pid_file") died." >&2
|
log -p "Process $(cat "$pid_file") died." >&2
|
||||||
rm "$__pid_file"
|
rm "$pid_file"
|
||||||
else
|
else
|
||||||
echo "Process $(cat "$__pid_file") still running." >&2
|
echo "Process $(cat "$pid_file") still running." >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Touch PID file
|
# Touch PID file
|
||||||
echo "$$" > "$__pid_file"
|
echo "$$" > "$pid_file"
|
||||||
|
|
||||||
# Scripts counter.
|
# Scripts counter.
|
||||||
__count="${#__args[@]}" # count
|
__count="${#__args[@]}" # count
|
||||||
@ -149,9 +204,12 @@ __i=1 # iterator
|
|||||||
# Startup log.
|
# Startup log.
|
||||||
date +'Start: %d %b %Y %T %z'
|
date +'Start: %d %b %Y %T %z'
|
||||||
log -p "Library path: $LIBRARY"
|
log -p "Library path: $LIBRARY"
|
||||||
log -p "Log file: $__log_file"
|
log -p "Log file: $log_file"
|
||||||
log -p "Configuration file:" \
|
log -p "Configuration file:" "$(\
|
||||||
"$([ "$__config" ] || echo not specified && echo "$__config")"
|
if [ -f "$bb_config" ];
|
||||||
|
then echo "$bb_config";
|
||||||
|
else echo not specified;
|
||||||
|
fi)"
|
||||||
log -p "Total scripts: $__count"
|
log -p "Total scripts: $__count"
|
||||||
log "Scripts to process (${__count}): ${__args[*]}"
|
log "Scripts to process (${__count}): ${__args[*]}"
|
||||||
|
|
||||||
@ -171,7 +229,7 @@ for script in "${__args[@]}"; do
|
|||||||
|
|
||||||
# Config can ovewrite script functions and variables
|
# Config can ovewrite script functions and variables
|
||||||
# shellcheck source=/dev/null
|
# shellcheck source=/dev/null
|
||||||
[ -n "$__config" ] && . "$__config"
|
[ -f "$bb_config" ] && . "$bb_config"
|
||||||
|
|
||||||
# --- Run user script -- #
|
# --- Run user script -- #
|
||||||
|
|
||||||
@ -208,17 +266,10 @@ for script in "${__args[@]}"; do
|
|||||||
|
|
||||||
# Unset user defined variables
|
# Unset user defined variables
|
||||||
unset compression
|
unset compression
|
||||||
unset name_prefix
|
unset name_prefix name_date_format name_prefix name_suffix
|
||||||
unset name_date_format
|
unset s3cmd_config s3cmd_options
|
||||||
unset s3cmd_options
|
unset s3_access_key s3_secret_key s3_region s3_host s3_host_bucket
|
||||||
unset s3cmd_config
|
unset tar_options tar_exclude
|
||||||
unset s3_access_key
|
|
||||||
unset s3_secret_key
|
|
||||||
unset s3_region
|
|
||||||
unset s3_host
|
|
||||||
unset s3_host_bucket
|
|
||||||
unset tar_options
|
|
||||||
unset tar_exclude
|
|
||||||
unset mysqldump_options
|
unset mysqldump_options
|
||||||
unset pg_dump_options
|
unset pg_dump_options
|
||||||
done
|
done
|
||||||
@ -227,4 +278,6 @@ echo -e "\nBackup [Done]"
|
|||||||
log -V "Backup FINISHED"
|
log -V "Backup FINISHED"
|
||||||
|
|
||||||
# Remove PID file
|
# Remove PID file
|
||||||
rm "$__pid_file"
|
rm "$pid_file"
|
||||||
|
|
||||||
|
exit "${__exit:-0}"
|
@ -25,7 +25,6 @@ tgt_s3cmd() {
|
|||||||
log "Run handler ${FUNCNAME[0]}()"
|
log "Run handler ${FUNCNAME[0]}()"
|
||||||
|
|
||||||
local uri
|
local uri
|
||||||
local src_path
|
|
||||||
|
|
||||||
uri="$1"
|
uri="$1"
|
||||||
|
|
||||||
@ -44,7 +43,7 @@ tgt_s3cmd() {
|
|||||||
# Set s3cmd comand. See s3cmd(1)
|
# Set s3cmd comand. See s3cmd(1)
|
||||||
if [ -n "$s3cmd_config" ]; then
|
if [ -n "$s3cmd_config" ]; then
|
||||||
# Use configuration file
|
# Use configuration file
|
||||||
# shellcheck disable=SC2154
|
# shellcheck disable=SC2154,SC2086
|
||||||
set -- s3cmd $s3cmd_options --config "$s3cmd_config" \
|
set -- s3cmd $s3cmd_options --config "$s3cmd_config" \
|
||||||
put "${backups[@]}" "$uri"
|
put "${backups[@]}" "$uri"
|
||||||
elif [ -n "$s3_access_key" ] && \
|
elif [ -n "$s3_access_key" ] && \
|
||||||
@ -54,7 +53,7 @@ tgt_s3cmd() {
|
|||||||
then
|
then
|
||||||
s3_region="${s3_region:-na}" # fallback to 'no available' region
|
s3_region="${s3_region:-na}" # fallback to 'no available' region
|
||||||
# Use parameters provided from backup script
|
# Use parameters provided from backup script
|
||||||
# shellcheck disable=SC2154
|
# shellcheck disable=SC2154,SC2086
|
||||||
set -- s3cmd $s3cmd_options \
|
set -- s3cmd $s3cmd_options \
|
||||||
--access_key="$s3_access_key" \
|
--access_key="$s3_access_key" \
|
||||||
--secret_key="$s3_secret_key" \
|
--secret_key="$s3_secret_key" \
|
||||||
@ -74,6 +73,7 @@ tgt_s3cmd() {
|
|||||||
# ^^^ hide secret_key from output ^^^
|
# ^^^ hide secret_key from output ^^^
|
||||||
|
|
||||||
# Upload backups
|
# Upload backups
|
||||||
|
# shellcheck disable=SC2154
|
||||||
if "$@" 2>> "$__log_file"; then
|
if "$@" 2>> "$__log_file"; then
|
||||||
: # Success
|
: # Success
|
||||||
else
|
else
|
||||||
|
Loading…
Reference in New Issue
Block a user