Backup на Яндекс.Диск
Для того чтобы сливать бэкапы на сторонний сервер или в локальную директорию уже давным давно можно не писать самопальные скрипты, а воспользоваться гемом Backup. И то, что это гем и написан он на Ruby, совершенно не означает, что организовывать бэкапы он может только для Ruby.
Backup много чего умеет делать, работает с двумя вагонами СУБД (MySQL, PostgreSQL, MongoDB итд), может закачивать сами бэкапы на триллионы различных площадок (Dropbox, CloudFiles, S3 итд) используя килотонны всевозможных протоколов (SFTP, FTP, SCP итд), подробнее об этом давно уже расписано на Хабре. Одна беда у гема: он не поддерживает протокол WebDAV и площадку Яндекс.Диск. Ну, а почему собственно необходим Яндекс.Диск и чем он лучше всех остальных можно узнать перейдя по моей партнерской ссылке (новый шедевр скрытой рекламы).
установка backup
Тут ничего нового, все тоже самое, что и в официальной инструкции.
Сама установка:
# gem install backup |
Генерация конфига:
$ backup generate:model --trigger my_backup Generated model file: '~/Backup/models/my_backup.rb'. |
В результате этих манипуляций возникнет директория ~/Backup
с какой-то лабудой в ~/Backup/config.rb
и собственно с конфигом одной из задач в ~/Backup/models/my_backup.rb
.
интерфейс для Яндекс.Диска
Управлять ЯДом можно как через API, так и напрямую через WebDAV. Для взаимодействия по WebDAV есть отдельные специальные гемы, но нормально закачать что-нибудь вряд ли удастся т.к. для авторизации по WebDAV придется использовать пару логин:пароль, в то время как ЯД позволяет загружать только при авторизации по ключу приложения, насколько я понял.
К счастью существует гем yandex-disk, через который и будут заливаться бэкапы.
После установки гема:
# gem install yandex-disk |
чтобы иметь права не только на чтение, необходимо получить токен от Яндекса. Для этого надо:
- авторизоваться в Яндексе
- выбрать имеющееся приложение или создать новое
- получить токен пройдя по ссылке: https://oauth.yandex.ru/authorize?response_type=token&client_id=YOUR_APP_ID
настройка backup под Яндекс.Диск
Удивительно, но на странице гема yandex-disk в самом низу приведен конфиг модели под backup, лично для себя, я приведу указанную конфигурацию к mysql-евскому виду:
# encoding: utf-8 ## # Backup Generated: my_backup # Once configured, you can run the backup with the following command: # # $ backup perform -t my_backup [-c ] # require 'yandex/disk/backup/storage' Backup::Model.new(:my_backup, 'My backup DB to Yandex.Disk') do ## # Split [Splitter] # # Split the backup file in to chunks of 250 megabytes # if the backup file size exceeds 250 megabytes # split_into_chunks_of 500 database MySQL do |db| db.name = 'mydb' db.username = 'myuser' db.password = 'mypass' end compress_with Gzip store_with Yandex::Disk do |disk| disk.access_token = 'mysupersecretyandexapptoken' disk.path = '/backups/' disk.keep = 5 end end |
запуск
И вот казалось бы все готово, осталось только запустить backup:
$ backup perform -t my_backup [2014/01/08 18:53:04][info] Performing Backup for 'My backup DB to Yandex.Disk (my_backup)'! [2014/01/08 18:53:04][info] [ backup 3.4.0 : ruby 2.0.0p247 (2013-06-27 revision 41674) [x86_64-linux] ] [2014/01/08 18:53:04][info] Database::MySQL Started... [2014/01/08 18:53:04][info] Using Compressor::Gzip for compression. [2014/01/08 18:53:04][info] Command: '/bin/gzip' [2014/01/08 18:53:04][info] Ext: '.gz' [2014/01/08 18:53:06][info] Database::MySQL Finished! [2014/01/08 18:53:06][info] Packaging the backup files... [2014/01/08 18:53:06][info] Splitter configured with a chunk size of 500MB. [2014/01/08 18:53:06][info] Packaging Complete! [2014/01/08 18:53:06][info] Cleaning up the temporary files... [2014/01/08 18:53:06][info] Yandex::Disk Started... [2014/01/08 18:53:06][error] ModelError: Backup for Backup OA DB to Yandex.Disk (oabackup) Failed! [2014/01/08 18:53:06][error] An Error occured which has caused this Backup to abort before completion. [2014/01/08 18:53:06][error] Reason: NoMethodError [2014/01/08 18:53:06][error] undefined method `present?' for "mysupersecretyandexapptoken":String [2014/01/08 18:53:06][error] [2014/01/08 18:53:06][error] Backtrace: [2014/01/08 18:53:06][error] /usr/local/rvm/gems/ruby-2.0.0-p247/gems/yandex-disk-0.0.5/lib/yandex/disk/client.rb:17:in `block in initialize' [2014/01/08 18:53:06][error] /usr/local/rvm/gems/ruby-2.0.0-p247/gems/faraday-0.8.8/lib/faraday/connection.rb:65:in `initialize' [2014/01/08 18:53:06][error] /usr/local/rvm/gems/ruby-2.0.0-p247/gems/faraday-0.8.8/lib/faraday.rb:11:in `new' [2014/01/08 18:53:06][error] /usr/local/rvm/gems/ruby-2.0.0-p247/gems/faraday-0.8.8/lib/faraday.rb:11:in `new' [2014/01/08 18:53:06][error] /usr/local/rvm/gems/ruby-2.0.0-p247/gems/yandex-disk-0.0.5/lib/yandex/disk/client.rb:16:in `initialize' [2014/01/08 18:53:06][error] /usr/local/rvm/gems/ruby-2.0.0-p247/gems/yandex-disk-0.0.5/lib/yandex/disk/backup/storage.rb:18:in `new' [2014/01/08 18:53:06][error] /usr/local/rvm/gems/ruby-2.0.0-p247/gems/yandex-disk-0.0.5/lib/yandex/disk/backup/storage.rb:18:in `connection' [2014/01/08 18:53:06][error] /usr/local/rvm/gems/ruby-2.0.0-p247/gems/yandex-disk-0.0.5/lib/yandex/disk/backup/storage.rb:22:in `transfer!' [2014/01/08 18:53:06][error] /usr/local/rvm/gems/ruby-2.0.0-p247/gems/backup-3.4.0/lib/backup/storage/base.rb:34:in `perform!' [2014/01/08 18:53:06][error] /usr/local/rvm/gems/ruby-2.0.0-p247/gems/backup-3.4.0/lib/backup/model.rb:242:in `each' [2014/01/08 18:53:06][error] /usr/local/rvm/gems/ruby-2.0.0-p247/gems/backup-3.4.0/lib/backup/model.rb:242:in `block in perform!' [2014/01/08 18:53:06][error] /usr/local/rvm/gems/ruby-2.0.0-p247/gems/backup-3.4.0/lib/backup/model.rb:240:in `each' [2014/01/08 18:53:06][error] /usr/local/rvm/gems/ruby-2.0.0-p247/gems/backup-3.4.0/lib/backup/model.rb:240:in `perform!' [2014/01/08 18:53:06][error] /usr/local/rvm/gems/ruby-2.0.0-p247/gems/backup-3.4.0/lib/backup/cli.rb:163:in `block in perform' [2014/01/08 18:53:06][error] /usr/local/rvm/gems/ruby-2.0.0-p247/gems/backup-3.4.0/lib/backup/cli.rb:162:in `each' [2014/01/08 18:53:06][error] /usr/local/rvm/gems/ruby-2.0.0-p247/gems/backup-3.4.0/lib/backup/cli.rb:162:in `perform' [2014/01/08 18:53:06][error] /usr/local/rvm/gems/ruby-2.0.0-p247/gems/thor-0.18.1/lib/thor/command.rb:27:in `run' [2014/01/08 18:53:06][error] /usr/local/rvm/gems/ruby-2.0.0-p247/gems/thor-0.18.1/lib/thor/invocation.rb:120:in `invoke_command' [2014/01/08 18:53:06][error] /usr/local/rvm/gems/ruby-2.0.0-p247/gems/thor-0.18.1/lib/thor.rb:363:in `dispatch' [2014/01/08 18:53:06][error] /usr/local/rvm/gems/ruby-2.0.0-p247/gems/thor-0.18.1/lib/thor/base.rb:439:in `start' [2014/01/08 18:53:06][error] /usr/local/rvm/gems/ruby-2.0.0-p247/gems/backup-3.4.0/bin/backup:5:in `<top (required)>' [2014/01/08 18:53:06][error] /usr/local/rvm/gems/ruby-2.0.0-p247/bin/backup:23:in `load' [2014/01/08 18:53:06][error] /usr/local/rvm/gems/ruby-2.0.0-p247/bin/backup:23:in `<main>' [2014/01/08 18:53:06][error] /usr/local/rvm/gems/ruby-2.0.0-p247/bin/ruby_executable_hooks:15:in `eval' [2014/01/08 18:53:06][error] /usr/local/rvm/gems/ruby-2.0.0-p247/bin/ruby_executable_hooks:15:in `<main>' [2014/01/08 18:53:06][warn] CleanerError: Cleanup Warning [2014/01/08 18:53:06][warn] The temporary backup folder '~/Backup/.tmp' [2014/01/08 18:53:06][warn] appears to contain the backup files which were to be stored: [2014/01/08 18:53:06][warn] ~/Backup/.tmp/my_backup.tar [2014/01/08 18:53:06][warn] [2014/01/08 18:53:06][warn] Make sure you check these files before the next scheduled backup for [2014/01/08 18:53:06][warn] 'My backup DB to Yandex.Disk (my_backup)' [2014/01/08 18:53:06][warn] These files will be removed at that time! [2014/01/08 18:53:06][info] ModelError: If you have other Backup jobs (triggers) configured to run, [2014/01/08 18:53:06][info] Backup will now attempt to continue... |
И, как уже догадался проницательный читатель, бэкап не залился на ЯД, но не стоит расстраиваться. Пристально и с презрением посмотрите на строки:
[2014/01/08 18:53:06][error] undefined method `present?' for "mysupersecretyandexapptoken":String [2014/01/08 18:53:06][error] [2014/01/08 18:53:06][error] Backtrace: [2014/01/08 18:53:06][error] /usr/local/rvm/gems/ruby-2.0.0-p247/gems/yandex-disk-0.0.5/lib/yandex/disk/client.rb:17:in `block in initialize' |
и откройте файл /usr/local/rvm/gems/ruby-2.0.0-p247/gems/yandex-disk-0.0.5/lib/yandex/disk/client.rb
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | # coding: utf-8 require 'base64' require 'faraday' require 'faraday_middleware' Faraday::Connection::METHODS << :propfind module Yandex module Disk class Client autoload :Request, 'yandex/disk/client/request' def initialize options={} @timeout = options[:timeout] || 300 @http = Faraday.new(:url => 'https://webdav.yandex.ru') do |builder| if options[:access_token].present? builder.request :authorization, "OAuth", options[:access_token] else basic_token = Base64.encode64("#{options[:login]}:#{options[:password]}") builder.request :authorization, "Basic", basic_token end builder.response :follow_redirects if faraday_configurator = options[:faraday_configurator] faraday_configurator.call(builder) else builder.adapter :excon end end end ... |
По неизвестным науке обстоятельствам ошибка возникает при вызове метода present?
для String-элемента в хэше. Наивный читатель может предложить заменить
if options[:access_token].present? |
на
unless options[:access_token].blank? |
но спешу заметить, что такая рокировка вызовет аналогичную ошибку, поэтому в данном случае я предлагаю строку №17 привести к виду:
16 17 18 | @http = Faraday.new(:url => 'https://webdav.yandex.ru') do |builder| if options[:access_token] builder.request :authorization, "OAuth", options[:access_token] |
После такой магии у меня все запустилось:
$ backup perform -t my_backup [2014/01/08 19:09:03][info] Performing Backup for 'My backup DB to Yandex.Disk (my_backup)'! [2014/01/08 19:09:03][info] [ backup 3.4.0 : ruby 2.0.0p247 (2013-06-27 revision 41674) [x86_64-linux] ] [2014/01/08 19:09:04][warn] CleanerError: Cleanup Warning [2014/01/08 19:09:04][warn] The temporary backup folder '~/Backup/.tmp' [2014/01/08 19:09:04][warn] appears to contain the package files from the previous backup! [2014/01/08 19:09:04][warn] ~/Backup/.tmp/my_backup.tar [2014/01/08 19:09:04][warn] These files will now be removed. [2014/01/08 19:09:04][warn] [2014/01/08 19:09:04][warn] Please check the log for messages and/or your notifications [2014/01/08 19:09:04][warn] concerning this backup: 'My backup DB to Yandex.Disk (my_backup)' [2014/01/08 19:09:04][warn] The temporary files which had to be removed should not have existed. [2014/01/08 19:09:04][info] Database::MySQL Started... [2014/01/08 19:09:04][info] Using Compressor::Gzip for compression. [2014/01/08 19:09:04][info] Command: '/bin/gzip' [2014/01/08 19:09:04][info] Ext: '.gz' [2014/01/08 19:09:10][info] Database::MySQL Finished! [2014/01/08 19:09:10][info] Packaging the backup files... [2014/01/08 19:09:10][info] Splitter configured with a chunk size of 500MB. [2014/01/08 19:09:10][info] Packaging Complete! [2014/01/08 19:09:10][info] Cleaning up the temporary files... [2014/01/08 19:09:10][info] Yandex::Disk Started... [2014/01/08 19:09:12][info] Storing '/backups/my_backup/2014.01.08.19.09.03/my_backup.tar'... [2014/01/08 19:10:13][info] Cycling Started... [2014/01/08 19:10:13][info] Yandex::Disk Finished! [2014/01/08 19:10:13][info] Cleaning up the package files... [2014/01/08 19:10:13][warn] Backup for 'My backup DB to Yandex.Disk (my_backup)' Completed Successfully (with Warnings) in 00:01:10 |
слишком пафосно написано…
“триллионы”, “килотонны” и т.п…
ишь ты наркоман, разошелся, иди кнопки в лифтах жечь, пафосно