05 October 2013

В одном из прошлых постов, я начал рассказывал о том, как Fabric позволяет автоматизировать различные операции на серверах. Сейчас я бы хотел поделиться своим небольшим рецептом по управлению сервисами на продакшен серверах.

С своем примере я буду использовать сервер, который состоит из следующих компонент:

  • Nginx
  • PostgreSQL
  • Redis
  • Supervisor+Gunicorn

Связку Supervisor+Gunicorn я использую для запуска application-сервера. Я предполагаю, что сервера уже установлены и настроены. Рецепты для установки и настройки я выложу как-нибудь позднее.

So where is code?

Итак, для начала нам нужен список самих сервисов:

    SERVICES = {
                'nginx': '/etc/init.d/nginx %s',
                'postgresql': '/etc/init.d/postgresql %s',
                'redis': '/etc/init.d/redis-server %s',
                'supervisor': '/etc/init.d/supervisor %s',
                'gunicorn': 'supervisorctl %s gunicorn',
                # other services
               }

В данном, случае ключами в словаре являются названия сервисов, а значениям - шаблоны команд, в которые мы будет подставлять нужные действия.

Со временем я понял, что обращаться к сервисам по названию не всегда удобно, поэтому пронумеровал все сервисы цифрами:

    SERVICES_LIST = ['nginx',
                     'mongo',
                     'postgresql',
                     'redis']
    
    def _clean(service):
        try:
            # -1 --> we use one based indexes in console
            service = SERVICES_LIST[int(service) - 1]
        except (ValueError, IndexError):
            pass
    
        if service not in SERVICES:
            print "Bad argument. Should be one of " + str(SERVICES.keys())
            print "You can use int for service number: "
            for i in enumerate(SERVICES_LIST):
                print "%s) %s" % (i[0] + 1, i[1])
            exit()
        return service
    

_clean, выполняет две функции:
• преобразует числовые значения сервисов в строковые
• проверяет наличие такого сервиса в общем списке и выводи сообщение с подсказкой в случае проблем.

Теперь все готово для написать самих функции управления сервисами:

@task
def stop(service):
    service = _clean(service)
    sudo(SERVICES[service] % ("stop",)) 
@task
def start(service):
    service = _clean(service)
    sudo(SERVICES[service] % ("start",))
@task
def restart(service):
    service = _clean(service)
    sudo(SERVICES[service] % ("restart",))
@task
def status(service):
    service = _clean(service)
    sudo(SERVICES[service] % ("status",))    

Теперь можно опробовать их в деле, используя следующие консольные команды:

fab -H <hostname> status:1
fab -H <hostname> status:nginx
fab -H <hostname> status:asdf 

Последняя команда отобразит небольшую подсказку со списком доступных сервисов. Данный рецепт для fabric можно скачать здесь.



blog comments powered by Disqus

Fork me on GitHub