Автоматизация обновления темплейтов OpenVZ на Proxmox

от автора

Однажды появилась такая необходимость обновить версии темплейтов OpenVZ загруженных в кэш Proxmox’а.

Задача в общем-то простая и тривиальная. Всего то и необходимо, это скачать новый темплейт и заменить им старый. Но в глобальном плане задача мне виделась шире, а именно периодически проверять обновления и загружать по необходимости новые версии темплейтов. То есть постоянно поддерживать их в актуальном состоянии.

Желание вполне естественное и понятное. И было бы глупо выполнять эти рутинные и простые операции каждый раз вручную, а по сему, решение вопроса напрашивалось само собой: сделать некий скрипт, который сам будет всё это делать, в то время как админ будет отдыхать и лишь время от времени проверять работает ли обновление.

Итак, есть желание и пора приступать к его осуществлению. Для начала решим, что же конкретно должен делать наш скрипт.

Постановка задачи

1. Время от времени, через определённые промежутки, скрипт должен запускаться.
2. Подключаться к серверу на котором лежат официальные обновлённые темплейты OpenVZ.
3. Сравнивать темплейты, которые есть на сервере с теми, которые загружены в кэш.
4. Загружать новый темплейт (если он есть), и заменять им старый в том случае, если версия на сервере отличается от локальной.
5. Вести лог того что загружено, а что нет, и когда загружено (обновлено).

Вот собственно и всё.

Реализация

Для написания скрипта мной был выбран старый и надёжный Perl, по причине моей давней с ним дружбы, а так же потому что для этого языка уже написано огромное количество готовых модулей на все случаи жизни для выполнения системных задач и не только.

Пропускаем первый пункт задания, о нём будет написано в самом конце, когда скрипт уже будет готов к работе. Тем более что это задача не относящаяся к самому скрипту и выполняться будет сторонними средствами, а именно, всю ответственность за своевременный запуск нашего скрипта мы возложим на Cron. Это его задача и обязаннось всё планировать и запускать. Мы же двинемся дальше и вернёмся к вопросу планирования позже.

В качестве источника темплейтов будем использовать официальный FTP сервер openvz.org, а для подключения к нему средствами Perl воспользуемся стандартным модулем Net::FTP.

Далее следует описание самого скрипта с пояснениями.

Для начала подключаем модули.

#!/usr/bin/perl -w  use strict; use Fcntl qw(:DEFAULT :flock); use Net::FTP;  

Теперь объявим необходимые нам переменные, с которыми будет работать скрипт. По сути это константы, которые не будут меняться в ходе выполнения скрипта.

# директория темлейтов OpenVZ на ноде Proxmox my $vzdir = "/var/lib/vz/template/cache";  # Путь на FTP сервере, по которому нужно искать обновления my $urldir = "ftp://ftp.openvz.org/template/precreated/";  # Директория в которой будет лежать log-файл с результатами выполнения скрипта my $logdir ="/var/log/";  # Собственно сам log-файл, его имя my $logfile = "ovzupdate.log";  

Как можно догадаться из имени log-файла, сам скрипт называется ovzupdate. Расширение .pl необязательно, достаточно того, что первой строкой скрипта указан интерпретатор, который обработает этот файл.

Итак, продолжим…

# Открываем log-файл для записи open(STDOUT, '>>',$logdir.$logfile) or die "Can't open file '$logfile' $!";  # Наводим красоту :) Чтобы всё выглядело прилично, а не выводилось как попало. print "\n=========================\n".getdate()."\n=========================\n"; print gettime()." * Starting OpenVZ templates update\n";  

И наконец-то мы добрались до настоящей работы и подошли к тому, для чего собственно и создавался сам скрипт. Подключаемся к FTP серверу openvz.org.

# Подключение к ftp-серверу my $server_name = 'ftp.openvz.org'; my $ftp_username = 'anonymous'; my $ftp_password = ''; my $ftp_source_dir = '/template/precreated';  my $ftp = Net::FTP->new($server_name, Debug => 1); $ftp->login($ftp_username,$ftp_password); $ftp->cwd($ftp_source_dir); $ftp->binary();  

Теперь объявим переменную, в которой будет храниться список (массив) имён локальных темплейтов и открываем локальную директорию (кэш Proxmox’а) в которой хранятся уже загруженные темплейты для проверки актуальности файлов.

my $file; opendir(DIR, $vzdir) or die "Can't open $vzdir: $!";  

