Various improvements
This commit is contained in:
		
							
								
								
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -1,6 +1,6 @@
 | 
			
		||||
*.txt
 | 
			
		||||
build/
 | 
			
		||||
dist/
 | 
			
		||||
tests/helpers/*
 | 
			
		||||
src/backups/
 | 
			
		||||
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.
 | 
			
		||||
							
								
								
									
										93
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										93
									
								
								Makefile
									
									
									
									
									
								
							@@ -1,24 +1,28 @@
 | 
			
		||||
SRC_DIR := ./src
 | 
			
		||||
DOCS_DIR := ./docs
 | 
			
		||||
TESTS_DIR := ./tests
 | 
			
		||||
BUILD_DIR := ./build
 | 
			
		||||
DOCS_BUILD_DIR := ./build/docs
 | 
			
		||||
SRC_DIR 	:= ./src
 | 
			
		||||
DOCS_DIR 	:= ./docs
 | 
			
		||||
TESTS_DIR 	:= ./tests
 | 
			
		||||
BUILD_DIR 	:= ./dist
 | 
			
		||||
 | 
			
		||||
.PHONY: help tests docs man install uninstall
 | 
			
		||||
.PHONY: help tests manpages install uninstall fixpath
 | 
			
		||||
 | 
			
		||||
all: man
 | 
			
		||||
all: manpages
 | 
			
		||||
 | 
			
		||||
help:
 | 
			
		||||
	@echo Usage: make TARGET
 | 
			
		||||
	@echo 'Usage:  make TARGET'
 | 
			
		||||
	@echo '	make prefix=/path install'
 | 
			
		||||
	@echo '	make prefix=/path uninstall'
 | 
			
		||||
	@echo
 | 
			
		||||
	@echo Available targets:
 | 
			
		||||
	@echo
 | 
			
		||||
	@echo 'help	print this help message'
 | 
			
		||||
	@echo 'tests	run tests from $(TESTS_DIR)'
 | 
			
		||||
	@echo 'lint	run shellcheck'
 | 
			
		||||
	@echo 'man	build manual pages from $(DOCS_DIR)'
 | 
			
		||||
	@echo '	help		print this help message'
 | 
			
		||||
	@echo '	tests		run tests from $(TESTS_DIR)'
 | 
			
		||||
	@echo '	lint		run shellcheck'
 | 
			
		||||
	@echo '	manpages	build manual pages from $(DOCS_DIR)'
 | 
			
		||||
	@echo '	install		install boring-backup with prefix'
 | 
			
		||||
	@echo '	uninstall	uninstall boring-backup with prefix'
 | 
			
		||||
	@echo
 | 
			
		||||
	@echo See README.md for more info.
 | 
			
		||||
	@echo 'prefix examples: $$HOME/.local, /usr/local, /usr/bin'
 | 
			
		||||
	@echo See README for more info.
 | 
			
		||||
 | 
			
		||||
tests:
 | 
			
		||||
	# 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/targets/*.sh
 | 
			
		||||
 | 
			
		||||
man: build_dir
 | 
			
		||||
	# See rst2man(1), rst2html(1),
 | 
			
		||||
manpages:
 | 
			
		||||
	mkdir -pv $(BUILD_DIR)/share/man/ru/man1
 | 
			
		||||
	# See rst2man(1)
 | 
			
		||||
	# https://docutils.sourceforge.io/docs/index.html
 | 
			
		||||
	rst2man $(DOCS_DIR)/boring-backup.ru.1.rst \
 | 
			
		||||
		> $(DOCS_BUILD_DIR)/boring-backup.ru.1
 | 
			
		||||
	rst2man -v $(DOCS_DIR)/manpages/boring-backup.ru.1.rst \
 | 
			
		||||
		> $(BUILD_DIR)/share/man/ru/man1/boring-backup.1
 | 
			
		||||
	sed -e 's/.SH NAME/.SH ИМЯ/' \
 | 
			
		||||
		-e 's/.SH AUTHOR/.SH АВТОРЫ/' \
 | 
			
		||||
		-e 's/.SH COPYRIGHT/.SH АВТОРСКИЕ ПРАВА/' \
 | 
			
		||||
		-i $(DOCS_BUILD_DIR)/boring-backup.ru.1
 | 
			
		||||
	gzip -9 $(DOCS_BUILD_DIR)/boring-backup.ru.1
 | 
			
		||||
		-i $(BUILD_DIR)/share/man/ru/man1/boring-backup.1
 | 
			
		||||
	gzip -vf9 $(BUILD_DIR)/share/man/ru/man1/boring-backup.1
 | 
			
		||||
 | 
			
		||||
build_dir:
 | 
			
		||||
	mkdir -p $(BUILD_DIR)
 | 
			
		||||
	mkdir -p $(DOCS_BUILD_DIR)
 | 
			
		||||
html: manpages
 | 
			
		||||
	mkdir -p $(BUILD_DIR)/share/doc/boring-backup
 | 
			
		||||
	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
 | 
			
		||||
install: manpages
 | 
			
		||||
	@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
 | 
			
		||||
	@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
 | 
			
		||||
 | 
			
		||||
# boring-backup -- backup files and databases.
 | 
			
		||||
# boring_backup -- backup files and databases.
 | 
			
		||||
# Copyright (c) 2022 ge <https://nixhacks.net/>
 | 
			
		||||
#
 | 
			
		||||
# 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
 | 
			
		||||
# along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
__version='0.1.0'
 | 
			
		||||
__config=
 | 
			
		||||
__verbose=
 | 
			
		||||
__log_file='./log.txt'
 | 
			
		||||
__pid_file='/tmp/boring-backup.pid'
 | 
			
		||||
 | 
			
		||||
VERSION='0.1.0'
 | 
			
		||||
LIBRARY="${LIBRARY:-./lib}"
 | 
			
		||||
 | 
			
		||||
# Source library
 | 
			
		||||
@@ -30,24 +25,47 @@ if [ -f "$LIBRARY/lib.sh" ]; then
 | 
			
		||||
    . "$LIBRARY/lib.sh"
 | 
			
		||||
else
 | 
			
		||||
    echo "Error: Cannot source library $LIBRARY/lib.sh: No such file" >&2
 | 
			
		||||
    __exit=1
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
print_help() {
 | 
			
		||||
    cat <<- EOF
 | 
			
		||||
Backup files and databases.
 | 
			
		||||
    printf << EOF \
 | 
			
		||||
"USAGE:
 | 
			
		||||
 | 
			
		||||
Usage: $0 [-cvlphV] FILES..
 | 
			
		||||
    $0 [-hVvs] [-c \033[4mfile\033[0m] [-l \033[4mfile\033[0m] \
 | 
			
		||||
[-p \033[4mfile\033[0m] file ...
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
OPTIONS:
 | 
			
		||||
 | 
			
		||||
Environment:
 | 
			
		||||
    LIBRARY         path to bb library [current: $LIBRARY]
 | 
			
		||||
    -h, --help
 | 
			
		||||
        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
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -88,33 +106,70 @@ for args in "$@"; do
 | 
			
		||||
    shift
 | 
			
		||||
    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
 | 
			
		||||
            set -- "$@" $args;; # 'args' must be unquoted!
 | 
			
		||||
            set -- "$@" $args  # 'args' must be unquoted!
 | 
			
		||||
            ;;
 | 
			
		||||
        *)
 | 
			
		||||
            set -- "$@" "$args";;  # save positional arguments
 | 
			
		||||
            set -- "$@" "$args"  # save positional arguments
 | 
			
		||||
            ;;
 | 
			
		||||
    esac
 | 
			
		||||
done
 | 
			
		||||
 | 
			
		||||
# Final arguments parser
 | 
			
		||||
while (( "$#" )); do
 | 
			
		||||
    case "$1" in
 | 
			
		||||
        -h|--help)
 | 
			
		||||
            print_help
 | 
			
		||||
            exit 0
 | 
			
		||||
            ;;
 | 
			
		||||
        -V|--version)
 | 
			
		||||
            echo "$VERSION"
 | 
			
		||||
            exit 0
 | 
			
		||||
            ;;
 | 
			
		||||
        -v|--verbose)
 | 
			
		||||
            verbose_output=1
 | 
			
		||||
            shift
 | 
			
		||||
            ;;
 | 
			
		||||
        -c|--config|--config=*)
 | 
			
		||||
            optval "$1" "$2"; __config="$val"; shift "$sft";;
 | 
			
		||||
        -v|--verbose) __verbose=1; shift;;
 | 
			
		||||
            optval "$1" "$2"
 | 
			
		||||
            bb_config="$val"
 | 
			
		||||
            shift "$sft"
 | 
			
		||||
            ;;
 | 
			
		||||
        -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=*)
 | 
			
		||||
            optval "$1" "$2"; __pid_file="$val"; shift "$sft";;
 | 
			
		||||
        -h|--help) print_help; exit 0;;
 | 
			
		||||
        -V|--version) echo "$__version"; exit 0;;
 | 
			
		||||
        -*) echo "Error: Unknown option: $1" >&2; exit 1;;
 | 
			
		||||
        *)  __args+=("$1"); shift;; # Save positional args
 | 
			
		||||
            optval "$1" "$2"
 | 
			
		||||
            pid_file="$val"
 | 
			
		||||
            shift "$sft"
 | 
			
		||||
            ;;
 | 
			
		||||
        -*)
 | 
			
		||||
            echo "Error: Unknown option: $1" >&2
 | 
			
		||||
            exit 1
 | 
			
		||||
            ;;
 | 
			
		||||
        *)
 | 
			
		||||
            __args+=("$1") # Save positional args
 | 
			
		||||
            shift
 | 
			
		||||
            ;;
 | 
			
		||||
    esac
 | 
			
		||||
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
 | 
			
		||||
if ! declare -F -- log > /dev/null 2>&1; then
 | 
			
		||||
    exit 1
 | 
			
		||||
@@ -127,20 +182,20 @@ fi
 | 
			
		||||
log -V "Backup STARTED"
 | 
			
		||||
 | 
			
		||||
# Check PID file
 | 
			
		||||
if [ -e "$__pid_file" ]; then
 | 
			
		||||
if [ -e "$pid_file" ]; then
 | 
			
		||||
    # shellcheck disable=SC2009
 | 
			
		||||
    # shellcheck disable=SC2143
 | 
			
		||||
    if [ -z "$(ps ax -o pid | grep "$(cat "$__pid_file")")" ]; then
 | 
			
		||||
        log -p "Process $(cat "$__pid_file") died." >&2
 | 
			
		||||
        rm "$__pid_file"
 | 
			
		||||
    if [ -z "$(ps ax -o pid | grep "$(cat "$pid_file")")" ]; then
 | 
			
		||||
        log -p "Process $(cat "$pid_file") died." >&2
 | 
			
		||||
        rm "$pid_file"
 | 
			
		||||
    else
 | 
			
		||||
        echo "Process $(cat "$__pid_file") still running." >&2
 | 
			
		||||
        echo "Process $(cat "$pid_file") still running." >&2
 | 
			
		||||
        exit 1
 | 
			
		||||
    fi
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Touch PID file
 | 
			
		||||
echo "$$" > "$__pid_file"
 | 
			
		||||
echo "$$" > "$pid_file"
 | 
			
		||||
 | 
			
		||||
# Scripts counter.
 | 
			
		||||
__count="${#__args[@]}" # count
 | 
			
		||||
@@ -149,9 +204,12 @@ __i=1                   # iterator
 | 
			
		||||
# Startup log.
 | 
			
		||||
date +'Start: %d %b %Y %T %z'
 | 
			
		||||
log -p "Library path: $LIBRARY"
 | 
			
		||||
log -p "Log file: $__log_file"
 | 
			
		||||
log -p "Configuration file:" \
 | 
			
		||||
    "$([ "$__config" ] || echo not specified && echo "$__config")"
 | 
			
		||||
log -p "Log file: $log_file"
 | 
			
		||||
log -p "Configuration file:" "$(\
 | 
			
		||||
    if [ -f "$bb_config" ];
 | 
			
		||||
        then echo "$bb_config";
 | 
			
		||||
        else echo not specified;
 | 
			
		||||
    fi)"
 | 
			
		||||
log -p "Total scripts: $__count"
 | 
			
		||||
log "Scripts to process (${__count}): ${__args[*]}"
 | 
			
		||||
 | 
			
		||||
@@ -171,7 +229,7 @@ for script in "${__args[@]}"; do
 | 
			
		||||
 | 
			
		||||
    # Config can ovewrite script functions and variables
 | 
			
		||||
    # shellcheck source=/dev/null
 | 
			
		||||
    [ -n "$__config" ] && . "$__config"
 | 
			
		||||
    [ -f "$bb_config" ] && . "$bb_config"
 | 
			
		||||
 | 
			
		||||
    # --- Run user script -- #
 | 
			
		||||
 | 
			
		||||
@@ -208,17 +266,10 @@ for script in "${__args[@]}"; do
 | 
			
		||||
 | 
			
		||||
    # Unset user defined variables
 | 
			
		||||
    unset compression
 | 
			
		||||
    unset name_prefix
 | 
			
		||||
    unset name_date_format
 | 
			
		||||
    unset s3cmd_options
 | 
			
		||||
    unset s3cmd_config
 | 
			
		||||
    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 name_prefix name_date_format name_prefix name_suffix
 | 
			
		||||
    unset s3cmd_config s3cmd_options
 | 
			
		||||
    unset s3_access_key s3_secret_key s3_region s3_host s3_host_bucket
 | 
			
		||||
    unset tar_options tar_exclude
 | 
			
		||||
    unset mysqldump_options
 | 
			
		||||
    unset pg_dump_options
 | 
			
		||||
done
 | 
			
		||||
@@ -227,4 +278,6 @@ echo -e "\nBackup [Done]"
 | 
			
		||||
log -V "Backup FINISHED"
 | 
			
		||||
 | 
			
		||||
# Remove PID file
 | 
			
		||||
rm "$__pid_file"
 | 
			
		||||
rm "$pid_file"
 | 
			
		||||
 | 
			
		||||
exit "${__exit:-0}"
 | 
			
		||||
@@ -25,7 +25,6 @@ tgt_s3cmd() {
 | 
			
		||||
    log "Run handler ${FUNCNAME[0]}()"
 | 
			
		||||
 | 
			
		||||
    local uri
 | 
			
		||||
    local src_path
 | 
			
		||||
 | 
			
		||||
    uri="$1"
 | 
			
		||||
 | 
			
		||||
@@ -44,7 +43,7 @@ tgt_s3cmd() {
 | 
			
		||||
    # Set s3cmd comand. See s3cmd(1)
 | 
			
		||||
    if [ -n "$s3cmd_config" ]; then
 | 
			
		||||
        # Use configuration file
 | 
			
		||||
        # shellcheck disable=SC2154
 | 
			
		||||
        # shellcheck disable=SC2154,SC2086
 | 
			
		||||
        set -- s3cmd $s3cmd_options --config "$s3cmd_config" \
 | 
			
		||||
            put "${backups[@]}" "$uri"
 | 
			
		||||
    elif [ -n "$s3_access_key" ]    && \
 | 
			
		||||
@@ -54,7 +53,7 @@ tgt_s3cmd() {
 | 
			
		||||
    then
 | 
			
		||||
        s3_region="${s3_region:-na}" # fallback to 'no available' region
 | 
			
		||||
        # Use parameters provided from backup script
 | 
			
		||||
        # shellcheck disable=SC2154
 | 
			
		||||
        # shellcheck disable=SC2154,SC2086
 | 
			
		||||
        set -- s3cmd $s3cmd_options \
 | 
			
		||||
            --access_key="$s3_access_key" \
 | 
			
		||||
            --secret_key="$s3_secret_key" \
 | 
			
		||||
@@ -74,6 +73,7 @@ tgt_s3cmd() {
 | 
			
		||||
        # ^^^ hide secret_key from output ^^^
 | 
			
		||||
 | 
			
		||||
    # Upload backups
 | 
			
		||||
    # shellcheck disable=SC2154
 | 
			
		||||
    if "$@" 2>> "$__log_file"; then
 | 
			
		||||
        : # Success
 | 
			
		||||
    else
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user