sprinkle 0.7.4 → 0.7.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. data/CHANGELOG.md +18 -14
  2. data/Gemfile.lock +11 -11
  3. data/lib/sprinkle.rb +19 -9
  4. data/lib/sprinkle/actors/capistrano.rb +2 -1
  5. data/lib/sprinkle/actors/dummy.rb +3 -3
  6. data/lib/sprinkle/actors/local.rb +7 -9
  7. data/lib/sprinkle/actors/ssh.rb +5 -5
  8. data/lib/sprinkle/deployment.rb +2 -1
  9. data/lib/sprinkle/extensions/sudo.rb +8 -4
  10. data/lib/sprinkle/installers/installer.rb +48 -37
  11. data/lib/sprinkle/installers/npm.rb +31 -30
  12. data/lib/sprinkle/installers/source.rb +6 -6
  13. data/lib/sprinkle/installers/user.rb +7 -6
  14. data/lib/sprinkle/package.rb +55 -51
  15. data/lib/sprinkle/package/chooser.rb +5 -4
  16. data/lib/sprinkle/package/rendering.rb +2 -2
  17. data/lib/sprinkle/policy.rb +13 -13
  18. data/lib/sprinkle/script.rb +5 -1
  19. data/lib/sprinkle/verify.rb +1 -0
  20. data/lib/sprinkle/version.rb +1 -1
  21. data/spec/spec_helper.rb +13 -7
  22. data/spec/sprinkle/actors/capistrano_spec.rb +18 -18
  23. data/spec/sprinkle/actors/local_spec.rb +3 -3
  24. data/spec/sprinkle/deployment_spec.rb +3 -3
  25. data/spec/sprinkle/installers/apt_spec.rb +1 -1
  26. data/spec/sprinkle/installers/binary_spec.rb +1 -1
  27. data/spec/sprinkle/installers/brew_spec.rb +1 -1
  28. data/spec/sprinkle/installers/bsd_port_spec.rb +1 -1
  29. data/spec/sprinkle/installers/file_spec.rb +9 -9
  30. data/spec/sprinkle/installers/freebsd_pkg_spec.rb +1 -1
  31. data/spec/sprinkle/installers/freebsd_portinstall_spec.rb +1 -1
  32. data/spec/sprinkle/installers/gem_spec.rb +1 -1
  33. data/spec/sprinkle/installers/installer_spec.rb +62 -25
  34. data/spec/sprinkle/installers/mac_port_spec.rb +1 -1
  35. data/spec/sprinkle/installers/npm_spec.rb +1 -1
  36. data/spec/sprinkle/installers/openbsd_pkg_spec.rb +1 -1
  37. data/spec/sprinkle/installers/opensolaris_pkg_spec.rb +1 -1
  38. data/spec/sprinkle/installers/pear_spec.rb +1 -1
  39. data/spec/sprinkle/installers/push_text_spec.rb +12 -12
  40. data/spec/sprinkle/installers/rake_spec.rb +1 -1
  41. data/spec/sprinkle/installers/replace_text_spec.rb +10 -10
  42. data/spec/sprinkle/installers/rpm_spec.rb +1 -1
  43. data/spec/sprinkle/installers/runner_spec.rb +9 -9
  44. data/spec/sprinkle/installers/smart_spec.rb +1 -1
  45. data/spec/sprinkle/installers/source_spec.rb +22 -27
  46. data/spec/sprinkle/installers/thor_spec.rb +1 -1
  47. data/spec/sprinkle/installers/transfer_spec.rb +35 -35
  48. data/spec/sprinkle/installers/user_spec.rb +13 -7
  49. data/spec/sprinkle/installers/yum_spec.rb +1 -1
  50. data/spec/sprinkle/installers/zypper_spec.rb +1 -1
  51. data/spec/sprinkle/package/package_repository_spec.rb +7 -7
  52. data/spec/sprinkle/package_spec.rb +58 -58
  53. data/spec/sprinkle/policy_spec.rb +20 -20
  54. data/spec/sprinkle/script_spec.rb +1 -1
  55. data/spec/sprinkle/verify_spec.rb +2 -2
  56. metadata +2 -2
