2015-12-23 6 views
2

Я искал способ выполнения задач на нескольких серверах (да, я знаю о roledefs -R и hosts -H), но мне нужны дополнительные параметры, такие как разные пользователи для каждый хост и т.д., и я хотел, чтобы держать его в чистоте и порядке, как я держу хозяина, как функции определения (как предложено в стеке где-то), чтобы иметь возможность выполнить задачу только на один, как этотТкань развертывается на несколько хостов с настраиваемыми параметрами для каждого

def test(): 
    user='root' 
    env.host='myapp-test.com' 

Я начал с изменения окр .tasks, но оказалось, что они повторяются генератором, и доступ к ним через context_manager был только для просмотра (как в fab docs).

Я хотел сохранить свои «функциональные хосты», поэтому я решил динамически изменять env.hosts и писать декоратор, который обновляет данные, зависящие от сервера, в зависимости от текущего env.host (в будущем переопределит дефолт по умолчанию) Приведенный ниже код (я должен был изменить имена в коде по соображениям безопасности надежды не нарушала какие-либо функции):

APP_SERVERS= { 
    'test':{ 
     'envname':'test', 
     'user':'deploy_user', 
     'host':'myapp-test.com', 
     'host_string':'myapp-test.com', 
     'path':'/opt/myapp/test/', 
     'www_root':'http://myapp-test.com/', 
     'retries_before_killing':3, 
     'retry_sleep':2 
    }, 
    'staging':{ 
     'envname':'staging', 
     'user':'deploy_user', 
     'host':'myapp-staging.com', 
     'host_string':'myapp-staging.com', 
     'path':'/opt/myapp/staging/', 
     'www_root':'http://myapp-staging.com/', 
     'retries_before_killing':3, 
     'retry_sleep':2 
    }, 
    'uat':{ 
     'envname':'uat', 
     'user':'deploy_user', 
     'host':'myapp-uat.com', 
     'host_string':'myapp-uat.com', 
     'path':'/opt/myapp/uat/', 
     'www_root':'http://myapp-uat.com/', 
     'retries_before_killing':3, 
     'retry_sleep':2 
    }, 
    'live1':{ 
     'envname':'live1', 
     'user':'deploy_user', 
     'host':'myapp-live1.com', 
     'host_string':'myapp-live1.com', 
     'path':'/opt/myapp/live1/', 
     'www_root':'http://myapp-live1.com/', 
     'retries_before_killing':1, 
     'retry_sleep':1 
    }, 
    'live2':{ 
     'envname':'live2', 
     'user':'deploy_user', 
     'host':'myapp-live2.com', 
     'host_string':'myapp-live2.com', 
     'path':'/opt/myapp/live2/', 
     'www_root':'http://myapp.com/', 
     'retries_before_killing':1, 
     'retry_sleep':1 
    } 
} 

TEST_HOSTS = ['test','staging','uat'] 
LIVE_HOSTS = ['live1','live2'] 

def test(): 
    env.update(dict(APP_SERVERS['test'])) 

def staging(): 
    env.update(dict(APP_SERVERS['staging'])) 

def uat(): 
    env.update(dict(APP_SERVERS['uat'])) 

def live1(): 
    env.update(dict(APP_SERVERS['live1'])) 

def live2(): 
    env.update(dict(APP_SERVERS['live2'])) 


# GROUPS OF SERVERS DEFINITION 
def live_servers(): 
    env['hosts'] = [APP_SERVERS[a]['host'] for a in APP_HOSTS] 

def test_servers(): 
    env['hosts'] = [APP_SERVERS[a]['host'] for a in APP_HOSTS] 

def env_update(func): 
    def func_wrapper(*args,**kwargs): 
     if not len(env.hosts): 
      return func(*args,**kwargs) 
     else: 
      env.update(dict(APP_SERVERS[filter(lambda x: APP_SERVERS[x]['host']==env.host,APP_SERVERS)[0]])) 
      func(*args,**kwargs) 
    return func_wrapper 

@env_update 
def pull_commits(): 
    #some_code 
    run('uptime') 

у меня есть возможность запускать группу выполнять задачи FAB live_servers pull_commits, а также одиночные FAB live1 pull_commits.

Я знаю, что может быть также то, как дублирование задач с отдельными серверами FAB live1 pull_commits live2 pull_commits, но я считаю, что ткань была написана для распределенных систем, которая имеет разные пути приложений и пользователей и т.д.

Так что мой вопрос is: Есть ли более простой способ сделать это? как что-то встраивается в ткань (также рулефы с дополнительными ключами для ключей не работали для меня)? Или я не вижу каких-либо функциональных возможностей ткани? Я хочу, чтобы этот простой одиночный/многократный развертывания хост-команды, как: Fab live_servers pull_commits, FAB тест pull_commits

ответ

0

Вместо того чтобы использовать свой существующий подход, рассмотрим только с помощью host_string в качестве ключа к словарю ARG_SERVERS, а затем загрузить информацию . как это требуется в задачах (включая любые требуемые обновления в окружающей среде ткани делая эту регулировку означает, что вы также должны иметь возможность получить роль работая

Например:.

@task 
def pull_commits(): 
    hostinfo = ARG_SERVERS[env.host_string] 
    # ... more code 
    run(...) 

Еще одно предложение рассмотреть вопрос об использованииssh config file (~/.ssh/config) для определения псевдонимов ssh для всех ваших машин. Это помещает всю вашу информацию об имени хоста/хоста_штрины/пользователя в центральное место и имеет то преимущество, что вы можете обратиться к узлу с единственным значимым именем и упростить ARG_SERVERS.

# contents of $HOME/.ssh/config 
Host test 
    HostName myapp-test.com 
    User deploy-user 

Host staging 
    HostName myapp-staging.com 
    User deploy-user 

Host uat 
    HostName myapp-uat.com 
    User deploy-user 

Host live1 
    HostName myapp-live1.com 
    User deploy-user 

Host live2 
    HostName myapp-live2.com 
    User deploy-user 

В соответствии с более традиционной модели целевой ткани, теперь вы должны быть в состоянии делать такие вещи, как:

# single host 
$ fab -H live1 pull_commits 

# multiple hosts 
$ fab -H test,staging pull_commits 

или роли (согласно документации ткани).

+0

Спасибо за ваш ответ Андрей, но это не то, что я хотел. Прежде всего об определении ~/.ssh/config - я не думаю, что это хорошая идея, потому что это должно было бы быть сделано каждым разработчиком, который хочет использовать ткань, и в моей ситуации разработчики просто хотят запустить команду ткани и не делать заботиться о конфигурации своих клиентов ssh, и я не думаю, что это хорошо для будущего и «централизованного расположения». Я беспокоюсь о вашем решении, например, о том, что некоторые детали узла (IP, учетные данные) меняются. Все разработчики, использующие ткань, должны будут изменить их конфигурацию ssh, я прав? –

+1

Также я хочу использовать дополнительные параметры конфигурации для Django, а в вашем решении он потерян. Не думайте, что положить их в конфигурацию ssh будет хорошо.Подводя итог: если я не буду использовать конфигурацию ssh, я не могу следовать за вашим решением -H-R, так как это не сработает. Я также хотел, чтобы группа хостов (что-то вроде roledefs) с одним именем в большой среде -H обыкновенная работа, определяющая fab deploy live1, live2 ... live10 - это всего лишь типизация, которую я хотел избежать. –