А теперь собственно прописываем сам цикл сравнения файлов. Надо сказать, что мы не будем обновлять и качать все файлы с FTP без разбора, а будем выбирать только те, которые уже находятся в нашем локальном кэше и будем сравнивать их по размеру с файлами на ftp-сервере. Если размер файла в локальном кэше будет отличаться от размера файла с таким же именем на удалённом сервере, то файл в кэше будет удалён, а на его место загружен новый файл с FTP.

# Заносим в переменную список файлов в директории кэша while( defined ($file = readdir (DIR)) ) {  # Исключаем из списка обработку ссылок на директории находящиеся выше   if ($file ne "." and $file ne "..")  {  # Определяем размер локального файла      my $local_file_size = -s $vzdir."/".$file;  # Определяем размер файла с таким же именем, находящегося в директории ftp-сервера      my $remote_file_size = $ftp->size($file);  # Здесь мы просто выводим в log размеры одного и другого файла # В принципе, эти две строчки можно закоментировать,  # если не хотите перегружать лог лишней информацией      print gettime()."   Удалённый файл: $file -> ",$remote_file_size,"\n";      print gettime()."   Локальный файл: $file -> ",$local_file_size,"\n";  # Собственно сравнение размеров файлов      if ($local_file_size ne $remote_file_size) {  # Если размер не совпадает, удаляем локальный файл         unlink $vzdir."/".$file;  # и скачиваем актуальную версию файла темплейта         system ("wget -P ".$vzdir." ".$urldir.$file);  # Пишем в log отчёт о том, что файл обновлён         print gettime()." + Загрузка новой версии ".$file."\n";      }      else {  # Иначе, пишем в log что файл является актуальным         print gettime()."   Версия ".$file." актуальна\n"      }   } }  

Закрываем директорию, ftp-соединение и стандартный поток вывода.

closedir(DIR); $ftp->quit; print gettime()." * Проверка обновлений окончена\n"; close STDOUT;  

Ну вот, практически и всё. Сам скрипт содержит три дополнительных функции, которые выполняют всего лишь вспомогательную роль и к сути вопроса не относятся. Готовый скрипт можно посмотреть тут.

Завершение

А теперь, как и обещал, вернёмся к пункту номер один. Скрипт можно положить на сервере Proxmox’а в любое удобное место. И остаётся только прописать его в crontab, чтобы он запускался на выполнение через нужный период времени. Периодичность выбирайте сами, но думаю что нет необходимости запускать его чаще раза в неделю.

Чтобы добавить задание обновления, зайдем в режим редактирования заданий crontab.

crontab -e

И последней добавляем строку, которая и будет выполнять наш скрипт обновления в определённое время и день. Для примера, в приведённой ниже строке указано, что скрипт будет выполняться каждый четверг в три часа ночи.

0 3 * * 4 /root/bin/ovzupdate 2>/dev/null 

2>/dev/null — перенаправляет вывод потока STDERR в «чёрную дыру» нигде не сохраняя, но это уже на личное усмотрение, можно тоже сохранять в лог.

Сохраняем сделанные нами изменения и на этом всё, автоматическое обновление настроено. Теперь нам остаётся только время от времени проверять лог /var/log/ovzupdate.log, чтобы знать было или нет обновление. И когда это произойдёт, мы увидим что-то наподобие этого:

========================= 12-03-2015 ========================= 03:00:01 * Начало обновления OpenVZ templates 03:00:03   Удалённый файл: debian-7.0-x86_64.tar.gz -> 235043942 03:00:03   Локальный файл: debian-7.0-x86_64.tar.gz -> 235004350 03:01:52 + Загрузка новой версии debian-7.0-x86_64.tar.gz 03:01:52   Удалённый файл: ubuntu-12.04-x86_64.tar.gz -> 131011759 03:01:52   Локальный файл: ubuntu-12.04-x86_64.tar.gz -> 130987444 03:02:48 + Загрузка новой версии ubuntu-12.04-x86_64.tar.gz 03:02:48   Удалённый файл: scientific-6-x86_64.tar.gz -> 221101244 03:02:48   Локальный файл: scientific-6-x86_64.tar.gz -> 219898164 03:03:45 + Загрузка новой версии scientific-6-x86_64.tar.gz 03:03:45   Удалённый файл: centos-7-x86_64.tar.gz -> 211178690 03:03:45   Локальный файл: centos-7-x86_64.tar.gz -> 211139455 ... 03:16:31 * Проверка обновлений окончена 

Удачного обновления!

ссылка на оригинал статьи http://habrahabr.ru/post/263269/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *