Пользователь
0,0
рейтинг
30 октября 2014 в 08:06

Разработка → Python + vshadow + robocopy — синхронизация каталога с удаленной машиной

Не так давно у меня встала задача копировать базу данных из удаленного филиала для получения в нашем офисе ее полной копии на момент создания. По идее ежедневное копирование. Первое, что пришло на ум, это rsync сервер, на который выполняется копирование, а уже с него копия используется далее. Быстрый поиск навел на боле менее адекватную инструкцию тут же.

Проблема в том, что на клиентской машине стоит Win система. И принимающая сторона тоже использует аналогичную OS. Rsync сервер на Linux — это лишняя прослойка между двумя машинами. Ставить Rsync на Win сервере возможно, но по другим отвлеченным соображениям, излишне. В итоге наткнулся на свой скрипт синхронизации каталогов и совместив его с созданием теневой копии создал новое решение.

Получившийся скрипт полностью здесь. В статье просто приведу основные вехи и полученный функционал.

Скрипт создает теневую копию диска. Выполняет копирование заданных каталогов на удаленный ресурс по smb. Вычислят отличия между источником и полученной копией. Формирует отчет о копировании и полученных отличиях, после чего отправляет по почте отчет заданным адресатам.

Как и в выше указанной статье, для начала качаем Volume Shadow Copy Service SDK 7.2 с сайта Microsoft. Устанавливаем на машину и выдергиваем нужные нам утилиты.
Нам понадобятся vshadow.exe и vshadow.pdb файлы из этого SDK. Внимание — они разные для 64-битных, и 32-битных систем.

После инсталляции их можно будет найти тут:

64-bit — %PROGRAMFILES%\Microsoft\VSSSDK72\TestApps\vshadow\bin\obj-chk\amd64
32-bit — %PROGRAMFILES%\Microsoft\VSSSDK72\TestApps\vshadow\bin\release-xp


Складываем в отдельный каталог. Я обычно создаю под разные задачи каталог c:\Windows\!Script и в нем уже подкаталоги. Тут личное дело каждого. Полученные два файла и скрипт можно копировать на целевую машину и подгонять скрипт под свои задачи. А вот Python необходимый для выполнения скрипта придется устанавливать на каждой клиентской машине.

Непосредственно тело скрипта начинается со строки 137. Для настройки целей копирования и прочего сопутствующего хозяйства требуется определить переменные.

####################
##  Переменные        ##
####################
work_dir = 'C:\Windows\!Script\Backup'             # рабочий каталог скрипта. Изменить на тот в который выложенна утилита vshadow.exe и сам скрипт
source_disk = 'c:'
destin_disk = 'o:'
param_script = 'vs_generated.cmd'
# список каталогов для копирования
cwd_list = [['o:\\Windows\\!Script\\Backup', '\\\\master\\apps\\temp\\viv\\backup'],['o:\\ocs-ng', '\\\\master\\apps\\temp\\viv\\ocs-ng']]
# настройка почты
from_addr = 'admin@typa.ru'                                       # адрес отправителя отчета
tech_addr = ['user1@typa.ru', 'user1@typa.ru']           # список адресатов


В данном случае это рабочий каталог, в котором находится скрипт, целевой диск с копией, имя диска, к которому будет примонтированна созданная теневая копия, название файла, в который утилита vshadow.exe сохраняет значения своих переменных. Далее переменная cwd_list содержит список каталогов, которые требуется копировать и места куда выполнять копирование. Переменная содержит список из двух элементных списков. Обратите внимание, что для экранирования косой черты в путях в Python ее требуется проставлять два раза, а для указания ссылки на сетевой путь — даже четыре.

И завершает определение переменных настройки отправки электронной почты. Переменная, содержащая адрес отправителя письма и переменная, содержащая список получателей.

Собственно, определить переменные в этой секции — это все, что требуется для успешной работы. Далее вешаем выполнение скрипта в планировщик заданий, не забывая указывать выполнение с правами администратора. Без админ прав создание теневой копии не происходит. Если копировать будем на сетевой ресурс в домене, желательно завести под это специально заведенную учетную запись в домене. Соответственно, права на целевой каталог в домене задаем для этой учетной записи под наши предпочтения. Следует учесть, что утилита robocopy имеет много опций для своего запуска. В данном случае идет синхронизация каталога источника и удаленного каталога полностью, вплоть до ntfs прав, аудита и владельца каталога. В общем, для сетевого каталога придется еще повозится с заданием первоначальных прав ntfs на расшаренном сетевом ресурсе. Если вся эта информация вам не требуется, можно просто убрать лишние ключи в вызове копирования.

