capistrano 2.1.0 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +20 -0
- data/.travis.yml +7 -0
- data/CHANGELOG.md +89 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +674 -0
- data/README.md +226 -0
- data/Rakefile +5 -0
- data/bin/cap +2 -3
- data/bin/capify +7 -77
- data/capistrano-public_cert.pem +22 -0
- data/capistrano.gemspec +35 -0
- data/features/deploy.feature +52 -0
- data/features/installation.feature +16 -0
- data/features/remote_file_task.feature +14 -0
- data/features/step_definitions/assertions.rb +90 -0
- data/features/step_definitions/cap_commands.rb +8 -0
- data/features/step_definitions/setup.rb +25 -0
- data/features/support/env.rb +12 -0
- data/features/support/remote_command_helpers.rb +20 -0
- data/lib/Capfile +3 -0
- data/lib/capistrano/all.rb +16 -0
- data/lib/capistrano/application.rb +60 -0
- data/lib/capistrano/configuration/question.rb +42 -0
- data/lib/capistrano/configuration/server.rb +133 -0
- data/lib/capistrano/configuration/servers/role_filter.rb +86 -0
- data/lib/capistrano/configuration/servers.rb +53 -58
- data/lib/capistrano/configuration.rb +84 -30
- data/lib/capistrano/console.rb +1 -0
- data/lib/capistrano/defaults.rb +13 -0
- data/lib/capistrano/deploy.rb +3 -0
- data/lib/capistrano/dotfile.rb +3 -0
- data/lib/capistrano/dsl/env.rb +64 -0
- data/lib/capistrano/dsl/paths.rb +94 -0
- data/lib/capistrano/dsl/stages.rb +15 -0
- data/lib/capistrano/dsl/task_enhancements.rb +53 -0
- data/lib/capistrano/dsl.rb +48 -0
- data/lib/capistrano/git.rb +1 -0
- data/lib/capistrano/hg.rb +1 -0
- data/lib/capistrano/i18n.rb +34 -0
- data/lib/capistrano/install.rb +1 -0
- data/lib/capistrano/setup.rb +21 -0
- data/lib/capistrano/tasks/console.rake +21 -0
- data/lib/capistrano/tasks/deploy.rake +204 -0
- data/lib/capistrano/tasks/framework.rake +67 -0
- data/lib/capistrano/tasks/git.rake +62 -0
- data/lib/capistrano/tasks/hg.rake +39 -0
- data/lib/capistrano/tasks/install.rake +39 -0
- data/lib/capistrano/templates/Capfile +26 -0
- data/lib/capistrano/templates/deploy.rb.erb +40 -0
- data/lib/capistrano/templates/stage.rb.erb +42 -0
- data/lib/capistrano/version.rb +1 -20
- data/lib/capistrano/version_validator.rb +37 -0
- data/lib/capistrano.rb +0 -2
- data/spec/integration/dsl_spec.rb +344 -0
- data/spec/integration_spec_helper.rb +7 -0
- data/spec/lib/capistrano/application_spec.rb +61 -0
- data/spec/lib/capistrano/configuration/question_spec.rb +54 -0
- data/spec/lib/capistrano/configuration/server_spec.rb +249 -0
- data/spec/lib/capistrano/configuration/servers/role_filter_spec.rb +140 -0
- data/spec/lib/capistrano/configuration/servers_spec.rb +184 -0
- data/spec/lib/capistrano/configuration_spec.rb +101 -0
- data/spec/lib/capistrano/dsl/env_spec.rb +10 -0
- data/spec/lib/capistrano/dsl/paths_spec.rb +69 -0
- data/spec/lib/capistrano/dsl_spec.rb +63 -0
- data/spec/lib/capistrano/version_validator_spec.rb +103 -0
- data/spec/lib/capistrano_spec.rb +8 -0
- data/spec/spec_helper.rb +15 -0
- data/spec/support/.gitignore +1 -0
- data/spec/support/Vagrantfile +13 -0
- data/spec/support/matchers.rb +5 -0
- data/spec/support/tasks/database.cap +11 -0
- data/spec/support/test_app.rb +138 -0
- metadata +251 -179
- data/CHANGELOG +0 -512
- data/MIT-LICENSE +0 -20
- data/README +0 -43
- data/examples/sample.rb +0 -14
- data/lib/capistrano/callback.rb +0 -45
- data/lib/capistrano/cli/execute.rb +0 -82
- data/lib/capistrano/cli/help.rb +0 -102
- data/lib/capistrano/cli/help.txt +0 -53
- data/lib/capistrano/cli/options.rb +0 -183
- data/lib/capistrano/cli/ui.rb +0 -28
- data/lib/capistrano/cli.rb +0 -47
- data/lib/capistrano/command.rb +0 -161
- data/lib/capistrano/configuration/actions/file_transfer.rb +0 -35
- data/lib/capistrano/configuration/actions/inspect.rb +0 -46
- data/lib/capistrano/configuration/actions/invocation.rb +0 -134
- data/lib/capistrano/configuration/callbacks.rb +0 -148
- data/lib/capistrano/configuration/connections.rb +0 -159
- data/lib/capistrano/configuration/execution.rb +0 -126
- data/lib/capistrano/configuration/loading.rb +0 -198
- data/lib/capistrano/configuration/namespaces.rb +0 -196
- data/lib/capistrano/configuration/roles.rb +0 -51
- data/lib/capistrano/configuration/variables.rb +0 -127
- data/lib/capistrano/errors.rb +0 -15
- data/lib/capistrano/extensions.rb +0 -57
- data/lib/capistrano/gateway.rb +0 -131
- data/lib/capistrano/logger.rb +0 -59
- data/lib/capistrano/recipes/compat.rb +0 -32
- data/lib/capistrano/recipes/deploy/dependencies.rb +0 -44
- data/lib/capistrano/recipes/deploy/local_dependency.rb +0 -46
- data/lib/capistrano/recipes/deploy/remote_dependency.rb +0 -96
- data/lib/capistrano/recipes/deploy/scm/accurev.rb +0 -169
- data/lib/capistrano/recipes/deploy/scm/base.rb +0 -192
- data/lib/capistrano/recipes/deploy/scm/bzr.rb +0 -86
- data/lib/capistrano/recipes/deploy/scm/cvs.rb +0 -151
- data/lib/capistrano/recipes/deploy/scm/darcs.rb +0 -85
- data/lib/capistrano/recipes/deploy/scm/git.rb +0 -191
- data/lib/capistrano/recipes/deploy/scm/mercurial.rb +0 -129
- data/lib/capistrano/recipes/deploy/scm/perforce.rb +0 -126
- data/lib/capistrano/recipes/deploy/scm/subversion.rb +0 -114
- data/lib/capistrano/recipes/deploy/scm.rb +0 -19
- data/lib/capistrano/recipes/deploy/strategy/base.rb +0 -64
- data/lib/capistrano/recipes/deploy/strategy/checkout.rb +0 -20
- data/lib/capistrano/recipes/deploy/strategy/copy.rb +0 -144
- data/lib/capistrano/recipes/deploy/strategy/export.rb +0 -20
- data/lib/capistrano/recipes/deploy/strategy/remote.rb +0 -52
- data/lib/capistrano/recipes/deploy/strategy/remote_cache.rb +0 -47
- data/lib/capistrano/recipes/deploy/strategy.rb +0 -19
- data/lib/capistrano/recipes/deploy/templates/maintenance.rhtml +0 -53
- data/lib/capistrano/recipes/deploy.rb +0 -494
- data/lib/capistrano/recipes/standard.rb +0 -37
- data/lib/capistrano/recipes/templates/maintenance.rhtml +0 -53
- data/lib/capistrano/recipes/upgrade.rb +0 -33
- data/lib/capistrano/server_definition.rb +0 -51
- data/lib/capistrano/shell.rb +0 -256
- data/lib/capistrano/ssh.rb +0 -109
- data/lib/capistrano/task_definition.rb +0 -69
- data/lib/capistrano/upload.rb +0 -146
- data/test/cli/execute_test.rb +0 -132
- data/test/cli/help_test.rb +0 -139
- data/test/cli/options_test.rb +0 -226
- data/test/cli/ui_test.rb +0 -28
- data/test/cli_test.rb +0 -17
- data/test/command_test.rb +0 -309
- data/test/configuration/actions/file_transfer_test.rb +0 -40
- data/test/configuration/actions/inspect_test.rb +0 -62
- data/test/configuration/actions/invocation_test.rb +0 -202
- data/test/configuration/callbacks_test.rb +0 -206
- data/test/configuration/connections_test.rb +0 -288
- data/test/configuration/execution_test.rb +0 -159
- data/test/configuration/loading_test.rb +0 -127
- data/test/configuration/namespace_dsl_test.rb +0 -297
- data/test/configuration/roles_test.rb +0 -47
- data/test/configuration/servers_test.rb +0 -90
- data/test/configuration/variables_test.rb +0 -180
- data/test/configuration_test.rb +0 -81
- data/test/deploy/scm/accurev_test.rb +0 -23
- data/test/deploy/scm/base_test.rb +0 -55
- data/test/deploy/scm/git_test.rb +0 -112
- data/test/deploy/strategy/copy_test.rb +0 -147
- data/test/extensions_test.rb +0 -69
- data/test/fixtures/cli_integration.rb +0 -5
- data/test/fixtures/config.rb +0 -5
- data/test/fixtures/custom.rb +0 -3
- data/test/gateway_test.rb +0 -167
- data/test/logger_test.rb +0 -123
- data/test/server_definition_test.rb +0 -108
- data/test/shell_test.rb +0 -64
- data/test/ssh_test.rb +0 -97
- data/test/task_definition_test.rb +0 -101
- data/test/upload_test.rb +0 -131
- data/test/utils.rb +0 -42
- data/test/version_test.rb +0 -24
@@ -0,0 +1,60 @@
|
|
1
|
+
module Capistrano
|
2
|
+
class Application < Rake::Application
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
super
|
6
|
+
@name = "cap"
|
7
|
+
@rakefiles = %w{capfile Capfile capfile.rb Capfile.rb} << capfile
|
8
|
+
end
|
9
|
+
|
10
|
+
def run
|
11
|
+
Rake.application = self
|
12
|
+
super
|
13
|
+
end
|
14
|
+
|
15
|
+
def sort_options(options)
|
16
|
+
options.push(version,dry_run)
|
17
|
+
super
|
18
|
+
end
|
19
|
+
|
20
|
+
def load_rakefile
|
21
|
+
@name = 'cap'
|
22
|
+
super
|
23
|
+
end
|
24
|
+
|
25
|
+
def top_level_tasks
|
26
|
+
if tasks_without_stage_dependency.include?(@top_level_tasks.first)
|
27
|
+
@top_level_tasks
|
28
|
+
else
|
29
|
+
@top_level_tasks.unshift(ensure_stage)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
# allows the `cap install` task to load without a capfile
|
36
|
+
def capfile
|
37
|
+
File.expand_path(File.join(File.dirname(__FILE__),'..','Capfile'))
|
38
|
+
end
|
39
|
+
|
40
|
+
def version
|
41
|
+
['--version', '-V',
|
42
|
+
"Display the program version.",
|
43
|
+
lambda { |value|
|
44
|
+
puts "Capistrano Version: #{Capistrano::VERSION} (Rake Version: #{RAKEVERSION})"
|
45
|
+
exit
|
46
|
+
}
|
47
|
+
]
|
48
|
+
end
|
49
|
+
|
50
|
+
def dry_run
|
51
|
+
['--dry-run', '-n',
|
52
|
+
"Do a dry run without executing actions",
|
53
|
+
lambda { |value|
|
54
|
+
Configuration.env.set(:sshkit_backend, SSHKit::Backend::Printer)
|
55
|
+
}
|
56
|
+
]
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Capistrano
|
2
|
+
class Configuration
|
3
|
+
class Question
|
4
|
+
|
5
|
+
def initialize(env, key, default)
|
6
|
+
@env, @key, @default = env, key, default
|
7
|
+
end
|
8
|
+
|
9
|
+
def call
|
10
|
+
ask_question
|
11
|
+
save_response
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
attr_reader :env, :key, :default
|
16
|
+
|
17
|
+
def ask_question
|
18
|
+
$stdout.puts question
|
19
|
+
end
|
20
|
+
|
21
|
+
def save_response
|
22
|
+
env.set(key, value)
|
23
|
+
end
|
24
|
+
|
25
|
+
def value
|
26
|
+
if response.empty?
|
27
|
+
default
|
28
|
+
else
|
29
|
+
response
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def response
|
34
|
+
@response ||= $stdin.gets.chomp
|
35
|
+
end
|
36
|
+
|
37
|
+
def question
|
38
|
+
I18n.t(:question, key: key, default_value: default, scope: :capistrano)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
require 'set'
|
2
|
+
module Capistrano
|
3
|
+
class Configuration
|
4
|
+
class Server < SSHKit::Host
|
5
|
+
extend Forwardable
|
6
|
+
def_delegators :properties, :roles, :fetch, :set
|
7
|
+
|
8
|
+
def add_roles(roles)
|
9
|
+
Array(roles).each { |role| add_role(role) }
|
10
|
+
end
|
11
|
+
alias roles= add_roles
|
12
|
+
|
13
|
+
def add_role(role)
|
14
|
+
roles.add role.to_sym
|
15
|
+
end
|
16
|
+
|
17
|
+
def has_role?(role)
|
18
|
+
roles.include? role.to_sym
|
19
|
+
end
|
20
|
+
|
21
|
+
def matches?(host)
|
22
|
+
hostname == Server.new(host).hostname
|
23
|
+
end
|
24
|
+
|
25
|
+
def select?(options)
|
26
|
+
selector = Selector.new(options)
|
27
|
+
selector.call(self)
|
28
|
+
end
|
29
|
+
|
30
|
+
def primary
|
31
|
+
self if fetch(:primary)
|
32
|
+
end
|
33
|
+
|
34
|
+
def with(properties)
|
35
|
+
properties.each { |key, value| add_property(key, value) }
|
36
|
+
self
|
37
|
+
end
|
38
|
+
|
39
|
+
def properties
|
40
|
+
@properties ||= Properties.new
|
41
|
+
end
|
42
|
+
|
43
|
+
def netssh_options_with_options
|
44
|
+
@netssh_options ||= netssh_options_without_options.merge( fetch(:ssh_options) || {} )
|
45
|
+
end
|
46
|
+
alias_method :netssh_options_without_options, :netssh_options
|
47
|
+
alias_method :netssh_options, :netssh_options_with_options
|
48
|
+
|
49
|
+
def roles_array
|
50
|
+
roles.to_a
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def add_property(key, value)
|
56
|
+
if respond_to?("#{key}=")
|
57
|
+
send("#{key}=", value)
|
58
|
+
else
|
59
|
+
set(key, value)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
class Properties
|
64
|
+
|
65
|
+
def initialize
|
66
|
+
@properties = {}
|
67
|
+
end
|
68
|
+
|
69
|
+
def set(key, value)
|
70
|
+
@properties[key] = value
|
71
|
+
end
|
72
|
+
|
73
|
+
def fetch(key)
|
74
|
+
@properties[key]
|
75
|
+
end
|
76
|
+
|
77
|
+
def respond_to?(method)
|
78
|
+
@properties.has_key?(method)
|
79
|
+
end
|
80
|
+
|
81
|
+
def roles
|
82
|
+
@roles ||= Set.new
|
83
|
+
end
|
84
|
+
|
85
|
+
def method_missing(key, value=nil)
|
86
|
+
if value
|
87
|
+
set(lvalue(key), value)
|
88
|
+
else
|
89
|
+
fetch(key)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
|
95
|
+
def lvalue(key)
|
96
|
+
key.to_s.chomp('=').to_sym
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
class Selector
|
102
|
+
def initialize(options)
|
103
|
+
@options = options
|
104
|
+
end
|
105
|
+
|
106
|
+
def callable
|
107
|
+
if key.respond_to?(:call)
|
108
|
+
key
|
109
|
+
else
|
110
|
+
->(server) { server.fetch(key) }
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def call(server)
|
115
|
+
callable.call(server)
|
116
|
+
end
|
117
|
+
|
118
|
+
private
|
119
|
+
attr_reader :options
|
120
|
+
|
121
|
+
def key
|
122
|
+
options[:filter] || options[:select] || all
|
123
|
+
end
|
124
|
+
|
125
|
+
def all
|
126
|
+
->(server) { :all }
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module Capistrano
|
2
|
+
class Configuration
|
3
|
+
class Servers
|
4
|
+
class RoleFilter
|
5
|
+
|
6
|
+
def initialize(required, available)
|
7
|
+
@required, @available = required, available
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.for(required, available)
|
11
|
+
new(required, available).roles
|
12
|
+
end
|
13
|
+
|
14
|
+
def roles
|
15
|
+
if required.include?(:all)
|
16
|
+
available
|
17
|
+
else
|
18
|
+
required.select { |name| available.include? name }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def required
|
25
|
+
Array(@required).flat_map(&:to_sym)
|
26
|
+
end
|
27
|
+
|
28
|
+
def available
|
29
|
+
if role_filter.any?
|
30
|
+
role_filter
|
31
|
+
else
|
32
|
+
@available
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def role_filter
|
37
|
+
env_filter | configuration_filter
|
38
|
+
end
|
39
|
+
|
40
|
+
def configuration_filter
|
41
|
+
ConfigurationFilter.new.roles
|
42
|
+
end
|
43
|
+
|
44
|
+
def env_filter
|
45
|
+
EnvFilter.new.roles
|
46
|
+
end
|
47
|
+
|
48
|
+
class ConfigurationFilter
|
49
|
+
|
50
|
+
def roles
|
51
|
+
if filter
|
52
|
+
Array(filter.fetch(:roles, [])).map(&:to_sym)
|
53
|
+
else
|
54
|
+
[]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def config
|
59
|
+
Configuration.env
|
60
|
+
end
|
61
|
+
|
62
|
+
def filter
|
63
|
+
config.fetch(:filter) || config.fetch(:select)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
class EnvFilter
|
69
|
+
|
70
|
+
def roles
|
71
|
+
if filter
|
72
|
+
filter.split(',').map(&:to_sym)
|
73
|
+
else
|
74
|
+
[]
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def filter
|
79
|
+
ENV['ROLES']
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -1,75 +1,70 @@
|
|
1
|
+
require 'set'
|
2
|
+
require_relative 'servers/role_filter'
|
1
3
|
module Capistrano
|
2
4
|
class Configuration
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
5
|
+
class Servers
|
6
|
+
include Enumerable
|
7
|
+
|
8
|
+
def add_host(host, properties={})
|
9
|
+
servers.add server(host).with(properties)
|
10
|
+
end
|
11
|
+
|
12
|
+
def add_role(role, hosts, options={})
|
13
|
+
Array(hosts).each { |host| add_host(host, options.merge(roles: role)) }
|
14
|
+
end
|
15
|
+
|
16
|
+
def roles_for(names)
|
17
|
+
options = extract_options(names)
|
18
|
+
fetch_roles(names, options)
|
19
|
+
end
|
20
|
+
|
21
|
+
def fetch_primary(role)
|
22
|
+
hosts = fetch(role)
|
23
|
+
hosts.find(&:primary) || hosts.first
|
24
|
+
end
|
25
|
+
|
26
|
+
def each
|
27
|
+
servers.each { |server| yield server }
|
10
28
|
end
|
11
29
|
|
12
|
-
|
13
|
-
# The options hash may include a :hosts option (which should specify
|
14
|
-
# an array of host names or ServerDefinition instances), a :roles
|
15
|
-
# option (specifying an array of roles), an :only option (specifying
|
16
|
-
# a hash of key/value pairs that any matching server must match), and
|
17
|
-
# an :exception option (like :only, but the inverse).
|
18
|
-
#
|
19
|
-
# Additionally, if the HOSTS environment variable is set, it will take
|
20
|
-
# precedence over any other options. Similarly, the ROLES environment
|
21
|
-
# variable will take precedence over other options. If both HOSTS and
|
22
|
-
# ROLES are given, HOSTS wins.
|
23
|
-
#
|
24
|
-
# Usage:
|
25
|
-
#
|
26
|
-
# # return all known servers
|
27
|
-
# servers = find_servers
|
28
|
-
#
|
29
|
-
# # find all servers in the app role that are not exempted from
|
30
|
-
# # deployment
|
31
|
-
# servers = find_servers :roles => :app,
|
32
|
-
# :except => { :no_release => true }
|
33
|
-
#
|
34
|
-
# # returns the given hosts, translated to ServerDefinition objects
|
35
|
-
# servers = find_servers :hosts => "jamis@example.host.com"
|
36
|
-
def find_servers(options={})
|
37
|
-
hosts = server_list_from(ENV['HOSTS'] || options[:hosts])
|
38
|
-
roles = role_list_from(ENV['ROLES'] || options[:roles] || self.roles.keys)
|
39
|
-
only = options[:only] || {}
|
40
|
-
except = options[:except] || {}
|
30
|
+
private
|
41
31
|
|
42
|
-
|
43
|
-
|
32
|
+
def server(host)
|
33
|
+
if host.is_a? Server
|
34
|
+
host
|
44
35
|
else
|
45
|
-
servers
|
46
|
-
servers = servers.select { |server| only.all? { |key,value| server.options[key] == value } }
|
47
|
-
servers = servers.reject { |server| except.any? { |key,value| server.options[key] == value } }
|
48
|
-
servers.uniq
|
36
|
+
servers.find { |server| server.matches?(host) } || Server.new(host)
|
49
37
|
end
|
50
38
|
end
|
51
39
|
|
52
|
-
|
40
|
+
def fetch(role)
|
41
|
+
servers.find_all { |server| server.has_role? role}
|
42
|
+
end
|
53
43
|
|
54
|
-
def
|
55
|
-
|
56
|
-
|
57
|
-
hosts.map { |s| String === s ? ServerDefinition.new(s.strip) : s }
|
44
|
+
def fetch_roles(required, options)
|
45
|
+
filter_roles = RoleFilter.for(required, available_roles)
|
46
|
+
select(servers_with_roles(filter_roles), options)
|
58
47
|
end
|
59
48
|
|
60
|
-
def
|
61
|
-
roles
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
49
|
+
def servers_with_roles(roles)
|
50
|
+
roles.flat_map { |role| fetch role }.uniq
|
51
|
+
end
|
52
|
+
|
53
|
+
def select(servers, options)
|
54
|
+
servers.select { |server| server.select?(options) }
|
55
|
+
end
|
56
|
+
|
57
|
+
def available_roles
|
58
|
+
servers.flat_map { |server| server.roles_array }.uniq
|
59
|
+
end
|
60
|
+
|
61
|
+
def servers
|
62
|
+
@servers ||= Set.new
|
68
63
|
end
|
69
64
|
|
70
|
-
def
|
71
|
-
|
65
|
+
def extract_options(array)
|
66
|
+
array.last.is_a?(::Hash) ? array.pop : {}
|
72
67
|
end
|
73
68
|
end
|
74
69
|
end
|
75
|
-
end
|
70
|
+
end
|
@@ -1,41 +1,95 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
require 'capistrano/configuration/connections'
|
5
|
-
require 'capistrano/configuration/execution'
|
6
|
-
require 'capistrano/configuration/loading'
|
7
|
-
require 'capistrano/configuration/namespaces'
|
8
|
-
require 'capistrano/configuration/roles'
|
9
|
-
require 'capistrano/configuration/servers'
|
10
|
-
require 'capistrano/configuration/variables'
|
11
|
-
|
12
|
-
require 'capistrano/configuration/actions/file_transfer'
|
13
|
-
require 'capistrano/configuration/actions/inspect'
|
14
|
-
require 'capistrano/configuration/actions/invocation'
|
1
|
+
require_relative 'configuration/question'
|
2
|
+
require_relative 'configuration/servers'
|
3
|
+
require_relative 'configuration/server'
|
15
4
|
|
16
5
|
module Capistrano
|
17
|
-
# Represents a specific Capistrano configuration. A Configuration instance
|
18
|
-
# may be used to load multiple recipe files, define and describe tasks,
|
19
|
-
# define roles, and set configuration variables.
|
20
6
|
class Configuration
|
21
|
-
# The logger instance defined for this configuration.
|
22
|
-
attr_accessor :logger
|
23
7
|
|
24
|
-
|
25
|
-
|
8
|
+
class << self
|
9
|
+
def env
|
10
|
+
@env ||= new
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def ask(key, default=nil)
|
15
|
+
question = Question.new(self, key, default)
|
16
|
+
set(key, question)
|
26
17
|
end
|
27
18
|
|
28
|
-
|
29
|
-
|
19
|
+
def set(key, value)
|
20
|
+
config[key] = value
|
21
|
+
end
|
22
|
+
|
23
|
+
def delete(key)
|
24
|
+
config.delete(key)
|
25
|
+
end
|
30
26
|
|
31
|
-
|
32
|
-
|
33
|
-
|
27
|
+
def fetch(key, default=nil, &block)
|
28
|
+
value = fetch_for(key, default, &block)
|
29
|
+
if value.respond_to?(:call)
|
30
|
+
set(key, value.call)
|
31
|
+
else
|
32
|
+
value
|
33
|
+
end
|
34
|
+
end
|
34
35
|
|
35
|
-
|
36
|
-
|
36
|
+
def role(name, hosts, options={})
|
37
|
+
servers.add_role(name, hosts, options)
|
38
|
+
end
|
39
|
+
|
40
|
+
def server(name, properties={})
|
41
|
+
servers.add_host(name, properties)
|
42
|
+
end
|
43
|
+
|
44
|
+
def roles_for(names)
|
45
|
+
servers.roles_for(names)
|
46
|
+
end
|
47
|
+
|
48
|
+
def primary(role)
|
49
|
+
servers.fetch_primary(role)
|
50
|
+
end
|
51
|
+
|
52
|
+
def backend
|
53
|
+
@backend ||= SSHKit
|
54
|
+
end
|
55
|
+
|
56
|
+
attr_writer :backend
|
57
|
+
|
58
|
+
def configure_backend
|
59
|
+
backend.configure do |sshkit|
|
60
|
+
sshkit.format = fetch(:format)
|
61
|
+
sshkit.output_verbosity = fetch(:log_level)
|
62
|
+
sshkit.default_env = fetch(:default_env)
|
63
|
+
sshkit.backend = fetch(:sshkit_backend, SSHKit::Backend::Netssh)
|
64
|
+
sshkit.backend.configure do |backend|
|
65
|
+
backend.pty = fetch(:pty)
|
66
|
+
backend.connection_timeout = fetch(:connection_timeout)
|
67
|
+
backend.ssh_options = fetch(:ssh_options) if fetch(:ssh_options)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def timestamp
|
73
|
+
@timestamp ||= Time.now.utc
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def servers
|
79
|
+
@servers ||= Servers.new
|
80
|
+
end
|
81
|
+
|
82
|
+
def config
|
83
|
+
@config ||= Hash.new
|
84
|
+
end
|
85
|
+
|
86
|
+
def fetch_for(key, default, &block)
|
87
|
+
if block_given?
|
88
|
+
config.fetch(key, &block)
|
89
|
+
else
|
90
|
+
config.fetch(key, default)
|
91
|
+
end
|
92
|
+
end
|
37
93
|
|
38
|
-
# Must mix last, because it hooks into previously defined methods
|
39
|
-
include Callbacks
|
40
94
|
end
|
41
95
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
load File.expand_path("../tasks/console.rake", __FILE__)
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Capistrano
|
2
|
+
module DSL
|
3
|
+
module Env
|
4
|
+
|
5
|
+
def configure_backend
|
6
|
+
env.configure_backend
|
7
|
+
end
|
8
|
+
|
9
|
+
def fetch(key, default=nil, &block)
|
10
|
+
env.fetch(key, default, &block)
|
11
|
+
end
|
12
|
+
|
13
|
+
def any?(key)
|
14
|
+
value = fetch(key)
|
15
|
+
if value && value.respond_to?(:any?)
|
16
|
+
value.any?
|
17
|
+
else
|
18
|
+
!fetch(key).nil?
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def set(key, value)
|
23
|
+
env.set(key, value)
|
24
|
+
end
|
25
|
+
|
26
|
+
def delete(key)
|
27
|
+
env.delete(key)
|
28
|
+
end
|
29
|
+
|
30
|
+
def ask(key, value)
|
31
|
+
env.ask(key, value)
|
32
|
+
end
|
33
|
+
|
34
|
+
def role(name, servers, options={})
|
35
|
+
env.role(name, servers, options)
|
36
|
+
end
|
37
|
+
|
38
|
+
def server(name, properties={})
|
39
|
+
env.server(name, properties)
|
40
|
+
end
|
41
|
+
|
42
|
+
def roles(*names)
|
43
|
+
env.roles_for(names)
|
44
|
+
end
|
45
|
+
|
46
|
+
def primary(role)
|
47
|
+
env.primary(role)
|
48
|
+
end
|
49
|
+
|
50
|
+
def env
|
51
|
+
Configuration.env
|
52
|
+
end
|
53
|
+
|
54
|
+
def release_timestamp
|
55
|
+
env.timestamp.strftime("%Y%m%d%H%M%S")
|
56
|
+
end
|
57
|
+
|
58
|
+
def asset_timestamp
|
59
|
+
env.timestamp.strftime("%Y%m%d%H%M.%S")
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|