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

Mar*_*cel 1 python deployment capistrano fabric

我是 Python 和 Fabric 的新手。我们目前使用 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
Run Code Online (Sandbox Code Playgroud)

我们对 capistrano 处理我们的 Java 应用程序不满意——fabric 看起来是一个更好(更简单)的替代方案。

到目前为止,我看到的所有示例 fabfile 都“相对简单”,因为它们仅处理不同主机的一个应用程序。我想看到一些代码,其中不同的应用程序/主机由相同的结构文件/基础设施(如继承等)处理,以便为 git 处理、目录创建、符号链接等常见任务共享相同的逻辑。我希望你明白我的意思。我希望整个逻辑相同,只是应用程序配置不同(git repo,目标目录)。所有其余的在应用程序中都是相同的(相同的服务器布局......)

我希望能够输入这样的东西

$ cd api-b2b
$ fab env_prod deploy
$ cd api-b2c
$ fab env_prod deploy
Run Code Online (Sandbox Code Playgroud)

或者

$ fab env_prod deploy:app=api=b2b
$ fab env_prod deploy:app=api=b2c
Run Code Online (Sandbox Code Playgroud)

非常感谢任何帮助(以及指向示例文件的指针)

欢呼马塞尔

And*_*ker 5

如果您真的希望在您的结构代码中重用,最可靠的方法是重构共性并使其成为 python 模块。有喜欢的模块fabtools料理是什么就可以做的很好的例子。

如果您希望拥有多个项目,则有几种方法可以实现该结果。假设您使用的是 fabfile 目录(而不是单个 fabfile.py),您将拥有这样的结构。

/fabfile
  __init__.py
  b2b.py
  b2c.py
Run Code Online (Sandbox Code Playgroud)

假设你有:

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

@task
def deploy():
    # b2b/b2c logic
    pass
Run Code Online (Sandbox Code Playgroud)

当您运行fab -l(带有一个空的__init__.py)时,您会看到:

Available commands:

    b2b.deploy
    b2c.deploy
Run Code Online (Sandbox Code Playgroud)

为了更接近您要查找的内容,您可以从参数中动态查找要运行的部署目标:

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

@task
def deploy(api):
    globals()[api].deploy()
Run Code Online (Sandbox Code Playgroud)

这意味着在命令行上,我可以运行fab deploy:api=b2bfab deploy:api=b2c.


1月27日编辑

可以在命令行上使用-Hor-R开关、使用@task@role装饰器或结构环境中的设置(env.hosts 和 env.roles)指定一台或多台机器运行任务。结构文档有大量关于执行模型的示例,向您展示了所有细节。

执行此操作的一种方法(根据您的应用程序可能不是最佳方法)是根据 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) 
Run Code Online (Sandbox Code Playgroud)

现在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]
Run Code Online (Sandbox Code Playgroud)