:Title: boring_backup :Title upper: BORING_BACKUP :Subtitle: бэкап файлов и баз данных :Author: ge :Copyright: \(C) 2022, ge , 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