baptize 0.0.8 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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