sprinkle 0.5.2 → 0.6.0
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.
- data/CHANGELOG.md +20 -0
- data/lib/sprinkle/actors/capistrano.rb +9 -9
- data/lib/sprinkle/actors/dummy.rb +1 -1
- data/lib/sprinkle/actors/ssh.rb +1 -1
- data/lib/sprinkle/extensions/attributes.rb +56 -0
- data/lib/sprinkle/installers/apt.rb +4 -2
- data/lib/sprinkle/installers/binary.rb +4 -4
- data/lib/sprinkle/installers/gem.rb +2 -8
- data/lib/sprinkle/installers/installer.rb +27 -9
- data/lib/sprinkle/installers/replace_text.rb +5 -1
- data/lib/sprinkle/installers/runner.rb +4 -0
- data/lib/sprinkle/installers/source.rb +26 -11
- data/lib/sprinkle/installers/transfer.rb +0 -2
- data/lib/sprinkle/installers/user.rb +6 -3
- data/lib/sprinkle/package.rb +23 -6
- data/lib/sprinkle/verify.rb +3 -3
- data/lib/sprinkle/version.rb +1 -1
- data/spec/sprinkle/actors/capistrano_spec.rb +11 -10
- data/spec/sprinkle/installers/apt_spec.rb +2 -2
- data/spec/sprinkle/installers/gem_spec.rb +1 -1
- data/spec/sprinkle/installers/installer_spec.rb +25 -15
- data/spec/sprinkle/installers/push_text_spec.rb +15 -0
- data/spec/sprinkle/installers/rpm_spec.rb +0 -4
- data/spec/sprinkle/installers/source_spec.rb +20 -10
- data/spec/sprinkle/installers/user_spec.rb +30 -0
- data/spec/sprinkle/verify_spec.rb +0 -11
- metadata +5 -7
- data/lib/sprinkle/configurable.rb +0 -32
- data/lib/sprinkle/extensions/arbitrary_options.rb +0 -10
- data/lib/sprinkle/extensions/dsl_accessor.rb +0 -15
- data/spec/sprinkle/configurable_spec.rb +0 -47
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
* push_text was escaping & and / when it should not be
|
2
|
+
|
3
|
+
*Stefano Diem Benatti*
|
4
|
+
|
1
5
|
* Sprinkle `sudo_cmd` and Capistrino should work together instead of getting in each others way
|
2
6
|
|
3
7
|
When using the capistrano actor `sudo_cmd` will now use the capistrano
|
@@ -13,3 +17,19 @@
|
|
13
17
|
* verify of local actor was never returning false so installers would never be executed
|
14
18
|
|
15
19
|
*Edgars Beigarts*
|
20
|
+
|
21
|
+
* Capistrano actor now defaults to loading "Capfile" not "deploy" when no block is given.
|
22
|
+
If for some reason you just have a 'deploy' file in your root folder you
|
23
|
+
should `capify .` your setup and move your deploy.rb file into the config
|
24
|
+
folder. Or you can provide a block with `recipe 'deploy'` to force the
|
25
|
+
old behavior.
|
26
|
+
|
27
|
+
*Josh Goebel*
|
28
|
+
|
29
|
+
* Capistrano actor now uses the configured setting of `run_method`, instead of always sudo.
|
30
|
+
The default Capistrano setup prefers sudo, so nothing should change for
|
31
|
+
most users. If you want to NOT use sudo to run commands you can set
|
32
|
+
`use_sudo` or `run_method` accordingly in your capistrano recipes:
|
33
|
+
`set :use_sudo, false` or `set :run_method, :run`
|
34
|
+
|
35
|
+
*Michael Nigh*
|
@@ -30,16 +30,16 @@ module Sprinkle
|
|
30
30
|
def @config.recipes(script)
|
31
31
|
_sprinkle_actor.recipes(script)
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
if block
|
35
35
|
@config.instance_eval &block
|
36
36
|
else
|
37
|
-
@config.load
|
37
|
+
@config.load "Capfile" if File.exist?("Capfile")
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
41
|
def sudo?
|
42
|
-
@config.fetch(:run_method, :
|
42
|
+
@config.fetch(:run_method, :run) == :sudo
|
43
43
|
end
|
44
44
|
|
45
45
|
def sudo_command
|
@@ -49,7 +49,7 @@ module Sprinkle
|
|
49
49
|
# Determines if there are any servers for the given roles
|
50
50
|
def servers_for_role?(roles)
|
51
51
|
roles=Array(roles)
|
52
|
-
roles.any? { |r| @config.roles.keys.include?
|
52
|
+
roles.any? { |r| @config.roles.keys.include?(r) }
|
53
53
|
end
|
54
54
|
|
55
55
|
|
@@ -97,7 +97,7 @@ module Sprinkle
|
|
97
97
|
@log_recorder = log_recorder = Sprinkle::Utility::LogRecorder.new
|
98
98
|
commands = commands.map {|x| rewrite_command(x)}
|
99
99
|
define_task(name, roles) do
|
100
|
-
via = fetch(:run_method, :
|
100
|
+
via = fetch(:run_method, :run)
|
101
101
|
commands.each do |command|
|
102
102
|
if command == :TRANSFER
|
103
103
|
opts.reverse_merge!(:recursive => true)
|
@@ -108,9 +108,9 @@ module Sprinkle
|
|
108
108
|
else
|
109
109
|
# this reset the log
|
110
110
|
log_recorder.reset command
|
111
|
-
invoke_command(command, {:via => via}) do |
|
112
|
-
|
113
|
-
log_recorder.log(
|
111
|
+
invoke_command(command, {:via => via}) do |ch, stream, out|
|
112
|
+
::Capistrano::Configuration.default_io_proc.call(ch, stream, out) if Sprinkle::OPTIONS[:verbose]
|
113
|
+
log_recorder.log(stream, out)
|
114
114
|
end
|
115
115
|
end
|
116
116
|
end
|
@@ -123,7 +123,7 @@ module Sprinkle
|
|
123
123
|
# rip out any double sudos from the beginning of the command
|
124
124
|
def rewrite_command(cmd)
|
125
125
|
return cmd if cmd.is_a?(Symbol)
|
126
|
-
via = @config.fetch(:run_method, :
|
126
|
+
via = @config.fetch(:run_method, :run)
|
127
127
|
if via == :sudo and cmd =~ /^#{sudo_command}/
|
128
128
|
cmd.gsub(/^#{sudo_command}\s?/,"")
|
129
129
|
else
|
@@ -19,7 +19,7 @@ module Sprinkle
|
|
19
19
|
# Determines if there are any servers for the given roles
|
20
20
|
def servers_for_role?(roles)
|
21
21
|
roles=Array(roles)
|
22
|
-
roles.any? { |r| @roles.keys.include?
|
22
|
+
roles.any? { |r| @roles.keys.include?(r) }
|
23
23
|
end
|
24
24
|
|
25
25
|
def install(installer, roles, opts={})
|
data/lib/sprinkle/actors/ssh.rb
CHANGED
@@ -43,7 +43,7 @@ module Sprinkle
|
|
43
43
|
|
44
44
|
def initialize(options = {}, &block) #:nodoc:
|
45
45
|
@options = options.update(:user => 'root')
|
46
|
-
@roles = {}
|
46
|
+
@roles = {}
|
47
47
|
@connection_cache = SSHConnectionCache.new
|
48
48
|
self.instance_eval &block if block
|
49
49
|
raise "You must define at least a single role." if @roles.empty?
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Sprinkle
|
2
|
+
module Attributes
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
attr_accessor :delivery
|
7
|
+
end
|
8
|
+
|
9
|
+
def defaults(deployment)
|
10
|
+
defaults = deployment.defaults[self.class.name.split(/::/).last.downcase.to_sym]
|
11
|
+
self.set_defaults(&defaults) if defaults
|
12
|
+
@delivery = deployment.style
|
13
|
+
end
|
14
|
+
|
15
|
+
def set_defaults(&block)
|
16
|
+
before = @options
|
17
|
+
@options = {}
|
18
|
+
self.instance_eval(&block) if block
|
19
|
+
@options = before.reverse_merge(@options)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def read_from_package(m)
|
25
|
+
@package.send(m) if @package.respond_to?(m)
|
26
|
+
end
|
27
|
+
|
28
|
+
def option?(sym)
|
29
|
+
!!@options[sym]
|
30
|
+
end
|
31
|
+
|
32
|
+
module ClassMethods
|
33
|
+
|
34
|
+
def attributes(*list)
|
35
|
+
list.each do |a|
|
36
|
+
define_method a do |*val|
|
37
|
+
val=nil if val.empty?
|
38
|
+
val ? @options[a] = val.first : @options[a] || read_from_package(a)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def multi_attributes(*list)
|
44
|
+
list.each do |a|
|
45
|
+
define_method a do |*val|
|
46
|
+
val = val.try(:first)
|
47
|
+
return @options[a] unless val
|
48
|
+
@options[a]||=[]
|
49
|
+
val.is_a?(Array) ? @options[a] += val : @options[a] << val
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
@@ -31,6 +31,8 @@ module Sprinkle
|
|
31
31
|
super parent, *packages, &block
|
32
32
|
@options.reverse_merge!(:dependencies_only => false)
|
33
33
|
end
|
34
|
+
|
35
|
+
attributes :dependencies_only
|
34
36
|
|
35
37
|
auto_api
|
36
38
|
|
@@ -44,8 +46,8 @@ module Sprinkle
|
|
44
46
|
|
45
47
|
def install_commands #:nodoc:
|
46
48
|
command = @options[:dependencies_only] ? 'build-dep' : 'install'
|
47
|
-
noninteractive = "env DEBCONF_TERSE='yes' DEBIAN_PRIORITY='critical' DEBIAN_FRONTEND=noninteractive"
|
48
|
-
"#{noninteractive}
|
49
|
+
noninteractive = "#{sudo_cmd}env DEBCONF_TERSE='yes' DEBIAN_PRIORITY='critical' DEBIAN_FRONTEND=noninteractive"
|
50
|
+
"#{noninteractive} apt-get --force-yes -qyu #{command} #{@packages.join(' ')}"
|
49
51
|
end
|
50
52
|
|
51
53
|
end
|
@@ -29,13 +29,13 @@ module Sprinkle
|
|
29
29
|
raise 'No installation area defined' unless @options[:prefix]
|
30
30
|
raise 'No archive download area defined' unless @options[:archives]
|
31
31
|
|
32
|
-
[ "mkdir -p #{@options[:prefix]
|
33
|
-
"mkdir -p #{@options[:archives]
|
32
|
+
[ "mkdir -p #{@options[:prefix]}",
|
33
|
+
"mkdir -p #{@options[:archives]}" ]
|
34
34
|
end
|
35
35
|
|
36
36
|
def install_commands #:nodoc:
|
37
|
-
commands = [ "bash -c 'wget -cq --directory-prefix=#{@options[:archives]
|
38
|
-
commands << "bash -c \"cd #{@options[:prefix]
|
37
|
+
commands = [ "bash -c 'wget -cq --directory-prefix=#{@options[:archives]} #{@binary_archive}'" ]
|
38
|
+
commands << "bash -c \"cd #{@options[:prefix]} && #{extract_command} '#{@options[:archives]}/#{archive_name}'\""
|
39
39
|
end
|
40
40
|
|
41
41
|
def archive_name #:nodoc:
|
@@ -41,14 +41,8 @@ module Sprinkle
|
|
41
41
|
super parent, options, &block
|
42
42
|
@gem = gem
|
43
43
|
end
|
44
|
-
|
45
|
-
|
46
|
-
# package defines an installer called source so here we specify a method directly
|
47
|
-
# rather than rely on the automatic options processing since packages' method missing
|
48
|
-
# won't be run
|
49
|
-
return @options[:source] unless location
|
50
|
-
@options[:source] = location
|
51
|
-
end
|
44
|
+
|
45
|
+
attributes :source, :repository, :http_proxy, :build_flags, :version
|
52
46
|
|
53
47
|
protected
|
54
48
|
|
@@ -51,7 +51,8 @@ module Sprinkle
|
|
51
51
|
# or post :install. If this is the case, it will be documented on
|
52
52
|
# the installation method's corresponding documentation page.
|
53
53
|
class Installer
|
54
|
-
include Sprinkle::
|
54
|
+
include Sprinkle::Attributes
|
55
|
+
|
55
56
|
attr_accessor :delivery, :package, :options, :pre, :post #:nodoc:
|
56
57
|
|
57
58
|
def initialize(package, options = {}, &block) #:nodoc:
|
@@ -60,6 +61,8 @@ module Sprinkle
|
|
60
61
|
@pre = {}; @post = {}
|
61
62
|
self.instance_eval(&block) if block
|
62
63
|
end
|
64
|
+
|
65
|
+
attributes :prefix, :archives, :builds
|
63
66
|
|
64
67
|
class << self
|
65
68
|
def subclasses
|
@@ -67,7 +70,7 @@ module Sprinkle
|
|
67
70
|
end
|
68
71
|
|
69
72
|
def api(&block)
|
70
|
-
Sprinkle::Package::Package.
|
73
|
+
Sprinkle::Package::Package.add_api &block
|
71
74
|
end
|
72
75
|
|
73
76
|
def verify_api(&block)
|
@@ -88,19 +91,36 @@ module Sprinkle
|
|
88
91
|
end
|
89
92
|
|
90
93
|
def escape_shell_arg(str)
|
91
|
-
str.gsub("'", "'\\\\''").gsub("
|
94
|
+
str.gsub("'", "'\\\\''").gsub("\n", '\n')
|
92
95
|
end
|
93
96
|
|
94
|
-
def pre(stage, *commands)
|
97
|
+
def pre(stage, *commands, &block)
|
95
98
|
@pre[stage] ||= []
|
96
99
|
@pre[stage] += commands
|
97
|
-
@pre[stage] +=
|
100
|
+
@pre[stage] += commands_from_block(block)
|
98
101
|
end
|
99
102
|
|
100
|
-
def post(stage, *commands)
|
103
|
+
def post(stage, *commands, &block)
|
101
104
|
@post[stage] ||= []
|
102
105
|
@post[stage] += commands
|
103
|
-
@post[stage] +=
|
106
|
+
@post[stage] += commands_from_block(block)
|
107
|
+
end
|
108
|
+
|
109
|
+
def commands_from_block(block)
|
110
|
+
return [] unless block
|
111
|
+
out = nil
|
112
|
+
diff = @package.with_private_install_queue do
|
113
|
+
out = block.call
|
114
|
+
end
|
115
|
+
diff.empty? ? out : diff.map {|x| x.install_sequence }
|
116
|
+
end
|
117
|
+
|
118
|
+
def method_missing(method, *args, &block)
|
119
|
+
if package.class.installer_methods.include?(method)
|
120
|
+
@package.send(method, *args, &block)
|
121
|
+
else
|
122
|
+
super(method, *args, &block)
|
123
|
+
end
|
104
124
|
end
|
105
125
|
|
106
126
|
def per_host?
|
@@ -113,8 +133,6 @@ module Sprinkle
|
|
113
133
|
def announce; end
|
114
134
|
|
115
135
|
def process(roles) #:nodoc:
|
116
|
-
assert_delivery
|
117
|
-
|
118
136
|
if logger.debug?
|
119
137
|
sequence = install_sequence; sequence = sequence.join('; ') if sequence.is_a? Array
|
120
138
|
logger.debug "#{@package.name} install sequence: #{sequence} for roles: #{roles}\n"
|
@@ -45,8 +45,12 @@ module Sprinkle
|
|
45
45
|
|
46
46
|
protected
|
47
47
|
|
48
|
+
def escape_sed_arg(s)
|
49
|
+
escape_shell_arg(s).gsub("/", "\\\\/").gsub('&', '\\\&')
|
50
|
+
end
|
51
|
+
|
48
52
|
def install_commands #:nodoc:
|
49
|
-
"#{sudo_cmd}sed -i 's/#{
|
53
|
+
"#{sudo_cmd}sed -i 's/#{escape_sed_arg(@regex)}/#{escape_sed_arg(@text)}/g' #{@path}"
|
50
54
|
end
|
51
55
|
|
52
56
|
end
|
@@ -90,6 +90,9 @@ module Sprinkle
|
|
90
90
|
@source = source
|
91
91
|
end
|
92
92
|
|
93
|
+
multi_attributes :enable, :disable, :with, :without, :option,
|
94
|
+
:custom_install
|
95
|
+
|
93
96
|
def install_sequence #:nodoc:
|
94
97
|
prepare + download + extract + configure + build + install
|
95
98
|
end
|
@@ -107,23 +110,23 @@ module Sprinkle
|
|
107
110
|
raise 'No build area defined' unless @options[:builds]
|
108
111
|
raise 'No source download area defined' unless @options[:archives]
|
109
112
|
|
110
|
-
[ "mkdir -p #{@options[:prefix]
|
111
|
-
"mkdir -p #{@options[:builds]
|
112
|
-
"mkdir -p #{@options[:archives]
|
113
|
+
[ "mkdir -p #{@options[:prefix]}",
|
114
|
+
"mkdir -p #{@options[:builds]}",
|
115
|
+
"mkdir -p #{@options[:archives]}" ]
|
113
116
|
end
|
114
117
|
|
115
118
|
def download_commands #:nodoc:
|
116
|
-
[ "wget -cq -O '#{@options[:archives]
|
119
|
+
[ "wget -cq -O '#{@options[:archives]}/#{archive_name}' #{@source}" ]
|
117
120
|
end
|
118
121
|
|
119
122
|
def extract_commands #:nodoc:
|
120
|
-
[ "bash -c 'cd #{@options[:builds]
|
123
|
+
[ "bash -c 'cd #{@options[:builds]} && #{extract_command} #{@options[:archives]}/#{archive_name}'" ]
|
121
124
|
end
|
122
125
|
|
123
126
|
def configure_commands #:nodoc:
|
124
127
|
return [] if custom_install?
|
125
128
|
|
126
|
-
command = "bash -c 'cd #{build_dir} && ./configure --prefix=#{@options[:prefix]
|
129
|
+
command = "bash -c 'cd #{build_dir} && ./configure --prefix=#{@options[:prefix]} "
|
127
130
|
|
128
131
|
extras = {
|
129
132
|
:enable => '--enable', :disable => '--disable',
|
@@ -152,21 +155,33 @@ module Sprinkle
|
|
152
155
|
|
153
156
|
# REVISIT: must be better processing of custom install commands somehow? use splat operator?
|
154
157
|
def custom_install_commands #:nodoc:
|
155
|
-
dress @options[:custom_install], :install
|
158
|
+
dress @options[:custom_install], nil, :install
|
156
159
|
end
|
157
160
|
|
158
161
|
protected
|
162
|
+
|
163
|
+
def pre_commands(stage) #:nodoc:
|
164
|
+
dress @pre[stage] || [], :pre, stage
|
165
|
+
end
|
166
|
+
|
167
|
+
def post_commands(stage) #:nodoc:
|
168
|
+
dress @post[stage] || [], :post, stage
|
169
|
+
end
|
170
|
+
|
159
171
|
|
160
172
|
# dress is overriden from the base Sprinkle::Installers::Installer class so that the command changes
|
161
173
|
# directory to the build directory first. Also, the result of the command is logged.
|
162
|
-
def dress(commands, stage)
|
163
|
-
|
174
|
+
def dress(commands, pre_or_post, stage)
|
175
|
+
chdir = "cd #{build_dir} && "
|
176
|
+
chdir = "" if [:prepare, :download].include?(stage)
|
177
|
+
chdir = "" if stage == :extract and pre_or_post == :pre
|
178
|
+
commands.collect { |command| "bash -c '#{chdir}#{command} >> #{@package.name}-#{stage}.log 2>&1'" }
|
164
179
|
end
|
165
180
|
|
166
181
|
private
|
167
182
|
|
168
183
|
def create_options(key, prefix) #:nodoc:
|
169
|
-
@options[key].
|
184
|
+
@options[key].inject('') { |m, option| m << "#{prefix}-#{option} "; m }
|
170
185
|
end
|
171
186
|
|
172
187
|
def extract_command #:nodoc:
|
@@ -195,7 +210,7 @@ module Sprinkle
|
|
195
210
|
end
|
196
211
|
|
197
212
|
def build_dir #:nodoc:
|
198
|
-
"#{@options[:builds]
|
213
|
+
"#{@options[:builds]}/#{options[:custom_dir] || base_dir}"
|
199
214
|
end
|
200
215
|
|
201
216
|
def base_dir #:nodoc:
|
@@ -29,16 +29,19 @@ module Sprinkle
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
33
|
def initialize(package, username, options = {}, &block) #:nodoc:
|
34
34
|
super package, options, &block
|
35
35
|
@username = username
|
36
36
|
end
|
37
|
-
|
37
|
+
|
38
38
|
protected
|
39
39
|
|
40
40
|
def install_commands #:nodoc:
|
41
|
-
|
41
|
+
noninteractive = "--gecos ,,,"
|
42
|
+
flags = @options[:flags] || ""
|
43
|
+
flags << noninteractive unless flags =~ /--gecos/
|
44
|
+
"adduser #{flags} #{@username}"
|
42
45
|
end
|
43
46
|
end
|
44
47
|
end
|
data/lib/sprinkle/package.rb
CHANGED
@@ -106,9 +106,17 @@ module Sprinkle
|
|
106
106
|
end
|
107
107
|
|
108
108
|
class Package #:nodoc:
|
109
|
-
# include ArbitraryOptions
|
110
109
|
attr_accessor :name, :provides, :installers, :verifications
|
111
110
|
attr_accessor :args, :opts
|
111
|
+
cattr_reader :installer_methods
|
112
|
+
@@installer_methods = []
|
113
|
+
|
114
|
+
def self.add_api(&block)
|
115
|
+
before = self.instance_methods
|
116
|
+
self.class_eval &block
|
117
|
+
added = self.instance_methods - before
|
118
|
+
@@installer_methods += added.map(&:to_sym)
|
119
|
+
end
|
112
120
|
|
113
121
|
def initialize(name, metadata = {}, &block)
|
114
122
|
raise 'No package name supplied' unless name
|
@@ -166,10 +174,6 @@ module Sprinkle
|
|
166
174
|
raise ContextError, "Cannot call get inside a package, must be inside an Installer block"
|
167
175
|
end
|
168
176
|
|
169
|
-
def noop(&block)
|
170
|
-
install Sprinkle::Installers::Runner.new(self, "echo noop", &block)
|
171
|
-
end
|
172
|
-
|
173
177
|
# meta installer
|
174
178
|
# TODO - fix to be atomic
|
175
179
|
def push_file(file, options ={}, &block)
|
@@ -249,6 +253,19 @@ module Sprinkle
|
|
249
253
|
end
|
250
254
|
|
251
255
|
def to_s; @name; end
|
256
|
+
|
257
|
+
# allow an installer to request a private install queue from the package
|
258
|
+
# for example to allow pre and post hooks to have their own installers that
|
259
|
+
# do not mess with the packages installer list
|
260
|
+
#
|
261
|
+
# returns: the private queue
|
262
|
+
def with_private_install_queue()
|
263
|
+
b = @installers
|
264
|
+
@installers = private_queue =[]
|
265
|
+
yield
|
266
|
+
@installers = b
|
267
|
+
private_queue
|
268
|
+
end
|
252
269
|
|
253
270
|
protected
|
254
271
|
|
@@ -256,7 +273,7 @@ module Sprinkle
|
|
256
273
|
@installers << i
|
257
274
|
i
|
258
275
|
end
|
259
|
-
|
276
|
+
|
260
277
|
private
|
261
278
|
|
262
279
|
def add_dependencies(packages, kind)
|
data/lib/sprinkle/verify.rb
CHANGED
@@ -59,7 +59,7 @@ module Sprinkle
|
|
59
59
|
# verify { has_magic_beans('ranch') }
|
60
60
|
# end
|
61
61
|
class Verify
|
62
|
-
include Sprinkle::
|
62
|
+
include Sprinkle::Attributes
|
63
63
|
attr_accessor :package, :description, :commands #:nodoc:
|
64
64
|
|
65
65
|
class <<self
|
@@ -69,6 +69,8 @@ module Sprinkle
|
|
69
69
|
end
|
70
70
|
end
|
71
71
|
|
72
|
+
attributes :padding
|
73
|
+
|
72
74
|
def initialize(package, description = '', &block) #:nodoc:
|
73
75
|
raise 'Verify requires a block.' unless block
|
74
76
|
|
@@ -82,8 +84,6 @@ module Sprinkle
|
|
82
84
|
end
|
83
85
|
|
84
86
|
def process(roles, pre = false) #:nodoc:
|
85
|
-
assert_delivery
|
86
|
-
|
87
87
|
description = @description.empty? ? " (#{@package.name})" : @description
|
88
88
|
|
89
89
|
if logger.debug?
|
data/lib/sprinkle/version.rb
CHANGED
@@ -55,7 +55,7 @@ describe Sprinkle::Actors::Capistrano do
|
|
55
55
|
end
|
56
56
|
|
57
57
|
it 'should evaluate the block against the actor instance' do
|
58
|
-
@actor.loaded_recipes.should
|
58
|
+
@actor.loaded_recipes.should == ['cool gear']
|
59
59
|
end
|
60
60
|
|
61
61
|
end
|
@@ -63,7 +63,8 @@ describe Sprinkle::Actors::Capistrano do
|
|
63
63
|
describe 'without a block' do
|
64
64
|
|
65
65
|
it 'should automatically load the default capistrano configuration' do
|
66
|
-
|
66
|
+
File.stub!(:exist?).with("Capfile").and_return true
|
67
|
+
@cap.should_receive(:load).with('Capfile').and_return
|
67
68
|
end
|
68
69
|
|
69
70
|
after do
|
@@ -77,15 +78,13 @@ describe Sprinkle::Actors::Capistrano do
|
|
77
78
|
describe 'recipes' do
|
78
79
|
|
79
80
|
it 'should add the recipe location to an internal store' do
|
80
|
-
@cap = create_cap
|
81
|
-
recipes 'deploy'
|
82
|
-
end
|
81
|
+
@cap = create_cap { recipes "deploy" }
|
83
82
|
@cap.loaded_recipes.should == [ @recipes ]
|
84
83
|
end
|
85
84
|
|
86
85
|
it 'should load the given recipe' do
|
87
86
|
@cap.should_receive(:load).with(@recipes).and_return
|
88
|
-
create_cap
|
87
|
+
@cap = create_cap { recipes "deploy" }
|
89
88
|
end
|
90
89
|
|
91
90
|
end
|
@@ -131,6 +130,7 @@ describe Sprinkle::Actors::Capistrano do
|
|
131
130
|
# pretend the package or installer has also added sudo
|
132
131
|
@commands =["sudo op1"]
|
133
132
|
@cap.stub(:sudo_command).and_return("sudo")
|
133
|
+
@cap.config.stub!(:fetch).and_return(:sudo)
|
134
134
|
@cap.unstub!(:run)
|
135
135
|
@cap.config.should_receive(:invoke_command).with('op1', :via => :sudo).ordered.and_return
|
136
136
|
end
|
@@ -205,12 +205,13 @@ describe Sprinkle::Actors::Capistrano do
|
|
205
205
|
@cap.config.stub!(:invoke_command).and_return
|
206
206
|
end
|
207
207
|
|
208
|
-
it 'should
|
209
|
-
@cap.config.should_receive(:invoke_command).with('op1', :via => :
|
210
|
-
@cap.config.should_receive(:invoke_command).with('op2', :via => :
|
208
|
+
it 'should run the supplied commands by default' do
|
209
|
+
@cap.config.should_receive(:invoke_command).with('op1', :via => :run).ordered.and_return
|
210
|
+
@cap.config.should_receive(:invoke_command).with('op2', :via => :run).ordered.and_return
|
211
211
|
end
|
212
212
|
|
213
|
-
it 'should
|
213
|
+
it 'should use sudo to invoke commands when so configured' do
|
214
|
+
@cap.config.set :run_method, :sudo
|
214
215
|
@cap.config.should_receive(:invoke_command).with('op1', :via => :sudo).ordered.and_return
|
215
216
|
@cap.config.should_receive(:invoke_command).with('op2', :via => :sudo).ordered.and_return
|
216
217
|
end
|
@@ -50,14 +50,14 @@ describe Sprinkle::Installers::Apt do
|
|
50
50
|
@package = create_pkg "name", :use_sudo => true
|
51
51
|
@installer = create_apt 'ruby'
|
52
52
|
@install_commands = @installer.send :install_commands
|
53
|
-
@install_commands.should =~ /sudo
|
53
|
+
@install_commands.should =~ /sudo env/
|
54
54
|
end
|
55
55
|
|
56
56
|
it 'should use sudo if installer specifies' do
|
57
57
|
@package = create_pkg "name", :use_sudo => false
|
58
58
|
@installer = create_apt 'ruby', :sudo => true
|
59
59
|
@install_commands = @installer.send :install_commands
|
60
|
-
@install_commands.should =~ /sudo
|
60
|
+
@install_commands.should =~ /sudo env/
|
61
61
|
end
|
62
62
|
|
63
63
|
it 'should invoke the apt installer for all specified packages' do
|
@@ -9,7 +9,7 @@ describe Sprinkle::Installers::Gem do
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def create_gem(gem, version = nil, options = {}, &block)
|
12
|
-
@package = mock(Sprinkle::Package, :name => gem, :version => version
|
12
|
+
@package = mock(Sprinkle::Package, :name => gem, :version => version)
|
13
13
|
Sprinkle::Installers::Gem.new(@package, gem, options, &block)
|
14
14
|
end
|
15
15
|
|
@@ -42,19 +42,18 @@ describe Sprinkle::Installers::Installer do
|
|
42
42
|
|
43
43
|
it 'should accept an optional block to customize installers defaults' do
|
44
44
|
@installer = create_installer do; prefix '/usr/local'; end
|
45
|
-
@installer.prefix.
|
45
|
+
@installer.prefix.should == '/usr/local'
|
46
46
|
end
|
47
47
|
|
48
48
|
it 'should override any deployment level defaults' do
|
49
49
|
@installer = create_installer do; prefix '/usr/local'; end
|
50
50
|
@installer.defaults(@deployment)
|
51
|
-
@installer.prefix.
|
51
|
+
@installer.prefix.should == '/usr/local'
|
52
52
|
end
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
56
|
describe 'during configuration' do
|
57
|
-
# We just check to make sure it has the Sprinkle::Configurable method
|
58
57
|
it 'should be configurable' do
|
59
58
|
@installer.should respond_to(:defaults)
|
60
59
|
end
|
@@ -126,41 +125,52 @@ describe Sprinkle::Installers::Installer do
|
|
126
125
|
|
127
126
|
describe "with a pre command" do
|
128
127
|
|
129
|
-
def create_installer_with_pre_command(cmd=
|
128
|
+
def create_installer_with_pre_command(cmd = nil, &block)
|
130
129
|
installer = Sprinkle::Installers::Installer.new @package do
|
131
|
-
pre :install, cmd
|
130
|
+
pre :install, cmd if cmd
|
132
131
|
|
133
132
|
def install_commands
|
134
133
|
["installer"]
|
135
134
|
end
|
136
135
|
end
|
137
|
-
|
136
|
+
installer.instance_eval &block if block
|
138
137
|
installer.stub!(:puts).and_return
|
139
138
|
installer.delivery = @delivery
|
140
139
|
installer
|
141
140
|
end
|
142
141
|
before do
|
143
142
|
@installer = create_installer_with_pre_command('run')
|
143
|
+
@package.stub!(:installers).and_return []
|
144
144
|
end
|
145
145
|
describe "string commands" do
|
146
146
|
it "should insert the pre command for the specific package in the installation process" do
|
147
147
|
@installer.send(:install_sequence).should == [ 'run', 'installer' ]
|
148
148
|
end
|
149
|
-
end
|
149
|
+
end
|
150
|
+
describe "block with their embeded installers" do
|
151
|
+
before(:each) do
|
152
|
+
@package = Package.new("package") do; end
|
153
|
+
@installer = create_installer_with_pre_command do
|
154
|
+
pre :install do
|
155
|
+
runner "b" do
|
156
|
+
pre(:install) { runner "a" }
|
157
|
+
post(:install) { runner "c" }
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
it "should properly execute pre and post blocks" do
|
163
|
+
@installer.send(:install_sequence).should == [ "a", "b", "c", 'installer' ]
|
164
|
+
end
|
165
|
+
end
|
150
166
|
describe "blocks as commands" do
|
151
167
|
before(:each) do
|
152
|
-
@
|
168
|
+
@package = Package.new("package") do; end
|
169
|
+
@installer = create_installer_with_pre_command do
|
153
170
|
pre :install do
|
154
171
|
%w(a b c)
|
155
172
|
end
|
156
|
-
|
157
|
-
def install_commands
|
158
|
-
["installer"]
|
159
|
-
end
|
160
173
|
end
|
161
|
-
|
162
|
-
@installer.stub!(:puts).and_return
|
163
|
-
@installer.delivery = @delivery
|
164
174
|
end
|
165
175
|
it "should be able to store a block if it's the pre command" do
|
166
176
|
@installer.send(:install_sequence).should == [ "a", "b", "c", 'installer' ]
|
@@ -89,6 +89,21 @@ MULTI
|
|
89
89
|
end
|
90
90
|
end
|
91
91
|
|
92
|
+
describe 'sending a string with special characters' do
|
93
|
+
|
94
|
+
it "should not escape an ampersand" do
|
95
|
+
@installer = create_text "bob & lucy", "/dev/mind/the-day-after"
|
96
|
+
@install_commands = @installer.send :install_commands
|
97
|
+
@install_commands.should == %q[/bin/echo -e 'bob & lucy' |tee -a /dev/mind/the-day-after]
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should not escape a slash" do
|
101
|
+
@installer = create_text "bob/lucy", "/dev/mind/the-day-after"
|
102
|
+
@install_commands = @installer.send :install_commands
|
103
|
+
@install_commands.should == %q[/bin/echo -e 'bob/lucy' |tee -a /dev/mind/the-day-after]
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
92
107
|
describe 'sending a string with single quotes' do
|
93
108
|
before do
|
94
109
|
@installer = create_text "I'm a string with a single quote", "/dev/mind/the-day-after"
|
@@ -76,35 +76,35 @@ describe Sprinkle::Installers::Source do
|
|
76
76
|
describe 'customized configuration' do
|
77
77
|
|
78
78
|
it 'should support specification of "enable" options' do
|
79
|
-
@installer.enable.
|
79
|
+
@installer.enable.should == %w( headers ssl deflate so )
|
80
80
|
end
|
81
81
|
|
82
82
|
it 'should support specification of "disable" options' do
|
83
|
-
@installer.disable.
|
83
|
+
@installer.disable.should == %w( cache proxy rewrite )
|
84
84
|
end
|
85
85
|
|
86
86
|
it 'should support specification of "with" options' do
|
87
|
-
@installer.with.
|
87
|
+
@installer.with.should == %w( debug extras )
|
88
88
|
end
|
89
89
|
|
90
90
|
it 'should support specification of "without" options' do
|
91
|
-
@installer.without.
|
91
|
+
@installer.without.should == %w( fancyisms pandas )
|
92
92
|
end
|
93
93
|
|
94
94
|
it 'should support specification of "option" options' do
|
95
|
-
@installer.option.
|
95
|
+
@installer.option.should == %w( foo bar baz )
|
96
96
|
end
|
97
97
|
|
98
98
|
it 'should support customized build area' do
|
99
|
-
@installer.prefix.
|
99
|
+
@installer.prefix.should == '/usr/local'
|
100
100
|
end
|
101
101
|
|
102
102
|
it 'should support customized source area' do
|
103
|
-
@installer.archives.
|
103
|
+
@installer.archives.should == '/usr/local/archives'
|
104
104
|
end
|
105
105
|
|
106
106
|
it 'should support customized install area' do
|
107
|
-
@installer.builds.
|
107
|
+
@installer.builds.should == '/usr/local/builds'
|
108
108
|
end
|
109
109
|
end
|
110
110
|
|
@@ -285,9 +285,16 @@ describe Sprinkle::Installers::Source do
|
|
285
285
|
it 'should run all pre-prepare commands' do
|
286
286
|
@commands.each { |k, v| @installer.should_receive(:pre_commands).with(k).and_return(v) }
|
287
287
|
end
|
288
|
+
|
289
|
+
it "should be logged" do
|
290
|
+
pending
|
291
|
+
end
|
288
292
|
|
289
293
|
it 'should be run relative to the source build area' do
|
290
|
-
|
294
|
+
[:prepare, :download, :extract].each { |stage, command|
|
295
|
+
@installer.send(:pre_commands, stage).first.should_not =~ %r{cd /usr/builds/ruby-1.8.6-p111} }
|
296
|
+
[:configure, :build, :install].each { |stage, command|
|
297
|
+
@installer.send(:pre_commands, stage).first.should =~ %r{cd /usr/builds/ruby-1.8.6-p111} }
|
291
298
|
end
|
292
299
|
|
293
300
|
after do
|
@@ -318,7 +325,10 @@ describe Sprinkle::Installers::Source do
|
|
318
325
|
end
|
319
326
|
|
320
327
|
it 'should be run relative to the source build area' do
|
321
|
-
|
328
|
+
[:prepare, :download].each { |stage, command|
|
329
|
+
@installer.send(:post_commands, stage).first.should_not =~ %r{cd /usr/builds/ruby-1.8.6-p111} }
|
330
|
+
[:extract, :configure, :build, :install].each { |stage, command|
|
331
|
+
@installer.send(:post_commands, stage).first.should =~ %r{cd /usr/builds/ruby-1.8.6-p111} }
|
322
332
|
end
|
323
333
|
|
324
334
|
after do
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require File.expand_path("../../spec_helper", File.dirname(__FILE__))
|
2
|
+
|
3
|
+
describe Sprinkle::Installers::User do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@package = mock(Sprinkle::Package, :name => 'spec')
|
7
|
+
@user = "bob"
|
8
|
+
end
|
9
|
+
|
10
|
+
def create_user(name, options = {}, &block)
|
11
|
+
Sprinkle::Installers::User.new "spec", name, options, &block
|
12
|
+
end
|
13
|
+
|
14
|
+
describe 'during installation' do
|
15
|
+
|
16
|
+
it "should invoke add user" do
|
17
|
+
@installer = create_user 'bob'
|
18
|
+
@install_commands = @installer.send :install_commands
|
19
|
+
@install_commands.should == "adduser --gecos ,,, bob"
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should use actual gecos options if passed" do
|
23
|
+
@installer = create_user 'bob', :flags => "--gecos bob,,,"
|
24
|
+
@install_commands = @installer.send :install_commands
|
25
|
+
@install_commands.should == "adduser --gecos bob,,, bob"
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
@@ -140,17 +140,6 @@ describe Sprinkle::Verify do
|
|
140
140
|
end
|
141
141
|
end
|
142
142
|
|
143
|
-
describe 'with configurations' do
|
144
|
-
# Make sure it includes Sprinkle::Configurable
|
145
|
-
it 'should respond to configurable methods' do
|
146
|
-
@verification.should respond_to(:defaults)
|
147
|
-
end
|
148
|
-
|
149
|
-
it 'should default padding option to 4' do
|
150
|
-
@verification.padding.should eql(4)
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
143
|
describe 'with process' do
|
155
144
|
it 'should raise an error when no delivery mechanism is set' do
|
156
145
|
@verification.instance_variable_set(:@delivery, nil)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sprinkle
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-05-
|
13
|
+
date: 2013-05-27 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rspec
|
@@ -169,15 +169,13 @@ files:
|
|
169
169
|
- lib/sprinkle/actors/local.rb
|
170
170
|
- lib/sprinkle/actors/ssh.rb
|
171
171
|
- lib/sprinkle/actors/vlad.rb
|
172
|
-
- lib/sprinkle/configurable.rb
|
173
172
|
- lib/sprinkle/deployment.rb
|
174
173
|
- lib/sprinkle/errors/pretty_failure.rb
|
175
174
|
- lib/sprinkle/errors/remote_command_failure.rb
|
176
175
|
- lib/sprinkle/errors/transfer_failure.rb
|
177
|
-
- lib/sprinkle/extensions/arbitrary_options.rb
|
178
176
|
- lib/sprinkle/extensions/array.rb
|
177
|
+
- lib/sprinkle/extensions/attributes.rb
|
179
178
|
- lib/sprinkle/extensions/blank_slate.rb
|
180
|
-
- lib/sprinkle/extensions/dsl_accessor.rb
|
181
179
|
- lib/sprinkle/extensions/string.rb
|
182
180
|
- lib/sprinkle/extensions/symbol.rb
|
183
181
|
- lib/sprinkle/installers/apt.rb
|
@@ -235,7 +233,6 @@ files:
|
|
235
233
|
- spec/sprinkle/actors/capistrano_spec.rb
|
236
234
|
- spec/sprinkle/actors/local_spec.rb
|
237
235
|
- spec/sprinkle/actors/ssh_spec.rb
|
238
|
-
- spec/sprinkle/configurable_spec.rb
|
239
236
|
- spec/sprinkle/deployment_spec.rb
|
240
237
|
- spec/sprinkle/extensions/array_spec.rb
|
241
238
|
- spec/sprinkle/extensions/string_spec.rb
|
@@ -261,6 +258,7 @@ files:
|
|
261
258
|
- spec/sprinkle/installers/source_spec.rb
|
262
259
|
- spec/sprinkle/installers/thor_spec.rb
|
263
260
|
- spec/sprinkle/installers/transfer_spec.rb
|
261
|
+
- spec/sprinkle/installers/user_spec.rb
|
264
262
|
- spec/sprinkle/installers/yum_spec.rb
|
265
263
|
- spec/sprinkle/installers/zypper_spec.rb
|
266
264
|
- spec/sprinkle/package_spec.rb
|
@@ -300,7 +298,6 @@ test_files:
|
|
300
298
|
- spec/sprinkle/actors/capistrano_spec.rb
|
301
299
|
- spec/sprinkle/actors/local_spec.rb
|
302
300
|
- spec/sprinkle/actors/ssh_spec.rb
|
303
|
-
- spec/sprinkle/configurable_spec.rb
|
304
301
|
- spec/sprinkle/deployment_spec.rb
|
305
302
|
- spec/sprinkle/extensions/array_spec.rb
|
306
303
|
- spec/sprinkle/extensions/string_spec.rb
|
@@ -326,6 +323,7 @@ test_files:
|
|
326
323
|
- spec/sprinkle/installers/source_spec.rb
|
327
324
|
- spec/sprinkle/installers/thor_spec.rb
|
328
325
|
- spec/sprinkle/installers/transfer_spec.rb
|
326
|
+
- spec/sprinkle/installers/user_spec.rb
|
329
327
|
- spec/sprinkle/installers/yum_spec.rb
|
330
328
|
- spec/sprinkle/installers/zypper_spec.rb
|
331
329
|
- spec/sprinkle/package_spec.rb
|
@@ -1,32 +0,0 @@
|
|
1
|
-
module Sprinkle
|
2
|
-
#--
|
3
|
-
# TODO: Possible documentation?
|
4
|
-
#++
|
5
|
-
module Configurable #:nodoc:
|
6
|
-
attr_accessor :delivery
|
7
|
-
|
8
|
-
def defaults(deployment)
|
9
|
-
defaults = deployment.defaults[self.class.name.split(/::/).last.downcase.to_sym]
|
10
|
-
self.instance_eval(&defaults) if defaults
|
11
|
-
@delivery = deployment.style
|
12
|
-
end
|
13
|
-
|
14
|
-
def assert_delivery
|
15
|
-
raise 'Unknown command delivery target' unless @delivery
|
16
|
-
end
|
17
|
-
|
18
|
-
def method_missing(sym, *args, &block)
|
19
|
-
unless args.empty? # mutate if not set
|
20
|
-
@options ||= {}
|
21
|
-
@options[sym] = args unless @options[sym]
|
22
|
-
end
|
23
|
-
|
24
|
-
@options[sym] || @package.send(sym, *args, &block) # try the parents options if unknown
|
25
|
-
end
|
26
|
-
|
27
|
-
# both nil and false should return false
|
28
|
-
def option?(sym)
|
29
|
-
!!@options[sym]
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
@@ -1,10 +0,0 @@
|
|
1
|
-
module ArbitraryOptions #:nodoc:
|
2
|
-
def self.included(base)
|
3
|
-
base.alias_method_chain :method_missing, :arbitrary_options
|
4
|
-
end
|
5
|
-
|
6
|
-
def method_missing_with_arbitrary_options(sym, *args, &block)
|
7
|
-
self.class.dsl_accessor sym
|
8
|
-
send(sym, *args, &block)
|
9
|
-
end
|
10
|
-
end
|
@@ -1,47 +0,0 @@
|
|
1
|
-
require File.expand_path("../spec_helper", File.dirname(__FILE__))
|
2
|
-
|
3
|
-
describe Sprinkle::Configurable do
|
4
|
-
module MyPrefix
|
5
|
-
class Configurable
|
6
|
-
include Sprinkle::Configurable
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
before do
|
11
|
-
@configurable = MyPrefix::Configurable.new
|
12
|
-
@default = Proc.new { }
|
13
|
-
@defaults = { :configurable => @default }
|
14
|
-
@deployment = Object.new
|
15
|
-
@deployment.stub!(:defaults).and_return(@defaults)
|
16
|
-
@deployment.stub!(:style)
|
17
|
-
end
|
18
|
-
|
19
|
-
it 'should be configurable via external defaults' do
|
20
|
-
@configurable.should respond_to(:defaults)
|
21
|
-
end
|
22
|
-
|
23
|
-
it 'should select the defaults for the particular concrete installer class' do
|
24
|
-
@deployment.should_receive(:defaults).and_return(@defaults)
|
25
|
-
@defaults.should_receive(:[]).with(:configurable).and_return(@default)
|
26
|
-
end
|
27
|
-
|
28
|
-
it 'should configure the installer delivery mechansim' do
|
29
|
-
@configurable.should_receive(:instance_eval)
|
30
|
-
end
|
31
|
-
|
32
|
-
it 'should maintain an options hash set arbitrarily via method missing' do
|
33
|
-
@configurable.instance_eval do
|
34
|
-
hsv 'gts'
|
35
|
-
end
|
36
|
-
@configurable.hsv.first.should == 'gts'
|
37
|
-
end
|
38
|
-
|
39
|
-
it 'should allow the delivery instance variable to be accessed' do
|
40
|
-
@configurable.delivery = "string"
|
41
|
-
@configurable.instance_variable_get(:@delivery).should eql("string")
|
42
|
-
end
|
43
|
-
|
44
|
-
after do
|
45
|
-
@configurable.defaults(@deployment)
|
46
|
-
end
|
47
|
-
end
|