jamie 0.1.0.alpha20 → 0.1.0.alpha21
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/jamie.gemspec +1 -0
- data/lib/jamie/cli.rb +22 -8
- data/lib/jamie/driver/dummy.rb +10 -5
- data/lib/jamie/version.rb +1 -1
- data/lib/jamie.rb +107 -123
- data/spec/jamie_spec.rb +44 -44
- metadata +4 -3
data/jamie.gemspec
CHANGED
@@ -6,6 +6,7 @@ require 'jamie/version'
|
|
6
6
|
Gem::Specification.new do |gem|
|
7
7
|
gem.name = "jamie"
|
8
8
|
gem.version = Jamie::VERSION
|
9
|
+
gem.license = 'Apache 2.0'
|
9
10
|
gem.authors = ["Fletcher Nichol"]
|
10
11
|
gem.email = ["fnichol@nichol.ca"]
|
11
12
|
gem.description = %q{A Chef convergence integration test harness}
|
data/lib/jamie/cli.rb
CHANGED
@@ -16,6 +16,7 @@
|
|
16
16
|
# See the License for the specific language governing permissions and
|
17
17
|
# limitations under the License.
|
18
18
|
|
19
|
+
require 'benchmark'
|
19
20
|
require 'ostruct'
|
20
21
|
require 'thor'
|
21
22
|
|
@@ -29,6 +30,7 @@ module Jamie
|
|
29
30
|
class CLI < Thor
|
30
31
|
|
31
32
|
include Thor::Actions
|
33
|
+
include Logging
|
32
34
|
|
33
35
|
# Constructs a new instance.
|
34
36
|
def initialize(*args)
|
@@ -64,12 +66,16 @@ module Jamie
|
|
64
66
|
method_option :destroy, :aliases => "-d", :default => "passing",
|
65
67
|
:desc => "Destroy strategy to use after testing (passing, always, never)."
|
66
68
|
def test(*args)
|
67
|
-
|
68
|
-
|
69
|
-
|
69
|
+
banner "Starting Jamie"
|
70
|
+
elapsed = Benchmark.measure do
|
71
|
+
destroy_mode = options[:destroy]
|
72
|
+
if ! %w{passing always never}.include?(options[:destroy])
|
73
|
+
raise ArgumentError, "Destroy mode must be passing, always, or never."
|
74
|
+
end
|
75
|
+
result = parse_subcommand(args.first)
|
76
|
+
Array(result).each { |instance| instance.test(destroy_mode.to_sym) }
|
70
77
|
end
|
71
|
-
|
72
|
-
Array(result).each { |instance| instance.test(destroy_mode.to_sym) }
|
78
|
+
banner "Jamie is finished. (#{elapsed.real} seconds)"
|
73
79
|
end
|
74
80
|
|
75
81
|
desc "login (['REGEX']|[INSTANCE])", "Log in to one instance"
|
@@ -118,10 +124,18 @@ module Jamie
|
|
118
124
|
|
119
125
|
attr_reader :task
|
120
126
|
|
127
|
+
def logger
|
128
|
+
Jamie.logger
|
129
|
+
end
|
130
|
+
|
121
131
|
def exec_action(action)
|
122
|
-
|
123
|
-
|
124
|
-
|
132
|
+
banner "Starting Jamie"
|
133
|
+
elapsed = Benchmark.measure do
|
134
|
+
@task = action
|
135
|
+
result = parse_subcommand(args.first)
|
136
|
+
Array(result).each { |instance| instance.send(task) }
|
137
|
+
end
|
138
|
+
banner "Jamie is finished. (#{elapsed.real} seconds)"
|
125
139
|
end
|
126
140
|
|
127
141
|
def parse_subcommand(arg = nil)
|
data/lib/jamie/driver/dummy.rb
CHANGED
@@ -27,10 +27,11 @@ module Jamie
|
|
27
27
|
# @author Fletcher Nichol <fnichol@nichol.ca>
|
28
28
|
class Dummy < Jamie::Driver::Base
|
29
29
|
|
30
|
-
default_config
|
30
|
+
default_config :sleep, 0
|
31
|
+
default_config :random_failure, false
|
31
32
|
|
32
33
|
def create(state)
|
33
|
-
state[
|
34
|
+
state[:my_id] = "#{instance.name}-#{Time.now.to_i}"
|
34
35
|
report(:create, state)
|
35
36
|
end
|
36
37
|
|
@@ -48,7 +49,7 @@ module Jamie
|
|
48
49
|
|
49
50
|
def destroy(state)
|
50
51
|
report(:destroy, state)
|
51
|
-
state.delete(
|
52
|
+
state.delete(:my_id)
|
52
53
|
end
|
53
54
|
|
54
55
|
private
|
@@ -56,8 +57,12 @@ module Jamie
|
|
56
57
|
def report(action, state)
|
57
58
|
info("[Dummy] Action ##{action} called on " +
|
58
59
|
"instance=#{instance} with state=#{state}")
|
59
|
-
sleep(config[
|
60
|
-
|
60
|
+
sleep(config[:sleep].to_f) if config[:sleep].to_f > 0.0
|
61
|
+
if config[:random_failure] && [true, false].sample
|
62
|
+
debug("[Dummy] Random failure for action ##{action}.")
|
63
|
+
raise ActionFailed, "Action ##{action} failed for #{instance.to_str}."
|
64
|
+
end
|
65
|
+
debug("[Dummy] Action ##{action} completed (#{config[:sleep]}s).")
|
61
66
|
end
|
62
67
|
end
|
63
68
|
end
|
data/lib/jamie/version.rb
CHANGED
data/lib/jamie.rb
CHANGED
@@ -88,14 +88,14 @@ module Jamie
|
|
88
88
|
# convergence integration
|
89
89
|
def platforms
|
90
90
|
@platforms ||= Collection.new(
|
91
|
-
Array(yaml[
|
91
|
+
Array(yaml[:platforms]).map { |hash| new_platform(hash) })
|
92
92
|
end
|
93
93
|
|
94
94
|
# @return [Array<Suite>] all defined suites which will be used in
|
95
95
|
# convergence integration
|
96
96
|
def suites
|
97
97
|
@suites ||= Collection.new(
|
98
|
-
Array(yaml[
|
98
|
+
Array(yaml[:suites]).map { |hash| new_suite(hash) })
|
99
99
|
end
|
100
100
|
|
101
101
|
# @return [Array<Instance>] all instances, resulting from all platform and
|
@@ -163,12 +163,11 @@ module Jamie
|
|
163
163
|
private
|
164
164
|
|
165
165
|
def new_suite(hash)
|
166
|
-
data_bags_path = calculate_data_bags_path(hash['name'])
|
167
|
-
roles_path = calculate_roles_path(hash['name'])
|
168
166
|
path_hash = {
|
169
|
-
|
170
|
-
|
167
|
+
:data_bags_path => calculate_path("data_bags", hash[:name]),
|
168
|
+
:roles_path => calculate_path("roles", hash[:name]),
|
171
169
|
}
|
170
|
+
|
172
171
|
Suite.new(hash.rmerge(path_hash))
|
173
172
|
end
|
174
173
|
|
@@ -177,9 +176,10 @@ module Jamie
|
|
177
176
|
end
|
178
177
|
|
179
178
|
def new_driver(hash)
|
180
|
-
hash[
|
181
|
-
hash[
|
182
|
-
|
179
|
+
hash[:driver_config] ||= Hash.new
|
180
|
+
hash[:driver_config][:jamie_root] = jamie_root
|
181
|
+
|
182
|
+
Driver.for_plugin(hash[:driver_plugin], hash[:driver_config])
|
183
183
|
end
|
184
184
|
|
185
185
|
def new_instance(suite, platform)
|
@@ -189,18 +189,18 @@ module Jamie
|
|
189
189
|
FileUtils.mkdir_p(log_root)
|
190
190
|
|
191
191
|
Instance.new(
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
192
|
+
:suite => suite,
|
193
|
+
:platform => platform,
|
194
|
+
:driver => driver,
|
195
|
+
:jr => Jr.new(suite.name),
|
196
|
+
:logger => new_instance_logger(log_root)
|
197
197
|
)
|
198
198
|
end
|
199
199
|
|
200
200
|
def platform_driver_hash(platform_name)
|
201
|
-
h = yaml[
|
201
|
+
h = yaml[:platforms].find { |p| p[:name] == platform_name } || Hash.new
|
202
202
|
|
203
|
-
h.select { |key, value|
|
203
|
+
h.select { |key, value| [ :driver_plugin, :driver_config ].include?(key) }
|
204
204
|
end
|
205
205
|
|
206
206
|
def new_instance_logger(log_root)
|
@@ -215,7 +215,8 @@ module Jamie
|
|
215
215
|
end
|
216
216
|
|
217
217
|
def yaml
|
218
|
-
@yaml ||=
|
218
|
+
@yaml ||= Util.symbolized_hash(
|
219
|
+
YAML.load(yaml_contents).rmerge(local_yaml))
|
219
220
|
end
|
220
221
|
|
221
222
|
def yaml_contents
|
@@ -245,44 +246,30 @@ module Jamie
|
|
245
246
|
default_driver_hash.rmerge(common_driver_hash.rmerge(driver_hash))
|
246
247
|
end
|
247
248
|
|
248
|
-
def
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
if File.directory?(suite_roles_path)
|
254
|
-
suite_roles_path
|
255
|
-
elsif File.directory?(common_roles_path)
|
256
|
-
common_roles_path
|
257
|
-
elsif File.directory?(top_level_roles_path)
|
258
|
-
top_level_roles_path
|
259
|
-
else
|
260
|
-
nil
|
261
|
-
end
|
262
|
-
end
|
263
|
-
|
264
|
-
def calculate_data_bags_path(suite_name)
|
265
|
-
suite_data_bags_path = File.join(test_base_path, suite_name, "data_bags")
|
266
|
-
common_data_bags_path = File.join(test_base_path, "data_bags")
|
267
|
-
top_level_data_bags_path = File.join(Dir.pwd, "data_bags")
|
249
|
+
def calculate_path(path, suite_name)
|
250
|
+
suite_path = File.join(test_base_path, suite_name, path)
|
251
|
+
common_path = File.join(test_base_path, path)
|
252
|
+
top_level_path = File.join(Dir.pwd, path)
|
268
253
|
|
269
|
-
if File.directory?(
|
270
|
-
|
271
|
-
elsif File.directory?(
|
272
|
-
|
273
|
-
elsif File.directory?(
|
274
|
-
|
254
|
+
if File.directory?(suite_path)
|
255
|
+
suite_path
|
256
|
+
elsif File.directory?(common_path)
|
257
|
+
common_path
|
258
|
+
elsif File.directory?(top_level_path)
|
259
|
+
top_level_path
|
275
260
|
else
|
276
261
|
nil
|
277
262
|
end
|
278
263
|
end
|
279
264
|
|
280
265
|
def default_driver_hash
|
281
|
-
{
|
266
|
+
{ :driver_plugin => DEFAULT_DRIVER_PLUGIN, :driver_config => {} }
|
282
267
|
end
|
283
268
|
|
284
269
|
def common_driver_hash
|
285
|
-
yaml.select
|
270
|
+
yaml.select do |key, value|
|
271
|
+
[ :driver_plugin, :driver_config ].include?(key)
|
272
|
+
end
|
286
273
|
end
|
287
274
|
end
|
288
275
|
|
@@ -445,20 +432,21 @@ module Jamie
|
|
445
432
|
# (**Required**)
|
446
433
|
# @option options [Hash] :attributes Hash of Chef node attributes
|
447
434
|
# @option options [String] :data_bags_path path to data bags
|
435
|
+
# @option options [String] :roles_path path to roles
|
448
436
|
def initialize(options = {})
|
449
437
|
validate_options(options)
|
450
438
|
|
451
|
-
@name = options[
|
452
|
-
@run_list = options[
|
453
|
-
@attributes = options[
|
454
|
-
@data_bags_path = options[
|
455
|
-
@roles_path = options[
|
439
|
+
@name = options[:name]
|
440
|
+
@run_list = options[:run_list]
|
441
|
+
@attributes = options[:attributes] || Hash.new
|
442
|
+
@data_bags_path = options[:data_bags_path]
|
443
|
+
@roles_path = options[:roles_path]
|
456
444
|
end
|
457
445
|
|
458
446
|
private
|
459
447
|
|
460
448
|
def validate_options(opts)
|
461
|
-
|
449
|
+
[ :name, :run_list ].each do |k|
|
462
450
|
raise ArgumentError, "Attribute '#{k}' is required." if opts[k].nil?
|
463
451
|
end
|
464
452
|
end
|
@@ -491,15 +479,15 @@ module Jamie
|
|
491
479
|
def initialize(options = {})
|
492
480
|
validate_options(options)
|
493
481
|
|
494
|
-
@name = options[
|
495
|
-
@run_list = Array(options[
|
496
|
-
@attributes = options[
|
482
|
+
@name = options[:name]
|
483
|
+
@run_list = Array(options[:run_list])
|
484
|
+
@attributes = options[:attributes] || Hash.new
|
497
485
|
end
|
498
486
|
|
499
487
|
private
|
500
488
|
|
501
489
|
def validate_options(opts)
|
502
|
-
|
490
|
+
[ :name ].each do |k|
|
503
491
|
raise ArgumentError, "Attribute '#{k}' is required." if opts[k].nil?
|
504
492
|
end
|
505
493
|
end
|
@@ -539,14 +527,14 @@ module Jamie
|
|
539
527
|
# @option options [Jr] :jr the jr command string generator
|
540
528
|
# @option options [Logger] :logger the instance logger
|
541
529
|
def initialize(options = {})
|
542
|
-
options = {
|
530
|
+
options = { :logger => Jamie.logger }.merge(options)
|
543
531
|
validate_options(options)
|
544
|
-
logger = options[
|
532
|
+
logger = options[:logger]
|
545
533
|
|
546
|
-
@suite = options[
|
547
|
-
@platform = options[
|
548
|
-
@driver = options[
|
549
|
-
@jr = options[
|
534
|
+
@suite = options[:suite]
|
535
|
+
@platform = options[:platform]
|
536
|
+
@driver = options[:driver]
|
537
|
+
@jr = options[:jr]
|
550
538
|
@logger = logger.is_a?(Proc) ? logger.call(name) : logger
|
551
539
|
|
552
540
|
@driver.instance = self
|
@@ -557,7 +545,7 @@ module Jamie
|
|
557
545
|
"#{suite.name}-#{platform.name}".gsub(/_/, '-').gsub(/\./, '')
|
558
546
|
end
|
559
547
|
|
560
|
-
def
|
548
|
+
def to_str
|
561
549
|
"<#{name}>"
|
562
550
|
end
|
563
551
|
|
@@ -578,7 +566,7 @@ module Jamie
|
|
578
566
|
end
|
579
567
|
|
580
568
|
def dna
|
581
|
-
attributes.rmerge({
|
569
|
+
attributes.rmerge({ :run_list => run_list })
|
582
570
|
end
|
583
571
|
|
584
572
|
# Creates this instance.
|
@@ -648,13 +636,13 @@ module Jamie
|
|
648
636
|
# to gracfully stop action chaining
|
649
637
|
def test(destroy_mode = :passing)
|
650
638
|
elapsed = Benchmark.measure do
|
651
|
-
banner "Cleaning up any prior instances of #{
|
639
|
+
banner "Cleaning up any prior instances of #{to_str}"
|
652
640
|
destroy
|
653
|
-
banner "Testing #{
|
641
|
+
banner "Testing #{to_str}"
|
654
642
|
verify
|
655
643
|
destroy if destroy_mode == :passing
|
656
644
|
end
|
657
|
-
info "
|
645
|
+
info "Finished testing #{to_str} (#{elapsed.real} seconds)."
|
658
646
|
self
|
659
647
|
ensure
|
660
648
|
destroy if destroy_mode == :always
|
@@ -677,7 +665,7 @@ module Jamie
|
|
677
665
|
private
|
678
666
|
|
679
667
|
def validate_options(opts)
|
680
|
-
|
668
|
+
[ :suite, :platform, :driver, :jr, :logger ].each do |k|
|
681
669
|
raise ArgumentError, "Attribute '#{k}' is required." if opts[k].nil?
|
682
670
|
end
|
683
671
|
end
|
@@ -691,38 +679,31 @@ module Jamie
|
|
691
679
|
end
|
692
680
|
|
693
681
|
def create_action
|
694
|
-
|
695
|
-
elapsed = action(:create) { |state| driver.create(state) }
|
696
|
-
info "Creation of #{self} complete (#{elapsed.real} seconds)."
|
697
|
-
self
|
682
|
+
perform_action(:create, "Creating")
|
698
683
|
end
|
699
684
|
|
700
685
|
def converge_action
|
701
|
-
|
702
|
-
elapsed = action(:converge) { |state| driver.converge(state) }
|
703
|
-
info "Convergence of #{self} complete (#{elapsed.real} seconds)."
|
704
|
-
self
|
686
|
+
perform_action(:converge, "Converging")
|
705
687
|
end
|
706
688
|
|
707
689
|
def setup_action
|
708
|
-
|
709
|
-
elapsed = action(:setup) { |state| driver.setup(state) }
|
710
|
-
info "Setup of #{self} complete (#{elapsed.real} seconds)."
|
711
|
-
self
|
690
|
+
perform_action(:setup, "Setting up")
|
712
691
|
end
|
713
692
|
|
714
693
|
def verify_action
|
715
|
-
|
716
|
-
elapsed = action(:verify) { |state| driver.verify(state) }
|
717
|
-
info "Verification of #{self} complete (#{elapsed.real} seconds)."
|
718
|
-
self
|
694
|
+
perform_action(:verify, "Verifying")
|
719
695
|
end
|
720
696
|
|
721
697
|
def destroy_action
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
698
|
+
perform_action(:destroy, "Destroying") { destroy_state }
|
699
|
+
end
|
700
|
+
|
701
|
+
def perform_action(verb, output_verb)
|
702
|
+
banner "#{output_verb} #{to_str}"
|
703
|
+
elapsed = action(verb) { |state| driver.public_send(verb, state) }
|
704
|
+
info("Finished #{output_verb.downcase} #{to_str}" +
|
705
|
+
" (#{elapsed.real} seconds).")
|
706
|
+
yield if block_given?
|
726
707
|
self
|
727
708
|
end
|
728
709
|
|
@@ -731,14 +712,18 @@ module Jamie
|
|
731
712
|
elapsed = Benchmark.measure do
|
732
713
|
yield state if block_given?
|
733
714
|
end
|
734
|
-
state[
|
715
|
+
state[:last_action] = what.to_s
|
735
716
|
elapsed
|
736
717
|
ensure
|
737
718
|
dump_state(state)
|
738
719
|
end
|
739
720
|
|
740
721
|
def load_state
|
741
|
-
File.exists?(statefile)
|
722
|
+
if File.exists?(statefile)
|
723
|
+
Util.symbolized_hash(YAML.load_file(statefile))
|
724
|
+
else
|
725
|
+
Hash.new
|
726
|
+
end
|
742
727
|
end
|
743
728
|
|
744
729
|
def dump_state(state)
|
@@ -754,12 +739,12 @@ module Jamie
|
|
754
739
|
|
755
740
|
def statefile
|
756
741
|
File.expand_path(File.join(
|
757
|
-
driver[
|
742
|
+
driver[:jamie_root], ".jamie", "#{name}.yml"
|
758
743
|
))
|
759
744
|
end
|
760
745
|
|
761
746
|
def last_action
|
762
|
-
load_state[
|
747
|
+
load_state[:last_action]
|
763
748
|
end
|
764
749
|
|
765
750
|
# The simplest finite state machine pseudo-implementation needed to manage
|
@@ -974,6 +959,16 @@ module Jamie
|
|
974
959
|
else :fatal
|
975
960
|
end
|
976
961
|
end
|
962
|
+
|
963
|
+
def self.symbolized_hash(obj)
|
964
|
+
if obj.is_a?(Hash)
|
965
|
+
obj.inject({}) { |h, (k,v)| h[k.to_sym] = symbolized_hash(v) ; h }
|
966
|
+
elsif obj.is_a?(Array)
|
967
|
+
obj.inject([]) { |a, v| a << symbolized_hash(v) ; a }
|
968
|
+
else
|
969
|
+
obj
|
970
|
+
end
|
971
|
+
end
|
977
972
|
end
|
978
973
|
|
979
974
|
# Mixin that wraps a command shell out invocation, providing a #run_command
|
@@ -1114,7 +1109,7 @@ module Jamie
|
|
1114
1109
|
end
|
1115
1110
|
|
1116
1111
|
def run_command(cmd, use_sudo = nil, log_subject = nil)
|
1117
|
-
use_sudo = config[
|
1112
|
+
use_sudo = config[:use_sudo] if use_sudo.nil?
|
1118
1113
|
log_subject = Util.to_snake_case(self.class.to_s)
|
1119
1114
|
|
1120
1115
|
super(cmd, use_sudo, log_subject)
|
@@ -1144,7 +1139,7 @@ module Jamie
|
|
1144
1139
|
def converge(state)
|
1145
1140
|
ssh_args = build_ssh_args(state)
|
1146
1141
|
|
1147
|
-
install_omnibus(ssh_args) if config[
|
1142
|
+
install_omnibus(ssh_args) if config[:require_chef_omnibus]
|
1148
1143
|
prepare_chef_home(ssh_args)
|
1149
1144
|
upload_chef_data(ssh_args)
|
1150
1145
|
run_chef_solo(ssh_args)
|
@@ -1174,8 +1169,8 @@ module Jamie
|
|
1174
1169
|
def login_command(state)
|
1175
1170
|
args = %W{ -o UserKnownHostsFile=/dev/null }
|
1176
1171
|
args += %W{ -o StrictHostKeyChecking=no }
|
1177
|
-
args += %W{ -i #{config[
|
1178
|
-
args += %W{ #{config[
|
1172
|
+
args += %W{ -i #{config[:ssh_key]}} if config[:ssh_key]
|
1173
|
+
args += %W{ #{config[:username]}@#{state[:hostname]}}
|
1179
1174
|
|
1180
1175
|
["ssh", *args]
|
1181
1176
|
end
|
@@ -1186,10 +1181,10 @@ module Jamie
|
|
1186
1181
|
opts = Hash.new
|
1187
1182
|
opts[:user_known_hosts_file] = "/dev/null"
|
1188
1183
|
opts[:paranoid] = false
|
1189
|
-
opts[:password] = config[
|
1190
|
-
opts[:keys] = Array(config[
|
1184
|
+
opts[:password] = config[:password] if config[:password]
|
1185
|
+
opts[:keys] = Array(config[:ssh_key]) if config[:ssh_key]
|
1191
1186
|
|
1192
|
-
[ state[
|
1187
|
+
[ state[:hostname], config[:username], opts ]
|
1193
1188
|
end
|
1194
1189
|
|
1195
1190
|
def chef_home
|
@@ -1210,7 +1205,7 @@ module Jamie
|
|
1210
1205
|
|
1211
1206
|
def upload_chef_data(ssh_args)
|
1212
1207
|
Jamie::ChefDataUploader.new(
|
1213
|
-
instance, ssh_args, config[
|
1208
|
+
instance, ssh_args, config[:jamie_root], chef_home
|
1214
1209
|
).upload
|
1215
1210
|
end
|
1216
1211
|
|
@@ -1262,7 +1257,7 @@ module Jamie
|
|
1262
1257
|
end
|
1263
1258
|
|
1264
1259
|
def test_ssh(hostname)
|
1265
|
-
socket = TCPSocket.new(hostname, config[
|
1260
|
+
socket = TCPSocket.new(hostname, config[:port])
|
1266
1261
|
IO.select([socket], nil, nil, 5)
|
1267
1262
|
rescue SocketError, Errno::ECONNREFUSED,
|
1268
1263
|
Errno::EHOSTUNREACH, Errno::ENETUNREACH, IOError
|
@@ -1321,36 +1316,25 @@ module Jamie
|
|
1321
1316
|
end
|
1322
1317
|
|
1323
1318
|
def upload_cookbooks(scp)
|
1324
|
-
|
1325
|
-
scp
|
1326
|
-
:recursive => true
|
1327
|
-
) do |ch, name, sent, total|
|
1328
|
-
if sent == total
|
1329
|
-
info("Uploaded #{name.sub(%r{^#{ckbks_dir}/}, '')} (#{total} bytes)")
|
1330
|
-
end
|
1331
|
-
end
|
1319
|
+
cookbooks_dir = local_cookbooks
|
1320
|
+
upload_path(scp, cookbooks_dir, "cookbooks")
|
1332
1321
|
ensure
|
1333
|
-
FileUtils.rmtree(
|
1322
|
+
FileUtils.rmtree(cookbooks_dir)
|
1334
1323
|
end
|
1335
1324
|
|
1336
1325
|
def upload_data_bags(scp)
|
1337
|
-
|
1338
|
-
scp.upload!(dbags_dir, "#{chef_home}/data_bags",
|
1339
|
-
:recursive => true
|
1340
|
-
) do |ch, name, sent, total|
|
1341
|
-
if sent == total
|
1342
|
-
info("Uploaded #{name.sub(%r{^#{dbags_dir}/}, '')} (#{total} bytes)")
|
1343
|
-
end
|
1344
|
-
end
|
1326
|
+
upload_path(scp, instance.suite.data_bags_path)
|
1345
1327
|
end
|
1346
1328
|
|
1347
1329
|
def upload_roles(scp)
|
1348
|
-
|
1349
|
-
|
1350
|
-
|
1330
|
+
upload_path(scp, instance.suite.roles_path)
|
1331
|
+
end
|
1332
|
+
|
1333
|
+
def upload_path(scp, path, dir = File.basename(path))
|
1334
|
+
scp.upload!(path, "#{chef_home}/#{dir}", :recursive => true
|
1351
1335
|
) do |ch, name, sent, total|
|
1352
1336
|
if sent == total
|
1353
|
-
info("Uploaded #{name.sub(%r{^#{
|
1337
|
+
info("Uploaded #{name.sub(%r{^#{path}/}, '')} (#{total} bytes)")
|
1354
1338
|
end
|
1355
1339
|
end
|
1356
1340
|
end
|
@@ -1389,7 +1373,7 @@ module Jamie
|
|
1389
1373
|
def run_berks(tmpdir)
|
1390
1374
|
begin
|
1391
1375
|
run_command "if ! command -v berks >/dev/null; then exit 1; fi"
|
1392
|
-
rescue
|
1376
|
+
rescue Jamie::ShellOut::ShellCommandFailed
|
1393
1377
|
abort ">>>>>> Berkshelf must be installed, add it to your Gemfile."
|
1394
1378
|
end
|
1395
1379
|
run_command "berks install --path #{tmpdir}"
|
@@ -1398,7 +1382,7 @@ module Jamie
|
|
1398
1382
|
def run_librarian(tmpdir)
|
1399
1383
|
begin
|
1400
1384
|
run_command "if ! command -v librarian-chef >/dev/null; then exit 1; fi"
|
1401
|
-
rescue
|
1385
|
+
rescue Jamie::ShellOut::ShellCommandFailed
|
1402
1386
|
abort ">>>>>> Librarian must be installed, add it to your Gemfile."
|
1403
1387
|
end
|
1404
1388
|
run_command "librarian-chef install --path #{tmpdir}"
|
data/spec/jamie_spec.rb
CHANGED
@@ -151,7 +151,7 @@ describe Jamie::Config do
|
|
151
151
|
'platforms' => [ { 'name' => 'platform', 'driver_plugin' => 'dummy' } ],
|
152
152
|
'suites' => [ { 'name' => 'suite', 'run_list' => [] }]
|
153
153
|
})
|
154
|
-
config.instances.first.driver[
|
154
|
+
config.instances.first.driver[:jamie_root].must_equal "/tmp"
|
155
155
|
end
|
156
156
|
|
157
157
|
it "returns an instance with a driver initialized with passed in config" do
|
@@ -162,7 +162,7 @@ describe Jamie::Config do
|
|
162
162
|
],
|
163
163
|
'suites' => [ { 'name' => 'suite', 'run_list' => [] }]
|
164
164
|
})
|
165
|
-
config.instances.first.driver[
|
165
|
+
config.instances.first.driver[:foo].must_equal "bar"
|
166
166
|
end
|
167
167
|
end
|
168
168
|
|
@@ -176,7 +176,7 @@ describe Jamie::Config do
|
|
176
176
|
stub_yaml!(".jamie.local.yml", {
|
177
177
|
'driver_config' => { 'foo' => 'bar' }
|
178
178
|
})
|
179
|
-
config.instances.first.driver[
|
179
|
+
config.instances.first.driver[:foo].must_equal 'bar'
|
180
180
|
end
|
181
181
|
|
182
182
|
it "merges over configuration in jamie.yml" do
|
@@ -188,7 +188,7 @@ describe Jamie::Config do
|
|
188
188
|
stub_yaml!(".jamie.local.yml", {
|
189
189
|
'driver_config' => { 'foo' => 'bar' }
|
190
190
|
})
|
191
|
-
config.instances.first.driver[
|
191
|
+
config.instances.first.driver[:foo].must_equal 'bar'
|
192
192
|
end
|
193
193
|
end
|
194
194
|
|
@@ -222,8 +222,8 @@ describe Jamie::Config do
|
|
222
222
|
<% end %>
|
223
223
|
YAML
|
224
224
|
end
|
225
|
-
config.instances.first.driver[
|
226
|
-
config.instances.first.driver[
|
225
|
+
config.instances.first.driver[:noodle].must_equal "soup"
|
226
|
+
config.instances.first.driver[:mushroom].must_equal "soup"
|
227
227
|
end
|
228
228
|
end
|
229
229
|
|
@@ -307,16 +307,16 @@ end
|
|
307
307
|
|
308
308
|
describe Jamie::Suite do
|
309
309
|
|
310
|
-
let(:opts) do ; {
|
310
|
+
let(:opts) do ; { :name => 'suitezy', :run_list => [ 'doowah' ] } ; end
|
311
311
|
let(:suite) { Jamie::Suite.new(opts) }
|
312
312
|
|
313
313
|
it "raises an ArgumentError if name is missing" do
|
314
|
-
opts.delete(
|
314
|
+
opts.delete(:name)
|
315
315
|
proc { Jamie::Suite.new(opts) }.must_raise ArgumentError
|
316
316
|
end
|
317
317
|
|
318
318
|
it "raises an ArgumentError if run_list is missing" do
|
319
|
-
opts.delete(
|
319
|
+
opts.delete(:run_list)
|
320
320
|
proc { Jamie::Suite.new(opts) }.must_raise ArgumentError
|
321
321
|
end
|
322
322
|
|
@@ -333,11 +333,11 @@ describe Jamie::Suite do
|
|
333
333
|
end
|
334
334
|
|
335
335
|
it "returns attributes from constructor" do
|
336
|
-
opts.merge!({
|
337
|
-
|
336
|
+
opts.merge!({ :attributes => { :a => 'b' }, :data_bags_path => 'crazy',
|
337
|
+
:roles_path => 'town' })
|
338
338
|
suite.name.must_equal 'suitezy'
|
339
339
|
suite.run_list.must_equal [ 'doowah' ]
|
340
|
-
suite.attributes.must_equal({
|
340
|
+
suite.attributes.must_equal({ :a => 'b' })
|
341
341
|
suite.data_bags_path.must_equal 'crazy'
|
342
342
|
suite.roles_path.must_equal 'town'
|
343
343
|
end
|
@@ -345,11 +345,11 @@ end
|
|
345
345
|
|
346
346
|
describe Jamie::Platform do
|
347
347
|
|
348
|
-
let(:opts) do ; {
|
348
|
+
let(:opts) do ; { :name => 'plata' } ; end
|
349
349
|
let(:platform) { Jamie::Platform.new(opts) }
|
350
350
|
|
351
351
|
it "raises an ArgumentError if name is missing" do
|
352
|
-
opts.delete(
|
352
|
+
opts.delete(:name)
|
353
353
|
proc { Jamie::Platform.new(opts) }.must_raise ArgumentError
|
354
354
|
end
|
355
355
|
|
@@ -362,23 +362,23 @@ describe Jamie::Platform do
|
|
362
362
|
end
|
363
363
|
|
364
364
|
it "returns attributes from constructor" do
|
365
|
-
opts.merge!({
|
365
|
+
opts.merge!({ :run_list => [ 'a', 'b' ], :attributes => { :c => 'd' }})
|
366
366
|
platform.name.must_equal 'plata'
|
367
367
|
platform.run_list.must_equal [ 'a', 'b' ]
|
368
|
-
platform.attributes.must_equal({
|
368
|
+
platform.attributes.must_equal({ :c => 'd' })
|
369
369
|
end
|
370
370
|
end
|
371
371
|
|
372
372
|
describe Jamie::Instance do
|
373
373
|
|
374
374
|
let(:suite) do
|
375
|
-
Jamie::Suite.new({
|
376
|
-
|
375
|
+
Jamie::Suite.new({ :name => 'suite',
|
376
|
+
:run_list => 'suite_list', :attributes => { :s => 'ss' } })
|
377
377
|
end
|
378
378
|
|
379
379
|
let(:platform) do
|
380
|
-
Jamie::Platform.new({
|
381
|
-
|
380
|
+
Jamie::Platform.new({ :name => 'platform',
|
381
|
+
:run_list => 'platform_list', :attributes => { :p => 'pp' } })
|
382
382
|
end
|
383
383
|
|
384
384
|
let(:driver) { Jamie::Driver::Dummy.new({}) }
|
@@ -386,18 +386,18 @@ describe Jamie::Instance do
|
|
386
386
|
let(:jr) { Jamie::Jr.new(suite.name) }
|
387
387
|
|
388
388
|
let(:opts) do
|
389
|
-
{
|
389
|
+
{ :suite => suite, :platform => platform, :driver => driver, :jr => jr }
|
390
390
|
end
|
391
391
|
|
392
392
|
let(:instance) { Jamie::Instance.new(opts) }
|
393
393
|
|
394
394
|
it "raises an ArgumentError if suite is missing" do
|
395
|
-
opts.delete(
|
395
|
+
opts.delete(:suite)
|
396
396
|
proc { Jamie::Instance.new(opts) }.must_raise ArgumentError
|
397
397
|
end
|
398
398
|
|
399
399
|
it "raises an ArgumentError if platform is missing" do
|
400
|
-
opts.delete(
|
400
|
+
opts.delete(:platform)
|
401
401
|
proc { Jamie::Instance.new(opts) }.must_raise ArgumentError
|
402
402
|
end
|
403
403
|
|
@@ -416,11 +416,11 @@ describe Jamie::Instance do
|
|
416
416
|
describe "#name" do
|
417
417
|
|
418
418
|
def combo(suite_name, platform_name)
|
419
|
-
opts[
|
420
|
-
|
419
|
+
opts[:suite] = Jamie::Suite.new(
|
420
|
+
:name => suite_name, :run_list => []
|
421
421
|
)
|
422
|
-
opts[
|
423
|
-
|
422
|
+
opts[:platform] = Jamie::Platform.new(
|
423
|
+
:name => platform_name
|
424
424
|
)
|
425
425
|
Jamie::Instance.new(opts)
|
426
426
|
end
|
@@ -445,11 +445,11 @@ describe Jamie::Instance do
|
|
445
445
|
describe "#run_list" do
|
446
446
|
|
447
447
|
def combo(suite_list, platform_list)
|
448
|
-
opts[
|
449
|
-
|
448
|
+
opts[:suite] = Jamie::Suite.new(
|
449
|
+
:name => 'suite', :run_list => suite_list
|
450
450
|
)
|
451
|
-
opts[
|
452
|
-
|
451
|
+
opts[:platform] = Jamie::Platform.new(
|
452
|
+
:name => 'platform', :run_list => platform_list
|
453
453
|
)
|
454
454
|
Jamie::Instance.new(opts)
|
455
455
|
end
|
@@ -470,37 +470,37 @@ describe Jamie::Instance do
|
|
470
470
|
describe "#attributes" do
|
471
471
|
|
472
472
|
def combo(suite_attrs, platform_attrs)
|
473
|
-
opts[
|
474
|
-
|
473
|
+
opts[:suite] = Jamie::Suite.new(
|
474
|
+
:name => 'suite', :run_list => [], :attributes => suite_attrs
|
475
475
|
)
|
476
|
-
opts[
|
477
|
-
|
476
|
+
opts[:platform] = Jamie::Platform.new(
|
477
|
+
:name => 'platform', :attributes => platform_attrs
|
478
478
|
)
|
479
479
|
Jamie::Instance.new(opts)
|
480
480
|
end
|
481
481
|
|
482
482
|
it "merges suite and platform hashes together" do
|
483
483
|
combo(
|
484
|
-
{
|
485
|
-
{
|
484
|
+
{ :suite => { :s1 => 'sv1' } },
|
485
|
+
{ :suite => { :p1 => 'pv1' }, :platform => 'pp' }
|
486
486
|
).attributes.must_equal({
|
487
|
-
|
488
|
-
|
487
|
+
:suite => { :s1 => 'sv1', :p1 => 'pv1' },
|
488
|
+
:platform => 'pp'
|
489
489
|
})
|
490
490
|
end
|
491
491
|
|
492
492
|
it "merges suite values over platform values" do
|
493
493
|
combo(
|
494
|
-
{
|
495
|
-
{
|
494
|
+
{ :common => { :c1 => 'xxx' } },
|
495
|
+
{ :common => { :c1 => 'cv1', :c2 => 'cv2' } },
|
496
496
|
).attributes.must_equal({
|
497
|
-
|
497
|
+
:common => { :c1 => 'xxx', :c2 => 'cv2' }
|
498
498
|
})
|
499
499
|
end
|
500
500
|
end
|
501
501
|
|
502
502
|
it "#dna combines attributes with the run_list" do
|
503
|
-
instance.dna.must_equal({
|
504
|
-
|
503
|
+
instance.dna.must_equal({ :s => 'ss', :p => 'pp',
|
504
|
+
:run_list => [ 'platform_list', 'suite_list' ] })
|
505
505
|
end
|
506
506
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jamie
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.0.
|
4
|
+
version: 0.1.0.alpha21
|
5
5
|
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-01-
|
12
|
+
date: 2013-01-09 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: thor
|
@@ -253,7 +253,8 @@ files:
|
|
253
253
|
- templates/plugin/license_reserved.erb
|
254
254
|
- templates/plugin/version.rb.erb
|
255
255
|
homepage: https://github.com/jamie-ci/jamie
|
256
|
-
licenses:
|
256
|
+
licenses:
|
257
|
+
- Apache 2.0
|
257
258
|
post_install_message:
|
258
259
|
rdoc_options: []
|
259
260
|
require_paths:
|