data/CHANGELOG.md CHANGED
@@ -1,7 +1,11 @@
1
+ * Lots of sudo fixes
2
+
3
+ *Various people*
4
+
1
5
  * Default package options (see Package docs)
2
6
 
3
7
  *Koen Punt*
4
-
8
+
5
9
  * Add the file installer so we can stop doing templates with `transfer`
6
10
 
7
11
  *Josh Goebel*
@@ -9,22 +13,22 @@
9
13
  * Officially depreciate transfer :render and the ability to render just by passing
10
14
  a multi-line string as the transfer source. If you want to render templates see the
11
15
  new `render()` and `template()` (rendering.rb) helpers and the `file` installer.
12
-
16
+
13
17
  *Josh Goebel*
14
18
 
15
19
  * A users own post :install hooks should happen after a file has completely been moved
16
20
  (when using sudo this was not the case)
17
-
21
+
18
22
  *Koen Punt*
19
23
 
20
- * Remove the Deployment module from Object.
24
+ * Remove the Deployment module from Object.
21
25
 
22
- If anyone is relying on the behavior of placing their deployment block in a required
26
+ If anyone is relying on the behavior of placing their deployment block in a required
23
27
  file then they will first need to manually add the module back to the Object class
24
28
  themselves. Polluting Object is generally bad.
25
29
 
26
30
  *Josh Goebel*
27
-
31
+
28
32
  * Add support for specifying the Net::SSH keys property
29
33
 
30
34
  *Chris Kimpton*
@@ -34,17 +38,17 @@
34
38
  *Stefano Diem Benatti*
35
39
 
36
40
  * Sprinkle `sudo_cmd` and Capistrino should work together instead of getting in each others way
37
-
41
+
38
42
  When using the capistrano actor `sudo_cmd` will now use the capistrano
39
43
  generated sudo command and therefore automatically deal with password
40
- prompts, etc. This should fix hangs when installers try to call `sudo` on
44
+ prompts, etc. This should fix hangs when installers try to call `sudo` on
41
45
  the other side of a pipe operation and capistrano can not recognize the
42
46
  password prompt.
43
47
 
44
48
  * Sprinkle executable should return an error code if there was a failure
45
49
 
46
50
  *Michael Nigh*
47
-
51
+
48
52
  * verify of local actor was never returning false so installers would never be executed
49
53
 
50
54
  *Edgars Beigarts*
@@ -54,13 +58,13 @@
54
58
  should `capify .` your setup and move your deploy.rb file into the config
55
59
  folder. Or you can provide a block with `recipe 'deploy'` to force the
56
60
  old behavior.
57
-
61
+
58
62
  *Josh Goebel*
59
-
63
+
60
64
  * Capistrano actor now uses the configured setting of `run_method`, instead of always sudo.
61
- The default Capistrano setup prefers sudo, so nothing should change for
62
- most users. If you want to NOT use sudo to run commands you can set
65
+ The default Capistrano setup prefers sudo, so nothing should change for
66
+ most users. If you want to NOT use sudo to run commands you can set
63
67
  `use_sudo` or `run_method` accordingly in your capistrano recipes:
64
68
  `set :use_sudo, false` or `set :run_method, :run`
65
-
69
+
66
70
  *Michael Nigh*
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- sprinkle (0.7.3)
4
+ sprinkle (0.7.4)
5
5
  activesupport (>= 2.0.2)
6
6
  capistrano (>= 2.5.5)
7
7
  erubis (>= 2.7.0)
@@ -28,7 +28,7 @@ GEM
28
28
  i18n (= 0.6.1)
29
29
  multi_json (~> 1.0)
30
30
  builder (3.0.4)
31
- capistrano (2.15.4)
31
+ capistrano (2.15.5)
32
32
  highline
33
33
  net-scp (>= 1.0.0)
34
34
  net-sftp (>= 2.0.0)
@@ -45,11 +45,11 @@ GEM
45
45
  json (1.8.0)
46
46
  method_source (0.8.1)
47
47
  multi_json (1.7.7)
