Skip to content

Instantly share code, notes, and snippets.

@dmkuznetsov
Created March 31, 2017 06:39
Show Gist options
  • Save dmkuznetsov/8de81eb1ef80f1b056d593590e8ef4c8 to your computer and use it in GitHub Desktop.
Save dmkuznetsov/8de81eb1ef80f1b056d593590e8ef4c8 to your computer and use it in GitHub Desktop.
Yandex.Disk
#!/bin/bash
#
# Yandex.Disk backup script v1.0 by Sergey Lukonin (neblog.info)
#
# # # # # # # # # # НАСТРОЙКИ БЕКАПА MYSQL # # # # # # # # # #
# Сервер БД
MYSQL_SERVER=mysql.some-server.ru
# Юзер, под которым будем делать бекап доступных баз, руту mysql обычно доступны все БД, отдельному пользователю обычно доступна БД конкретного проекта
MYSQL_USER=some-user
# Пароль пользователя базы данных (Пароль от рута сервера и от рута mysql разные не путайте)
MYSQL_PASSWORD=some-password
# # # # # # # # # # ОБЩИЕ НАСТРОЙКИ # # # # # # # # # #
# Директория для временного хранения бекапов, которые удаляются после отправки на Яндекс.Диск
BACKUP_DIR='/home/www/backup'
# Название проекта, используется в логах и именах архивов
PROJECT='neblog.info'
# Максимальное количество хранимых на Яндекс.Диске бекапов (0 - хранить все бекапы):
MAX_BACKUPS='14'
# Дата, используется в именах архивов
DATE=`date '+%Y-%m-%d'`
# Директории для архивации (указываются через пробел), которые будут помещены в единый архив и отправлены на Яндекс.Диск
DIRS='/home/www/projects/neblog'
# Yandex.Disk токен (как получить - см. на neblog.info)
TOKEN=''
# Имя лог-файла, хранится в директории, указанной в $BACKUP_DIR
LOGFILE='backup.log'
# E-mail для отправки результата выполнения скрипта. Оставьте пустым, если отправлять результаты не требуется.
sendLog='your-mail@yandex.ru'
# Отправлять только ошибки (true). Укажите false, если нужно отправлять логи при любом результате выполнения скрипта.
sendLogErrorsOnly='false'
# # # # # # # # # # КОНЕЦ НАСТРОЕК # # # # # # # # # # # # #
# # # # # # # # ДАЛЬШЕ НИЧЕГО НЕ МЕНЯЕМ! # # # # # # # # # #
function mailing()
{
if [ ! $sendLog = '' ];then
if [ "$sendLogErrorsOnly" == true ];
then
if echo "$1" | grep -q 'error'
then
echo "$2" | mail -s "$1" $sendLog > /dev/null
fi
else
echo "$2" | mail -s "$1" $sendLog > /dev/null
fi
fi
}
function logger()
{
echo "["`date "+%Y-%m-%d %H:%M:%S"`"] File $BACKUP_DIR: $1" >> $BACKUP_DIR/$LOGFILE
}
function parseJson()
{
local output
regex="(\"$1\":[\"]?)([^\",\}]+)([\"]?)"
[[ $2 =~ $regex ]] && output=${BASH_REMATCH[2]}
echo $output
}
function checkError()
{
echo $(parseJson 'error' "$1")
}
function getUploadUrl()
{
json_out=`curl -s -H "Authorization: OAuth $TOKEN" https://cloud-api.yandex.net:443/v1/disk/resources/upload/?path=app:/$backupName&overwrite=true`
json_error=$(checkError "$json_out")
if [[ $json_error != '' ]];
then
logger "$PROJECT - Yandex.Disk error: $json_error"
mailing "$PROJECT - Yandex.Disk backup error" "ERROR copy file $FILENAME. Yandex.Disk error: $json_error"
echo ''
else
output=$(parseJson 'href' $json_out)
echo $output
fi
}
function uploadFile
{
local json_out
local uploadUrl
local json_error
uploadUrl=$(getUploadUrl)
if [[ $uploadUrl != '' ]];
then
echo $UploadUrl
json_out=`curl -s -T $1 -H "Authorization: OAuth $TOKEN" $uploadUrl`
json_error=$(checkError "$json_out")
if [[ $json_error != '' ]];
then
logger "$PROJECT - Yandex.Disk error: $json_error"
mailing "$PROJECT - Yandex.Disk backup error" "ERROR copy file $FILENAME. Yandex.Disk error: $json_error"
else
logger "$PROJECT - Copying file to Yandex.Disk success"
mailing "$PROJECT - Yandex.Disk backup success" "SUCCESS copy file $FILENAME"
fi
else
echo 'Some errors occured. Check log file for detail'
fi
}
function backups_list() {
# Ищем в директории приложения все файлы бекапов и выводим их названия:
curl -s -H "Authorization: OAuth $TOKEN" "https://cloud-api.yandex.net:443/v1/disk/resources?path=app:/&sort=created&limit=100" | tr "{},[]" "\n" | grep "name[[:graph:]]*.tar.gz" | cut -d: -f 2 | tr -d '"'
}
function backups_count() {
local bkps=$(backups_list | wc -l)
# Если мы бекапим и файлы, и БД, то на 1 бекап у нас приходится 2 файла. Поэтому количество бекапов = количество файлов / 2:
expr $bkps / 2
}
function remove_old_backups() {
bkps=$(backups_count)
old_bkps=$((bkps - MAX_BACKUPS))
if [ "$old_bkps" -gt "0" ];then
logger "Удаляем старые бекапы с Яндекс.Диска"
# Цикл удаления старых бекапов:
# Выполняем удаление первого в списке файла 2*old_bkps раз
for i in `eval echo {1..$((old_bkps * 2))}`; do
curl -X DELETE -s -H "Authorization: OAuth $TOKEN" "https://cloud-api.yandex.net:443/v1/disk/resources?path=app:/$(backups_list | awk '(NR == 1)')&permanently=true"
done
fi
}
logger "--- $PROJECT START BACKUP $DATE ---"
logger "Выгружаем дампы баз"
mkdir $BACKUP_DIR/$DATE
for i in `mysql -h $MYSQL_SERVER -u $MYSQL_USER -p$MYSQL_PASSWORD -e'show databases;' | grep -v information_schema | grep -v Database`;
do mysqldump -h $MYSQL_SERVER -u $MYSQL_USER -p$MYSQL_PASSWORD $i > $BACKUP_DIR/$DATE/$i.sql;
done
logger "Создаем архив mysql $BACKUP_DIR/$DATE-mysql-$PROJECT.tar.gz"
tar -czf $BACKUP_DIR/$DATE-mysql-$PROJECT.tar.gz $BACKUP_DIR/$DATE
rm -rf $BACKUP_DIR/$DATE
logger "Создаем архив каталогов $BACKUP_DIR/$DATE-files-$PROJECT.tar.gz"
tar -czf $BACKUP_DIR/$DATE-files-$PROJECT.tar.gz $DIRS
FILENAME=$DATE-mysql-$PROJECT.tar.gz
logger "Выгружаем на Яндекс.Диск архив mysql $BACKUP_DIR/$DATE-mysql-$PROJECT.tar.gz"
backupName=$DATE-mysql-$PROJECT.tar.gz
uploadFile $BACKUP_DIR/$DATE-mysql-$PROJECT.tar.gz
FILENAME=$DATE-files-$PROJECT.tar.gz
logger "Выгружаем на Яндекс.Диск архив с файлами $BACKUP_DIR/$DATE-files-$PROJECT.tar.gz"
backupName=$DATE-files-$PROJECT.tar.gz
uploadFile $BACKUP_DIR/$DATE-files-$PROJECT.tar.gz
logger "Удаляем архивы с диска"
find $BACKUP_DIR -type f -name "*.gz" -exec rm '{}' \;
# Удаляем старые бекапы с Яндекс.Диска (если MAX_BACKUPS > 0)
if [ $MAX_BACKUPS -gt 0 ];then remove_old_backups; fi
logger "Завершение скрипта бекапа"
@dmkuznetsov
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment