UMGUM.COM (лучше) 

Автоматизация ( Автоматизация процедур сборки и разборки распределённой файловой системы. )

18 сентября 2012  (обновлено 17 июля 2019)

Эта публикация отнесена в архив. Она неактуальна.

OS: "Linux Debian 5/6/7 (Lenny/Squeeze/Wheezy)".

Скрипты, конфигурационные и журнальные файлы нашей самодельной сетевой файловой системы будут располагаться одинаково на всех серверах, как ведущих, так и ведомых:

# mkdir -p /usr/local/etc/default/ /usr/local/etc/storage/fnc.d/ /usr/local/etc/storage/cnf.d/ /var/log/storage

Прежде всего создаём конфигурационный файл с параметрами для скрипта автоматизации:

# vi /usr/local/etc/default/storage-custom

# Default configuration file for /etc/init.d/storage-control

# Адрес директории динамически включаемых в тело скрипта управления описаний функций
FNCDIR="/usr/local/etc/storage/fnc.d"

# Адрес директории индивидуальных конфигураций сервисов хранилища
CNFDIR="/usr/local/etc/storage/cnf.d"

# Адрес директории файлов блокировок сервисов хранилища
LOCK="/tmp/storage/lck"

# Адрес файла журнала
LOG="/var/log/storage/default.log"

EMAIL=`cat /usr/local/etc/storage/email >/dev/null 2>&1`


Пишем скрипт автоматизации контроля подсистемы хранения:

# vi /etc/init.d/storage-control && chmod ugo+rx /etc/init.d/storage-control

#!/bin/bash

### BEGIN INIT INFO
# Provides:          storage-control
# Required-Start:    $local_fs $syslog $network
# Required-Stop:     $local_fs $syslog $network
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Script management of storage
# Description:       Script management of storage
### END INIT INFO

# Подключаем первичный конфигурационный файл
source "/usr/local/etc/default/storage-custom"
[ ${?} -ne 0 ] && { echo "Fatal error: missing default custom storage configuration file. Operation aborted."; exit 1; }

# Принимаем в переменные с "говорящими" именами входящие аргументы
INSTANCE=${0}
OPERATION=${1}
TARGET=${2}
DATE=`date +"%Y-%m-%d %H:%M:%S"`

# Перебираем в цикле все объекты (по маске) в целевой директории динамически подключаемых описаний функций
cd "${FNCDIR}"
for OBJECT in *\.fnc ; do
  # Включаем в тело скрипта текст обнаруженных фрагментов описаний функций
  [ -f "${FNCDIR}/${OBJECT}" ] && source "${FNCDIR}/${OBJECT}"
done

# Создаём директорию для файлов блокировки
mkdir -p "${LOCK}"

# Определяем функцию предварительной инициализации конфигурационных файлов хранилища
function start-init() {

  # Создаём временный файл журнала событий
  LOGT=$(mktemp /tmp/storage-start.log.XXXXXXXX)

  # Создаём временный файл глобальной конфигурации
  CNF=$(mktemp /tmp/storage.cnf.XXXXXXXX)

  cd "${CNFDIR}"
  for OBJECT in *\.cnf ; do
    # Включаем в тело временного глобального файла все обнаруженные фрагменты конфигураций
    [ -f "${CNFDIR}/${OBJECT}" ] && cat "${CNFDIR}/${OBJECT}" >> "${CNF}"
  done

  DATE=`date +"%Y-%m-%d %H:%M:%S"`
  start

  # Если запуск системы хранилища завершился неудачно, то отсылаем отчёт и "разбираем" его
  if [ "${?}" -ne "0" ] ; then
    send-report "Storage assembling error!" "$(cat ${LOGT})"
    return 1
  fi

  # Включаем временный журнал событий в основной и удаляем временный
  cat "${LOGT}" >> "${LOG}"
  rm --force "${LOGT}"

  # Удаляем временный файл глобальной конфигурации
  rm --force "${CNF}"

return ${?}
}

# Определяем функцию предварительной инициализации конфигурационных файлов хранилища
function stop-init() {

  # Создаём временный файл журнала событий
  LOGT=$(mktemp /tmp/storage-stop.log.XXXXXXXX)

  # Создаём временный файл глобальной конфигурации
  CNF=$(mktemp /tmp/storage.cnf.XXXXXXXX)

  cd "${CNFDIR}"
  for OBJECT in *\.cnf ; do
    # Включаем в тело временного глобального файла все обнаруженные фрагменты конфигураций
    [ -f "${CNFDIR}/${OBJECT}" ] && cat "${CNFDIR}/${OBJECT}" >> "${CNF}"
  done

  DATE=`date +"%Y-%m-%d %H:%M:%S"`
  stop

  # Если остановка системы хранилища завершилась неудачно, то отсылаем отчёт
  if [ "${?}" -ne "0" ] ; then
    send-report "Storage disassembling error!" "$(cat ${LOGT})"
  fi

  # Включаем временный журнал событий в основной и удаляем временный
  cat "${LOGT}" >> "${LOG}"
  rm --force "${LOGT}"

  # Удаляем временный файл глобальной конфигурации
  rm --force "${CNF}"

return ${?}
}