48
- net-scp (1.1.1)
48
+ net-scp (1.1.2)
49
49
  net-ssh (>= 2.6.5)
50
50
  net-sftp (2.1.2)
51
51
  net-ssh (>= 2.6.5)
52
- net-ssh (2.6.7)
52
+ net-ssh (2.6.8)
53
53
  net-ssh-gateway (1.2.0)
54
54
  net-ssh (>= 2.6.5)
55
55
  open4 (1.3.0)
@@ -79,14 +79,14 @@ GEM
79
79
  rake (10.1.0)
80
80
  rdoc (3.10)
81
81
  json (~> 1.4)
82
- rspec (2.13.0)
83
- rspec-core (~> 2.13.0)
84
- rspec-expectations (~> 2.13.0)
85
- rspec-mocks (~> 2.13.0)
86
- rspec-core (2.13.1)
87
- rspec-expectations (2.13.0)
82
+ rspec (2.14.1)
83
+ rspec-core (~> 2.14.0)
84
+ rspec-expectations (~> 2.14.0)
85
+ rspec-mocks (~> 2.14.0)
86
+ rspec-core (2.14.5)
87
+ rspec-expectations (2.14.1)
88
88
  diff-lcs (>= 1.1.3, < 2.0)
89
- rspec-mocks (2.13.1)
89
+ rspec-mocks (2.14.3)
90
90
  sdoc (0.3.20)
91
91
  json (>= 1.1.3)
92
92
  rdoc (~> 3.10)
data/lib/sprinkle.rb CHANGED
@@ -17,11 +17,28 @@ def require_all(*args) # :nodoc:
17
17
  Dir[File.dirname(__FILE__) + "/sprinkle/#{f}"].each { |e| require e } }
18
18
  end
19
19
 
20
- require_all "version.rb", "extensions/*.rb", "verifiers/*.rb", "installers/*.rb"
20
+ require 'sprinkle/version'
21
+
22
+ require_all "extensions/*.rb"
23
+
24
+ require 'sprinkle/package'
25
+ require 'sprinkle/verify'
26
+ require 'sprinkle/installers/installer'
27
+ require 'sprinkle/installers/package_installer'
28
+ require_all "verifiers/*.rb", "installers/*.rb"
21
29
 
22
30
  module Sprinkle
23
31
  # Configuration options
24
32
  OPTIONS = { :testing => false, :verbose => false, :force => false }
33
+
34
+ module Logger
35
+ def logger # :nodoc:
36
+ # ActiveSupport::BufferedLogger was deprecated and replaced by ActiveSupport::Logger in Rails 4.
37
+ # Use ActiveSupport::Logger if available.
38
+ active_support_logger = defined?(ActiveSupport::Logger) ? ActiveSupport::Logger : ActiveSupport::BufferedLogger
39
+ @@__log__ ||= active_support_logger.new($stdout, active_support_logger::Severity::INFO)
40
+ end
41
+ end
25
42
  end
26
43
 
27
44
  # Object is extended with a few helper methods. Please see Sprinkle::Core.
@@ -29,12 +46,5 @@ end
29
46
  # Define a logging target and understand packages, policies and deployment DSL
30
47
  #++
31
48
  class Object
32
- include Sprinkle::Package, Sprinkle::Core
33
-
34
- def logger # :nodoc:
35
- # ActiveSupport::BufferedLogger was deprecated and replaced by ActiveSupport::Logger in Rails 4.
36
- # Use ActiveSupport::Logger if available.
37
- active_support_logger = defined?(ActiveSupport::Logger) ? ActiveSupport::Logger : ActiveSupport::BufferedLogger
38
- @@__log__ ||= active_support_logger.new($stdout, active_support_logger::Severity::INFO)
39
- end
49
+ include Sprinkle::Package, Sprinkle::Core, Sprinkle::Logger
40
50
  end
@@ -21,6 +21,7 @@ module Sprinkle
21
21
  attr_accessor :config, :loaded_recipes #:nodoc:
22
22
 
23
23
  def initialize(&block) #:nodoc:
24
+ @installer = nil
24
25
  @config = ::Capistrano::Configuration.new
