mirror of
https://github.com/capistrano/capistrano
synced 2023-03-27 23:21:18 -04:00
Merge pull request #810 from forward3d/host_filter
Add ability to filter tasks to specific servers (host filtering).
This commit is contained in:
commit
20fec69f99
6 changed files with 183 additions and 2 deletions
|
@ -4,6 +4,7 @@ Reverse Chronological Order:
|
|||
|
||||
## master
|
||||
|
||||
* Add ability to filter tasks to specific servers (host filtering). (@andytinycat)
|
||||
* Add a command line option to control role filter (`--roles`) (@andytinycat)
|
||||
* Use an SCM object with a pluggable strategy
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ module Capistrano
|
|||
end
|
||||
|
||||
def sort_options(options)
|
||||
options.push(version, dry_run, roles)
|
||||
options.push(version, roles, dry_run, hostfilter)
|
||||
super
|
||||
end
|
||||
|
||||
|
@ -74,6 +74,16 @@ module Capistrano
|
|||
}
|
||||
]
|
||||
end
|
||||
|
||||
def hostfilter
|
||||
['--hosts HOSTS', '-z',
|
||||
"Filter command to only apply to these hosts (separate multiple hosts with a comma)",
|
||||
lambda { |value|
|
||||
Configuration.env.set(:filter, :hosts => value.split(","))
|
||||
}
|
||||
]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
require 'set'
|
||||
require_relative 'servers/role_filter'
|
||||
require_relative 'servers/host_filter'
|
||||
module Capistrano
|
||||
class Configuration
|
||||
class Servers
|
||||
|
@ -39,7 +40,7 @@ module Capistrano
|
|||
|
||||
def fetch_roles(required, options)
|
||||
filter_roles = RoleFilter.for(required, available_roles)
|
||||
select(servers_with_roles(filter_roles), options)
|
||||
HostFilter.for(select(servers_with_roles(filter_roles), options))
|
||||
end
|
||||
|
||||
def servers_with_roles(roles)
|
||||
|
|
82
lib/capistrano/configuration/servers/host_filter.rb
Normal file
82
lib/capistrano/configuration/servers/host_filter.rb
Normal file
|
@ -0,0 +1,82 @@
|
|||
module Capistrano
|
||||
class Configuration
|
||||
class Servers
|
||||
class HostFilter
|
||||
|
||||
def initialize(available)
|
||||
@available = available
|
||||
end
|
||||
|
||||
def self.for(available)
|
||||
new(available).hosts
|
||||
end
|
||||
|
||||
def hosts
|
||||
if host_filter.any?
|
||||
@available.select { |server| host_filter.include? server.hostname }
|
||||
else
|
||||
@available
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def filter
|
||||
if host_filter.any?
|
||||
host_filter
|
||||
else
|
||||
@available
|
||||
end
|
||||
end
|
||||
|
||||
def host_filter
|
||||
env_filter | configuration_filter
|
||||
end
|
||||
|
||||
def configuration_filter
|
||||
ConfigurationFilter.new.hosts
|
||||
end
|
||||
|
||||
def env_filter
|
||||
EnvFilter.new.hosts
|
||||
end
|
||||
|
||||
class ConfigurationFilter
|
||||
|
||||
def hosts
|
||||
if filter
|
||||
Array(filter.fetch(:hosts, []))
|
||||
else
|
||||
[]
|
||||
end
|
||||
end
|
||||
|
||||
def config
|
||||
Configuration.env
|
||||
end
|
||||
|
||||
def filter
|
||||
config.fetch(:filter) || config.fetch(:select)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
class EnvFilter
|
||||
|
||||
def hosts
|
||||
if filter
|
||||
filter.split(',')
|
||||
else
|
||||
[]
|
||||
end
|
||||
end
|
||||
|
||||
def filter
|
||||
ENV['HOSTS']
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,86 @@
|
|||
require 'spec_helper'
|
||||
|
||||
module Capistrano
|
||||
class Configuration
|
||||
class Servers
|
||||
|
||||
describe HostFilter do
|
||||
let(:host_filter) { HostFilter.new(available) }
|
||||
let(:available) { [ Server.new('server1'), Server.new('server2'), Server.new('server3') ] }
|
||||
|
||||
describe '#new' do
|
||||
it 'takes one array of hostnames' do
|
||||
expect(host_filter)
|
||||
end
|
||||
end
|
||||
|
||||
describe '.for' do
|
||||
|
||||
subject { HostFilter.for(available) }
|
||||
|
||||
context 'without env vars' do
|
||||
|
||||
it 'returns all available hosts' do
|
||||
expect(subject).to eq available
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context 'with ENV vars' do
|
||||
before do
|
||||
ENV.stubs(:[]).with('HOSTS').returns('server1,server2')
|
||||
end
|
||||
|
||||
it 'returns all required hosts defined in HOSTS' do
|
||||
expect(subject).to eq [Server.new('server1'), Server.new('server2')]
|
||||
end
|
||||
end
|
||||
|
||||
context 'with configuration filters' do
|
||||
before do
|
||||
Configuration.env.set(:filter, hosts: %w{server1 server2})
|
||||
end
|
||||
|
||||
it 'returns all required hosts defined in the filter' do
|
||||
expect(subject).to eq [Server.new('server1'), Server.new('server2')]
|
||||
end
|
||||
|
||||
after do
|
||||
Configuration.env.delete(:filter)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a single configuration filter' do
|
||||
before do
|
||||
Configuration.env.set(:filter, hosts: 'server3')
|
||||
end
|
||||
|
||||
it 'returns all required hosts defined in the filter' do
|
||||
expect(subject).to eq [Server.new('server3')]
|
||||
end
|
||||
|
||||
after do
|
||||
Configuration.env.delete(:filter)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with configuration filters and ENV vars' do
|
||||
before do
|
||||
Configuration.env.set(:filter, hosts: 'server1')
|
||||
ENV.stubs(:[]).with('HOSTS').returns('server3')
|
||||
end
|
||||
|
||||
it 'returns all required hosts defined in the filter' do
|
||||
expect(subject).to eq [Server.new('server1'), Server.new('server3')]
|
||||
end
|
||||
|
||||
after do
|
||||
Configuration.env.delete(:filter)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -179,6 +179,7 @@ module Capistrano
|
|||
|
||||
before do
|
||||
ENV.stubs(:[]).with('ROLES').returns('web,db')
|
||||
ENV.stubs(:[]).with('HOSTS').returns(nil)
|
||||
servers.add_host('1', roles: :app, active: true)
|
||||
servers.add_host('2', roles: :app)
|
||||
servers.add_host('3', roles: :web)
|
||||
|
|
Loading…
Reference in a new issue