# Описываем функцию формирования опций хранилища и непосредственного её запуска
function start() {

  echo | tee -a "${LOGT}"
  echo "${DATE}: Procedure is running store is initialized." | tee -a "${LOGT}"
  echo | tee -a "${LOGT}"

  # Сборка массивов
  declare -f start-mdadm >/dev/null
  if [ ${?} -ne 0 ]; then
    echo "Notice. Не определена функция сборки RAID." | tee -a "${LOGT}"
  else
    start-mdadm
    if [ "${?}" -ne "0" ] ; then
      echo "${DATE}: Assembly arrays failed. Aborting." | tee -a "${LOGT}"
      return 1
    fi
  fi

  # Активация групп томов LVM
  declare -f start-lvm >/dev/null
  if [ ${?} -ne 0 ]; then
    echo "Notice. Не определена функция сборки LVM." | tee -a "${LOGT}"
  else
    start-lvm
    if [ "${?}" -ne "0" ] ; then
      echo "${DATE}: Activating LVM volume groups failed. Aborting." | tee -a "${LOGT}"
      return 1
    fi
  fi

  # Создание символической ссылки на заданный раздел целевого диска
  declare -f make-symlink >/dev/null
  if [ ${?} -ne 0 ]; then
    echo "Notice. Не определена функция создания символической ссылки на раздел целевого диска." | tee -a "${LOGT}"
  else
    make-symlink
    if [ "${?}" -ne "0" ] ; then
      echo "${DATE}: Create a symbolic link with error. Aborting." | tee -a "${LOGT}"
      return 1
    fi
  fi

  # Монтирование локальных файловых систем хранилища
  declare -f start-fs >/dev/null
  if [ ${?} -ne 0 ]; then
    echo "Notice. Не определена функция монтирования локальных файловых систем хранилища." | tee -a "${LOGT}"
  else
    start-fs
    if [ "${?}" -ne "0" ] ; then
      echo "${DATE}: Mounting file systems store with error. Aborting." | tee -a "${LOGT}"
      return 1
    fi
  fi

  # Публикация файловых систем хранилища посредством NFS
  declare -f start-nfs-export >/dev/null
  if [ ${?} -ne 0 ]; then
    echo "Notice. Не определена функция публикации файловых систем посредством NFS." | tee -a "${LOGT}"
  else
    start-nfs-export
    if [ "${?}" -ne "0" ] ; then
      echo "${DATE}: Publication of file systems via NFS storage failed. Aborting." | tee -a "${LOGT}"
      return 1
    fi
  fi

  # Сборка файловых систем хранилища из ресурсов NFS
  declare -f start-nfs-import >/dev/null
  if [ ${?} -ne 0 ]; then
    echo "Notice. Не определена функция сборки файловых систем из ресурсов NFS." | tee -a "${LOGT}"
  else

    # Учитывая то, что нам неизвестно, когда станут доступными все импортируемые ресурсы, закручиваем бесконечный цикл в ожидании полностью безошибочного импорта всех ресурсов
    STERR=""
    while [ "${STERR}" != "0" ] ; do

      # Ждём некоторое время, перед повторением операции (кроме первой итерации)
      [ ! -z "${STERR}" ] && sleep 10

      start-nfs-import
      STERR="${?}"

    done

    # Проверяем успешность завершения функции импортирования
    if [ "${STERR}" -ne "0" ] ; then
      echo "${DATE}: The assembly of the storage file system NFS resource failed. Aborting." | tee -a "${LOGT}"
      return 1
    fi

  fi

  # Сборка файловых систем в единую точку монтирования
  declare -f start-mhddfs >/dev/null
  if [ ${?} -ne 0 ]; then
    echo "Notice. Не определена функция сборки файловых систем в единой точке монтирования." | tee -a "${LOGT}"
  else
    start-mhddfs
    if [ "${?}" -ne "0" ] ; then
      echo "${DATE}: Assembly file systems into a single mount point failed. Aborting." | tee -a "${LOGT}"
      return 1
    fi
  fi

return ${?}
}