25
26
  @config.logger.level = Sprinkle::OPTIONS[:verbose] ? ::Capistrano::Logger::INFO : ::Capistrano::Logger::IMPORTANT
26
27
  @config.set(:password) { ::Capistrano::CLI.password_prompt }
@@ -32,7 +33,7 @@ module Sprinkle
32
33
  end
33
34
 
34
35
  if block
35
- @config.instance_eval &block
36
+ @config.instance_eval(&block)
36
37
  else
37
38
  @config.load "Capfile" if File.exist?("Capfile")
38
39
  end
@@ -8,7 +8,7 @@ module Sprinkle
8
8
  def initialize(&block) #:nodoc:
9
9
  # @config.set(:_sprinkle_actor, self)
10
10
  @roles={}
11
- self.instance_eval &block
11
+ self.instance_eval(&block)
12
12
  end
13
13
 
14
14
  def role(role, server, opts={})
@@ -23,7 +23,7 @@ module Sprinkle
23
23
  end
24
24
 
25
25
  def install(installer, roles, opts={})
26
- if per_host=opts.delete(:per_host)
26
+ if self.per_host=opts.delete(:per_host)
27
27
  servers_per_role(roles).each do |server|
28
28
  installer.reconfigure_for(server)
29
29
  installer.announce
@@ -54,4 +54,4 @@ module Sprinkle
54
54
  end
55
55
  end
56
56
  end
57
- end
57
+ end
@@ -68,8 +68,8 @@ module Sprinkle
68
68
 
69
69
  def run_command(cmd) #:nodoc:
70
70
  @log_recorder.reset cmd
71
- pid, stdin, out, err = Open4.popen4(cmd)
72
- ignored, status = Process::waitpid2 pid
71
+ pid, _, out, err = Open4.popen4(cmd)
72
+ _, status = Process::waitpid2 pid
73
73
  @log_recorder.log :err, err.read
74
74
  @log_recorder.log :out, out.read
75
75
  @log_recorder.code = status.to_i
@@ -80,13 +80,11 @@ module Sprinkle
80
80
  end
81
81
 
82
82
  def transfer(source, destination, roles, opts ={}) #:nodoc:
83
- opts.reverse_merge!(:recursive => true)
84
- flags = "-R " if opts[:recursive]
85
-
86
- run_command "cp #{flags}#{source} #{destination}"
87
- end
88
-
89
-
83
+ opts.reverse_merge!(:recursive => true)
84
+ flags = "-R " if opts[:recursive]
85
+
86
+ run_command "cp #{flags}#{source} #{destination}"
87
+ end
90
88
  end
91
89
  end
92
90
  end
@@ -49,7 +49,7 @@ module Sprinkle
49
49
  def initialize(options = {}, &block) #:nodoc:
50
50
  @options = options.update(:user => 'root', :port => 22)
51
51
  @roles = {}
52
- self.instance_eval &block if block
52
+ self.instance_eval(&block) if block
53
53
  raise "You must define at least a single role." if @roles.empty?
54
54
  end
55
55
 
@@ -119,9 +119,9 @@ module Sprinkle
119
119
 
120
120
  def verify(verifier, roles) #:nodoc:
121
121
  # issue all the verification steps in a single SSH command
122
- commands=[verifier.commands.join(" && ")]
122
+ commands=[prepare_commands(verifier.commands).join(" && ")]
123
123
  process(verifier.package.name, commands, roles)
124
- rescue SSHCommandFailure => e
124
+ rescue SSHCommandFailure
125
125
  false
126
126
  end
127
127
 
@@ -146,8 +146,8 @@ module Sprinkle
146
146
 
147
147
  def execute_on_role(commands, role) #:nodoc:
148
148
  hosts = @roles[role]
149
- Array(hosts).each do |host|
150
- success = execute_on_host(commands, host)
149
+ Array(hosts).each do |host|
150
+ execute_on_host(commands, host)
151
151
  end
152
152
  end
153
153
 
@@ -48,6 +48,7 @@ module Sprinkle
48
48
 
49
49
  def initialize(&block) #:nodoc:
