cuken 0.1.13 → 0.1.15
Sign up to get free protection for your applications and to get access to all the features.
- data/.rvmrc +61 -0
- data/Gemfile +17 -15
- data/Gemfile.lock +55 -63
- data/VERSION +1 -1
- data/cuken.gems +46 -0
- data/cuken.gemspec +85 -31
- data/features/about.md +4 -0
- data/features/avagrant_steps/vagrant_steps.feature +13 -0
- data/features/chef_examples/cookbooks_cookbook.feature +1 -1
- data/features/chef_examples/cookbooks_metadata.feature +5 -5
- data/features/chef_examples/cookbooks_repo.feature +1 -1
- data/features/chef_examples/knife_admin_client.feature +12 -12
- data/features/chef_examples/knife_client_create.feature +1 -1
- data/features/chef_examples/zenoss_example/01_chef_server_setup.feature +1 -1
- data/features/chef_examples/zenoss_example/02_monitor_vm_setup.feature +1 -1
- data/features/chef_steps/cookbook_steps.feature +6 -16
- data/features/command_examples/commands.feature +3 -3
- data/features/command_examples/exit_statuses.feature +49 -0
- data/features/command_examples/file_system_commands.feature +128 -0
- data/features/command_examples/flushing.feature +24 -0
- data/features/command_examples/interactive.feature +57 -0
- data/features/command_examples/no_clobber.feature +41 -0
- data/features/command_examples/output.feature +205 -0
- data/features/command_steps/command_steps.feature +49 -42
- data/features/file_examples/files.feature +5 -5
- data/features/git_examples/git_clone.feature +33 -0
- data/features/ssh_examples/ssh.feature +11 -2
- data/features/step_definitions/cuken_steps.rb +3 -2
- data/features/support/env.rb +2 -1
- data/lib/cuken/all.rb +1 -0
- data/lib/cuken/api/aruba/api.rb +342 -0
- data/lib/cuken/api/aruba/hooks.rb +63 -0
- data/lib/cuken/api/aruba/process.rb +74 -0
- data/lib/cuken/api/aruba.rb +5 -0
- data/lib/cuken/api/chef/common.rb +8 -1
- data/lib/cuken/api/chef/cookbook.rb +31 -5
- data/lib/cuken/api/chef/knife.rb +3 -3
- data/lib/cuken/api/chef/role.rb +3 -3
- data/lib/cuken/api/chef.rb +98 -9
- data/lib/cuken/api/cmd.rb +8 -8
- data/lib/cuken/api/common.rb +11 -23
- data/lib/cuken/api/file.rb +38 -38
- data/lib/cuken/api/git/clone.rb +25 -0
- data/lib/cuken/api/git/common.rb +37 -0
- data/lib/cuken/api/git/remote.rb +16 -0
- data/lib/cuken/api/git/repository.rb +62 -0
- data/lib/cuken/api/git.rb +69 -0
- data/lib/cuken/api/rvm/common.rb +10 -0
- data/lib/cuken/api/rvm/gemsets.rb +33 -0
- data/lib/cuken/api/rvm/wip.rb +554 -0
- data/lib/cuken/api/rvm.rb +25 -479
- data/lib/cuken/api/ssh.rb +85 -4
- data/lib/cuken/api/vagrant/common.rb +7 -4
- data/lib/cuken/api/vagrant/v_m.rb +2 -2
- data/lib/cuken/api/vagrant.rb +3 -3
- data/lib/cuken/common.rb +3 -1
- data/lib/cuken/cucumber/chef/common.rb +3 -3
- data/lib/cuken/cucumber/chef/cookbook/action.rb +81 -0
- data/lib/cuken/cucumber/chef/cookbook/local.rb +71 -0
- data/lib/cuken/cucumber/chef/cookbook/remote.rb +37 -0
- data/lib/cuken/cucumber/chef/cookbook.rb +3 -140
- data/lib/cuken/cucumber/chef/cookbook_steps.rb +1 -1
- data/lib/cuken/cucumber/chef/deploy_steps.rb +1 -1
- data/lib/cuken/cucumber/chef/done_directory_steps.rb +2 -2
- data/lib/cuken/cucumber/chef/done_file_steps.rb +5 -5
- data/lib/cuken/cucumber/chef/knife.rb +1 -1
- data/lib/cuken/cucumber/chef.rb +1 -1
- data/lib/cuken/cucumber/cmd/execution.rb +34 -0
- data/lib/cuken/cucumber/cmd/exit_status.rb +30 -0
- data/lib/cuken/cucumber/cmd.rb +2 -36
- data/lib/cuken/cucumber/common.rb +42 -6
- data/lib/cuken/cucumber/file.rb +42 -37
- data/lib/cuken/cucumber/git/clone.rb +51 -0
- data/lib/cuken/cucumber/git/common.rb +36 -0
- data/lib/cuken/cucumber/git/local.rb +19 -0
- data/lib/cuken/cucumber/git/remote.rb +22 -0
- data/lib/cuken/cucumber/git.rb +26 -0
- data/lib/cuken/cucumber/output/all.rb +41 -0
- data/lib/cuken/cucumber/output/cmd.rb +46 -0
- data/lib/cuken/cucumber/output/stderr.rb +33 -0
- data/lib/cuken/cucumber/output/stdout.rb +34 -0
- data/lib/cuken/cucumber/rvm/common.rb +0 -0
- data/lib/cuken/cucumber/rvm/gemsets.rb +32 -0
- data/lib/cuken/cucumber/rvm/hooks.rb +0 -0
- data/lib/cuken/cucumber/rvm.rb +3 -1
- data/lib/cuken/cucumber/ssh/common.rb +51 -0
- data/lib/cuken/cucumber/ssh.rb +3 -35
- data/lib/cuken/cucumber/vagrant.rb +1 -1
- data/lib/cuken/git.rb +21 -0
- data/spec/api/rvm/gemsets/api_spec.rb +41 -0
- data/spec/api/rvm/gemsets/helper_spec.rb +19 -0
- data/spec/api/rvm_spec.rb +63 -15
- data/spec/api/vagrant/v_m/Vagrantfile +82 -0
- data/spec/api/vagrant/v_m/api_spec.rb +37 -0
- data/spec/spec_helper.rb +39 -0
- metadata +123 -45
- data/spec/cuken_spec.rb +0 -7
@@ -24,9 +24,10 @@ end
|
|
24
24
|
|
25
25
|
Then /^these steps are defined for "([^\"]*)":$/ do |file, table|
|
26
26
|
rsc = ::Cucumber::Runtime::SupportCode.new 'ui', :autoload_code_paths => 'lib/cuken/cucumber'
|
27
|
-
|
27
|
+
announce_or_puts("Loading: lib/#{file}") if @announce
|
28
|
+
rsc.load_files! ["lib/#{file}"] #"#{ENV['GEM_HOME']}/gems/aruba-0.3.6/lib/aruba/cucumber.rb"
|
28
29
|
sd_array = rsc.step_definitions
|
29
|
-
|
30
|
+
sd_array.each{|sd| puts sd.regexp_source}
|
30
31
|
table.hashes.each do |hsh|
|
31
32
|
sd_array.each{|sd| res = sd.regexp_source == %Q{/^#{hsh['step']}$/}; break('found') if res}.should == 'found'
|
32
33
|
end
|
data/features/support/env.rb
CHANGED
@@ -6,6 +6,7 @@ rescue Bundler::BundlerError => e
|
|
6
6
|
$stderr.puts "Run `bundle install` to install missing gems"
|
7
7
|
exit e.status_code
|
8
8
|
end
|
9
|
+
require 'rspec/expectations'
|
9
10
|
|
10
11
|
$LOAD_PATH.unshift(File.dirname(__FILE__) + '/../../lib')
|
11
12
|
require 'cuken/ssh'
|
@@ -13,5 +14,5 @@ require 'cuken/cmd'
|
|
13
14
|
require 'cuken/file'
|
14
15
|
require 'cuken/chef'
|
15
16
|
require 'cuken/vagrant'
|
17
|
+
require 'cuken/git'
|
16
18
|
|
17
|
-
require 'rspec/expectations'
|
data/lib/cuken/all.rb
CHANGED
@@ -0,0 +1,342 @@
|
|
1
|
+
#require 'fileutils'
|
2
|
+
#require 'rbconfig'
|
3
|
+
#require 'aruba/process'
|
4
|
+
module ::Cuken
|
5
|
+
module Api
|
6
|
+
module Aruba
|
7
|
+
module Api
|
8
|
+
def in_dir(dir=current_dir, &block)
|
9
|
+
exp_dir = ::File.expand_path(dir)
|
10
|
+
_mkdir(exp_dir)
|
11
|
+
Dir.chdir(exp_dir, &block)
|
12
|
+
end
|
13
|
+
|
14
|
+
def current_dir
|
15
|
+
::File.join(*dirs)
|
16
|
+
end
|
17
|
+
|
18
|
+
def cd(dir)
|
19
|
+
dirs << dir
|
20
|
+
raise "#{current_dir} is not a directory." unless ::File.directory?(current_dir)
|
21
|
+
end
|
22
|
+
|
23
|
+
def dirs
|
24
|
+
@dirs ||= ['tmp/aruba']
|
25
|
+
end
|
26
|
+
|
27
|
+
def write_file(file_name, file_content)
|
28
|
+
_create_file(file_name, file_content, false)
|
29
|
+
end
|
30
|
+
|
31
|
+
def overwrite_file(file_name, file_content)
|
32
|
+
_create_file(file_name, file_content, true)
|
33
|
+
end
|
34
|
+
|
35
|
+
def _create_file(file_name, file_content, check_presence)
|
36
|
+
in_dir do
|
37
|
+
raise "expected #{file_name} to be present" if check_presence && !::File.file?(file_name)
|
38
|
+
_mkdir(::File.dirname(file_name))
|
39
|
+
::File.open(file_name, 'w') { |f| f << file_content }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def remove_file(file_name)
|
44
|
+
in_dir do
|
45
|
+
::FileUtils.rm(file_name)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def append_to_file(file_name, file_content)
|
50
|
+
in_dir do
|
51
|
+
::File.open(file_name, 'a') { |f| f << file_content }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def create_dir(dir_name)
|
56
|
+
in_dir do
|
57
|
+
_mkdir(dir_name)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def check_file_presence(paths, expect_presence)
|
62
|
+
prep_for_fs_check do
|
63
|
+
paths.each do |path|
|
64
|
+
if expect_presence
|
65
|
+
::File.should be_file(path)
|
66
|
+
else
|
67
|
+
::File.should_not be_file(path)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# def check_file_content(file, partial_content, expect_match)
|
74
|
+
# regexp = regexp(partial_content)
|
75
|
+
# prep_for_fs_check do
|
76
|
+
# content = IO.read(file)
|
77
|
+
# if expect_match
|
78
|
+
# content.should =~ regexp
|
79
|
+
# else
|
80
|
+
# content.should_not =~ regexp
|
81
|
+
# end
|
82
|
+
# end
|
83
|
+
# end
|
84
|
+
|
85
|
+
def check_file_content(file, partial_content, expect_match, times = 1)
|
86
|
+
regexp = regexp(partial_content)
|
87
|
+
seen_count = 0
|
88
|
+
prep_for_fs_check do
|
89
|
+
content = IO.read(file)
|
90
|
+
while (seen_count < times.to_i || content =~ regexp)do
|
91
|
+
if content =~ regexp
|
92
|
+
content = content.sub(regexp,'')
|
93
|
+
seen_count+=1
|
94
|
+
end
|
95
|
+
end
|
96
|
+
if expect_match
|
97
|
+
seen_count.should == times.to_i
|
98
|
+
else
|
99
|
+
seen_count.should_not == times.to_i
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
def check_exact_file_content(file, exact_content)
|
106
|
+
prep_for_fs_check { IO.read(file).should == exact_content }
|
107
|
+
end
|
108
|
+
|
109
|
+
def check_directory_presence(paths, expect_presence)
|
110
|
+
prep_for_fs_check do
|
111
|
+
paths.each do |path|
|
112
|
+
if expect_presence
|
113
|
+
::File.should be_directory(path)
|
114
|
+
else
|
115
|
+
::File.should_not be_directory(path)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def prep_for_fs_check(&block)
|
122
|
+
stop_processes!
|
123
|
+
in_dir{ block.call }
|
124
|
+
end
|
125
|
+
|
126
|
+
def _mkdir(dir_name)
|
127
|
+
::FileUtils.mkdir_p(dir_name) unless ::File.directory?(dir_name)
|
128
|
+
end
|
129
|
+
|
130
|
+
def unescape(string)
|
131
|
+
string.gsub('\n', "\n").gsub('\"', '"')
|
132
|
+
end
|
133
|
+
|
134
|
+
def regexp(string_or_regexp)
|
135
|
+
Regexp === string_or_regexp ? string_or_regexp : Regexp.compile(Regexp.escape(string_or_regexp))
|
136
|
+
end
|
137
|
+
|
138
|
+
def output_from(cmd)
|
139
|
+
cmd = detect_ruby(cmd)
|
140
|
+
get_process(cmd).output
|
141
|
+
end
|
142
|
+
|
143
|
+
def stdout_from(cmd)
|
144
|
+
cmd = detect_ruby(cmd)
|
145
|
+
get_process(cmd).stdout
|
146
|
+
end
|
147
|
+
|
148
|
+
def stderr_from(cmd)
|
149
|
+
cmd = detect_ruby(cmd)
|
150
|
+
get_process(cmd).stderr
|
151
|
+
end
|
152
|
+
|
153
|
+
def all_stdout
|
154
|
+
only_processes.inject("") { |out, ps| out << ps.stdout }
|
155
|
+
end
|
156
|
+
|
157
|
+
def all_stderr
|
158
|
+
only_processes.inject("") { |out, ps| out << ps.stderr }
|
159
|
+
end
|
160
|
+
|
161
|
+
def all_output
|
162
|
+
all_stdout << all_stderr
|
163
|
+
end
|
164
|
+
|
165
|
+
def assert_exact_output(exact_output)
|
166
|
+
all_output.should == exact_output
|
167
|
+
end
|
168
|
+
|
169
|
+
def assert_partial_output(partial_output)
|
170
|
+
all_output.should include(unescape(partial_output))
|
171
|
+
end
|
172
|
+
|
173
|
+
def assert_passing_with(partial_output)
|
174
|
+
assert_exit_status_and_partial_output(true, partial_output)
|
175
|
+
end
|
176
|
+
|
177
|
+
def assert_failing_with(partial_output)
|
178
|
+
assert_exit_status_and_partial_output(false, partial_output)
|
179
|
+
end
|
180
|
+
|
181
|
+
def assert_exit_status_and_partial_output(expect_to_pass, partial_output)
|
182
|
+
assert_partial_output(partial_output)
|
183
|
+
assert_exiting_with(expect_to_pass)
|
184
|
+
end
|
185
|
+
|
186
|
+
def assert_exit_status_and_output(expect_to_pass, output, expect_exact_output)
|
187
|
+
if expect_exact_output
|
188
|
+
assert_exact_output(output)
|
189
|
+
else
|
190
|
+
assert_partial_output(output)
|
191
|
+
end
|
192
|
+
assert_exiting_with(expect_to_pass)
|
193
|
+
end
|
194
|
+
|
195
|
+
def assert_exiting_with(expect_to_pass)
|
196
|
+
if expect_to_pass
|
197
|
+
@last_exit_status.should == 0
|
198
|
+
else
|
199
|
+
@last_exit_status.should_not == 0
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
def processes
|
204
|
+
@processes ||= []
|
205
|
+
end
|
206
|
+
|
207
|
+
def stop_processes!
|
208
|
+
processes.each do |_, process|
|
209
|
+
process.stop
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
def register_process(name, process)
|
214
|
+
processes << [name, process]
|
215
|
+
end
|
216
|
+
|
217
|
+
def get_process(wanted)
|
218
|
+
processes.find{ |name, _| name == wanted }[-1]
|
219
|
+
end
|
220
|
+
|
221
|
+
def only_processes
|
222
|
+
processes.collect{ |_, process| process }
|
223
|
+
end
|
224
|
+
|
225
|
+
def run(cmd, dir=current_dir)
|
226
|
+
cmd = detect_ruby(cmd)
|
227
|
+
|
228
|
+
in_dir(dir) do
|
229
|
+
announce_or_puts("$ cd #{Dir.pwd}") if @announce_dir
|
230
|
+
announce_or_puts("$ #{cmd}") if @announce_cmd
|
231
|
+
|
232
|
+
process = Process.new(cmd, exit_timeout, io_wait)
|
233
|
+
register_process(cmd, process)
|
234
|
+
process.run!
|
235
|
+
|
236
|
+
block_given? ? yield(process) : process
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
DEFAULT_TIMEOUT_SECONDS = 3
|
241
|
+
|
242
|
+
def exit_timeout
|
243
|
+
@aruba_timeout_seconds || DEFAULT_TIMEOUT_SECONDS
|
244
|
+
end
|
245
|
+
|
246
|
+
DEFAULT_IO_WAIT_SECONDS = 0.1
|
247
|
+
|
248
|
+
def io_wait
|
249
|
+
@aruba_io_wait_seconds || DEFAULT_IO_WAIT_SECONDS
|
250
|
+
end
|
251
|
+
|
252
|
+
def run_simple(cmd, dir=current_dir, fail_on_error=true)
|
253
|
+
@last_exit_status = run(cmd, dir) do |process|
|
254
|
+
process.stop
|
255
|
+
announce_or_puts(process.stdout) if @announce_stdout
|
256
|
+
announce_or_puts(process.stderr) if @announce_stderr
|
257
|
+
# need to replace with process.exit_code or similar, or remove the block entirely... it doesn't add as much as I thought it would
|
258
|
+
process.stop
|
259
|
+
end
|
260
|
+
@timed_out = @last_exit_status.nil?
|
261
|
+
|
262
|
+
if(@last_exit_status != 0 && fail_on_error)
|
263
|
+
fail("Exit status was #{@last_exit_status}. Output:\n#{all_output}")
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
def run_interactive(cmd, dir=current_dir)
|
268
|
+
@interactive = run(cmd, dir)
|
269
|
+
end
|
270
|
+
|
271
|
+
def type(input)
|
272
|
+
_write_interactive(_ensure_newline(input))
|
273
|
+
end
|
274
|
+
|
275
|
+
def _write_interactive(input)
|
276
|
+
@interactive.stdin.write(input)
|
277
|
+
end
|
278
|
+
|
279
|
+
def _ensure_newline(str)
|
280
|
+
str.chomp << "\n"
|
281
|
+
end
|
282
|
+
|
283
|
+
def announce_or_puts(msg)
|
284
|
+
puts(msg)
|
285
|
+
end
|
286
|
+
|
287
|
+
def detect_ruby(cmd)
|
288
|
+
if cmd =~ /^ruby\s/
|
289
|
+
cmd.gsub(/^ruby\s/, "#{current_ruby} ")
|
290
|
+
else
|
291
|
+
cmd
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
def current_ruby
|
296
|
+
::File.join(RbConfig::CONFIG['bindir'], RbConfig::CONFIG['ruby_install_name'])
|
297
|
+
end
|
298
|
+
|
299
|
+
def use_clean_gemset(gemset)
|
300
|
+
run_simple(%{rvm gemset create "#{gemset}"}, true)
|
301
|
+
if all_stdout =~ /'#{gemset}' gemset created \((.*)\)\./
|
302
|
+
gem_home = $1
|
303
|
+
set_env('GEM_HOME', gem_home)
|
304
|
+
set_env('GEM_PATH', gem_home)
|
305
|
+
set_env('BUNDLE_PATH', gem_home)
|
306
|
+
|
307
|
+
paths = (ENV['PATH'] || "").split(File::PATH_SEPARATOR)
|
308
|
+
paths.unshift(::File.join(gem_home, 'bin'))
|
309
|
+
set_env('PATH', paths.uniq.join(File::PATH_SEPARATOR))
|
310
|
+
|
311
|
+
run_simple("gem install bundler", true)
|
312
|
+
else
|
313
|
+
raise "I didn't understand rvm's output: #{all_stdout}"
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
def unset_bundler_env_vars
|
318
|
+
%w[RUBYOPT BUNDLE_PATH BUNDLE_BIN_PATH BUNDLE_GEMFILE].each do |key|
|
319
|
+
set_env(key, nil)
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
def set_env(key, value)
|
324
|
+
announce_or_puts(%{$ export #{key}="#{value}"}) if @announce_env
|
325
|
+
original_env[key] = ENV.delete(key)
|
326
|
+
ENV[key] = value
|
327
|
+
end
|
328
|
+
|
329
|
+
def restore_env
|
330
|
+
original_env.each do |key, value|
|
331
|
+
ENV[key] = value
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
def original_env
|
336
|
+
@original_env ||= {}
|
337
|
+
end
|
338
|
+
end
|
339
|
+
end
|
340
|
+
end
|
341
|
+
end
|
342
|
+
|
@@ -0,0 +1,63 @@
|
|
1
|
+
|
2
|
+
unless defined?(::Before) && !Before.is_a?(Class)
|
3
|
+
puts "#{defined?(Before).inspect}"
|
4
|
+
puts "do we see this?"
|
5
|
+
puts require 'cucumber'
|
6
|
+
puts 'are we loaded?'
|
7
|
+
puts "#{defined?(Before).inspect}"
|
8
|
+
puts "do we see this?"
|
9
|
+
puts !Before.is_a?(Class)
|
10
|
+
end
|
11
|
+
|
12
|
+
Before('@disable-bundler') do
|
13
|
+
unset_bundler_env_vars
|
14
|
+
end
|
15
|
+
|
16
|
+
Before do
|
17
|
+
@__aruba_original_paths = (ENV['PATH'] || '').split(File::PATH_SEPARATOR)
|
18
|
+
ENV['PATH'] = ([File.expand_path('bin')] + @__aruba_original_paths).join(File::PATH_SEPARATOR)
|
19
|
+
end
|
20
|
+
|
21
|
+
After do
|
22
|
+
ENV['PATH'] = @__aruba_original_paths.join(File::PATH_SEPARATOR)
|
23
|
+
end
|
24
|
+
|
25
|
+
Before('~@no-clobber') do
|
26
|
+
FileUtils.rm_rf(current_dir)
|
27
|
+
end
|
28
|
+
|
29
|
+
Before('@puts') do
|
30
|
+
@puts = true
|
31
|
+
end
|
32
|
+
|
33
|
+
Before('@announce-cmd') do
|
34
|
+
@announce_cmd = true
|
35
|
+
end
|
36
|
+
|
37
|
+
Before('@announce-stdout') do
|
38
|
+
@announce_stdout = true
|
39
|
+
end
|
40
|
+
|
41
|
+
Before('@announce-stderr') do
|
42
|
+
@announce_stderr = true
|
43
|
+
end
|
44
|
+
|
45
|
+
Before('@announce-dir') do
|
46
|
+
@announce_dir = true
|
47
|
+
end
|
48
|
+
|
49
|
+
Before('@announce-env') do
|
50
|
+
@announce_env = true
|
51
|
+
end
|
52
|
+
|
53
|
+
Before('@announce') do
|
54
|
+
@announce_stdout = true
|
55
|
+
@announce_stderr = true
|
56
|
+
@announce_cmd = true
|
57
|
+
@announce_dir = true
|
58
|
+
@announce_env = true
|
59
|
+
end
|
60
|
+
|
61
|
+
After do
|
62
|
+
restore_env
|
63
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'childprocess'
|
2
|
+
require 'tempfile'
|
3
|
+
require 'shellwords'
|
4
|
+
|
5
|
+
module ::Cuken
|
6
|
+
module Api
|
7
|
+
module Aruba
|
8
|
+
class Process
|
9
|
+
include Shellwords
|
10
|
+
|
11
|
+
def remove_ansi_codes(str)
|
12
|
+
str.gsub(/\e\[(\d+)m/, '')
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(cmd, exit_timeout, io_wait)
|
16
|
+
@exit_timeout = exit_timeout
|
17
|
+
@io_wait = io_wait
|
18
|
+
|
19
|
+
@out = ::Tempfile.new("aruba-out")
|
20
|
+
@err = ::Tempfile.new("aruba-err")
|
21
|
+
@process = ChildProcess.build(*shellwords(cmd))
|
22
|
+
@process.io.stdout = @out
|
23
|
+
@process.io.stderr = @err
|
24
|
+
@process.duplex = true
|
25
|
+
end
|
26
|
+
|
27
|
+
def run!(&block)
|
28
|
+
@process.start
|
29
|
+
yield self if block_given?
|
30
|
+
end
|
31
|
+
|
32
|
+
def stdin
|
33
|
+
wait_for_io do
|
34
|
+
@process.io.stdin
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def output
|
39
|
+
stdout + stderr
|
40
|
+
end
|
41
|
+
|
42
|
+
def stdout
|
43
|
+
wait_for_io do
|
44
|
+
@out.rewind
|
45
|
+
remove_ansi_codes(@out.read)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def stderr
|
50
|
+
wait_for_io do
|
51
|
+
@err.rewind
|
52
|
+
remove_ansi_codes(@err.read)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def stop
|
57
|
+
if @process
|
58
|
+
stdout && stderr # flush output
|
59
|
+
@process.poll_for_exit(@exit_timeout)
|
60
|
+
@process.exit_code
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def wait_for_io(&block)
|
67
|
+
sleep @io_wait if @process.alive?
|
68
|
+
yield
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
@@ -57,7 +57,14 @@ module ::Cuken
|
|
57
57
|
|
58
58
|
def in_chef_root(&block)
|
59
59
|
raise "You need to specify a Chef root directory." unless chef.root_dir
|
60
|
-
|
60
|
+
if chef.root_dir.to_s[0] == '/'
|
61
|
+
::Dir.chdir(chef.root_dir, &block)
|
62
|
+
else
|
63
|
+
in_dir do
|
64
|
+
chef.root_dir = ::File.expand_path(chef.root_dir)
|
65
|
+
::Dir.chdir(chef.root_dir, &block)
|
66
|
+
end
|
67
|
+
end
|
61
68
|
end
|
62
69
|
|
63
70
|
def knife
|
@@ -21,10 +21,10 @@ module ::Cuken
|
|
21
21
|
|
22
22
|
def parse_to_cookbooks_path(hsh)
|
23
23
|
case
|
24
|
-
when
|
24
|
+
when !(hsh['cookbook'].nil? || hsh['cookbook'].empty?)
|
25
25
|
ckbk = hsh['cookbook']
|
26
26
|
ckbk_src = "cookbooks/#{ckbk}"
|
27
|
-
when
|
27
|
+
when !(hsh['site-cookbook'].nil? || hsh['site-cookbook'].empty?)
|
28
28
|
ckbk = hsh['site-cookbook']
|
29
29
|
ckbk_src = "site-cookbooks/#{ckbk}"
|
30
30
|
else
|
@@ -61,8 +61,8 @@ module ::Cuken
|
|
61
61
|
in_chef_root do
|
62
62
|
list1 = chef.cookbooks_paths.find_all { |dir| Pathname(dir + path_fragment1 + path_fagment2).exist? }
|
63
63
|
list2 = chef.cookbook_paths.find_all { |dir| (dir.to_s[/#{ckbk_src}/] && Pathname(dir+path_fagment2).exist?) }
|
64
|
-
loc = list2[0] || ((list1[0] + ckbk) if list1[0].exist?)
|
65
|
-
if loc.nil? ||
|
64
|
+
loc = list2[0] || ((list1[0] + ckbk) if list1[0] && list1[0].exist?)
|
65
|
+
if loc.nil? || !(loc.exist?)
|
66
66
|
# TODO: error handling if data bags or cookbooks do not exist
|
67
67
|
else
|
68
68
|
full_data_bag_src = (loc + path_fagment2).expand_path.realdirpath.to_s
|
@@ -94,7 +94,7 @@ module ::Cuken
|
|
94
94
|
chef.cookbook_paths.each do |pn|
|
95
95
|
curr_ckbk = pn.basename.to_s
|
96
96
|
condition = Pathname(pn).exist?
|
97
|
-
given_ckbk = Pathname(ckbk).basename.to_s
|
97
|
+
given_ckbk = Pathname(ckbk).basename.to_s if ckbk
|
98
98
|
result = given_ckbk == curr_ckbk
|
99
99
|
if condition && result
|
100
100
|
given_ckbk.should == curr_ckbk
|
@@ -111,6 +111,15 @@ module ::Cuken
|
|
111
111
|
end
|
112
112
|
end
|
113
113
|
|
114
|
+
def cookbooks_delete(table)
|
115
|
+
table.hashes.each do |hsh|
|
116
|
+
ckbk, ckbk_src = parse_to_cookbooks_path(hsh)
|
117
|
+
full_cookbook_src = find_path_in_cookbook_folders(ckbk, ckbk_src, ckbk)
|
118
|
+
version = hsh['version'] ? hsh['version'] : 'all'
|
119
|
+
cookbook_delete(ckbk, version)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
114
123
|
def cookbook_load(ckbk)
|
115
124
|
|
116
125
|
knife_config_file_error_handling()
|
@@ -127,6 +136,23 @@ module ::Cuken
|
|
127
136
|
run_knife(argv)
|
128
137
|
end
|
129
138
|
|
139
|
+
def cookbook_delete(ckbk, version='all')
|
140
|
+
|
141
|
+
knife_config_file_error_handling()
|
142
|
+
|
143
|
+
ckbk_pth = nil
|
144
|
+
in_chef_root do
|
145
|
+
ckbk_pth = unless chef.cookbooks_paths.empty?
|
146
|
+
(chef.cookbooks_paths.collect { |pn| pn.expand_path.to_s }).join(':')
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
argv = ['cookbook', 'delete', ckbk]
|
151
|
+
version == 'all' ? argv << '--all' : argv << version
|
152
|
+
argv << '--yes' << '--no-editor'
|
153
|
+
run_knife(argv)
|
154
|
+
end
|
155
|
+
|
130
156
|
def cookbooks_list
|
131
157
|
|
132
158
|
knife_config_file_error_handling()
|
data/lib/cuken/api/chef/knife.rb
CHANGED
@@ -95,7 +95,7 @@ module ::Cuken
|
|
95
95
|
|
96
96
|
def node_show(node_name, attr = :all)
|
97
97
|
Pathname(chef.knife_config_file).exist?.should be_true
|
98
|
-
argv = ['node', 'show', node_name, '--no-editor', '--config', chef.knife_config_file]
|
98
|
+
argv = ['node', 'show', node_name, '--no-editor', '--config', chef.knife_config_file.to_s]
|
99
99
|
unless attr == :all
|
100
100
|
argv << '--attribute' << attr
|
101
101
|
end
|
@@ -110,7 +110,7 @@ module ::Cuken
|
|
110
110
|
end
|
111
111
|
|
112
112
|
def node_role_load(hsh)
|
113
|
-
argv = ['node', 'run_list', 'add', hsh[:node], "role[#{hsh[:role]}]", '--no-editor', '--config', chef.knife_config_file]
|
113
|
+
argv = ['node', 'run_list', 'add', hsh[:node], "role[#{hsh[:role]}]", '--no-editor', '--config', chef.knife_config_file.to_s]
|
114
114
|
if Pathname(chef.knife_config_file).exist?
|
115
115
|
with_args *argv do
|
116
116
|
::Chef::Application::Knife.new.run
|
@@ -122,7 +122,7 @@ module ::Cuken
|
|
122
122
|
end
|
123
123
|
|
124
124
|
def node_create(node_name)
|
125
|
-
argv = ['node', 'create', node_name, '--no-editor', '--config', chef.knife_config_file]
|
125
|
+
argv = ['node', 'create', node_name, '--no-editor', '--config', chef.knife_config_file.to_s]
|
126
126
|
if Pathname(chef.knife_config_file).exist?
|
127
127
|
with_args *argv do
|
128
128
|
::Chef::Application::Knife.new.run
|
data/lib/cuken/api/chef/role.rb
CHANGED
@@ -25,14 +25,14 @@ module ::Cuken
|
|
25
25
|
in_chef_root do
|
26
26
|
table.hashes.each do |hsh|
|
27
27
|
case
|
28
|
-
when
|
28
|
+
when !(hsh['cookbook'].nil? || hsh['cookbook'].empty?)
|
29
29
|
src = "cookbooks/#{hsh['cookbook']}/roles/#{hsh['role']}"
|
30
|
-
when
|
30
|
+
when !(hsh['site-cookbook'].nil? || hsh['site-cookbook'].empty?)
|
31
31
|
src = "site-cookbooks/#{hsh['site-cookbook']}/roles/#{hsh['role']}"
|
32
32
|
else
|
33
33
|
src =""
|
34
34
|
end
|
35
|
-
role_load(src)
|
35
|
+
role_load(::File.expand_path(src))
|
36
36
|
end
|
37
37
|
end
|
38
38
|
end
|