在撰写本文时,v2 分支有一个Group
类,该类应该能够作为以前称为“角色”的单位,也就是“一群主机来做事”。
但是,目前还没有组织或标记Group
对象的特定方法; 对于想要推出自己的特定创建方式的高级用户的纯 API 用例来说,它已经“完成”了,但对于面向 CLI 的用户或想要构建框架的中级用户来说,它缺乏任何东西。
换句话说,除非您纯粹使用 API,否则如果 CLI 或任务调用位无法找到 Group 对象,那么将 Group 对象放在某处是没有用的!
在 v1 中,角色实际上是一个单一的平面命名空间,将简单的字符串标签映射到 v2 中的组,并且可以在运行时在 CLI 上选择它们 ( fab --roles=web,db
) 和/或注册为任务的默认目标 ( @task('db') \n def migrate():
),很像主机。
用户在env.roledefs
定义了它们,一个简单的字典; 任何中级到高级功能都围绕着修改它,通常是在运行时(通过任务前或子程序),有时是在模块加载时。
Group
s 和/或Connection
s 的一些可迭代对象。Lexicon
而不是dict
。db
、 web
、 lb
直接映射,然后是名为prod
的第二层名称Lexicon
。 可能还有其他地图子类也已经这样做了。cxn
是一个不同的对象, if cxn in group
也会起作用来自group
内的相等成员。db
角色运行”@group
就像@task
,这些函数不是可执行的工作单元,而是产生 Group 对象。来自邮件列表:
我们实现了我们自己的内部 REST API,它根据正在部署的项目动态填充 env.roledefs,并且严重依赖于不将主机字符串嵌入到项目的 fabfile 中或在 CLI 中指定它们。
我们的用例是:
EnvironmentDatabaseAPIClient(
'https://rest.api.url/schema/',
env.service_name,
).apply_env()
服务器环境的数量 - 多个测试环境(其中一些是私有的,一些是公共的)和多个生产环境(针对不同的客户端)。 每个环境由一台或多台主机组成,并映射到结构角色。
每个服务(上例中的env.service_name
)都有不同的环境集。
我们还有元角色(角色组)。 它们以group-
为前缀: group-production
、 group-test
、 group-external
、 group-internal
、 group-all
。 这允许我们部署到多个服务器角色而无需一一指定它们,例如group-all
部署到所有角色,包括生产和测试。
我们有特殊的结构任务来打印有关角色组、角色和主机的信息。
我们还严重依赖将主机字符串反向映射回角色名称(每个 service_name 的主机字符串都是唯一的)。 这用于部署日志记录和通知。 基本上,我们将服务部署记录到每个主机,并在服务已部署到角色中的所有主机时发送 Slack 通知。 EnvironmentDatabaseAPI 服务器对此负责(它保留日志和部署状态)。 这是通过使用装饰器装饰结构任务来完成的,该装饰器将env.host
、 env.port
和env.service_name
(加上提交信息)提交回 API 服务器。
我们计划在未来添加部署身份验证,也很可能从服务器中提取更多env
变量以使其在任务上下文中可用。
谢谢@max-arnold! 我也从我过去的用例中认出了其中的许多。 特别是反向映射位,我记得在 v1 中出现过几次,所以我将它添加到列表中。
为了让 Fabric v2 对我有用,我需要一种方法来告诉fab
执行任务的主机集。
以前我定义了角色,然后运行fab -R ...
。 (实际上,角色是使用 IP 地址范围以编程方式定义的,但这不是必需的,YAML 文件中的静态列表就可以了。)
我在 Fabric v2 中找不到等效项,而且我也无法使用以下方法模拟此功能:
fabric.yaml
配置文件包含active_hostset: null
hostsets:
myhostset:
- ...
active_hostset = config["hostsets"][config["active_hostset"]]
在fabfile.py
env INVOKE_ACTIVE_HOSTSET=myhostset fab ...
我得到的不是预期的主机列表KeyError: 'active_hostset'
。
我们为 fabric v1 中的每个环境将不同的主机集映射到每个角色,并且通过运行role.environment:staging
任务来指定环境来设置环境。 因此,此任务会影响以下任务使用的主机。
在 v2 中,我们尝试使用自定义任务,但问题是Executor.expand_calls
在我们的role.environment
任务运行之前运行,因此以下任务都不知道环境以动态构建其主机列表。
使Executor.expand_calls
成为生成器允许任务执行影响以后的任务执行。 所以我上面的例子有效,我们有一个自定义的Task
需要知道它的环境才能正确地将角色扩展到主机。 例如fab role.environment dev deploy.app
- role.environment
任务现在在deploy.app
扩展之前运行,因此deploy.app
知道环境并且可以配置它的主机,然后扩展为正确的任务集。
我在我的叉子中制作了这个原型:
https://github.com/pyinvoke/invoke/compare/master...rectalogic :expand-generator
https://github.com/fabric/fabric/compare/master...rectalogic :expand-generator
嗨,我不知道多年后这个软件发生了什么,但我真的很想念[email protected] 中的“角色”概念,尤其是在运行$ fab -R dev
我们还使用角色来表示不同环境中的同一组操作。 也许将命名角色和命名环境的概念分开会很有用? 就像在开发环境中的 Web 角色一样。
最有用的评论
嗨,我不知道多年后这个软件发生了什么,但我真的很想念[email protected] 中的“角色”概念,尤其是在运行
$ fab -R dev