50
50
  @defaults = {}
51
+ @style = nil
51
52
  self.instance_eval(&block)
52
53
  raise 'No delivery mechanism defined' unless @style
53
54
  end
@@ -60,7 +61,7 @@ module Sprinkle
60
61
  def delivery(type, &block) #:doc:
61
62
  type=type.to_s.titleize
62
63
  type="SSH" if type=="Ssh"
63
- @style = ("Sprinkle::Actors::" + type).constantize.new &block
64
+ @style = ("Sprinkle::Actors::" + type).constantize.new(&block)
64
65
  end
65
66
 
66
67
  def method_missing(sym, *args, &block) #:nodoc:
@@ -1,13 +1,17 @@
1
1
  module Sprinkle
2
2
  module Sudo
3
-
3
+
4
4
  def sudo_cmd
5
5
  return "#{@delivery.try(:sudo_command) || "sudo"} " if sudo?
6
6
  end
7
7
 
8
8
  def sudo?
9
- options[:sudo] or package.sudo? or @delivery.try(:sudo?)
9
+ sudo_stack.detect { |x| x==true or x==false }
10
+ end
11
+
12
+ def sudo_stack
13
+ [ options[:sudo], package.sudo?, @delivery.try(:sudo?) ]
10
14
  end
11
-
15
+
12
16
  end
13
- end
17
+ end
@@ -2,27 +2,27 @@ module Sprinkle
2
2
  # Installers are where the bulk of the work in Sprinkle happens. Installers are
3
3
  # the building blocks of packages. Typically each unique type of install
4
4
  # command has it's own installer class.
5
- #
5
+ #
6
6
  module Installers
7
7
  # The base class which all installers must subclass, this class makes
8
8
  # sure all installers share some general features, which are outlined
9
- # below.
9
+ # below.
10
10
  #
11
11
  # = Pre/Post Installation Hooks
12
- #
12
+ #
13
13
  # With all installation methods you have the ability to specify multiple
14
14
  # pre/post installation hooks. This gives you the ability to specify
15
- # commands to run before and after an installation takes place.
15
+ # commands to run before and after an installation takes place.
16
16
  # There are three ways to specify a pre/post hook.
17
-
17
+
18
18
  # Note about sudo:
19
19
  # When using the Capistrano actor all commands by default are run using
20
- # sudo (unless your Capfile includes "set :use_sudo, false"). If you wish
21
- # to use sudo periodically with "set :user_sudo, false" or with an actor
22
- # other than Capistrano then you can just append it to your command. Some
23
- # installers (transfer) also support a :sudo option, so check each
20
+ # sudo (unless your Capfile includes "set :use_sudo, false"). If you wish
21
+ # to use sudo periodically with "set :user_sudo, false" or with an actor
22
+ # other than Capistrano then you can just append it to your command. Some
23
+ # installers (transfer) also support a :sudo option, so check each
24
24
  # installer for details.
25
- #
25
+ #
26
26
  # First, a single command:
27
27
  #
28
28
  # pre :install, 'echo "Hello, World!"'
@@ -49,42 +49,43 @@ module Sprinkle
49
49
  # Some installation methods actually grant you more fine grained
50
50
  # control of when commands are run rather than a blanket pre :install
51
51
  # or post :install. If this is the case, it will be documented on
52
- # the installation method's corresponding documentation page.
52
+ # the installation method's corresponding documentation page.
53
53
  class Installer
54
54
  include Sprinkle::Attributes
55
55
  include Sprinkle::Sudo
56
-
56
+
57
57
  delegate :version, :to => :package
58
-
58
+
59
59
  attr_accessor :delivery, :package, :options, :pre, :post #:nodoc:
60
60
 
61
61
  def initialize(package, options = {}, &block) #:nodoc:
62
62
  @package = package
63
63
  @options = options || {}
64
64
  @pre = {}; @post = {}
65
+ @delivery = nil
65
66
  self.instance_eval(&block) if block
66
67
  end
67
-
68
+
68
69
  attributes :prefix, :archives, :builds
69
-
70
+
70
71
  class << self
71
72
  def subclasses
72
73
  @subclasses ||= []
73
74
  end
74
-
75
+
75
76
  def api(&block)
76
- Sprinkle::Package::Package.add_api &block
77
+ Sprinkle::Package::Package.add_api(&block)
77
78
  end
78
-
79
+
79
80
  def verify_api(&block)
80
- Sprinkle::Verify.class_eval &block
81
+ Sprinkle::Verify.class_eval(&block)
81
82
  end
82
83
 
83
84
  def inherited(base)
84
85
  subclasses << base
85
86
  end
86
87
  end
87
-
88
+
88
89
  def escape_shell_arg(str)
89
90
  str.gsub("'", "'\\\\''").gsub("\n", '\n')
90
91
  end
@@ -92,24 +93,31 @@ module Sprinkle
92
93
  def pre(stage, *commands, &block)
93
94
  @pre[stage] ||= []
94
95
  @pre[stage] += commands
95
- @pre[stage] += commands_from_block(block)
96
+ @pre[stage] << defer(block) if block_given?
97
+ @pre[stage]
96
98
  end
97
99
 
98
100
  def post(stage, *commands, &block)
99
101
  @post[stage] ||= []
100
102
  @post[stage] += commands
101
- @post[stage] += commands_from_block(block)
103
+ @post[stage] << defer(block) if block_given?
104
+ @post[stage]
102
105
  end
103
-
106
+
107
+ # defer execution of command block until the package is being
108
+ # processed
109
+ def defer(block)
110
+ p = Proc.new { self.commands_from_block(block) }
111
+ end
112
+
104
113
  def commands_from_block(block)
105
114
  return [] unless block
106
115
  out = nil
107
- diff = @package.with_private_install_queue do
108
- out = block.call
109
- end
116
+ diff = @package.with_private_install_queue { out = block.call }
117
+ diff.each {|x| x.delivery = self.delivery }
110
118
  diff.empty? ? out : diff.map {|x| x.install_sequence }
111
119
  end
112
-
120
+
113
121
  def method_missing(method, *args, &block)
114
122
  if package.class.installer_methods.include?(method)
115
123
  @package.send(method, *args, &block)
@@ -117,12 +125,11 @@ module Sprinkle
117
125
  super(method, *args, &block)
118
126
  end
119
127
  end
120
-
128
+
121
129
  def per_host?
122
130
  return false
123
- @per_host
124
131
  end
125
-
132
+
126
133
  # Called right before an installer is exected, can be used for logging
127
134
  # and announcing what is about to happen
128
135
  def announce; end
@@ -144,17 +151,21 @@ module Sprinkle
144
151
  # command sequence construction (eg. source based installer).
145
152
  def install_sequence
146
153
  commands = pre_commands(:install) + [ install_commands ] + post_commands(:install)
147
- commands.flatten
154
+ flatten commands
148
155
  end
149
-
156
+
150
157
  protected
151
-
152
- def log(t, level=:info)
158
+
159
+ def log(t, level=:info) #:nodoc:
153
160
  logger.send(level, t)
154
161
  end
155
162
 
163
+ def flatten(commands) #:nodoc:
164
+ commands.flatten.map {|c| c.is_a?(Proc) ? c.call : c }.flatten
165
+ end
166
+
156
167
  # A concrete installer (subclass of this virtual class) must override this method
157
- # and return the commands it needs to run as either a string or an array.
168
+ # and return the commands it needs to run as either a string or an array.
158
169
  #
159
170
  # <b>Overriding this method is required.</b>
160
171
  def install_commands
@@ -171,9 +182,9 @@ module Sprinkle
171
182
 
172
183
  # Concrete installers (subclasses of this virtual class) can override this method to
173
184
  # specify stage-specific (pre-installation, post-installation, etc.) modifications
174
- # of commands.
185
+ # of commands.
175
186
  #
176
- # An example usage of overriding this would be to prefix all commands for a
187
+ # An example usage of overriding this would be to prefix all commands for a
177
188
  # certain stage to change to a certain directory. An example is given below:
178
189
  #
179
190
  # def dress(commands, stage)