You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
99 lines
3.1 KiB
99 lines
3.1 KiB
#!/usr/bin/env python |
|
# -*- coding: utf-8 -*- |
|
|
|
# Скрипт следит за деградацией RAID1-массивов с автоматической подменой дисков на резервный |
|
|
|
import subprocess |
|
import shlex |
|
import re |
|
import smtplib |
|
from email.mime.text import MIMEText |
|
|
|
# входящие параметры |
|
|
|
# от кого буд отправляться исходящие e-mail |
|
me = 'script@mysmtp.ru' |
|
# кому их отправлять |
|
you = 'me@mysmtp.ru' |
|
# сервер SMTP |
|
smtp_server = 'smtp.mysmtp.ru' |
|
|
|
# имя резервного диска |
|
spare = 'sda5' |
|
|
|
# инициализация глобальных переменных |
|
namemd = {} |
|
statemd = list() |
|
sd = '' |
|
sdn = '' |
|
md = '' |
|
|
|
# функция выполнения внешнего приложения с возвратом его вывода |
|
def get_cmd_output(cmd): |
|
args = shlex.split(cmd) |
|
p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) |
|
res = p.communicate()[0] |
|
|
|
return res |
|
|
|
# функция отсыла диагностических сообщений |
|
def send_eml(txt): |
|
msg = MIMEText(txt) |
|
msg['Subject'] = 'The contents of ' |
|
msg['From'] = me |
|
msg['To'] = you |
|
s = smtplib.SMTP(smtp_server) |
|
s.sendmail(me, [you], msg.as_string()) |
|
s.quit() |
|
|
|
# читаем из /proc/mdstat |
|
res = get_cmd_output('cat /home/netmoose/!/mdstat') |
|
# разбираем на ключевые слова результат |
|
result = re.finditer( ur"(md\d+)|(sd.\d+)\[(\d+)\][\s\n]|\[([U_]+)\]", res ) |
|
|
|
# пробегаем по найденному и создаем список |
|
for match in result : |
|
for group_index, group in enumerate( match.groups() ) : |
|
if group : |
|
if group.find('sd') and group.find('md') and len(group)==1 : |
|
sdn = group |
|
namemd[md][sdn] = dict({'name':sd,'state':''}) |
|
elif group.find('sd') and group.find('md') : |
|
statemd = list(group) |
|
i = 0 |
|
for st in statemd : |
|
# print "md: %s, i: %s, st: %s" % (md,i,st) |
|
namemd[md][str(i)]['state'] = st |
|
i += 1 |
|
elif group.find('md') : |
|
sd = group |
|
else : |
|
namemd[group] = dict() |
|
md = group |
|
|
|
|
|
# проходим по созданному выше списку и проверяем состояние дисков, в случае аварии удаляем старый из массива и добавляем резервный |
|
for md in namemd: |
|
for sd in namemd[md].keys(): |
|
if namemd[md][sd]['state'] == '_': |
|
try: |
|
fail = get_cmd_output("/sbin/mdadm /dev/%s -f /dev/%s" % (md,namemd[md][sd]['name'])) |
|
except: |
|
send_eml(fail) |
|
finally: |
|
exit(0) |
|
try: |
|
remv = get_cmd_output("/sbin/mdadm /dev/%s -r /dev/%s" % (md,namemd[md][sd]['name'])) |
|
except: |
|
send_eml(remv) |
|
finally: |
|
exit(0) |
|
try: |
|
newadd = get_cmd_output("/sbin/mdadm /dev/%s -a /dev/%s" % (md,spare)) |
|
except: |
|
send_eml(newadd) |
|
finally: |
|
exit(0) |
|
else: |
|
send_eml("В массиве %s диск /dev/%s заменен на /dev/%s" % (md,namemd[md][sd]['name'],spare)) |
|
exit(0)
|
|
|