kameleon-builder 2.10.9 → 2.10.11
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.
- 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
|