baptize 0.0.8 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- ZDA4YWUxNDAwNTlmOTQ3MTRkMzllOGVmYjZmMTIyMjIyYjlhZTQzMg==
5
- data.tar.gz: !binary |-
6
- OTNjN2Q2OTA2MWUwYTg3NGUzZWI3NDM2NDM2MWUwMzBiNTU2MTEzYw==
7
- !binary "U0hBNTEy":
8
- metadata.gz: !binary |-
9
- Y2MzN2JhNzQwN2RlMjI4YjNmYTVlOWYyZmYwM2ZjYjc4Y2RiNWYxNGRmOWIy
10
- ZWUxZmM3Mzc2MzJhMDZjZWYwOTNiYzcxOTc5OWI4NTQ0ZDQ0MjA3ZDE5OGUx
11
- ODJjZTgyNzcwNWIyOWJlNTFjOGI5NzNkMjE4Y2Q5MDM0MTk1ZWQ=
12
- data.tar.gz: !binary |-
13
- ZmMwZWE5OTQ2ZjVjNTliNTFjMjBmYjIxMTA0MmVhNzRlOTA0YzkxNzQ0MDZk
14
- ZDIyNzZjNDdiNGZlOGZiMzY2YTQ1YWM4YTFjOTBhNGE0NmI3MzdmNzA5MTQ2
15
- NDE5N2FhMmYwM2U4YmVkOGZiOTNjYzY4MmE0YTUzZTIwYTkwNzc=
2
+ SHA1:
3
+ metadata.gz: 6a940dc1a55b7aa62c6b41fe6134e36024d4e713
4
+ data.tar.gz: 2ef97b29ab2151e6d59b7a31ed2c2648189a594d
5
+ SHA512:
6
+ metadata.gz: 4ffae4ac6b4ccd2101d465e0aef62134768a05c3ce1e64227871d636ac53c471154d2f374c254f7d50c75acc5e4d3e18302109149e341166fa3fc3af5187c33d
7
+ data.tar.gz: 28b85c6a1f3a1038d0b462084544d7a564be7b99f968ebbb853dea98a361cdb0264a4bf0f4f2fa792914974113a98b306b40099ddbb239185dc211f497761c12
data/bin/baptize ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../lib")
3
+ require 'baptize'
4
+ Baptize::Application.new.run
data/lib/baptize.rb CHANGED
@@ -1,21 +1,28 @@
1
+ require 'rake'
2
+ require 'sshkit'
3
+ require 'capistrano/application'
4
+ require 'capistrano/dsl'
5
+ require 'capistrano/dsl/env'
6
+ require 'baptize/version'
7
+ require 'baptize/registry'
8
+ require 'baptize/package_definition'
9
+ require 'baptize/execution_scope'
10
+ require 'baptize/verification_failure'
11
+ require 'baptize/plugins/verifications'
12
+ require 'baptize/plugins/execution'
13
+ require 'baptize/plugins/apt'
1
14
  require 'baptize/dsl'
2
- require 'baptize/install'
3
- require 'baptize/helpers'
4
- Dir.glob(File.join(File.dirname(__FILE__), "baptize/plugins/**/*.rb")).each do |f|
5
- require f
6
- end
15
+ require 'baptize/application'
7
16
 
