kameleon-builder 2.10.9 → 2.10.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.bumpversion.cfg +1 -1
- data/CHANGES +263 -243
- data/lib/kameleon/cli.rb +62 -67
- data/lib/kameleon/context.rb +1 -1
- data/lib/kameleon/engine.rb +147 -101
- data/lib/kameleon/recipe.rb +26 -5
- data/lib/kameleon/shell.rb +2 -2
- data/lib/kameleon/step.rb +5 -3
- data/lib/kameleon/utils.rb +1 -1
- data/lib/kameleon/version.rb +1 -1
- data/tests/recipes/test_recipe_checkpoints.yaml +77 -0
- metadata +4 -2
data/lib/kameleon/engine.rb
CHANGED
@@ -17,6 +17,7 @@ module Kameleon
|
|
17
17
|
@cwd = @recipe.global["kameleon_cwd"]
|
18
18
|
@build_recipe_path = File.join(@cwd, ".build_recipe")
|
19
19
|
|
20
|
+
@recipe.global["checkpointing_enabled"] = @options[:enable_checkpointing] ? "true" : "false"
|
20
21
|
@recipe.global["persistent_cache"] = @options[:enable_cache] ? "true" : "false"
|
21
22
|
|
22
23
|
build_recipe = load_build_recipe
|
@@ -26,11 +27,9 @@ module Kameleon
|
|
26
27
|
@recipe.global[key] = build_recipe["global"][key]
|
27
28
|
end
|
28
29
|
end
|
29
|
-
@
|
30
|
-
@enable_checkpoint = true unless @options[:from_checkpoint].nil?
|
31
|
-
@microstep_checkpoint = @options[:microstep_checkpoint]
|
30
|
+
@checkpointing = @options[:enable_checkpointing]
|
32
31
|
# Check if the recipe have checkpoint entry
|
33
|
-
if @
|
32
|
+
if @checkpointing && @recipe.checkpoint.nil?
|
34
33
|
fail BuildError, "Checkpoint is unavailable for this recipe"
|
35
34
|
end
|
36
35
|
|
@@ -78,7 +77,7 @@ module Kameleon
|
|
78
77
|
end
|
79
78
|
unless @options[:no_create_build_dir]
|
80
79
|
begin
|
81
|
-
Kameleon.ui.info("Creating kameleon build directory
|
80
|
+
Kameleon.ui.info("Creating kameleon build directory: #{@cwd}")
|
82
81
|
FileUtils.mkdir_p @cwd
|
83
82
|
rescue
|
84
83
|
raise BuildError, "Failed to create build directory #{@cwd}"
|
@@ -145,7 +144,7 @@ module Kameleon
|
|
145
144
|
|
146
145
|
def create_checkpoint(microstep_id)
|
147
146
|
@recipe.checkpoint["create"].each do |cmd|
|
148
|
-
safe_exec_cmd(cmd.dup.gsub!("@microstep_id", microstep_id))
|
147
|
+
safe_exec_cmd(cmd.dup.gsub!("@microstep_id", microstep_id), :log_level => "warn")
|
149
148
|
end
|
150
149
|
end
|
151
150
|
|
@@ -164,22 +163,18 @@ module Kameleon
|
|
164
163
|
end
|
165
164
|
end
|
166
165
|
|
167
|
-
def list_all_checkpoints
|
168
|
-
list = ""
|
169
|
-
@recipe.checkpoint["list"].each do |cmd|
|
170
|
-
safe_exec_cmd(cmd, :stdout => list)
|
171
|
-
end
|
172
|
-
return list.split(/\r?\n/)
|
173
|
-
end
|
174
|
-
|
175
166
|
def list_checkpoints
|
176
167
|
if @list_checkpoints.nil?
|
177
|
-
checkpoints
|
178
|
-
|
168
|
+
# get existing checkpoints on the system
|
169
|
+
existing_checkpoint_str = ""
|
170
|
+
@recipe.checkpoint["list"].each do |cmd|
|
171
|
+
safe_exec_cmd(cmd, :stdout => existing_checkpoint_str)
|
172
|
+
end
|
173
|
+
existing_checkpoint_ids = existing_checkpoint_str.split(/\r?\n/)
|
179
174
|
# get sorted checkpoints by microsteps order
|
180
175
|
@list_checkpoints = []
|
181
|
-
|
182
|
-
@list_checkpoints.push(
|
176
|
+
@recipe.all_checkpoints.each do |checkpoint|
|
177
|
+
@list_checkpoints.push(checkpoint) if existing_checkpoint_ids.include?(checkpoint["id"])
|
183
178
|
end
|
184
179
|
end
|
185
180
|
return @list_checkpoints
|
@@ -202,15 +197,15 @@ module Kameleon
|
|
202
197
|
macrostep.sequence do |microstep|
|
203
198
|
microstep_time = Time.now.to_i
|
204
199
|
microstep_checkpoint_duration = 0
|
205
|
-
step_prefix = "Step #{ microstep.order }
|
200
|
+
step_prefix = "Step #{ microstep.order }: "
|
206
201
|
Kameleon.ui.info("#{step_prefix}#{ microstep.slug }")
|
207
|
-
if @
|
202
|
+
if @checkpointing
|
208
203
|
if microstep.on_checkpoint == "skip"
|
209
|
-
Kameleon.ui.msg("-->
|
204
|
+
Kameleon.ui.msg("--> Skip microstep as requested when checkpointing is activated")
|
210
205
|
next
|
211
206
|
end
|
212
|
-
if microstep.
|
213
|
-
Kameleon.ui.msg("-->
|
207
|
+
if microstep.has_checkpoint_ahead and microstep.on_checkpoint != "redo"
|
208
|
+
Kameleon.ui.msg("--> Checkpoint ahead, do nothing")
|
214
209
|
else
|
215
210
|
begin
|
216
211
|
Kameleon.ui.msg("--> Running the step...")
|
@@ -221,29 +216,53 @@ module Kameleon
|
|
221
216
|
reload_contexts
|
222
217
|
breakpoint(nil)
|
223
218
|
end
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
219
|
+
if checkpoint_enabled?
|
220
|
+
if (@options[:microstep_checkpoints].downcase == "first" and checkpointed)
|
221
|
+
Kameleon.ui.msg("--> Do not create a checkpoint for this microstep: macrostep already checkpointed once")
|
222
|
+
elsif microstep.on_checkpoint == "redo"
|
223
|
+
Kameleon.ui.msg("--> Do not create a checkpoint for this microstep: always redo microstep")
|
224
|
+
elsif microstep.on_checkpoint == "disabled"
|
225
|
+
Kameleon.ui.msg("--> Do not create a checkpoint for this microstep: disabled in the microstep definition")
|
226
|
+
elsif not microstep.in_checkpoint_window
|
227
|
+
if @end_checkpoint.nil?
|
228
|
+
unless @begin_checkpoint.nil?
|
229
|
+
msg = "only after step '#{@begin_checkpoint['step']}'"
|
230
|
+
end
|
231
|
+
else
|
232
|
+
if @begin_checkpoint.nil?
|
233
|
+
msg = "not after step '#{@end_checkpoint['step']}'"
|
234
|
+
else
|
235
|
+
msg = "only between steps '#{@begin_checkpoint['step']}' and '#{@end_checkpoint['step']}'"
|
236
|
+
end
|
234
237
|
end
|
238
|
+
Kameleon.ui.msg("--> Do not create a checkpoint for this microstep: #{msg}")
|
239
|
+
else
|
240
|
+
microstep_checkpoint_time = Time.now.to_i
|
241
|
+
Kameleon.ui.msg("--> Creating checkpoint: '#{@recipe.all_checkpoints.select{|c| c['id'] == microstep.identifier}.first['step']}' (#{microstep.identifier})")
|
242
|
+
create_checkpoint(microstep.identifier)
|
243
|
+
checkpointed = true
|
244
|
+
microstep_checkpoint_duration = Time.now.to_i - microstep_checkpoint_time
|
245
|
+
macrostep_checkpoint_duration += microstep_checkpoint_duration
|
246
|
+
Kameleon.ui.verbose("Checkpoint creation for MicroStep #{microstep.name} took: #{microstep_checkpoint_duration} secs")
|
235
247
|
end
|
248
|
+
else
|
249
|
+
Kameleon.ui.msg("--> Do not create a checkpoint for this microstep: disabled in backend")
|
236
250
|
end
|
237
251
|
end
|
238
252
|
else
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
253
|
+
if microstep.on_checkpoint == "only"
|
254
|
+
Kameleon.ui.msg("--> Skip microstep as requested when checkpointing is not activated")
|
255
|
+
next
|
256
|
+
else
|
257
|
+
begin
|
258
|
+
Kameleon.ui.msg("--> Running the step...")
|
259
|
+
microstep.commands.each do |cmd|
|
260
|
+
safe_exec_cmd(cmd)
|
261
|
+
end
|
262
|
+
rescue SystemExit, Interrupt
|
263
|
+
reload_contexts
|
264
|
+
breakpoint(nil)
|
265
|
+
end
|
247
266
|
end
|
248
267
|
end
|
249
268
|
Kameleon.ui.verbose("MicroStep #{microstep.name} took: #{Time.now.to_i - microstep_time - microstep_checkpoint_duration} secs")
|
@@ -278,7 +297,7 @@ module Kameleon
|
|
278
297
|
context = "exec_" + cmd.value
|
279
298
|
expected_names = map.keys.map { |k| k.gsub "exec_", "" }
|
280
299
|
unless map.keys.include? context
|
281
|
-
Kameleon.ui.error("Invalid context name arguments. Expected
|
300
|
+
Kameleon.ui.error("Invalid context name arguments. Expected: "\
|
282
301
|
"#{expected_names}")
|
283
302
|
fail ExecError
|
284
303
|
else
|
@@ -296,7 +315,7 @@ module Kameleon
|
|
296
315
|
execute = true
|
297
316
|
[first_cmd.key, second_cmd.key].each do |key|
|
298
317
|
unless expected_cmds.include?(key)
|
299
|
-
Kameleon.ui.error("Invalid pipe arguments. Expected
|
318
|
+
Kameleon.ui.error("Invalid pipe arguments. Expected: "\
|
300
319
|
"#{expected_cmds}")
|
301
320
|
fail ExecError
|
302
321
|
end
|
@@ -349,7 +368,7 @@ module Kameleon
|
|
349
368
|
exec_cmd(cmd, kwargs)
|
350
369
|
end
|
351
370
|
else
|
352
|
-
Kameleon.ui.warn("Unknown command
|
371
|
+
Kameleon.ui.warn("Unknown command: #{cmd.key}")
|
353
372
|
end
|
354
373
|
end
|
355
374
|
|
@@ -407,7 +426,7 @@ module Kameleon
|
|
407
426
|
end
|
408
427
|
|
409
428
|
def rescue_exec_error(cmd)
|
410
|
-
message = "Error occured when executing the following command
|
429
|
+
message = "Error occured when executing the following command:\n"
|
411
430
|
cmd.string_cmd.split( /\r?\n/ ).each {|m| message << "\n> #{m}" }
|
412
431
|
if Kameleon.env.script?
|
413
432
|
raise ExecError, message
|
@@ -423,7 +442,7 @@ module Kameleon
|
|
423
442
|
begin
|
424
443
|
exec_cmd(cmd, kwargs)
|
425
444
|
rescue
|
426
|
-
Kameleon.ui.warn("An error occurred while executing
|
445
|
+
Kameleon.ui.warn("An error occurred while executing: #{cmd.value}")
|
427
446
|
end
|
428
447
|
end
|
429
448
|
end
|
@@ -431,16 +450,20 @@ module Kameleon
|
|
431
450
|
next if @cleaned_sections.include?(section.name)
|
432
451
|
Kameleon.ui.info("Cleaning #{section.name} section")
|
433
452
|
section.clean_macrostep.sequence do |microstep|
|
434
|
-
if @
|
453
|
+
if @checkpointing
|
435
454
|
if microstep.on_checkpoint == "skip"
|
436
455
|
next
|
437
456
|
end
|
457
|
+
else
|
458
|
+
if microstep.on_checkpoint == "only"
|
459
|
+
next
|
460
|
+
end
|
438
461
|
end
|
439
462
|
microstep.commands.each do |cmd|
|
440
463
|
begin
|
441
464
|
exec_cmd(cmd, kwargs)
|
442
465
|
rescue
|
443
|
-
Kameleon.ui.warn("An error occurred while executing
|
466
|
+
Kameleon.ui.warn("An error occurred while executing: #{cmd.value}")
|
444
467
|
end
|
445
468
|
end
|
446
469
|
end
|
@@ -456,28 +479,37 @@ module Kameleon
|
|
456
479
|
return path
|
457
480
|
end
|
458
481
|
end
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
Kameleon.ui.shell.say "
|
475
|
-
Kameleon.ui.shell.say "#{
|
476
|
-
|
482
|
+
if @options[:list_checkpoints]
|
483
|
+
if @recipe.all_checkpoints.empty?
|
484
|
+
Kameleon.ui.shell.say "No checkpoints would be created by recipe '#{recipe.name}':"
|
485
|
+
else
|
486
|
+
Kameleon.ui.shell.say "The following checkpoints would be created by recipe '#{recipe.name}':"
|
487
|
+
tp @recipe.all_checkpoints, {"id" => {:width => 20}}, { "step" => {:width => 60}}
|
488
|
+
end
|
489
|
+
else
|
490
|
+
Kameleon.ui.shell.say ""
|
491
|
+
Kameleon.ui.shell.say "#{ @recipe.name } ", :bold
|
492
|
+
Kameleon.ui.shell.say "(#{ relative_or_absolute_path(@recipe.path) })", :cyan
|
493
|
+
["bootstrap", "setup", "export"].each do |section_name|
|
494
|
+
section = @recipe.sections.fetch(section_name)
|
495
|
+
Kameleon.ui.shell.say "[" << section.name.capitalize << "]", :red
|
496
|
+
section.sequence do |macrostep|
|
497
|
+
Kameleon.ui.shell.say " "
|
498
|
+
Kameleon.ui.shell.say "#{macrostep.name} ", :bold
|
499
|
+
if macrostep.path
|
500
|
+
Kameleon.ui.shell.say "(#{ relative_or_absolute_path(macrostep.path) })", :cyan
|
501
|
+
else
|
502
|
+
Kameleon.ui.shell.say "(internal)", :cyan
|
503
|
+
end
|
504
|
+
macrostep.sequence do |microstep|
|
505
|
+
Kameleon.ui.shell.say " --> ", :magenta
|
506
|
+
Kameleon.ui.shell.say "#{ microstep.order } ", :green
|
507
|
+
Kameleon.ui.shell.say "#{ microstep.name }", :yellow
|
508
|
+
end
|
477
509
|
end
|
478
510
|
end
|
511
|
+
Kameleon.ui.shell.say ""
|
479
512
|
end
|
480
|
-
Kameleon.ui.shell.say ""
|
481
513
|
end
|
482
514
|
|
483
515
|
def dag(graph, color, recipes_only)
|
@@ -555,27 +587,58 @@ module Kameleon
|
|
555
587
|
end
|
556
588
|
|
557
589
|
def build
|
558
|
-
if @
|
559
|
-
@from_checkpoint
|
560
|
-
if @from_checkpoint.nil? || @from_checkpoint == "last"
|
590
|
+
if @checkpointing
|
591
|
+
if @options[:from_checkpoint].nil? || @options[:from_checkpoint] == "last"
|
561
592
|
@from_checkpoint = list_checkpoints.last
|
562
593
|
else
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
594
|
+
@from_checkpoint = list_checkpoints.select {|c|
|
595
|
+
c["id"] == @options[:from_checkpoint] || c["step"] == @options[:from_checkpoint]
|
596
|
+
}.last
|
597
|
+
if @from_checkpoint.nil?
|
598
|
+
fail BuildError, "Unknown checkpoint '#{@options[:from_checkpoint]}'." \
|
599
|
+
" You may use the list checkpoints option to find a valid checkpoint."
|
567
600
|
end
|
568
601
|
end
|
569
|
-
unless @from_checkpoint.nil?
|
570
|
-
Kameleon.ui.info("Restoring last build from step
|
571
|
-
apply_checkpoint @from_checkpoint
|
602
|
+
unless @from_checkpoint.nil? # no checkpoint available at all
|
603
|
+
Kameleon.ui.info("Restoring last build from step: #{@from_checkpoint["step"]}")
|
604
|
+
apply_checkpoint @from_checkpoint["id"]
|
572
605
|
@recipe.microsteps.each do |microstep|
|
573
|
-
microstep.
|
574
|
-
if microstep.identifier == @from_checkpoint
|
606
|
+
microstep.has_checkpoint_ahead = true
|
607
|
+
if microstep.identifier == @from_checkpoint["id"]
|
575
608
|
break
|
576
609
|
end
|
577
610
|
end
|
578
611
|
end
|
612
|
+
@begin_checkpoint = nil
|
613
|
+
unless @options[:begin_checkpoint].nil?
|
614
|
+
@begin_checkpoint = @recipe.all_checkpoints.select {|c|
|
615
|
+
c["id"] == @options[:begin_checkpoint] || c["step"] == @options[:begin_checkpoint]
|
616
|
+
}.first
|
617
|
+
if @begin_checkpoint.nil?
|
618
|
+
fail BuildError, "Unknown checkpoint '#{@options[:begin_checkpoint]}'." \
|
619
|
+
" You may use the dryrun and list checkpoints options to find a valid checkpoint."
|
620
|
+
end
|
621
|
+
end
|
622
|
+
@end_checkpoint = nil
|
623
|
+
unless @options[:end_checkpoint].nil?
|
624
|
+
@end_checkpoint = @recipe.all_checkpoints.select {|c|
|
625
|
+
c["id"] == @options[:end_checkpoint] || c["step"] == @options[:end_checkpoint]
|
626
|
+
}.last
|
627
|
+
if @end_checkpoint.nil?
|
628
|
+
fail BuildError, "Unknown checkpoint '#{@options[:end_checkpoint]}'." \
|
629
|
+
" You may use the dryrun and list checkpoints options to find a valid checkpoint."
|
630
|
+
end
|
631
|
+
end
|
632
|
+
do_checkpoint = @begin_checkpoint.nil?
|
633
|
+
@recipe.microsteps.each do |microstep|
|
634
|
+
if not do_checkpoint and not @begin_checkpoint.nil? and @begin_checkpoint["id"] == microstep.identifier
|
635
|
+
do_checkpoint = true
|
636
|
+
end
|
637
|
+
microstep.in_checkpoint_window = do_checkpoint
|
638
|
+
if do_checkpoint and not @end_checkpoint.nil? and @end_checkpoint["id"] == microstep.identifier
|
639
|
+
do_checkpoint = false
|
640
|
+
end
|
641
|
+
end
|
579
642
|
end
|
580
643
|
dump_build_recipe
|
581
644
|
begin
|
@@ -619,29 +682,12 @@ module Kameleon
|
|
619
682
|
end
|
620
683
|
|
621
684
|
def pretty_checkpoints_list
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
end
|
626
|
-
end
|
627
|
-
dict_checkpoints = []
|
628
|
-
unless @recipe.checkpoint.nil?
|
629
|
-
list_checkpoints.each do |id|
|
630
|
-
slug = find_microstep_slug_by_id id
|
631
|
-
unless slug.nil?
|
632
|
-
dict_checkpoints.push({
|
633
|
-
"id" => id,
|
634
|
-
"step" => slug
|
635
|
-
})
|
636
|
-
end
|
637
|
-
end
|
638
|
-
end
|
639
|
-
if dict_checkpoints.empty?
|
640
|
-
puts "No checkpoint available for the recipe '#{recipe.name}'"
|
685
|
+
list_checkpoints
|
686
|
+
if list_checkpoints.empty?
|
687
|
+
Kameleon.ui.shell.say "No checkpoint found for recipe '#{recipe.name}'"
|
641
688
|
else
|
642
|
-
|
643
|
-
|
644
|
-
tp dict_checkpoints, {"id" => {:width => 20}}, { "step" => {:width => 60}}
|
689
|
+
Kameleon.ui.shell.say "The following checkpoints are available for recipe '#{recipe.name}':"
|
690
|
+
tp list_checkpoints, {"id" => {:width => 20}}, { "step" => {:width => 60}}
|
645
691
|
end
|
646
692
|
end
|
647
693
|
end
|
data/lib/kameleon/recipe.rb
CHANGED
@@ -46,6 +46,8 @@ module Kameleon
|
|
46
46
|
"proxy_local" => "",
|
47
47
|
"proxy_out" => "",
|
48
48
|
"proxy_in" => "",
|
49
|
+
"checkpointing_enabled" => "false",
|
50
|
+
"persistent_cache" => "false",
|
49
51
|
}
|
50
52
|
@aliases = {}
|
51
53
|
@checkpoint = nil
|
@@ -89,7 +91,7 @@ module Kameleon
|
|
89
91
|
def load!(kwargs = {})
|
90
92
|
# Find recipe path
|
91
93
|
Kameleon.ui.verbose("Loading #{@path}")
|
92
|
-
fail RecipeError, "Could not find this following recipe
|
94
|
+
fail RecipeError, "Could not find this following recipe: #{@path}" \
|
93
95
|
unless File.file? @path
|
94
96
|
yaml_recipe = YAML.load_file @path
|
95
97
|
unless yaml_recipe.kind_of? Hash
|
@@ -238,7 +240,7 @@ module Kameleon
|
|
238
240
|
update_steps_dirs()
|
239
241
|
|
240
242
|
base_recipe_path << ".yaml" unless base_recipe_path.end_with? ".yaml"
|
241
|
-
fail RecipeError, "Could not find this following recipe
|
243
|
+
fail RecipeError, "Could not find this following recipe: #{@recipe_path}" \
|
242
244
|
unless File.file? path
|
243
245
|
base_yaml_recipe = YAML.load_file base_recipe_path
|
244
246
|
unless yaml_recipe.kind_of? Hash
|
@@ -556,7 +558,7 @@ module Kameleon
|
|
556
558
|
Kameleon.ui.verbose("Resolving aliases")
|
557
559
|
@sections.values.each do |section|
|
558
560
|
section.macrosteps.each do |macrostep|
|
559
|
-
# First pass
|
561
|
+
# First pass: resolve aliases
|
560
562
|
Kameleon.ui.debug("Resolving aliases for macrostep '#{macrostep.name}'")
|
561
563
|
macrostep.microsteps.each do |microstep|
|
562
564
|
microstep.commands.map! do |cmd|
|
@@ -577,7 +579,7 @@ module Kameleon
|
|
577
579
|
|
578
580
|
@sections.values.each do |section|
|
579
581
|
section.macrosteps.each do |macrostep|
|
580
|
-
# Second pass
|
582
|
+
# Second pass: resolve variables + clean/init hooks
|
581
583
|
macrostep.microsteps.each do |microstep|
|
582
584
|
microstep.commands.map! do |cmd|
|
583
585
|
resolve_hooks(cmd, macrostep, microstep)
|
@@ -730,7 +732,7 @@ module Kameleon
|
|
730
732
|
end
|
731
733
|
end
|
732
734
|
end
|
733
|
-
fail RecipeError, "Invalid command
|
735
|
+
fail RecipeError, "Invalid command: '#{cmd.key}'"
|
734
736
|
else
|
735
737
|
return cmd
|
736
738
|
end
|
@@ -751,6 +753,25 @@ module Kameleon
|
|
751
753
|
return @microsteps
|
752
754
|
end
|
753
755
|
|
756
|
+
def all_checkpoints
|
757
|
+
if @all_checkpoints.nil?
|
758
|
+
@all_checkpoints = []
|
759
|
+
microsteps.each do |m|
|
760
|
+
step = m.slug
|
761
|
+
while @all_checkpoints.map{|c| c["step"]}.include?(step) do
|
762
|
+
prefix, suffix = step.split("%")
|
763
|
+
step = if suffix.nil?
|
764
|
+
"#{prefix}%1"
|
765
|
+
else
|
766
|
+
"#{prefix}%#{suffix.to_i+1}"
|
767
|
+
end
|
768
|
+
end
|
769
|
+
@all_checkpoints.push({ 'id' => m.identifier, 'step' => step })
|
770
|
+
end
|
771
|
+
end
|
772
|
+
return @all_checkpoints
|
773
|
+
end
|
774
|
+
|
754
775
|
def calculate_step_identifiers
|
755
776
|
Kameleon.ui.debug("Calculating microstep identifiers")
|
756
777
|
base_salt = ""
|
data/lib/kameleon/shell.rb
CHANGED
@@ -296,10 +296,10 @@ SCRIPT
|
|
296
296
|
def fork(io)
|
297
297
|
if io.eql? "interactive"
|
298
298
|
command = ["bash", "-c", @interactive_shell_cmd]
|
299
|
-
Kameleon.ui.
|
299
|
+
Kameleon.ui.verbose("Starting interactive command: #{@interactive_shell_cmd.inspect}")
|
300
300
|
else
|
301
301
|
command = ["bash", "-c", @shell_cmd]
|
302
|
-
Kameleon.ui.
|
302
|
+
Kameleon.ui.verbose("Starting command: #{@cmd.inspect}")
|
303
303
|
end
|
304
304
|
Kameleon.ui.debug("Starting shell process: #{ command.inspect}")
|
305
305
|
ChildProcess.posix_spawn = true
|
data/lib/kameleon/step.rb
CHANGED
@@ -33,7 +33,7 @@ module Kameleon
|
|
33
33
|
@key
|
34
34
|
rescue
|
35
35
|
lines = @string_cmd.split( /\r?\n/ ).map {|l| "> #{l}" }
|
36
|
-
fail RecipeError, "Syntax error for microstep #{@microstep_name}
|
36
|
+
fail RecipeError, "Syntax error for microstep #{@microstep_name}: \n"\
|
37
37
|
"#{ lines.join "\n"}"
|
38
38
|
end
|
39
39
|
|
@@ -103,13 +103,15 @@ module Kameleon
|
|
103
103
|
attr_accessor :name
|
104
104
|
attr_accessor :identifier
|
105
105
|
attr_accessor :slug
|
106
|
-
attr_accessor :
|
106
|
+
attr_accessor :has_checkpoint_ahead
|
107
|
+
attr_accessor :in_checkpoint_window
|
107
108
|
attr_accessor :on_checkpoint
|
108
109
|
attr_accessor :order
|
109
110
|
|
110
111
|
def initialize(string_or_hash)
|
111
112
|
@identifier = nil
|
112
|
-
@
|
113
|
+
@has_checkpoint_ahead = false
|
114
|
+
@in_checkpoint_window = true
|
113
115
|
@on_checkpoint = "use_cache"
|
114
116
|
@commands = []
|
115
117
|
@name, cmd_list = string_or_hash.first
|
data/lib/kameleon/utils.rb
CHANGED
@@ -6,7 +6,7 @@ module Kameleon
|
|
6
6
|
@@warned_vars = Array.new
|
7
7
|
def self.warn_var(var)
|
8
8
|
if ! @@warned_vars.include?(var)
|
9
|
-
Kameleon.ui.warn("Warning
|
9
|
+
Kameleon.ui.warn("Warning: variable $$#{var[0]} is not enclosed with braces, which may cause errors. Please prefer using $${#{var[0]}}.")
|
10
10
|
@@warned_vars.push(var)
|
11
11
|
end
|
12
12
|
end
|
data/lib/kameleon/version.rb
CHANGED
@@ -0,0 +1,77 @@
|
|
1
|
+
#===============================================================================
|
2
|
+
# vim: softtabstop=2 shiftwidth=2 expandtab fenc=utf-8 cc=81 tw=80
|
3
|
+
#===============================================================================
|
4
|
+
#
|
5
|
+
# DESCRIPTION: This is a test recipe made for unit testing
|
6
|
+
#
|
7
|
+
#===============================================================================
|
8
|
+
---
|
9
|
+
# Loads some helpful aliases
|
10
|
+
extend: ../test2/test2.yaml
|
11
|
+
aliases: defaults.yaml
|
12
|
+
checkpoint: test.yaml
|
13
|
+
#== Global variables use by Kameleon engine and the steps
|
14
|
+
global:
|
15
|
+
|
16
|
+
include_steps:
|
17
|
+
- $${distrib}
|
18
|
+
|
19
|
+
## User varibales : used by the recipe
|
20
|
+
user_name: kameleon_user
|
21
|
+
user_password: $${user_name}
|
22
|
+
|
23
|
+
# test overload
|
24
|
+
toto: $${toto} tata
|
25
|
+
|
26
|
+
# Distribution
|
27
|
+
distrib: linux
|
28
|
+
|
29
|
+
## System variables. Required by kameleon engine
|
30
|
+
# Include specific steps
|
31
|
+
include_steps:
|
32
|
+
- $${distrib}
|
33
|
+
|
34
|
+
bootstrap_packages: >
|
35
|
+
less vim python
|
36
|
+
sl sudo
|
37
|
+
|
38
|
+
version: 12.2
|
39
|
+
variant: toto-tata
|
40
|
+
|
41
|
+
uuid: $${kameleon_uuid}
|
42
|
+
|
43
|
+
appliance_filename: $${kameleon_recipe_name}_$${kameleon_short_uuid}
|
44
|
+
|
45
|
+
#== Bootstrap the new system and create the 'in_context'
|
46
|
+
bootstrap:
|
47
|
+
|
48
|
+
setup:
|
49
|
+
- MA:
|
50
|
+
- MA1:
|
51
|
+
- on_checkpoint: redo
|
52
|
+
- exec_local: echo "MicroStepA1 ($${checkpointing_enabled}, $${persistent_cache})"
|
53
|
+
- MB:
|
54
|
+
- MB1:
|
55
|
+
- exec_local: echo MicroStepB1; cp; echo coucou
|
56
|
+
- MB2:
|
57
|
+
- on_checkpoint: skip
|
58
|
+
- exec_local: echo MicroStepB2
|
59
|
+
- MB3:
|
60
|
+
- exec_local: echo MicroStepB3
|
61
|
+
- MC:
|
62
|
+
- MC1:
|
63
|
+
- exec_local: echo MicroStepC1
|
64
|
+
- MC1:
|
65
|
+
- exec_local: echo MicroStepC1
|
66
|
+
- MC2:
|
67
|
+
- on_checkpoint: only
|
68
|
+
- exec_local: echo MicroStepC2
|
69
|
+
- MC3:
|
70
|
+
- exec_local: echo MicroStepC3
|
71
|
+
- MD:
|
72
|
+
- MD1:
|
73
|
+
- on_checkpoint: use_cache
|
74
|
+
- exec_local: echo MicroStepD1
|
75
|
+
|
76
|
+
|
77
|
+
export:
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kameleon-builder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.10.
|
4
|
+
version: 2.10.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Salem Harrache
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2023-
|
15
|
+
date: 2023-10-10 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: childprocess
|
@@ -207,6 +207,7 @@ files:
|
|
207
207
|
- tests/recipes/steps/setup/linux/software_install.yaml
|
208
208
|
- tests/recipes/steps/test_uuid_step.yaml
|
209
209
|
- tests/recipes/test_recipe.yaml
|
210
|
+
- tests/recipes/test_recipe_checkpoints.yaml
|
210
211
|
- tests/recipes/test_recipe_child.yaml
|
211
212
|
- tests/test2/steps/data/mydata.txt
|
212
213
|
- tests/test2/test2.yaml
|
@@ -257,6 +258,7 @@ test_files:
|
|
257
258
|
- tests/recipes/steps/setup/linux/software_install.yaml
|
258
259
|
- tests/recipes/steps/test_uuid_step.yaml
|
259
260
|
- tests/recipes/test_recipe.yaml
|
261
|
+
- tests/recipes/test_recipe_checkpoints.yaml
|
260
262
|
- tests/recipes/test_recipe_child.yaml
|
261
263
|
- tests/test2/steps/data/mydata.txt
|
262
264
|
- tests/test2/test2.yaml
|