自定义过滤器

自定义过滤器(特别是自定义开启过滤器)限制了部署到的主机,与主机角色过滤器类似,但用于过滤服务器的具体方法取决于 Capistrano 的用户。

可以使用 Configuration#add_filter 方法将过滤器添加到 Capistrano 的过滤器列表中。过滤器必须响应 filter 方法,该方法将接收一个服务器数组,并应返回该数组的子集(通过过滤器的服务器)。

Configuration#add_filter 也可以接受一个代码块,在这种情况下,代码块应为一元运算符。代码块将接收一个服务器数组,并应返回该数组的子集。

可以向 add_filter 传递代码块或对象,但不能同时传递两者。

示例

您可能拥有一个大型服务器组,它们被划分为与实际地理区域相对应的独立区域。通常,您会部署到所有区域,但有些情况下您可能只想部署到特定区域。

Capistrano 认识服务器的 *角色* 和 *主机名* 概念,但没有 *区域* 的概念。在这种情况下,您可以构建自己的过滤器,根据服务器的区域来选择服务器。在定义服务器时,您可以为它们提供一个 region 属性,并在您的过滤器中使用该属性。

过滤器可能如下所示

config/deploy.rb

    class RegionFilter

      def initialize(regions)
        @regions = Array(regions)
      end

      def filter(servers)
        servers.select {|server|
          region = server.fetch(:region)
          region && @regions.include?(region)
        }
      end

    end

您将像这样添加服务器

config/deploy/production.rb

    server('123.123.123.123', region: 'north-east')
    server('12.12.12.12',     region: 'south-west')
    server('4.5.6.7',         region: 'mid-west')

要告诉 Capistrano 使用此过滤器,您将使用 Configuration#add_filter 方法。在本例中,我们查看 REGIONS 环境变量,并将其视为我们感兴趣的区域的逗号分隔列表。

config/deploy.rb

    if ENV['REGIONS']
      regions = ENV['REGIONS'].split(',')
      filter = RegionFilter.new(regions)
      Capistrano::Configuration.env.add_filter(filter)
    end

我们从环境变量中获取要部署到的区域列表,使用这些区域构建一个新的过滤器,并将其添加到 Capistrano 的过滤器列表中。

当然,我们并不局限于区域。只要您可以以您只想部署到其中一部分服务器的方式对服务器列表进行分类或分区,就可以使用自定义过滤器。例如,您可以任意将服务器分配到 *A* 组或 *B* 组,并将新版本仅部署到 *B* 组,作为 A/B 测试的简单变体。

Fork me on GitHub