# Определяем функцию остановки хранилища
function stop() {

  echo | tee -a "${LOGT}"
  echo "${DATE}: Running stop procedure storage." | tee -a "${LOGT}"
  echo | tee -a "${LOGT}"

  # Разборка файловых систем, смонтированных в единую точку монтирования
  declare -f stop-mhddfs >/dev/null
  if [ ${?} -ne 0 ]; then
    echo "Notice. Не определена функция разборки файловых систем в единой точке монтирования." | tee -a "${LOGT}"
  else
    stop-mhddfs
    if [ "${?}" -ne "0" ] ; then
      echo "${DATE}: Disassembly of file systems mounted in a single mount point failed. Aborting." | tee -a "${LOGT}"
      return 1
    fi
  fi

  # Разборка файловых систем хранилища из ресурсов NFS
  declare -f stop-nfs-import >/dev/null
  if [ ${?} -ne 0 ]; then
    echo "Notice. Не определена функция разборки файловых систем из ресурсов NFS." | tee -a "${LOGT}"
  else
    stop-nfs-import
    if [ "${?}" -ne "0" ] ; then
      echo "${DATE}: Disassembly of the storage file system NFS resource failed. Aborting." | tee -a "${LOGT}"
      return 1
    fi
  fi

  # Отключение публикации файловых систем хранилища посредством NFS
  declare -f stop-nfs-export >/dev/null
  if [ ${?} -ne 0 ]; then
    echo "Notice. Не определена функция публикации файловых систем посредством NFS." | tee -a "${LOGT}"
  else
    stop-nfs-export
    if [ "${?}" -ne "0" ] ; then
      echo "${DATE}: Disabling Publishing file systems via NFS storage failed. Aborting." | tee -a "${LOGT}"
      return 1
    fi
  fi

  # Демонтирование файловых систем хранилища
  declare -f stop-fs >/dev/null
  if [ ${?} -ne 0 ]; then
    echo "Notice. Не определена функция демонтирования локальных файловых систем хранилища." | tee -a "${LOGT}"
  else
    stop-fs
    if [ "${?}" -ne "0" ] ; then
      echo "${DATE}: Unmounting file systems store with error. Aborting." | tee -a "${LOGT}"
      return 1
    fi
  fi

  # Деактивация групп томов LVM
  declare -f stop-lvm >/dev/null
  if [ ${?} -ne 0 ]; then
    echo "Notice. Не определена функция деактивации групп томов LVM хранилища." | tee -a "${LOGT}"
  else
    stop-lvm
    if [ "${?}" -ne "0" ] ; then
      echo "${DATE}: Deactivating LVM volume groups failed. Aborting." | tee -a "${LOGT}"
      return 1
    fi
  fi

  # Остановка массивов
  declare -f stop-mdadm >/dev/null
  if [ ${?} -ne 0 ]; then
    echo "Notice. Не определена функция деактивации RAID." | tee -a "${LOGT}"
  else
    stop-mdadm
    if [ "${?}" -ne "0" ] ; then
      echo "${DATE}: Stop array failed. Aborting." | tee -a "${LOGT}"
      return 1
    fi
  fi
return ${?}
}

# Блок выбора варианта исполнения скрипта
case "$1" in
  start)
    start-init

    # В случае ошибочного завершения сборки хранилища разбираем его
    if [ "${?}" -ne "0" ] ; then
      stop-init
    fi

  ;;
  stop)
    stop-init
  ;;
  check)

    echo | tee -a "${LOGT}"
    echo "${DATE}: Running the test procedure component." | tee -a "${LOGT}"
    echo | tee -a "${LOGT}"

    check-mdadm
    check-lvm
    check-fs
    check-nfs-export
    check-nfs-import
    check-mhddfs
  ;;
  *)
    echo "Usage $0 {start|stop|check}" >&2
    exit 1
  ;;
esac

exit $?

Прописываем наш скрипт для нужных уровней исполнения в системе:

# update-rc.d storage-control start 10 2 3 4 5 . stop 10 0 1 6 .

Для того, что бы не получать сильно разросшиеся файлы журналов, настроим их ротацию.

Устанавливаем приложение ротации текстовых файлов с одновременным их сжатием:

# aptitude install logrotate gzip

Создаем конфигурационный файл ротации журнальных файлов:

# mkdir -p /etc/logrotate.d
# vi /etc/logrotate.d/storage

# шаблон указывающий объекты подлежащие "ротации"
/var/log/storage/*.log {
  # размер журнального файла, после которого он обрабатывается утилитой
  size 10M
  # отсутствие файла не вызывает ошибку
  missingok
  # количество хранимых отработанных резервных копий
  rotate 10
  # указание сжимать отрабатываемые резервные копии
  compress
  # указание не сжимать первую резервную копию, делать это при повторном проходе
  delaycompress
  # указание не отрабатывать пустые файлы
  notifempty
  # добавлять к наименованию файла резервной копии даты в формате "-YYYYMMDD"
  dateext
  # задать права доступа, владельца и группу создаваемого журнального файла
  create 640 root root
}

Проверяем корректность конфигурационного файла:

# logrotate -d /etc/logrotate.d/storage

Переход к описанию вспомогательных функций.


Заметки и комментарии к публикации:


Оставьте свой комментарий ( выразите мнение относительно публикации, поделитесь дополнительными сведениями или укажите на ошибку )