8
- Capistrano::Configuration.instance(:must_exist).load do
9
- class << self
10
- include Capistrano::Baptize::DSL
11
- include Capistrano::Baptize::Helpers
12
- Capistrano::Baptize::Plugins.constants.collect do |const_name|
13
- Capistrano::Baptize::Plugins.const_get(const_name)
14
- end.select do |const|
15
- const.class == Module
16
- end.each do |m|
17
- include m
18
- end
19
- end
20
- Capistrano::Baptize.install(self)
21
- end
17
+ Baptize::Registry.plugins << Capistrano::DSL::Env
18
+ Baptize::Registry.plugins << Baptize::Plugins::Verifications
19
+ Baptize::Registry.plugins << Baptize::Plugins::Execution
20
+ Baptize::Registry.plugins << Baptize::Plugins::Apt
21
+
22
+ extend Capistrano::DSL
23
+ extend Baptize::DSL
24
+
25
+ set_if_empty :logger, Proc.new { Baptize::Registry.logger }
26
+ set_if_empty :dry_run, true
27
+ set_if_empty :use_sudo, true
28
+ set_if_empty :ssh_verbose, !!ENV['VERBOSE']
@@ -0,0 +1,101 @@
1
+ module Baptize
2
+ class Application < Rake::Application
3
+
4
+ def initialize
5
+ super
6
+ @rakefiles = %w(bapfile Bapfile bapfile.rb Bapfile.rb)
7
+ Rake.application = self
8
+ require 'baptize/rake'
9
+ end
10
+
11
+ def name
12
+ "baptize"
13
+ end
14
+
15
+ def sort_options(options)
16
+ super.push(version, dry_run, roles, hostfilter)
17
+ end
18
+
19
+ def handle_options
20
+ options.rakelib = ['rakelib']
21
+ options.trace_output = $stderr
22
+
23
+ OptionParser.new do |opts|
24
+ opts.banner = "Baptize prepares your servers"
25
+ opts.separator ""
26
+ opts.separator "Show available tasks:"
27
+ opts.separator " bundle exec baptize -T"
28
+ opts.separator ""
29
+ opts.separator "Invoke (or simulate invoking) a task:"
30
+ opts.separator " bundle exec baptize [--dry-run] TASK"
31
+ opts.separator ""
32
+ opts.separator "Advanced options:"
33
+
34
+ opts.on_tail("-h", "--help", "-H", "Display this help message.") do
35
+ puts opts
36
+ exit
37
+ end
38
+
39
+ standard_rake_options.each { |args| opts.on(*args) }
40
+ opts.environment('RAKEOPT')
41
+ end.parse!
42
+ end
43
+
44
+
45
+ def display_error_message(ex)
46
+ unless options.backtrace
47
+ if (loc = Rake.application.find_rakefile_location)
48
+ whitelist = (@imported.dup << loc[0]).map{|f| File.absolute_path(f, loc[1])}
49
+ pattern = %r@^(?!#{whitelist.map{|p| Regexp.quote(p)}.join('|')})@
50
+ Rake.application.options.suppress_backtrace_pattern = pattern
51
+ end
52
+ trace "(Backtrace restricted to imported tasks)"
53
+ end
54
+ super
55
+ end
56
+
57
+ private
58
+
59
+ def version
60
+ ['--version', '-V',
61
+ "Display the program version.",
62
+ lambda { |_value|
63
+ require 'capistrano/version'
64
+ puts "Baptize Version: #{Baptize::VERSION} (Capistrano Version: #{Capistrano::VERSION}, Rake Version: #{RAKEVERSION})"
65
+ exit
66
+ }
67
+ ]
68
+ end
69
+
70
+ def dry_run
71
+ ['--dry-run', '-n',
72
+ "Do a dry run without executing actions",
73
+ lambda { |_value|
74
+ raise "TODO: Port this"
75
+ Configuration.env.set(:sshkit_backend, SSHKit::Backend::Printer)
76
+ }
77
+ ]
78
+ end
79
+
80
+ def roles
81
+ ['--roles ROLES', '-r',
82
+ "Run SSH commands only on hosts matching these roles",
83
+ lambda { |value|
84
+ raise "TODO: Port this"
85
+ Configuration.env.add_cmdline_filter(:role, value)
86
+ }
87
+ ]
88
+ end
89
+
90
+ def hostfilter
91
+ ['--hosts HOSTS', '-z',
92
+ "Run SSH commands only on matching hosts",
93
+ lambda { |value|
94
+ raise "TODO: Port this"
95
+ Configuration.env.add_cmdline_filter(:host, value)
96
+ }
97
+ ]
98
+ end
99
+
100
+ end
101
+ end
data/lib/baptize/dsl.rb CHANGED
@@ -1,198 +1,13 @@
1
- module Capistrano
2
- module Baptize
1
+ module Baptize
3
2
 
4
- # Raised by verifiers, if conditions aren't met
5
- class VerificationFailure < RuntimeError
3
+ module DSL
4
+ def package(package_name, &config_block)
5
+ Registry.define_package(package_name, &config_block)
6
6
  end
7
7
 
8
- class PolicyDefinition
9
- attr_reader :role, :dependencies
10
-
11
- def initialize(role, parent)
12
- @role = role
13
- @dependencies = []
14
- @parent = parent
15
- end
16
-
17
- def respond_to?(sym, include_priv = false)
18
- super || @parent.respond_to?(sym, include_priv)
19
- end
20
-
21
- def method_missing(sym, *args, &block)
22
- if @parent.respond_to?(sym)
23
- @parent.send(sym, *args, &block)
24
- else
25
- super
26
- end
27
- end
28
-
29
- def full_name
30
- "baptize:policies:#{role}"
31
- end
32
-
33
- def requires(*tasks)
34
- Array(tasks).flatten.each do |name|
35
- @dependencies << (name.kind_of?(Symbol) ? "baptize:packages:#{name}" : name.to_s)
36
- end
37
- end
38
- end
39
-
40
- class PackageDefinition
41
- attr_reader :name, :description, :dependencies, :install_block, :verify_block, :before_block, :after_block
42
-
43
- def initialize(name, parent)
44
- @name = name
45
- @parent = parent
46
- @dependencies = []
47
- @install_block = nil
48
- @verify_block = nil
49
- @before_block = nil
50
- @after_block = nil
51
- end
52
-
53
- def respond_to?(sym, include_priv = false)
54
- super || @parent.respond_to?(sym, include_priv)
55
- end
56
-
57
- def method_missing(sym, *args, &block)
58
- if @parent.respond_to?(sym)
59
- @parent.send(sym, *args, &block)
60
- else
61
- super
62
- end
63
- end
64
-
65
- def full_name
66
- "baptize:packages:#{name}"
67
- end
68
-
69
- def description(desc = nil)
70
- @description = desc unless desc.nil?
71
- @description
72
- end
73
- alias_method :desc, :description
74
-
75
- def requires(*tasks)
76
- Array(tasks).flatten.each do |name|
77
- @dependencies << "baptize:packages:#{name}"
78
- end
79
- end
80
-
81
- def before(&block)
82
- @before_block = block
83
- end
84
-
85
- def after(&block)
86
- @after_block = block
87
- end
88
-
89
- def install(&block)
90
- @install_block = block
91
- end
92
-
93
- def verify(&block)
94
- @verify_block = block
95
- end
96
- end
97
-
98
- module DSL
99
-
100
- def self.packages_installed
101
- @packages_installed ||= []
102
- end
103
-
104
- def self.packages_installed=(value)
105
- @packages_installed = value
106
- end
107
-
108
- def self.policies
109
- @policies ||= {}
110
- end
111
-
112
- def policy(role_names, &block)
113
- Array(role_names).flatten.each do |role_name|
114
- if Capistrano::Baptize::DSL.policies[role_name]
115
- policy = Capistrano::Baptize::DSL.policies[role_name]
116
- policy.instance_eval &block
117
- else
118
- Capistrano::Baptize::DSL.policies[role_name] = PolicyDefinition.new(role_name, self)
119
- policy = Capistrano::Baptize::DSL.policies[role_name]
120
- policy.instance_eval &block
121
- namespace :baptize do
122
- namespace :policies do
123
- desc "Configures #{policy.role}"
124
- task policy.role do
125
- logger.info "Applying policy #{policy.role}"
126
- # TODO: This is maybe not ideal, as multiple roles would be applied in sequence, not parallel.
127
- # Also, I'm not sure if they would be skipped for later roles, if already run for an earlier one
128
- Capistrano::Baptize::DSL.packages_installed = []
129
- for_roles policy.role do
130
- policy.dependencies.each do |task_name|
131
- find_and_execute_task(task_name)
132
- end
133
- end
134
- end
135
- end
136
- end
137
- after "baptize:install", policy.full_name
138
- end
139
- end
140
- end
141
-
142
- def package(package_name, &block)
143
- package = PackageDefinition.new(package_name, self)
144
- package.instance_eval &block
145
- namespace :baptize do
146
- namespace :packages do
147
- desc "[package] #{package.description}" if package.description
148
- task package.name do
149
- # Cap doesn't track if a task has already been applied - we need to do this
150
- unless Capistrano::Baptize::DSL.packages_installed.include? package.name
151
- Capistrano::Baptize::DSL.packages_installed << package.name
152
- instance_eval(&package.before_block) if package.before_block
153
- if package.verify_block
154
- logger.debug "Verifying package #{package.name}"
155
- already_installed = begin
156
- instance_eval(&package.verify_block)
157
- true
158
- rescue VerificationFailure => err
159
- false
160
- end
161
- if already_installed && !ENV['FORCE_INSTALL']
162
- logger.info "Skipping previously installed package #{package.name}"
163
- else
164
- if already_installed && ENV['FORCE_INSTALL']
165
- logger.important "Force installing previously installed package #{package.name}"
166
- else
167
- logger.info "Installing package #{package.name}"
168
- end
169
- instance_eval(&package.install_block)
170
- instance_eval(&package.verify_block)
171
- end
172
- elsif package.install_block
173
- # logger.important "WARNING: `verify` block not implemented for package #{package.name}."
174
- logger.info "Installing package #{package.name}"
175
- instance_eval(&package.install_block)
176
- else
177
- # logger.important "WARNING: `install` block not implemented for package #{package.name}."
178
- logger.info "Nothing to do for package #{package.name}"
179
- end
180
- instance_eval(&package.after_block) if package.after_block
181
- end
182
- end
183
- end
184
- end
185
- if ENV['SKIP_DEPENDENCIES']
186
- before package.full_name do
187
- logger.important "Skipping dependencies for package #{package.name}"
188
- end
189
- else
190
- package.dependencies.each do |task_name|
191
- before package.full_name, task_name
192
- end
193
- end
194
- end
8
+ def policy(role, *packages)
9
+ Registry.define_policy role, [packages].flatten
195
10
  end
11
+ end # module DSL
196
12
 
197
- end
198
- end
13
+ end # module Baptize
@@ -0,0 +1,7 @@
1
+ module Baptize
2
+
3
+ class ExecutionScope
4
+ # This is emoty .. find all the meat in plugins/
5
+ end
6
+
7
+ end # module Baptize
@@ -0,0 +1,105 @@
1
+ module Baptize
2
+
3
+ class PackageDefinition
4
+ attr_reader :name, :description, :dependencies, :install_block, :verify_block, :before_block, :after_block
5
+
6
+ def initialize(name, execution_scope, registry)
7
+ @name = name
8
+ @execution_scope = execution_scope
9
+ @registry = registry
10
+ @dependencies = []
11
+ @install_block = nil
12
+ @verify_block = nil
13
+ @before_block = nil
14
+ @after_block = nil
15
+ end
16
+
17
+ def execute
18
+ unless @registry.packages_executed.include? full_name
19
+ @registry.packages_executed << full_name
20
+ @registry.before(self).each do |task|
21
+ task.call
22
+ end
23
+ instance_eval(&before_block) if self.before_block
24
+ if verify_block
25
+ logger.debug "Verifying package #{name}"
26
+ already_installed = begin
27
+ instance_eval(&verify_block)
28
+ true
29
+ rescue VerificationFailure
30
+ false
31
+ end
32
+ if already_installed && !ENV['FORCE_INSTALL']
33
+ logger.info "Skipping previously installed package #{name}"
34
+ else
35
+ if already_installed && ENV['FORCE_INSTALL']
36
+ logger.important "Force installing previously installed package #{name}"
37
+ else
38
+ logger.info "Installing package #{name}"
39
+ end
40
+ instance_eval(&install_block)
41
+ instance_eval(&verify_block)
42
+ end
43
+ elsif install_block
44
+ # logger.important "WARNING: `verify` block not implemented for package #{name}."
45
+ logger.info "Installing package #{name}"
46
+ instance_eval(&install_block)
47
+ else
48
+ # logger.important "WARNING: `install` block not implemented for package #{name}."
49
+ logger.info "Nothing to do for package #{name}"
50
+ end
51
+ instance_eval(&after_block) if after_block
52
+ @registry.after(self).each do |task|
53
+ task.call
54
+ end
55
+ end
56
+ end
57
+
58
+ def respond_to?(sym, include_priv = false)
59
+ super || @execution_scope.any?(sym) || @execution_scope.respond_to?(sym)
60
+ end
61
+
62
+ def method_missing(sym, *args, &block)
63
+ if @execution_scope.any?(sym)
64
+ @execution_scope.fetch(sym)
65
+ elsif @execution_scope.respond_to?(sym)
66
+ @execution_scope.send(sym, *args, &block)
67
+ else
68
+ super
69
+ end
70
+ end
71
+
72
+ def full_name
73
+ name.to_s
74
+ end
75
+
76
+ def description(desc = nil)
77
+ @description = desc unless desc.nil?
78
+ @description
79
+ end
80
+ alias_method :desc, :description
81
+
82
+ def requires(*tasks)
83
+ Array(tasks).flatten.each do |name|
84
+ @dependencies << name
85
+ end
86
+ end
87
+
88
+ def before(&block)
89
+ @before_block = block
90
+ end
91
+
92
+ def after(&block)
93
+ @after_block = block
94
+ end
95
+
96
+ def install(&block)
97
+ @install_block = block
98
+ end
99
+
100
+ def verify(&block)
101
+ @verify_block = block
102
+ end
103
+ end
104
+
105
+ end # module Baptize
@@ -1,22 +1,23 @@
1
- module Capistrano
2
- module Baptize
3
- module Plugins
4
- module Apt
1
+ module Baptize
5
2
 
6
- def apt(packages, options = {})
7
- command = options[:dependencies_only] ? 'build-dep' : 'install'
8
- noninteractive = "env DEBCONF_TERSE='yes' DEBIAN_PRIORITY='critical' DEBIAN_FRONTEND=noninteractive"
9
- packages = Array(packages).flatten.map{|p| p.to_s.shellescape }.join(" ")
10
- invoke_command "#{noninteractive} apt-get --assume-yes --force-yes --show-upgraded --quiet #{command} #{packages}"
11
- end
3
+ module Plugins
12
4
 
13
- def has_apt(packages)
14
- Array(packages).flatten.each do |p|
15
- raise VerificationFailure, "apt package #{p} not installed" unless remote_assert("dpkg --status #{p.to_s.shellescape} | grep 'ok installed'")
16
- end
17
- end
5
+ module Apt
18
6
 
7
+ def apt(packages, options = {})
8
+ command = options[:dependencies_only] ? 'build-dep' : 'install'
9
+ noninteractive = "env DEBCONF_TERSE='yes' DEBIAN_PRIORITY='critical' DEBIAN_FRONTEND=noninteractive"
10
+ packages = Array(packages).flatten.map{|p| p.to_s.shellescape }.join(" ")
11
+ remote_execute "#{noninteractive} apt-get --assume-yes --force-yes --show-upgraded --quiet #{command} #{packages}"
19
12
  end
13
+
14
+ def has_apt(packages)
15
+ Array(packages).flatten.each do |p|
16
+ raise VerificationFailure, "apt package #{p} not installed" unless remote_assert("dpkg --status #{p.to_s.shellescape} | grep 'ok installed'")
17
+ end
18
+ end
19
+
20
20
  end
21
- end
22
- end
21
+
22
+ end # module Plugins
23
+ end # module Baptize
@@ -0,0 +1,24 @@
1
+ require 'capistrano/dsl/env'
2
+
3
+ module Baptize
4
+ module Plugins
5
+ module Env
6
+
7
+ include Capistrano::DSL::Env
8
+
9
+ def respond_to?(sym, include_priv = false)
10
+ super || any?(sym)
11
+ end
12
+
13
+ def method_missing(sym, *args, &block)
14
+ if any?(sym)
15
+ fetch(sym)
16
+ else
17
+ super
18
+ end
19
+ end
20
+
21
+ end
22
+
23
+ end # module Plugins
24
+ end # module Baptize
@@ -0,0 +1,60 @@
1
+ module Baptize
2
+
3
+ module Plugins
4
+
5
+ module Execution
6
+
7
+ # logs the command then executes it locally.
8
+ # returns the command output as a string
9
+ def run_locally(cmd)
10
+ if fetch(:dry_run)
11
+ return logger.debug "executing locally: #{cmd.inspect}"
12
+ end
13
+ logger.trace "executing locally: #{cmd.inspect}" if logger
14
+ output_on_stdout = nil
15
+ elapsed = Benchmark.realtime do
16
+ output_on_stdout = `#{cmd}`
17
+ end
18
+ if $?.to_i > 0 # $? is command exit code (posix style)
19
+ raise ArgumentError, "Command #{cmd} returned status code #{$?}"
20
+ end
21
+ logger.trace "command finished in #{(elapsed * 1000).round}ms" if logger
22
+ output_on_stdout
23
+ end
24
+
25
+ def remote_execute(*args)
26
+ call_current_ssh_connection :execute, *args
27
+ end
28
+
29
+ def remote_capture(*args)
30
+ call_current_ssh_connection :capture, *args
31
+ end
32
+
33
+ def remote_assert(command)
34
+ command = Array(command).flatten.map {|c| "#{c} > /dev/null 2> /dev/null" }.join(" && ")
35
+ call_current_ssh_connection :test, command
36
+ end
37
+
38
+ private
39
+ def call_current_ssh_connection(action, *args)
40
+ ssh = fetch(:current_ssh_connection)
41
+ old_verbosity = nil
42
+ if fetch(:ssh_verbose)
43
+ old_verbosity = SSHKit.config.output_verbosity
44
+ SSHKit.config.output_verbosity = Logger::DEBUG
45
+ end
46
+ begin
47
+ if fetch(:use_sudo)
48
+ ssh.send(action, :sudo, *args)
49
+ else
50
+ ssh.send(action, *args)
51
+ end
52
+ ensure
53
+ SSHKit.config.output_verbosity = old_verbosity if old_verbosity
54
+ end
55
+ end
56
+
57
+ end
58
+
59
+ end # module Plugins
60
+ end # module Baptize
@@ -0,0 +1,38 @@
1
+ module Baptize
2
+
3
+ module Plugins
4
+
5
+ module Variables
6
+
7
+ def set(name, value)
8
+ @variables ||= {}
9
+ @variables[name.to_sym] = value
10
+ end
11
+
12
+ def fetch(name)
13
+ if @variables
14
+ value = @variables[name.to_sym]
15
+ if value.kind_of?(Proc)
16
+ value.call
17
+ else
18
+ value
19
+ end
20
+ end
21
+ end
22
+
23
+ def respond_to?(sym, include_priv = false)
24
+ super || (@variables && @variables[sym])
25
+ end
26
+
27
+ def method_missing(sym, *args, &block)
28
+ if @variables && @variables[sym]
29
+ fetch(sym)
30
+ else
31
+ super
32
+ end
33
+ end
34
+
35
+ end
36
+
37
+ end # module Plugins
38
+ end # module Baptize
@@ -0,0 +1,11 @@
1
+ module Baptize
2
+ module Plugins
3
+
4
+ module Verifications
5
+ def fail_verification
6
+ raise VerificationFailure.new
7
+ end
8
+ end
9
+
10
+ end
11
+ end
@@ -0,0 +1,21 @@
1
+ Rake.application.in_namespace('baptize') do
2
+
3
+ Rake::Task.define_task(:list) do
4
+ Baptize::Registry.packages.values.each do |package|
5
+ puts [package.name, "\t", package.description].join
6
+ end
7
+ end
8
+
9
+ Rake::Task.define_task(:apply) do
10
+ Baptize::Registry.policies.keys.each do |role|
11
+ on roles(role), in: :parallel do |host|
12
+ Baptize::Registry.apply_policy role, host, self
13
+ end
14
+ end
15
+ end
16
+
17
+ end
18
+
19
+ Rake::Task.define_task(:default) do
20
+ Rake::Task['baptize:list'].invoke
21
+ end
@@ -0,0 +1,91 @@
1
+ module Baptize
2
+
3
+ module Registry
4
+
5
+ def self.plugins
6
+ @plugins ||= []
7
+ end
8
+
9
+ def self.execution_scope
10
+ unless @execution_scope
11
+ @execution_scope = ExecutionScope.new
12
+ plugins.each do |plugin_module|
13
+ (class << @execution_scope ; self ; end).send(:include, plugin_module)
14
+ end
15
+ end
16
+ @execution_scope
17
+ end
18
+
19
+ def self.logger
20
+ @logger ||= ::Logger.new(STDOUT)
21
+ end
22
+
23
+ def self.packages
24
+ @packages ||= {}
25
+ end
26
+
27
+ def self.packages_executed
28
+ @packages_executed ||= []
29
+ end
30
+
31
+ def self.before(subject_name, other_task=nil, &block)
32
+ @befores ||= {}
33
+ @befores[subject_name] ||= []
34
+ if other_task
35
+ task = packages[other_task] if other_task.kind_of?(String)
36
+ raise "Didn't find a package by that name" if task.nil?
37
+ @befores[subject_name] << task.method(:execute)
38
+ elsif block_given?
39
+ @befores[subject_name] << block
40
+ end
41
+ @befores[subject_name]
42
+ end
43
+
44
+ def self.after(subject_name, other_task=nil, &block)
45
+ @afters ||= {}
46
+ @afters[subject_name] ||= []
47
+ if other_task
48
+ task = packages[other_task] if other_task.kind_of?(String)
49
+ raise "Didn't find a package by that name" if task.nil?
50
+ @afters[subject_name] << task.method(:execute)
51
+ elsif block_given?
52
+ @afters[subject_name] << block
53
+ end
54
+ @afters[subject_name]
55
+ end
56
+
57
+ def self.define_package(package_name, &config_block)
58
+ package = PackageDefinition.new(package_name, self.execution_scope, self)
59
+ packages[package.full_name] = package
60
+ package.instance_eval(&config_block)
61
+ if ENV['SKIP_DEPENDENCIES']
62
+ before package.full_name do
63
+ logger.important "Skipping dependencies for package #{package.name}"
64
+ end
65
+ else
66
+ package.dependencies.each do |task_name|
67
+ before package.full_name, task_name
68
+ end
69
+ end
70
+ end
71
+
72
+ def self.policies
73
+ @policies ||= {}
74
+ end
75
+
76
+ def self.define_policy(role, package_names)
77
+ policies[role.to_sym] = package_names.map(&:to_s)
78
+ end
79
+
80
+ def self.apply_policy(role, host, ssh_connection)
81
+ execution_scope.set :current_host, host
82
+ execution_scope.set :current_ssh_connection, ssh_connection
83
+ policies[role.to_sym].each do |package_name|
84
+ raise "No package '#{package_name}'" unless packages[package_name]
85
+ packages[package_name].execute
86
+ end
87
+ end
88
+
89
+ end # module Registry
90
+
91
+ end # module Baptize
@@ -0,0 +1,4 @@
1
+ module Baptize
2
+ class VerificationFailure < Exception
3
+ end
4
+ end
@@ -0,0 +1,3 @@
1
+ module Baptize
2
+ VERSION = "0.1.1"
3
+ end # module Baptize
metadata CHANGED
@@ -1,47 +1,68 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: baptize
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Troels Knak-Nielsen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-07 00:00:00.000000000 Z
11
+ date: 2016-01-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: capistrano
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 2.15.5
19
+ version: '3.4'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 2.15.5
26
+ version: '3.4'
27
+ - !ruby/object:Gem::Dependency
28
+ name: jeweler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.0'
27
41
  description: Baptize is an extension for Capistrano, that allows for server provisioning
28
42
  email:
29
43
  - troels@knak-nielsen.dk
30
- executables: []
44
+ executables:
45
+ - baptize
31
46
  extensions: []
32
47
  extra_rdoc_files:
33
48
  - README.markdown
34
49
  files:
50
+ - README.markdown
51
+ - bin/baptize
35
52
  - lib/baptize.rb
53
+ - lib/baptize/application.rb
36
54
  - lib/baptize/dsl.rb
37
- - lib/baptize/helpers.rb
38
- - lib/baptize/install.rb
55
+ - lib/baptize/execution_scope.rb
56
+ - lib/baptize/package_definition.rb
39
57
  - lib/baptize/plugins/apt.rb
40
- - lib/baptize/plugins/base.rb
41
- - lib/baptize/plugins/gem.rb
42
- - lib/baptize/plugins/pecl.rb
43
- - lib/baptize/plugins/transfer.rb
44
- - README.markdown
58
+ - lib/baptize/plugins/env.rb
59
+ - lib/baptize/plugins/execution.rb
60
+ - lib/baptize/plugins/variables.rb
61
+ - lib/baptize/plugins/verifications.rb
62
+ - lib/baptize/rake.rb
63
+ - lib/baptize/registry.rb
64
+ - lib/baptize/verification_failure.rb
65
+ - lib/baptize/version.rb
45
66
  homepage: http://github.com/troelskn/baptize
46
67
  licenses:
47
68
  - MIT
@@ -52,17 +73,17 @@ require_paths:
52
73
  - lib
53
74
  required_ruby_version: !ruby/object:Gem::Requirement
54
75
  requirements:
55
- - - ! '>='
76
+ - - ">="
56
77
  - !ruby/object:Gem::Version
57
78
  version: '0'
58
79
  required_rubygems_version: !ruby/object:Gem::Requirement
59
80
  requirements:
60
- - - ! '>='
81
+ - - ">="
61
82
  - !ruby/object:Gem::Version
62
83
  version: '0'
63
84
  requirements: []
64
85
  rubyforge_project:
65
- rubygems_version: 2.0.7
86
+ rubygems_version: 2.5.1
66
87
  signing_key:
67
88
  specification_version: 4
68
89
  summary: Baptize is an extension for Capistrano, that allows for server provisioning
@@ -1,110 +0,0 @@
1
- module Capistrano
2
- module Baptize
3
-
4
- module Helpers
5
-
6
- def for_roles(*roles, &block)
7
- old_env_roles = ENV['ROLES']
8
- ENV['ROLES'] = Array(roles).flatten.map(&:to_s).join(",")
9
- logger.info "Invoking for roles: #{ENV['ROLES']}"
10
- block.call
11
- ensure
12
- ENV['ROLES'] = old_env_roles
13
- end
14
-
15
- def asset_path(asset)
16
- File.join("#{capistrano_path}/assets", asset)
17
- end
18
-
19
- def remote_assert(command)
20
- results = []
21
- pipeline = Array(command).flatten.map {|c| "#{c} > /dev/null 2> /dev/null ; if [ $? -eq 0 ] ; then echo -n 'true' ; else echo -n 'false' ; fi" }.join(" ; ")
22
- invoke_command(pipeline) do |ch, stream, out|
23
- results << (out == 'true')
24
- end
25
- results.all?
26
- end
27
-
28
- # Runs a rake command remotely
29
- def remote_rake(rake_command, options = {})
30
- options = {:bundle_cmd => fetch(:bundle_cmd, "bundle"), :current_path => current_path, :rails_env => rails_env, :env => {}, :pty => false}.merge(options)
31
- command = ""
32
- command << "cd #{options[:current_path]} && " if options[:current_path]
33
- command << "RAILS_ENV=#{options[:rails_env]} " if options[:rails_env]
34
- options[:env].each do |k,v|
35
- command << "#{k}=#{v.shellescape} "
36
- end
37
- if options[:bundle_cmd]
38
- command << "#{options[:bundle_cmd]} exec rake #{rake_command}"
39
- else
40
- command << "rake #{rake_command}"
41
- end
42
- options[:norun] ? command : run(command, :pty => options[:pty])
43
- end
44
-
45
- # logs the command then executes it locally.
46
- # returns the command output as a string
47
- def run_locally(cmd)
48
- if dry_run
49
- return logger.debug "executing locally: #{cmd.inspect}"
50
- end
51
- logger.trace "executing locally: #{cmd.inspect}" if logger
52
- output_on_stdout = nil
53
- elapsed = Benchmark.realtime do
54
- output_on_stdout = `#{cmd}`
55
- end
56
- if $?.to_i > 0 # $? is command exit code (posix style)
57
- raise Capistrano::LocalArgumentError, "Command #{cmd} returned status code #{$?}"
58
- end
59
- logger.trace "command finished in #{(elapsed * 1000).round}ms" if logger
60
- output_on_stdout
61
- end
62
-
63
- def current_role
64
- ENV['ROLES'].to_sym
65
- end
66
-
67
- def load_configuration(environment)
68
- top.instance_eval do
69
- if environment == :all
70
- Dir.glob("#{capistrano_path}/config/**/*.rb").each do |conf|
71
- load(conf)
72
- end
73
- else
74
- Dir.glob("#{capistrano_path}/config/#{environment}.rb").each do |conf|
75
- load(conf)
76
- end
77
- Dir.glob("#{capistrano_path}/config/#{environment}/**/*.rb").each do |conf|
78
- load(conf)
79
- end
80
- end
81
- if fetch(:use_sudo, true)
82
- default_run_options[:shell] = 'sudo bash'
83
- else
84
- default_run_options[:shell].gsub!(/^sudo /, "")
85
- end
86
- end
87
- end
88
-
89
- def md5_of_file(path, md5)
90
- remote_assert "test $(md5sum #{path.shellescape} | cut -f1 -d' ') = #{md5.shellescape}"
91
- end
92
-
93
- def escape_sed_arg(s)
94
- s.gsub("'", "'\\\\''").gsub("\n", '\n').gsub("/", "\\\\/").gsub('&', '\\\&')
95
- end
96
-
97
- def replace_text(pattern, replacement, path)
98
- run "sed -i 's/#{escape_sed_arg(pattern)}/#{escape_sed_arg(replacement)}/g' #{path.shellescape}"
99
- end
100
-
101
- def render(path, locals = {})
102
- require 'erb'
103
- require 'ostruct'
104
- ERB.new(File.read(path)).result(locals.kind_of?(Binding) ? locals : OpenStruct.new(locals).instance_eval { binding })
105
- end
106
-
107
- end
108
-
109
- end
110
- end
@@ -1,87 +0,0 @@
1
- module Capistrano
2
- module Baptize
3
-
4
- # Defines all baptize top-level tasks
5
- def self.install(scope)
6
- scope.instance_eval do
7
- set(:root_path) { File.expand_path(Dir.pwd) }
8
- set(:capistrano_path) { "#{root_path}/capistrano" }
9
-
10
- # Can't run this here, since Capfile might want to redefine
11
- # load_configuration :roles
12
-
13
- namespace :baptize do
14
-
15
- desc "Loads baptize configuration files"
16
- task :load_configuration do
17
- top.load_configuration :baptize
18
- end
19
-
20
- task :default do
21
- install
22
- end
23
-
24
- desc "Configures all available policies"
25
- task :install do
26
- load_configuration
27
- end
28
-
29
- namespace :policies do
30
- desc "List available policies"
31
- task :default do
32
- load_configuration
33
- logger.info "Available policies:"
34
- tasks.flatten.each do |x|
35
- if x.kind_of?(Capistrano::TaskDefinition) && x.fully_qualified_name != "baptize:policies"
36
- name = x.fully_qualified_name.gsub(/^baptize:policies:/, "")
37
- policy = Capistrano::Baptize::DSL.policies[name.to_sym]
38
- logger.info "#{name}:"
39
- logger.info "-> servers:"
40
- top.roles[name.to_sym].servers.each do |s|
41
- logger.info "-> #{s}"
42
- end
43
- logger.info "-> dependencies:"
44
- policy.dependencies.each do |d|
45
- logger.info "-> #{d}"
46
- end
47
- end
48
- end
49
- end
50
- end # end namespace policies
51
- end # end namespace baptize
52
-
53
- namespace :ssh do
54
- desc "Describe available ssh connections"
55
- task :default do
56
- count = 1
57
- roles.each do |name,servers|
58
- servers.each do |host|
59
- puts "cap ssh:#{count} (#{name}) #{host}"
60
- count = count + 1
61
- end
62
- end
63
- end
64
-
65
- 1.upto(10).each do |num|
66
- task num.to_s.to_sym do
67
- count = 1
68
- roles.each do |name,servers|
69
- servers.each do |host|
70
- if count == num
71
- change_dir = exists?(:deploy_to) ? ("cd " + fetch(:deploy_to) + "/current ; ") : ""
72
- command = "ssh -i #{ssh_options[:keys]} #{user}@#{host} -t '#{change_dir}sudo su'"
73
- puts command
74
- exec command
75
- end
76
- count = count + 1
77
- end
78
- end
79
- end
80
- end
81
- end # end namespace ssh
82
-
83
- end
84
-
85
- end
86
- end
87
- end
@@ -1,46 +0,0 @@
1
- module Capistrano
2
- module Baptize
3
- module Plugins
4
- module Base
5
- def fail_verification(message = "Assertion failed")
6
- raise VerificationFailure, message
7
- end
8
-
9
- def has_file(path)
10
- remote_assert("test -e #{path.shellescape}") or fail_verification("Remote file #{path} does not exist")
11
- end
12
-
13
- def has_directory(path)
14
- remote_assert("test -d #{path.shellescape}") or fail_verification("Remote directory #{path} does not exist")
15
- end
16
-
17
- def matches_local(local_path, remote_path)
18
- raise VerificationFailure, "Couldn't find local file #{local_path}" unless ::File.exists?(local_path)
19
- require 'digest/md5'
20
- local_md5 = Digest::MD5.hexdigest(::File.read(local_path))
21
- md5_of_file(remote_path, local_md5) or fail_verification("Remote file #{remote_path} doesn't match local file #{local_path}")
22
- end
23
-
24
- def file_contains(path, text, options = {})
25
- options = {:mode => :text}.merge(options)
26
- if options[:mode] == :text
27
- command = Array(text.strip.split("\n")).flatten.map {|line| "grep --fixed-strings #{line.shellescape} #{path.shellescape}" }.join(" && ")
28
- elsif options[:mode] == :perl
29
- command = "grep --perl-regexp #{text.shellescape} #{path.shellescape}"
30
- else
31
- command = "grep --basic-regexp #{text.shellescape} #{path.shellescape}"
32
- end
33
- remote_assert command
34
- end
35
-
36
- def has_executable(path)
37
- remote_assert("which #{path.shellescape}") or fail_verification("No executable #{path} found")
38
- end
39
-
40
- def has_user(name)
41
- remote_assert("id -u #{name.to_s.shellescape}") or fail_verification("No user #{name}")
42
- end
43
- end
44
- end
45
- end
46
- end
@@ -1,26 +0,0 @@
1
- module Capistrano
2
- module Baptize
3
- module Plugins
4
- module Gem
5
-
6
- def install_gem(package_name, options = {})
7
- cmd = "gem install #{package_name}"
8
- cmd << " --version '#{options[:version]}'" if options[:version]
9
- cmd << " --source #{options[:source]}" if options[:source]
10
- cmd << " --install-dir #{options[:repository]}" if options[:repository]
11
- cmd << " --no-rdoc --no-ri" unless options[:build_docs]
12
- cmd << " --http-proxy #{options[:http_proxy]}" if options[:http_proxy]
13
- cmd << " -- #{options[:build_flags]}" if options[:build_flags]
14
- run "TERM= #{cmd}"
15
- end
16
-
17
- def has_gem(package_name, options = {})
18
- version = options[:version] ? "--version '#{options[:version]}'" : ''
19
- cmd = "gem list '#{package_name}' --installed #{version} > /dev/null"
20
- raise VerificationFailure, "Gem #{package_name} not installed" unless remote_assert cmd
21
- end
22
-
23
- end
24
- end
25
- end
26
- end
@@ -1,49 +0,0 @@
1
- module Capistrano
2
- module Baptize
3
- module Plugins
4
- module Pecl
5
-
6
- def pecl(package_name, options = {})
7
- package_version = options[:version]
8
- if package_version
9
- run "TERM= pecl install --alldeps #{package_name.shellescape}-#{package_version.shellescape}"
10
- else
11
- run "TERM= pecl install --alldeps #{package_name.shellescape}"
12
- end
13
- ini_file = ! options[:ini_file].nil?
14
- if ini_file
15
- if ini_file.is_a?(String)
16
- text = ini_file
17
- elsif ini_file.is_a?(Hash) && ini_file[:content]
18
- text = ini_file[:content]
19
- else
20
- text = "extension=#{package_name}.so"
21
- end
22
- if ini_file.is_a?(Hash) && ini_file[:path]
23
- path = ini_file[:path]
24
- else
25
- folder = "/etc/php5/conf.d"
26
- invoke_command("php --ini") do |ch, stream, out|
27
- if /Scan for additional .ini files in: (.*)/.match(out)
28
- folder = $1
29
- end
30
- end
31
- path = "#{folder}/#{package_name}.ini"
32
- end
33
- put(text, path)
34
- end
35
- end
36
-
37
- def has_pecl(package_name, options = {})
38
- package_version = options[:version]
39
- if package_version
40
- raise VerificationFailure, "PECL package #{package_name}-#{package_version} not installed" unless remote_assert "TERM= pecl list | grep \"^#{package_name.shellescape}\\\\s*#{package_version.shellescape}\""
41
- else
42
- raise VerificationFailure, "PECL package #{package_name} not installed" unless remote_assert "TERM= pecl list | grep \"^#{package_name.shellescape}\\\\s\""
43
- end
44
- end
45
-
46
- end
47
- end
48
- end
49
- end
@@ -1,52 +0,0 @@
1
- require 'tempfile'
2
-
3
- module Capistrano
4
- module Baptize
5
- module Plugins
6
- module Transfer
7
- def self.included(base)
8
- base.send :alias_method, :original_upload, :upload
9
- base.send :alias_method, :upload, :patched_upload
10
- end
11
-
12
- # Performs a two-step upload
13
- # File is first uploaded to /tmp/, then moved into place
14
- # Can optionally roll everything into a tarball
15
- # and may chmod the destination afterwards
16
- def patched_upload(from, to, options={}, &block)
17
- use_tarball = options.delete :tarball
18
- set_owner = options.delete :owner
19
- if use_tarball
20
- raise "Can't tarball streaming upload" if from.kind_of?(IO)
21
- exclude = use_tarball[:exclude] if (use_tarball.kind_of?(Hash) && use_tarball[:exclude])
22
- tar_options = Array(exclude).flatten.map {|glob| "--exclude \"#{glob}\" " }.join('')
23
- tempfile = Dir::Tmpname.make_tmpname(['/tmp/baptize-', '.tar.gz'], nil)
24
- local_command = "cd #{from.shellescape} ; #{local_tar_bin} -zcf #{tempfile.shellescape} #{tar_options}."
25
- raise "Unable to tar #{from}" unless run_locally(local_command)
26
- destination = "/tmp/#{File.basename(tempfile)}"
27
- else
28
- destination = "/tmp/#{File.basename(Dir::Tmpname.make_tmpname('/tmp/baptize-', nil))}"
29
- end
30
- original_upload(tempfile || from, destination, options, &block)
31
- if use_tarball
32
- run "tar -zxf #{destination.shellescape} -C #{to.shellescape}"
33
- run "rm #{destination.shellescape}"
34
- else
35
- run "mv #{destination.shellescape} #{to.shellescape}"
36
- end
37
- if set_owner
38
- run "chown -R #{set_owner}:#{set_owner} #{to.shellescape}"
39
- end
40
- if tempfile
41
- File.delete tempfile
42
- end
43
- end
44
-
45
- protected
46
- def local_tar_bin
47
- (`uname` =~ /Darwin/ ? "COPYFILE_DISABLE=true /usr/bin/gnutar" : "tar")
48
- end
49
- end
50
- end
51
- end
52
- end