Ну и в завершение быстро пройдусь на основных вехах в работе скрипта.

Со строки 169 выполняем создание теневой копии.

# проверяем наличие файла создания теневых копий
# без него работать не будем поэтому выход с ошибкой
if not(path.exists(getcwd() + '\\vshadow.exe')) and not(path.isfile(getcwd() + '\\vshadow.exe')) :
        exit(1)
proc = Popen('vshadow.exe -nw -p -script=' + param_script + ' ' + source_disk, shell=True, stdout=PIPE)
proc.wait()
out = proc.stdout.readlines()

Обратите внимание на параметр вызова -script=' + param_script, в результате работы vshadow.exe в этот файл выкладываются значения переменных. Нас из них интересует только SHADOW_ID_1, которая содержит идентификатор созданной теневой копии. Собственно, далее мы занимаемся тем, что читаем полученный файл и выдергиваем значение идентификатора для дальнейшей работы. И после того, как нашли идентификатор, подключаем теневую копию.

proc = Popen('vshadow.exe -el=' + SHADOW_ID + ',' + destin_disk, shell=True, stdout=PIPE)

Далее все рутинно. Перебираем список копирования. Натравливаем на него robocopy. Читаем логи формируем отчет. В завершении, отправляем отчет всем заинтересованным. Удаляем теневую копию и файл, содержащий переменные от vshadow.exe

P.S. Кстати, если при запуске этого скрипта файл определения остался, vshadow не сможет его переписать и скрипт будет пытаться подключить старую теневую копию по ее id. По идее в дальнейшем не помешает проверять наличие этого файла еще и в начале работы и удалять при необходимости.

P.P.S. Обратите внимание, что выполняется копирование каталогов. Если есть желание копировать диск целиком, требуется немного изменить процедуру sync. При копировании ведется лог и имя лог файла получается из названия каталога источника. Если будет указан просто диск, имя, лог файла сформируется что-то типа 'o:.txt' и скрипт выпадет с ошибкой. В данном случае лучше добавить проверку того, что все символы в полученном имени файла допустимы и удалять прочие.
Иван @Lector15
карма
3,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Спецпроект

Самое читаемое Разработка

Комментарии (9)

  • 0
    С интересом узнал про подобное использование Shadow copy. Спасибо.
    • 0
      Пожалуйста. Тут теневое копирование пришлось применять из за круглосуточной работы целевой машины. До этого был просто скрипт синхронизации каталогов на серверах выполняемый по ночам)
  • 0
    vshadow можно заменить штатным vssadmin
  • 0
    А как насчет разблокирования базы/файлов на момент копирования?
    • 0
      Для этого мы и делаем теневую копию. Пользователь продолжает работать со своими файлами, а мы спокойно копируем то что было на момент создания теневой копии.
  • 0
    Простите, но, почему не Powershell? И, да, vssadmin, imho, удобнее показался.
    • 0
      Ну во первых Python я лучше знаю. Части скрипта были написаны ранее и использовались в других утилитах. В частности процедура отправки почты используется мной и на win и на Linux серверах. Во вторых хотелось сделать достаточно универсальное решение. В нашей сети используются версии Windows начиная с 2000. Не так давно была даже одна NT4. На рабочих ПК до сих пор WinXP подавляющее большинство. PowerShell есть не везде.
      Использование vssadmin потребует после создания теневой копии парсить вывод vssadmin list shadows для получения id теневой копии. Для vshadow достаточно прочитать файл с переменными созданными при создании копии. И опять же vssadmin есть не везде.
  • 0
  • 0
    не так давно озаботился копированием структуры каталогов но так что бы некоторые каталоги ещё и с содержимым причем тоже по маске и обнаружил что без написания скрипта и в один проход ни robocopy ни xcopy сего не могут. Задумался на тему что хорошо бы разделять ключи по принадлежности к каталогам и к файлам и не ограничивать их одной маской. Короче сел в выходные и наваял утилитку копирования в которой подобные принципы реализовар. Получилось что то наподобии robocopy но с более тонкой настройкойб разделением масок и ключей по файлам и каталогам, что сделало возможным отказаться от написания скриптов копирования. Если кому интересно можно тут скачать. Прога ещё в процессе тестирования, но на моих задачах пока ошибок не вылезло. По мере надобности наращиваю возможности. Если кому чего надо обращайтесь (реквизиты на страничке есть).

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.