Можно ли использовать яндекс диск для резервного копирования
Содержание статьи
Резервное копирование в облако Яндекс диск.Бэкап файлов в облака
Со временем на вашем компьютере или ноутбуке накапливается достаточно большое количество файлов — 1000, 2000, а то и 500 000. Их важность может быть очень высока, особенно если это семейные фотографии, видео, рабочие документы.
Чтобы надежно сберечь ценные файлы от вирусов и повреждений в результате сбоя файловой системы, каждому пользователю ПК необходимо хотя бы 1 раз в 2-3 недели делать дубль своих данных — создавать резервные копии. Наличие «свежего» бэкапа поможет восстановить из него информацию в случае потери.
Где хранить резервные копии: на внешнем HDD или довериться облаку?
Когда еще не было «облаков», резервные копии обычно хранили:
- на локальном ПК
- внешнем (съемном) USB-носителе, флешке или DVD
- на сервере в локальной сети
- на удаленном FTP-сервере
Продвинутые пользователи и системные администраторы также копировали файлы на удаленные сервера по протоколам FTP / SSH / WebDAV и т.п. Теперь появилась дополнительная возможность — хранить папки в интернете, на сервере от компании Яндекс.
Что такое Яндекс Диск?
Яндекс диск — это облачный сервис, позволяющий хранить файлы на сервере, под вашей учетной записью. По-умолчанию, вам предоставляется 10 ГБ дискового пространства бесплатно и навсегда с возможностью дальнейшего увеличения. Благодаря доступности и удобству этот сервис быстро набрал популярность и по состоянию на октябрь 2018 года им пользуются уже более 16 млн. пользователей.
Преимущества хранения в облаке
- Хранение файлов вне офиса (вне дома) позволяет уберечь данные от пожара и вирусов
- Высокая надежность, так как папки дополнительно резервируются Yandex’ом, а передача осуществляется по защищенному протоколу
- Доступность данных из любой точки планеты
- Высокое доверие, поскольку компания Яндекс уже много лет работает на рынке ИТ- это лидер в области ИТ и интернет-сервисов в России и странах СНГ.
Недостатки
- Ресурс ограничен 10 ГБ, увеличение размера платное
- Очень секретную (конфиденциальную) информацию, представляющую коммерческую тайну, все же не рекомендуется хранить в «облаках»
Вывод
Хранить резервные копии в интернете или нет — решать вам. Если вы — обычный пользователь, у которого не слишком секретные данные и их объемы порядка 3 — 6 ГБ (не превышает 10 ГБ), то резервное копирование на Яндекс.Диск — отличное бесплатное решение для обеспечения сохранности файлов документов, бэкапа фото-видео! Как правило, для хранения нескольких копий наиболее важных файлов указанного объема вполне достаточно.
Exiland Backup — простой инструмент бэкапа в облако
Далее мы рассмотрим как сделать резервную копию на Яндекс Диск с помощью утилиты Exiland Backup версий Standard и Professional.
Начиная с версии 5.0, в программе появилась возможность резервного копирования в облако, а также проводить синхронизацию папок туда и обратно.
Передача файлов происходит по защищенному каналу, с использованием безопасного протокола REST (SFTP). Облачный Бэкап файлов осуществляется в несколько параллельных потоков, благодаря чему достигается высокая скорость передачи. И что очень важно, Exiland Backup работает с диском Yandex напрямую, без необходимости устанавливать на ваш компьютер какой-либо дополнительный софт и без предварительного копирования файлов в папку, синхронизируемую с «облаком». Это экономит место на локальном носителе.
Пошаговый мастер настройки
Создание учетной записи Яндекс
Если у вас уже есть учетная запись на любом из сервисов Yandex’а, то эта же учетная запись подойдет и для облака. Если у вас еще нет учетной записи, зайдите на сайт https://disk.yandex.ru, нажмите на кнопку «Завести Диск» и справа заполните небольшую форму регистрации.
Настройка задания для резервного копирования
Рассмотрим, как настроить утилиту Exiland Backup для автоматического сохранения резервных копий на ЯндексДиске. В качестве примера настроим утилиту таким образом, чтобы основные дубликаты информации она сохраняла на этот же ПК в папку D:BACKUP и дополнительно дублировала на Yandex.
Скачайте демо-версию Professional на официальной странице, установите на ПК Windows и запустите ее. В главном окне, в левом углу, нажмите кнопку создания задания — на экране появится пошаговый мастер.
Шаг 1: Наименование задания
Введите название задания, например «Мои рабочие документы» и нажмите «Далее».
Шаг 2: Тип резервного копирования
Укажите тип — «Добавочный» и нажмите «Далее».
Шаг 3: Исходные папки
Нажмите «Добавить» и выберите пункт «Локальные/сетевые файлы и папки». К примеру, выберем папку «C:Документы».
Шаг 4: Сжатие в ZIP
Если нужно архивировать данные в ZIP и шифровать их, всё это можно настроить. Выбираем сжатие в ZIP, степень сжатия — максимальная, шифрование 256 bit AES и установим пароль на ZIP-архив (все таки в облаке будем хранить данные). Проверку целостности архива — тоже установим на всякий случай.
Шаг 5: Куда сохранять резервные копии
Как и договаривались выше, основным местом хранения резервных копий у нас будет локальная папка «D:BACKUP» и дополнительно будем дублировать на Yandex.Disk.
Нажимаем «Добавить -> Локальная/сетевая папка» и выбираем «D:BACKUP».
Далее, добавляем второе место для хранения.
Нажимаем «Добавить -> Папка на Яндекс.Диске». В открывшемся окне из выпадающего списка выбираем «Новое соединение». Перед вами появится браузер, встроенный в программу, а в нем — окно авторизации.
Авторизация на сервисы Yandex
Авторизуемся (входим в вашу учетную запись). Далее, программа спросит разрешение на доступ к вашему аккаунту.
Разрешение доступа Exiland Backup к облаку
Нажимаем кнопку «Разрешить» и видим структуру каталогов вашего Яндекс-хранилища:
Структура каталогов на сервере
Выбираем заранее созданную на сервере Yandex папку «Резервные копии». Если заранее папка не была создана, то вы можете создать ее, нажав кнопку «* Новая папка». Нажимаем «ОК» для подтверждения выбора.
Шаг 6: Расписание
Для простоты укажем «Каждый день, каждый час»
Шаг 7: Уведомления
Здесь вы можете указать отправку отчета по SMS или по .
Нажимаем «Готово». Всё, задание создано.
Запуск задания
Создание облачного бэкапа на сервер Yandex
Не дожидаясь наступления расписания, запустим задание принудительно, нажав на кнопку «Выполнить» на верхней панели в главном окне и видим, как идет процесс резервного копирования. Сначала создается резервная копия на локальном HDD, затем созданный ZIP-архив копируется на Yandex.Disk в указанную нами папку.
Всё, резервная копия создана и теперь она видна на вкладке «Созданные резервные копии» нашего задания.
Восстановление данных
В случае потери данных вы можете восстановить их из резервной копии с локального накопителя или с Яндекс.Диска. Для этого переключитесь во вкладку «Созданные резервные копии» и двойным кликом войдите в последнюю созданную резервную копию. Перед вами откроется окно, отображающее содержимое бэкапа.
Восстановление данных с сервера Yandex
Отметьте галочками папки, которые необходимо восстановить и, кликнув правой кнопкой мыши, произведите восстановление либо в исходное расположение, либо в любую временную папку. Программа сначала скачает ZIP-архив с сервера, а затем извлечет из него выбранные папки.
Синхронизация файлов между ПК и Яндекс.Диском
Кроме резервного копирования, программа Exiland Backup позволяет выполнять синхронизацию файлов между вашим ноутбуком и Yandex. Вы можете настроить копирование с сервера Yandex на свой компьютер и наоборот. Это особенно удобно, если вы привыкли хранить и коллективно редактировать рабочие документы на этом облачном хранилище. В этом случае вы сможете обеспечить сохранность рабочей информации, если настроите бэкап из облачного хранилища на ваш ПК. Такая настройка выполняется не сложнее, чем та, что была описана выше, только в качестве источника вам необходимо выбрать «Файлы и папки на Яндекс.Диске», а папку куда сохранять — локальную.
Заключение
Мы использовали Yandex как дополнительное хранилище наших резервных копий (можно и как основное), показали как настроить облачный бэкап на Яндекс.Диск и показали обратный процесс — восстановление файлов в случае их потери. Этот вид хранилища очень удобен, но лучше всего его использовать для сохранения только наиболее важных данных, поскольку место все таки ограничено.
Утилита Exiland, которую мы рассмотрели, многофункциональна, может даже делать бэкап сайта на Яндекс диск и бэкап баз 1С.
На этом краткий обзор возможности заканчиваю. Если возникнут какие-либо вопросы, буду рад помочь. Пишите мне через форму обратной связи.
Михаил, разработчик Exiland Backup
29 апреля 2021
Источник
Резервное копирование веб-проектов на Яндекс.Диск
vasiatka 20 декабря 2013 в 13:09
В далекие детские годы я не понимал важность резервного копирования данных. Но, как говорится, понимание приходит с опытом. Зачастую опыт бывает очень горький. В моем случае хостинг два раза убивал базу сайта MathInfinity, созданного еще в студенческие годы.
Большие проекты могут позволить себе выделить целые сервера для резервного копирования. Однако, существует огромное количество небольших проектов, работающих лишь на вашем энтузиазме. Эти проекты также нуждаются в резервном копировании.
Идея создания архивов на сервисах вроде Dropbox, Ubuntu One, Яндекс Диск, Диск Google и др. уже давно притягивала мое внимание. Десятки гигабайт бесплатного места, которое теоретически можно использовать для резервирования данных.
Теперь эта идея получила мое первое воплощение. В качестве сервиса для создания архивов был выбран Яндекс Диск.
На гениальность идеи я не претендую. И, конечно, изобретение велосипеда началось с поиска готовых решений в Интернете. Весь найденный код либо уже не работал, либо имел совершенно нечитаемый вид. Я же предпочитаю понимать как работают мои приложения.
Не скажу, что API сервисов Яндекса имеют отличную документацию. Однако там есть примеры и ссылки на конкретные стандарты. Этого вполне хватило.
После изучения проблемы задача резервирования данных распалась на следующие пункты:
- Регистрация приложения
- Авторизация в Яндексе при помощи OAuth
- Операции с Яндекс.Диском
- Создание и отправка резервной копии на Яндекс диск
- Выполнение копирования по крону
Последние два пункта — дело техники, но все же я решил включить их в описание.
Я давно использую фреймворк Limb. И чтобы не изобретать колес к своему велосипеду ниже будут приводиться коды классов
с использованием данного фреймворка. Все классы и функции с префиксом lmb являются стандартными классами и функциями Limb.
Регистрация приложения
Сначала необходимо зарегистрировать свое приложение. Процесс регистрации приложения очень прост. Данная процедура описана в Документации Яндекса.
От вас требуется заполнить простую форму, в которой среди всего прочего необходимо дать разрешение на использование вашего Яндекс диска приложением. В результате заполнения полей формы вам будут выданы id приложения и пароль приложения. Их необходимо использовать для получения токена. У меня данный процесс занял 3 минуты.
Авторизация в Яндексе при помощи OAuth
Для выполнения операций с диском, необходимо указывать OAuth токен. В стандарте OAuth описано несколько вариантов получения токена. Ту решено идти самым простым путем. В соответствии со стандартом OAuth п.4.3.2 токен можно получить прямым запросом к сервису с использованим логина и пароля от учетной записи Яндекса (учетная запись может быть любой).
Небольшой поиск по документации, позволил написать следующий класс:
Код класса получения токена
class YaAuth { protected $token; protected $error; protected $create_; protected $ttl; protected $app_id; protected $conf; protected $logger; __construct($conf,$logger) { $this->logger = $logger; $this->app_id = $conf->get(‘oauth_app_id’); $this->clear(); $this->conf = $conf; } getToken() { if($this->checkToken()) return $this->token; $url = $this->conf->get(‘oauth_token_url’); $curl = lmbToolkit::instance()->getCurlRequest(); $curl->setOpt(CURLOPT_ER,0); $curl->setOpt(CURLOPT_REFERER,$this->conf->get(‘oauth_referer_url’)); $curl->setOpt(CURLOPT_URL,$url); $curl->setOpt(CURLOPT_CONNECTOUT,1); $curl->setOpt(CURLOPT_FRESH_CONNECT,1); $curl->setOpt(CURLOPT_RETURNTRANSFER,1); $curl->setOpt(CURLOPT_FORBID_REUSE,1); $curl->setOpt(CURLOPT_OUT,4); $curl->setOpt(CURLOPT_SSL_VERIFYPEER,false); $post = ‘grant_type=password&client_id=’.$this->conf->get(‘oauth_app_id’). ‘&client_secret=’.$this->conf->get(‘oauth_app_secret’). ‘&username=’.$this->conf->get(‘oauth_login’). ‘&password=’.$this->conf->get(‘oauth_password’); $er = array(/*’Host: oauth.yandex.ru’,*/ ‘Content-type: application/x-www-form-urlencoded’, ‘Content-Length: ‘.strlen($post) ); $curl->setOpt(CURLOPT_HTTPER,$er); $json = $curl->open($post); if(!$json) { $this->error = $curl->getError(); $this->logger->log(»,’ERROR’, $this->error); return false; } $http_code = $curl->getRequestus(); if(($http_code!=’200′) && ($http_code!=’400′)) { $this->error = «Request us is «.$http_code; $this->logger->log(»,’ERROR’, $this->error); return false; } $result = json_decode($json, true); if (isset($result[‘error’]) && ($result[‘error’] != »)) { $this->error = $result[‘error’]; $this->logger->log(»,’ERROR’, $this->error); return false; } $this->token = $result[‘access_token’]; $this->ttl = (int)$result[‘expires_in’]; $this->create_ = (int)(); return $this->token; } clear() { $this->token = »; $this->error = »; $this->counter_id = »; $this->create_ = 0; $this->ttl = -1; } checkToken() { if ($this->ttl <= 0) return false; if (()>($this->ttl+$this->create_)) { $this->error = ‘token_outd’; $this->logger->log(»,’ERROR’, $this->error); return false; } return true; } getError() { return $this->error; } }
Все параметры требуемые для авторизации выносим в конфиг. В качестве конфига может выступать любой объект поддерживающий get и set методы.
Для возможности ведения лога выполняемых действий в конструктор класса передается объект для ведения лога работы. Его код можно найти в архиве с примером.
Собственно у класса два основных метода getToken и checkToken. Первый выполняет cUrl запрос на получение токена, а второй проверяет не устарел ли токен.
Операции с Яндекс.Диском
После получения токена, можно выполнять операции с Яндекс диском.
Яндекс диск позволяет выполнять много различных запросов. Для моих целей необходимы следующие операции:
- Создание папки
- Загрузка файла на Яндекс диск
- Удаление файла с Яндекс диска
- Скачивание файла с Яндекс диска
- Получение списка объектов содержащихся в папке
- Определение существования объекта на диска и его тип
Все операции выполняем с использование cUrl. Конечно, все это можно сделать с использованием сокетов, однако мне важно простота кода. Все операции с Яндекс диском соответствуют протоколу WebDav. В документации API Яндекс диска подробно расписаны примеры выполнения запросов и ответов на эти запросы. Код класса для работы с диском приведен ниже:
Код класса выполнения операций с диском
class YaDisk { protected $auth; protected $config; protected $error; protected $token; protected $logger; protected $url; __construct($token,$config,$logger) { $this->auth = $auth; $this->config = $config; $this->token = $token; $this->logger = $logger; } getCurl($server_dst) { $curl = lmbToolkit::instance()->getCurlRequest(); $curl->setOpt(CURLOPT_SSL_VERIFYPEER,false); $curl->setOpt(CURLOPT_PORT,$this->config->get(‘disk_port’)); $curl->setOpt(CURLOPT_CONNECTOUT,2); $curl->setOpt(CURLOPT_RETURNTRANSFER,1); $curl->setOpt(CURLOPT_ER, 0); $curl->setOpt(CURLOPT_HTTP_VERSION,CURL_HTTP_VERSION_1_1); $uri = new lmbUri($this->config->get(‘disk_server_url’)); $uri = $uri->setPath($server_dst)->toString(); $curl->setOpt(CURLOPT_URL,$uri); $er = array(‘Accept: */*’, «ization: OAuth {$this->token}» ); $curl->setOpt(CURLOPT_HTTPER,$er); return $curl; } getResult($curl, $codes = array()) { if($curl->getError()) { $this->error = $curl->getError(); echo $this->error; $this->logger->log(»,’ERROR’, $this->error); return false; } else { if (!in_array($curl->getRequestus(),$codes)) { $this->error = ‘Response http error:’.$curl->getRequestus(); $this->logger->log(»,’ERROR’, $this->error); return false; } else { return true; } } } mkdir($server_dst) { $curl = $this->getCurl($server_dst); $curl->setOpt(CURLOPT_CUSTOMREQUEST,»MKCOL»); $response = $curl->open(); return $this->getResult($curl, array(201,405));//405 РєРѕРґ коЕвращаеђся если папка СѓР¶Рµ есђь РЅР° сервере } upload($local_src,$server_dst) { $local_file = fopen($local_src,»r»); $curl = $this->getCurl($server_dst); //$curl->setOpt(CURLOPT_CUSTOMREQUEST,»PUT»); $curl->setOpt(CURLOPT_PUT, 1); $curl->setOpt(CURLOPT_INFILE,$local_file); $curl->setOpt(CURLOPT_INFILESIZE, filesize($local_src)); $er = array(‘Accept: */*’, «ization: OAuth {$this->token}», ‘Expect: ‘ ); $curl->setOpt(CURLOPT_HTTPER,$er); $response = $curl->open(); fclose($local_file); return $this->getResult($curl, array(200,201,204)); } download($server_src,$local_dst) { $local_file = fopen($local_dst,»w»); $curl = $this->getCurl($server_src); $curl->setOpt(CURLOPT_HTTPGET, 1); $curl->setOpt(CURLOPT_ER, 0); $curl->setOpt(CURLOPT_FILE,$local_file); $response = $curl->open(); fclose($local_file); return $this->getResult($curl, array(200)); } rm($server_src) { $curl = $this->getCurl($server_src); $curl->setOpt(CURLOPT_CUSTOMREQUEST,»DELETE»); $response = $curl->open(); return $this->getResult($curl, array(200)); } ls($server_src) { $curl = $this->getCurl($server_src); $curl->setOpt(CURLOPT_CUSTOMREQUEST,»PROPFIND»); $er = array(‘Accept: */*’, «ization: OAuth {$this->token}», ‘Depth: 1’, ); $curl->setOpt(CURLOPT_HTTPER,$er); $response = $curl->open(); if($this->getResult($curl, array(207))) { $xml = simplexml_load_string($response,»SimpleXMLElement» ,0,»d»,true); $list = array(); foreach($xml as $item) { if(isset($item->prop->prop->resourcetype->collection)) $type = ‘d’; else $type = ‘f’; $list[]=array(‘href’=>(string)$item->href,’type’=>$type); } return $list; } return false; } //Ugly. exists($server_src) { $path = dirname($server_src); $list = $this->ls($path); if($list === false) { $this->error = ‘Не могу получить список файлов’; $this->logger->log(»,’ERROR’, $this->error); return false; } foreach($list as $item) if(rtrim($item[‘href’],’/’)==rtrim($server_src,’/’)) return true; return false; } //Ugly. is_file($server_src) { $path = dirname($server_src); $list = $this->ls($path); if($list === false) { $this->error = ‘Не могу получить список файлов’; $this->logger->log(»,’ERROR’, $this->error); return false; } foreach($list as $item) if( (rtrim($item[‘href’],’/’)==rtrim($server_src,’/’) ) && ($item[‘type’]==’f’) ) return true; return false; } //Ugly. is_dir($server_src) { $path = dirname($server_src); $list = $this->ls($path); if($list === false) { $this->error = ‘Не могу получить список файлов’; $this->logger->log(»,’ERROR’, $this->error); return false; } foreach($list as $item) if( (rtrim($item[‘href’],’/’)==rtrim($server_src,’/’) ) && ($item[‘type’]==’d’) ) return true; return false; } }
Все методы классов имеют говорящие имена mkdir, upload, download, ls, rm, поэтому подробно останавливаться на них не будем. Все сводятся формированию и выполнению запроса с помощью cUrl. К каждому запросу необходимо добавлять токен, полученный выше.
Делать полный разбор ответа, честно говоря делать было лень. Поэтому в ответе просто проверяется статус запроса, если он совпадает с ожидаемым, то считаем операцию выполненной успешно. В противном случае записываем ошибку в лог.
Реализация методов is_dir, is_file, exists ужасна, но я не собираюсь работать с папками в который больше 10 файлов. Именно поэтому они реализованы с использованием метода ls.
Теперь в моем распоряжении есть инструмент для управления диском. Пусть он немного ущербный, но все же — это инструмент.
Создание и отправка резервной копии на Яндекс диск
Резервную копию будем создавать по следующему алгоритму:
- Удаляем с Яндекс диска лишние бэкапы. Если на диске скопилось более n бэкапов, то старые удаляем., число n берем из конфига.
- В некоторой временной папке создаем дамп базы Mysql. В моем коде это выполняется вызовом команды mysqldump.
- В эту же папку копируем файлы которые надо сохранить.
- Архивируем папку с созданными файлами.
- Полученный архив копируем на Яндекс Диск
- Удаляем временные файлы
Возможны вариации последнего набора действий. Тут полет фантазии не ограничен. Мне же достаточно указанного набора.
Указанные действия можно выполнить при помощи следующего класса.
Создание архива и отправка его на диск
class YaBackup { protected $disk; protected $db; protected $logger; protected $backup_number; __construct($backupconfig) { $config = lmbToolkit::instance()->getConf(‘yandex’); $this->logger = YaLogger::instance(); $auth = new YaAuth($config,$this->logger); $token = $auth->getToken(); if($token == ») throw Exception(‘Не могу получить токен’); $this->disk = new YaDisk($token,$config,$this->logger); $this->db = $backupconfig->get(‘db’); $this->folders = $backupconfig->get(‘folders’); $this->tmp_dir = $backupconfig->get(‘tmp_dir’); $this->project = $backupconfig->get(‘project’); $this->backup_number = $backupconfig->get(‘stored_backups_number’); $this->server_dir = $backupconfig->get(‘dir’); $ = (); $this-> = («Y-m-d»,$).’-‘.$; } execute() { $this->logger->log(«Начат бекап проекта «.$this->project,»START_PROJECT»); $this->_clean(); $this->logger->log(«Удаление старых копий»); $this->_deleteOld(); $this->logger->log(«Создание дампа базы»); $this->_makeDump(); $this->logger->log(«Копирование необходимых файлов»); $this->_copyFolders(); $this->logger->log(«Создание архива»); $this->_create(); $this->logger->log(«Копирование на Яндекс.Диск»); $this->_upload(); $this->logger->log(«Удаление временных файлов»); $this->_clean(); $this->logger->log(«Бекап проекта «.$this->project.» завершен», «END_PROJECT»); } protected _clean() { lmbFs::rm($this->getProjectDir()); } protected _deleteOld() { $list = $this->disk->ls($this->server_dir.’/’.$this->project); $paths=array(); $n=0; foreach($list as $item) { //Имена архивов имеют вид Y-m-d-stamp.tar.gz. В качестве ключа массива используем stamp. $parts = explode(‘-‘,basename(rtrim($item[‘href’],’/’))); if(isset($parts[3]) && ($item[‘type’]==’f’)) { $tm = explode(‘.’,$parts[3]); $paths[(integer)$tm[0]] = $item[‘href’]; $n++; } } ksort($paths);//сортируем массив по ключам от меньшего к большему for($i=$n;$i>$this->backup_number-1;$i—) { $item = array_shift($paths); $this->logger->log(«Удаление «.$item); $this->disk->rm($item); } } protected _upload() { $ = $this->.’.tar.gz’; //создаем дирректории на яндекс диске $this->logger->log(«Создаем папки на Яндекс.Диске»); $this->disk->mkdir($this->server_dir); $res = $this->disk->mkdir($this->server_dir.’/’.$this->project); //Копируем архив $this->logger->log(«Копируем архив на Яндекс.Диск»); $this->disk->upload($this->getProjectDir().’/’.$,$this->server_dir.’/’.$this->project.’/’.$); if($res) $this->logger->log(«Копирование на Яндекс.Диск завершено успешно»); else $this->logger->log(«Копирование на Яндекс.Диск завершено завершено с ошибкой»); } protected getProjectDir() { return $this->tmp_dir.’/’.$this->project; } protected _copyFolders() { lmbFs:: mkdir($this->getProjectDir() . ‘/folders’); $folders = $this->folders; foreach($folders as $key => $value) { lmbFs:: mkdir($this->getProjectDir() . ‘/folders/’ . $key); lmbFs:: cp($value, $this->getProjectDir() . ‘/folders/’ . $key); } } protected _create() { $ = $this->; $dir = $this->getProjectDir(); //переписать через system `cd $dir && find . -type f -exec tar rvf «$.tar» ‘{}’ ;`; `cd $dir && gzip $.tar`; } protected _makeDump() { $host = $this->db[‘host’]; $user = $this->db[‘user’]; $password = $this->db[‘password’]; $database = $this->db[‘database’]; $charset = $this->db[‘charset’]; lmbFs:: mkdir($this->getProjectDir() . ‘/base’); $sql_schema = $this->getProjectDir() . ‘/base/schema.mysql’; $sql_data = $this->getProjectDir() . ‘/base/data.mysql’; //создаем дамп $this->mysql_dump_schema($host, $user, $password, $database, $charset, $sql_schema); $this->mysql_dump_data($host, $user, $password, $database, $charset, $sql_data); } //Следующие методы лучше вынести в отдельный файл protected mysql_dump_schema($host, $user, $password, $database, $charset, $file, $tables = array()) { $password = ($password)? ‘-p’ . $password : »; $cmd = «mysqldump -u$user $password -h$host » . «-d —default-character-set=$charset » . «—quote-names —allow-keywords —add-drop-table » . «—set-charset —result-file=$file » . «$database » . implode(», $tables); $this->logger->log(«Начинаем создавать дамп базы в ‘$file’ file…»); system($cmd, $ret); if(!$ret) $this->logger->log(«Дамп базы создан (» . filesize($file) . » bytes)»); else $this->logger->log(«Ошибка создания дампа базы»);; } protected mysql_dump_data($host, $user, $password, $database, $charset, $file, $tables = array()) { $password = ($password)? ‘-p’ . $password : »; $cmd = «mysqldump -u$user $password -h$host » . «-t —default-character-set=$charset » . «—add-drop-table —create-options —quick » . «—allow-keywords —max_allowed_packet=16M —quote-names » . «—complete-insert —set-charset —result-file=$file » . «$database » . implode(», $tables); $this->logger->log(«Начинаем создавать дамп данных в ‘$file’ file…»); system($cmd, $ret); if(!$ret) $this->logger->log(«Дамп данных создан! (» . filesize($file) . » bytes)»); else $this->logger->log(«Ошибка создания дампа базы»);; } }
Причесывать код последнего класса не стал. Думаю заинтересованный читатель сам сможет добавить, убрать или изменить методы под свои нужды. Работа с сводится к загрузке конфига в класс через конструктор и выполнению метода execute
Выполнение копирования по крону
Так сложилось, что все задачи крона я реализую в виде наследников класса:
CronJob
abstract class CronJob { abstract run(); }
Комментарии тут излишни.
Для каждого проекта я создаю класс примерно такого содержания:
Класс запуска задачи по расписанию
class YaBackupJob extends CronJob { protected $conf; protected $conf_name = ‘adevelop’; __construct() { $this->conf = lmbToolkit::instance()->getConf($this->conf_name); } run() { $backup = new YaBackup($this->conf); $backup->execute(); } }
Здесь как и везде выше используется стандартный механизм файлов конфигурации из Limb. В принципе класс можно сделать абстрактным, но это кому как удобно.
Остался вопрос запуска. Сама задача запускается при помощи скрипта cron_runner.php. Который подключает файл с классом задания, создает объект этого класса и следит, чтобы одновременно одно и то же задание не выполнялось двумя процессами (последнее реализовано на основе файловых локов).
cron_runner.php
set__limit(0); require_once(dirname(__FILE__) . ‘/../setup.php’); lmb_require(‘limb/core/src/lmbBacktrace.class.php’); lmb_require(‘limb/fs/src/lmbFs.class.php’); lmb_require(‘ya/src/YaLogger.class.php’); new lmbBacktrace; write_error_in_log($errno, $errstr, $errfile, $errline) { global $logger; $back_trace = new lmbBacktrace(10, 10); $error_str = » error: $errstrnfile: $errfilenline: $errlinenbacktrace:».$back_trace->toString(); $logger->log($error_str,»ERROR»,$errno); } set_error_handler(‘write_error_in_log’); error_reporting(E_ALL); ini_set(‘display_errors’, true); if($argc < 2) die(‘Usage: php cron_runner.php cron_job_file_path(starting from include_file_path)’ . PHP_EOL); $cron_job_file_path = $argv[1]; $logger = YaLogger::instance(); $lock_dir = LIMB_VAR_DIR . ‘/cron_job_lock/’; if(!file_exists($lock_dir)) lmbFs :: mkdir($lock_dir, 0777); $name = array_shift(explode(‘.’, basename($cron_job_file_path))); $lock_file = $lock_dir . $name; if(!file_exists($lock_file)) { file_put_contents($lock_file, »); chmod($lock_file, 0777); } $fp = fopen($lock_file, ‘w’); if(!flock($fp, LOCK_EX + LOCK_NB)) { $logger->flict(); return; } flock($fp, LOCK_EX + LOCK_NB); try { lmb_require($cron_job_file_path); $job = new $name; if(!in_array(‘-ld’, $argv)) $logger->log(»,»START»); ob_start(); echo $name . ‘ started’ . PHP_EOL; $result = $job->run(); $output = ob_get_contents(); ob_end_clean(); if(!in_array(‘-ld’, $argv)) $logger->log($output,»END»,$result); } catch (lmbException $e) { $logger->logException($e->getNiceTraceAsString()); throw $e; } flock($fp, LOCK_UN); fclose($fp); if(in_array(‘-v’, $argv)) { echo $output; var_dump($logger->getRecords()); }
В кронтаб прописывается команда:
php /path/to/cron_runner.php ya/src/YaBackupJob.class.php
В качестве аргумента скрипту передаем путь относительно include_path до файла с классом. Имя самого класса с задачей скрипт определяет по имени файла.
Заключение
Буду рад, если кому пригодится этот код. Ссылки на полный работающий пример приведены ниже.
Конструктивная критика приветствуется. Жду ваших замечаний и отзывов.
Ссылки и источники
- Последняя версия архива c примером может быть найдена тут или тут
- Репозиторий на github YaBackup
- Документация Яндекс OAuth и Диск
Стандарт OAuth
Стандарт WebDav
Фреймворк Limb
Теги:
- php
- яндекс.диск
Хабы:
- PHP
Источник