简体   繁体   English

样本结构(fabfile)共享通用逻辑并允许多个项目/环境

[英]sample fabric (fabfile) to share common logic and allow multiple projects/environments

i am new to python and fabric. 我是python和fabric的新手。 we currently use capistrano and have a setup similar to this: 我们目前使用capistrano并具有类似于以下的设置:

/api-b2b
  - Capfile (with generic deployment/setup info)
  /int - target host config (like ip, access etc.)
  /prod - target host config (like ip, access etc.)
  /dev - target host config (like ip, access etc.)
/api-b2c
  /int
  /prod
  /dev
/application1
  /int
  /prod
  /dev
/application2
  /int
  /prod
  /dev

we are not happy with capistrano for handling our java apps - fabric looks like a better (simpler) alternative. 对于Capistrano处理Java应用程序,我们不满意-织物看起来像是更好(更简单)的替代品。

all the example fabfiles i have seen so far are "relatively simple" in that they only handle one application for different hosts. 到目前为止,我所看到的所有示例fabfile示例都是“相对简单的”,因为它们只能为不同的主机处理一个应用程序。 i'd like to see some code where different app/hosts are handled by the same fabric files/infrastructure (like inheritance etc.) to share the same logic for common tasks like git handling, directory creation, symlinks etc.. i hope you get what i mean. 我想看一些代码,其中不同的应用程序/主机由相同的结构文件/基础结构(如继承等)处理,以为git处理,目录创建,符号链接等常见任务共享相同的逻辑。我希望您明白我的意思。 i want the whole logic to be the same, just the apps config is different (git repo, target directory). 我希望整个逻辑是相同的,只是应用程序的配置不同(git repo,目标目录)。 all the rest is the same accross the apps (same server layout...) 其余所有应用程序都相同(相同的服务器布局...)

i want to be able to enter something like this 我希望能够输入这样的内容

$ cd api-b2b
$ fab env_prod deploy
$ cd api-b2c
$ fab env_prod deploy

or 要么

$ fab env_prod deploy:app=api=b2b
$ fab env_prod deploy:app=api=b2c

any help (and pointers to sample files) highly appreciated 非常感谢任何帮助(以及指向示例文件的指针)

cheers marcel 欢呼声

If you genuinely want reuse amongst your fabric code, the most robust approach is to refactor the commonalities out and make it a python module. 如果您确实希望在结构代码中重用,则最可靠的方法是将通用性重构并使其成为python模块。 There are modules like fabtools and cusine that are good examples of what it is possible to do. 有喜欢的模块fabtools料理是什么就可以做的很好的例子。

If you're looking to have multiple projects, there are a few ways to achieve that result. 如果您正在寻找多个项目,则有几种方法可以实现这一目标。 Assuming you're using a fabfile directory (rather than a single fabfile.py), you'll have a structure like this. 假设您使用的是fabfile目录(而不是单个fabfile.py),则将具有这样的结构。

/fabfile
  __init__.py
  b2b.py
  b2c.py

Assuming that you have: 假设您有:

# b2b.py / b2c.py
from fabric.api import *

@task
def deploy():
    # b2b/b2c logic
    pass

When you run fab -l (with an empty __init__.py ) you'll see: 当您运行fab -l (带有空的__init__.py )时,您将看到:

Available commands:

    b2b.deploy
    b2c.deploy

To get closer to what you're looking for, you can dynamically lookup, from an argument, which deployment target you want to run: 为了更接近所要查找的内容,可以从参数动态查找要运行的部署目标:

# __init__.py 
from fabric.api import *
import b2b
import b2c

@task
def deploy(api):
    globals()[api].deploy()

Which means that on the command line, I can run fab deploy:api=b2b or fab deploy:api=b2c . 这意味着在命令行上,我可以运行fab deploy:api=b2bfab deploy:api=b2c


Edit 27th Jan 编辑1月27日

Specifying one or machines for a task to run on can be achieved on the command line with the -H or -R switches, using @task or @role decorators, or the settings in the fabric environment (env.hosts and env.roles). 可以在命令行上使用-H-R开关,使用@task@role装饰器或结构环境中的设置(env.hosts和env.roles)来指定要运行任务的一台或多台计算机。 。 The fabric documentation has extensive examples on the execution model that shows you all the details. Fabric文档中有关于执行模型的大量示例,向您显示了所有详细信息。

One way to do this (and potentially not the best way depending on your application) is to dynamically alter the host lists based on the api and the target environment. 一种方法(可能不是最好的方法,这取决于您的应用程序)是根据api和目标环境动态 更改主机列表。

# __init__.py
from fabric.api import *
import b2b
import b2c

@task
def deploy(api, target='test'):
    func  = globals()[api].deploy
    hosts = globals()[api].deploy_hosts(target)
    execute(func, hosts=hosts) 

And now the b2b.py and b2c.py files will look something like: 现在, b2b.pyb2c.py文件将类似于:

# b2b.py / b2c.py
@task
def deploy():
    # b2b/b2c logic
    pass

def deploy_hosts(target):
    return {
        'test' : ['localhost'],
        'prod' : ['localhost'],
        'int'  : ['localhost'],
    }[target]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM