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
|
## master
|
||||||
|
|
||||||
|
* Add ability to filter tasks to specific servers (host filtering). (@andytinycat)
|
||||||
* Add a command line option to control role filter (`--roles`) (@andytinycat)
|
* Add a command line option to control role filter (`--roles`) (@andytinycat)
|
||||||
* Use an SCM object with a pluggable strategy
|
* Use an SCM object with a pluggable strategy
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ module Capistrano
|
||||||
end
|
end
|
||||||
|
|
||||||
def sort_options(options)
|
def sort_options(options)
|
||||||
options.push(version, dry_run, roles)
|
options.push(version, roles, dry_run, hostfilter)
|
||||||
super
|
super
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -74,6 +74,16 @@ module Capistrano
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
end
|
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
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
require 'set'
|
require 'set'
|
||||||
require_relative 'servers/role_filter'
|
require_relative 'servers/role_filter'
|
||||||
|
require_relative 'servers/host_filter'
|
||||||
module Capistrano
|
module Capistrano
|
||||||
class Configuration
|
class Configuration
|
||||||
class Servers
|
class Servers
|
||||||
|
@ -39,7 +40,7 @@ module Capistrano
|
||||||
|
|
||||||
def fetch_roles(required, options)
|
def fetch_roles(required, options)
|
||||||
filter_roles = RoleFilter.for(required, available_roles)
|
filter_roles = RoleFilter.for(required, available_roles)
|
||||||
select(servers_with_roles(filter_roles), options)
|
HostFilter.for(select(servers_with_roles(filter_roles), options))
|
||||||
end
|
end
|
||||||
|
|
||||||
def servers_with_roles(roles)
|
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
|
before do
|
||||||
ENV.stubs(:[]).with('ROLES').returns('web,db')
|
ENV.stubs(:[]).with('ROLES').returns('web,db')
|
||||||
|
ENV.stubs(:[]).with('HOSTS').returns(nil)
|
||||||
servers.add_host('1', roles: :app, active: true)
|
servers.add_host('1', roles: :app, active: true)
|
||||||
servers.add_host('2', roles: :app)
|
servers.add_host('2', roles: :app)
|
||||||
servers.add_host('3', roles: :web)
|
servers.add_host('3', roles: :web)
|
||||||
|
|
Loading…
Reference in a new issue