kameleon-builder 2.10.9 → 2.10.10
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 +18 -3
- data/lib/kameleon/cli.rb +47 -51
- data/lib/kameleon/context.rb +1 -1
- data/lib/kameleon/engine.rb +54 -40
- data/lib/kameleon/recipe.rb +7 -5
- data/lib/kameleon/shell.rb +2 -2
- data/lib/kameleon/step.rb +1 -1
- data/lib/kameleon/utils.rb +1 -1
- data/lib/kameleon/version.rb +1 -1
- data/tests/recipes/test_recipe_checkpoints.yaml +75 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2492ad18812484a81bd0aa54360137ee497d43fcea554cd60f2d68eec3c951c7
|
4
|
+
data.tar.gz: 36c9ab6b6757a0930e8c3e0aec1dd69eef915d48aa1ef1f9d953fdd9b036c1d8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 703c0d4a6d43d24a3c6d455049f661a8d8eabcaad4d07168a4233acd5044f213fbc80abb4ef4074200afe98999f68a48e2ff52c07b27e6dfd40590609e08d6df
|
7
|
+
data.tar.gz: cc7c30c503c3e8c59c1b188adeddb63a0286367959428126b1dbcd10bd996abbe80c34e42abebb525ad6a06f107d9e4f4e1ae23ac5bc7e74645795b026dde32a
|
data/.bumpversion.cfg
CHANGED
data/CHANGES
CHANGED
@@ -1,6 +1,21 @@
|
|
1
1
|
Kameleon CHANGELOG
|
2
2
|
==================
|
3
3
|
|
4
|
+
Version 2.10.10
|
5
|
+
--------------
|
6
|
+
|
7
|
+
Released on June 13 2023
|
8
|
+
|
9
|
+
- Set kameleon build --microstep-checkpoint option to "all" by default.
|
10
|
+
- Rework the kameleon checkpoint documentation and more.
|
11
|
+
- Rework the kameleon build options.
|
12
|
+
- Add the on_checkpoint=only keyword, allowing a step to be run only when checkpoint is activated.
|
13
|
+
- Add the on_checkpoint=disabled keyword, allowing a step to be never be checkpointed.
|
14
|
+
- Add the $${checkpointing_enabled} global variable, value is "true" or "false" whether checkpointing is enabled or not.
|
15
|
+
- Fix error in kameleon info: variable not found $${checkpointing_enabled} / $${persistent_cache}.
|
16
|
+
- Make the context_reload command less verbose by default, and some other commands by side effects.
|
17
|
+
- Other cosmetic fixes.
|
18
|
+
|
4
19
|
Version 2.10.9
|
5
20
|
--------------
|
6
21
|
|
@@ -372,7 +387,7 @@ Released on Oct 16th 2014
|
|
372
387
|
- Handled Ctrl-C to make a breakpoint instead of quitting. (Fixed #29)
|
373
388
|
- Stored kameleon user configuration file in ``~/.kameleon.d/config`` (Fixed #24)
|
374
389
|
- Fixed ``kameleon new`` to take an absolute or relative path and place the recipe in a subdir (Fixed #22)
|
375
|
-
- Moved builtin recipes to an external repository
|
390
|
+
- Moved builtin recipes to an external repository: See [http://kameleon.imag.fr/repository.html](Docs) (Fixed #24)
|
376
391
|
- Renamed ``--cache`` option to ``--enable-cache``
|
377
392
|
- Renamed ``--checkpoint`` option to ``--enable-checkpoint``
|
378
393
|
- Removed ``kameleon import`` command
|
@@ -482,7 +497,7 @@ Released on July 20th 2014
|
|
482
497
|
- [template] Do not run qemu with nohup (Use ``-daemonize`` instead)
|
483
498
|
- [template] Improved context_out/in log readability
|
484
499
|
- [template] Removed fedora-rawhide templates
|
485
|
-
- [template] Added new templates
|
500
|
+
- [template] Added new templates:
|
486
501
|
|
487
502
|
- qemu/archlinux-desktop-i686
|
488
503
|
- qemu/archlinux-i686
|
@@ -547,7 +562,7 @@ Released on June 12th 2014
|
|
547
562
|
- [core] Set the variable ``KAMELEON_WORKDIR`` for all contexts
|
548
563
|
- [core] Used ``KAMELEON_WORKDIR`` when working with PIPE
|
549
564
|
- [core] Added persistent cache feature to Kameleon, So far it is caching just packages comming from the network using Polipo
|
550
|
-
- [template] Added new templates
|
565
|
+
- [template] Added new templates:
|
551
566
|
|
552
567
|
- archlinux
|
553
568
|
- archlinux-desktop
|
data/lib/kameleon/cli.rb
CHANGED
@@ -11,7 +11,7 @@ module Kameleon
|
|
11
11
|
class Repository < Thor
|
12
12
|
include Thor::Actions
|
13
13
|
|
14
|
-
desc "add <NAME> <GIT_URL>", "
|
14
|
+
desc "add <NAME> <GIT_URL>", "Add a new repository named <NAME> cloned from <GIT_URL>"
|
15
15
|
method_option :branch, :type => :string,
|
16
16
|
:default => nil,
|
17
17
|
:desc => "checkout <BRANCH>",
|
@@ -20,7 +20,7 @@ module Kameleon
|
|
20
20
|
Kameleon::Repository.add(name, url, options)
|
21
21
|
end
|
22
22
|
|
23
|
-
desc "list", "
|
23
|
+
desc "list", "List available repositories"
|
24
24
|
method_option :git, :type => :boolean,
|
25
25
|
:default => true,
|
26
26
|
:desc => "show the git repository and branch each repository comes from"
|
@@ -28,7 +28,7 @@ module Kameleon
|
|
28
28
|
Kameleon::Repository.list(options)
|
29
29
|
end
|
30
30
|
|
31
|
-
desc "update <NAME>", "
|
31
|
+
desc "update <NAME>", "Update repository named <NAME> from git"
|
32
32
|
def update(name)
|
33
33
|
Kameleon::Repository.update(name)
|
34
34
|
end
|
@@ -38,7 +38,7 @@ module Kameleon
|
|
38
38
|
Kameleon::Repository.remove(name)
|
39
39
|
end
|
40
40
|
|
41
|
-
desc "commands", "
|
41
|
+
desc "commands", "List all available commands", :hide => true
|
42
42
|
def commands
|
43
43
|
puts Repository.all_commands.keys - ["commands"]
|
44
44
|
end
|
@@ -56,7 +56,7 @@ module Kameleon
|
|
56
56
|
Kameleon.env.repositories_path
|
57
57
|
end
|
58
58
|
|
59
|
-
desc "list", "
|
59
|
+
desc "list", "List all available templates"
|
60
60
|
method_option :progress, :type => :boolean, :default => true,
|
61
61
|
:desc => "Show progress bar while resolving templates",
|
62
62
|
:aliases => "-p"
|
@@ -69,10 +69,10 @@ module Kameleon
|
|
69
69
|
Utils.list_recipes(Kameleon.env.repositories_path, options[:filter], options[:progress], true)
|
70
70
|
end
|
71
71
|
|
72
|
-
desc "import <TEMPLATE_NAME>", "
|
72
|
+
desc "import <TEMPLATE_NAME>", "Import the given template"
|
73
73
|
method_option :global, :type => :hash,
|
74
74
|
:default => {}, :aliases => "-g",
|
75
|
-
:desc => "Set custom global variables
|
75
|
+
:desc => "Set custom global variables"
|
76
76
|
def import(template_name)
|
77
77
|
Kameleon.env.root_dir = Kameleon.env.repositories_path
|
78
78
|
template_path = File.join(Kameleon.env.repositories_path, template_name)
|
@@ -104,7 +104,7 @@ module Kameleon
|
|
104
104
|
desc "info <TEMPLATE_NAME>", "Display detailed information about a template"
|
105
105
|
method_option :global, :type => :hash,
|
106
106
|
:default => {}, :aliases => "-g",
|
107
|
-
:desc => "Set custom global variables
|
107
|
+
:desc => "Set custom global variables"
|
108
108
|
def info(template_name)
|
109
109
|
Kameleon.env.root_dir = Kameleon.env.repositories_path
|
110
110
|
template_path = File.join(Kameleon.env.repositories_path, template_name)
|
@@ -133,7 +133,7 @@ module Kameleon
|
|
133
133
|
copy_file(Pathname.new(Kameleon.erb_dirpath).join("extend.yaml.erb"), erb_file)
|
134
134
|
end
|
135
135
|
|
136
|
-
desc "commands", "
|
136
|
+
desc "commands", "List all available commands", :hide => true
|
137
137
|
def commands
|
138
138
|
puts Template.all_commands.keys - ["commands"]
|
139
139
|
end
|
@@ -147,22 +147,22 @@ module Kameleon
|
|
147
147
|
class Main < Thor
|
148
148
|
include Thor::Actions
|
149
149
|
|
150
|
-
desc 'repository <SUBCOMMAND>', '
|
150
|
+
desc 'repository <SUBCOMMAND>', 'Manage repositories of recipes'
|
151
151
|
subcommand 'repository', CLI::Repository
|
152
|
-
desc 'template <SUBCOMMAND>', '
|
152
|
+
desc 'template <SUBCOMMAND>', 'List and import templates'
|
153
153
|
subcommand 'template', CLI::Template
|
154
154
|
|
155
155
|
class_option :color, :type => :boolean, :default => Kameleon.default_values[:color],
|
156
|
-
:desc => "
|
156
|
+
:desc => "Enable colorization in output"
|
157
157
|
class_option :verbose, :type => :boolean, :default => Kameleon.default_values[:verbose],
|
158
|
-
:desc => "
|
158
|
+
:desc => "Enable verbose output for kameleon users"
|
159
159
|
class_option :debug, :type => :boolean, :default => Kameleon.default_values[:debug],
|
160
|
-
:desc => "
|
160
|
+
:desc => "Enable debug output for kameleon developpers"
|
161
161
|
class_option :script, :type => :boolean, :default => Kameleon.default_values[:script],
|
162
|
-
:desc => "Never
|
162
|
+
:desc => "Never prompt for user intervention",
|
163
163
|
:aliases => "-s"
|
164
164
|
|
165
|
-
desc "version", "
|
165
|
+
desc "version", "Print the Kameleon's version information"
|
166
166
|
def version
|
167
167
|
puts "Kameleon version #{Kameleon::VERSION}"
|
168
168
|
end
|
@@ -171,7 +171,7 @@ module Kameleon
|
|
171
171
|
Kameleon.env.repositories_path
|
172
172
|
end
|
173
173
|
|
174
|
-
desc "list", "
|
174
|
+
desc "list", "List all defined recipes in the current directory"
|
175
175
|
method_option :progress, :type => :boolean, :default => false,
|
176
176
|
:desc => "Show progress bar while resolving recipes",
|
177
177
|
:aliases => "-p"
|
@@ -183,10 +183,10 @@ module Kameleon
|
|
183
183
|
Utils.list_recipes(Kameleon.env.workspace, options[:filter], options[:progress])
|
184
184
|
end
|
185
185
|
|
186
|
-
desc "new <RECIPE_PATH> <TEMPLATE_NAME>", "
|
186
|
+
desc "new <RECIPE_PATH> <TEMPLATE_NAME>", "Create a new recipe from template <TEMPLATE_NAME>"
|
187
187
|
method_option :global, :type => :hash,
|
188
188
|
:default => {}, :aliases => "-g",
|
189
|
-
:desc => "Set custom global variables
|
189
|
+
:desc => "Set custom global variables"
|
190
190
|
def new(recipe_name, template_name)
|
191
191
|
Kameleon.env.root_dir = Kameleon.env.repositories_path
|
192
192
|
unless template_name.end_with? '.yaml'
|
@@ -248,7 +248,7 @@ module Kameleon
|
|
248
248
|
desc "info <RECIPE_PATH>", "Display detailed information about a recipe"
|
249
249
|
method_option :global, :type => :hash,
|
250
250
|
:default => {}, :aliases => "-g",
|
251
|
-
:desc => "Set custom global variables
|
251
|
+
:desc => "Set custom global variables"
|
252
252
|
method_option :from_cache, :type => :string,
|
253
253
|
:default => nil,
|
254
254
|
:desc => "Get info from a persistent cache tar file (ignore recipe path)"
|
@@ -280,7 +280,7 @@ module Kameleon
|
|
280
280
|
desc "dag <RECIPE_PATH> [<RECIPE_PATH> [<...>]]", "Draw a DAG of the steps to build one or more recipes"
|
281
281
|
method_option :global, :type => :hash,
|
282
282
|
:default => {}, :aliases => "-g",
|
283
|
-
:desc => "Set custom global variables
|
283
|
+
:desc => "Set custom global variables"
|
284
284
|
method_option :file, :type => :string,
|
285
285
|
:default => "/tmp/kameleon.dag",
|
286
286
|
:desc => "DAG output filename"
|
@@ -322,7 +322,7 @@ module Kameleon
|
|
322
322
|
desc "dryrun <RECIPE_PATH>", "Show the steps the build would process"
|
323
323
|
method_option :global, :type => :hash,
|
324
324
|
:default => {}, :aliases => "-g",
|
325
|
-
:desc => "Set custom global variables
|
325
|
+
:desc => "Set custom global variables"
|
326
326
|
method_option :relative, :type => :boolean,
|
327
327
|
:default => false,
|
328
328
|
:desc => "Make pathnames relative to the current working directory"
|
@@ -337,7 +337,7 @@ module Kameleon
|
|
337
337
|
desc "export <RECIPE_PATH> <EXPORT_PATH>", "Export the given recipe with its steps and data to a given directory"
|
338
338
|
method_option :global, :type => :hash,
|
339
339
|
:default => {}, :aliases => "-g",
|
340
|
-
:desc => "Set custom global variables
|
340
|
+
:desc => "Set custom global variables"
|
341
341
|
method_option :add, :type => :boolean,
|
342
342
|
:default => false, :aliases => "-A",
|
343
343
|
:desc => "export recipe and steps to an existing directory (this may overwrite some existing files)"
|
@@ -377,56 +377,52 @@ module Kameleon
|
|
377
377
|
end
|
378
378
|
end
|
379
379
|
|
380
|
-
desc "build <RECIPE_PATH>", "
|
380
|
+
desc "build <RECIPE_PATH>", "Build the appliance from the given recipe"
|
381
381
|
method_option :build_path, :type => :string,
|
382
382
|
:default => nil, :aliases => "-b",
|
383
|
-
:desc => "
|
383
|
+
:desc => "Set the build directory path"
|
384
384
|
method_option :clean, :type => :boolean,
|
385
385
|
:default => false,
|
386
|
-
:desc => "
|
386
|
+
:desc => "Run the command `kameleon clean` first"
|
387
387
|
method_option :from_checkpoint, :type => :string,
|
388
388
|
:default => nil,
|
389
|
-
:desc => "
|
390
|
-
|
391
|
-
method_option :enable_checkpoint, :type => :boolean,
|
389
|
+
:desc => "Restart a build from a specific checkpoint, instead of the latest one"
|
390
|
+
method_option :enable_checkpointing, :type => :boolean, :aliases => "-c",
|
392
391
|
:default => false,
|
393
|
-
:desc => "
|
394
|
-
method_option :
|
392
|
+
:desc => "Enable creating and using checkpoints"
|
393
|
+
method_option :microstep_checkpoints, :type => :string,
|
395
394
|
:enum => ["first", "all"],
|
396
|
-
:default => "
|
395
|
+
:default => "all",
|
397
396
|
:desc => "Create checkpoint of the first microstep only, or all"
|
398
|
-
method_option :list_checkpoints, :type => :boolean, :aliases => "
|
397
|
+
method_option :list_checkpoints, :type => :boolean, :aliases => "-l",
|
399
398
|
:default => false,
|
400
|
-
:desc => "
|
401
|
-
method_option :enable_cache, :type => :boolean,
|
399
|
+
:desc => "List all availables checkpoints"
|
400
|
+
method_option :enable_cache, :type => :boolean, :aliases => "-C",
|
402
401
|
:default => false,
|
403
|
-
:desc => "
|
402
|
+
:desc => "Generate a persistent cache for the appliance"
|
404
403
|
method_option :cache_path, :type => :string,
|
405
404
|
:default => nil,
|
406
|
-
:desc => "
|
405
|
+
:desc => "Set the cache directory path"
|
407
406
|
method_option :from_cache, :type => :string,
|
408
407
|
:default => nil,
|
409
|
-
:desc => "
|
408
|
+
:desc => "Use a persistent cache tar file to build the image"
|
410
409
|
method_option :cache_archive_compression, :type => :string,
|
411
410
|
:enum => ["none", "gzip", "bz2", "xz"],
|
412
411
|
:default => "gzip",
|
413
|
-
:desc => "Set the persistent cache tar file compression
|
412
|
+
:desc => "Set the persistent cache tar file compression"
|
414
413
|
method_option :polipo_path, :type => :string,
|
415
414
|
:default => nil,
|
416
|
-
:desc => "Full path of the polipo binary to use for the persistent cache
|
415
|
+
:desc => "Full path of the polipo binary to use for the persistent cache"
|
417
416
|
method_option :proxy, :type => :string, :default => "",
|
418
|
-
:desc => "
|
419
|
-
"proxy; it should have the form 'host:port'"
|
417
|
+
:desc => "HTTP proxy address and port (expected format is hostname:port)"
|
420
418
|
method_option :proxy_credentials, :type => :string, :default => "",
|
421
|
-
:desc => "
|
422
|
-
"proxy requires authorisation it should have the "\
|
423
|
-
"form 'username:password'"
|
419
|
+
:desc => "Username and password if required by the parent proxy (expected format is username:password)"
|
424
420
|
method_option :proxy_offline, :type => :boolean,
|
425
|
-
:default => false,
|
426
|
-
:desc => "
|
421
|
+
:default => false,
|
422
|
+
:desc => "Prevent Polipo from contacting remote servers"
|
427
423
|
method_option :global, :type => :hash,
|
428
424
|
:default => {}, :aliases => "-g",
|
429
|
-
:desc => "Set custom global variables
|
425
|
+
:desc => "Set custom global variables"
|
430
426
|
def build(recipe_path=nil)
|
431
427
|
if recipe_path.nil? && !options[:from_cache].nil?
|
432
428
|
unless File.file?(options[:from_cache])
|
@@ -458,11 +454,11 @@ module Kameleon
|
|
458
454
|
total_time = Time.now.to_i - start_time
|
459
455
|
Kameleon.ui.info("")
|
460
456
|
Kameleon.ui.info("Successfully built '#{recipe_path}'")
|
461
|
-
Kameleon.ui.info("Total duration
|
457
|
+
Kameleon.ui.info("Total duration: #{total_time} secs")
|
462
458
|
end
|
463
459
|
end
|
464
460
|
|
465
|
-
desc "commands", "
|
461
|
+
desc "commands", "List all available commands", :hide => true
|
466
462
|
def commands(context="main")
|
467
463
|
Kameleon.ui.debug("Commands for '#{context}':")
|
468
464
|
case context
|
@@ -475,7 +471,7 @@ module Kameleon
|
|
475
471
|
end
|
476
472
|
end
|
477
473
|
|
478
|
-
desc "source_root", "
|
474
|
+
desc "source_root", "Print the kameleon directory path", :hide => true
|
479
475
|
def source_root
|
480
476
|
puts Kameleon.source_root
|
481
477
|
end
|
data/lib/kameleon/context.rb
CHANGED
@@ -79,7 +79,7 @@ module Kameleon
|
|
79
79
|
do_log(out, log_level) unless out.nil?
|
80
80
|
do_log(err, "error") unless err.nil?
|
81
81
|
end
|
82
|
-
Kameleon.ui.verbose("Exit status
|
82
|
+
Kameleon.ui.verbose("Exit status: #{exit_status}")
|
83
83
|
fail ExecError unless exit_status.eql? 0
|
84
84
|
rescue ShellError, Errno::EPIPE => e
|
85
85
|
Kameleon.ui.verbose("Shell cmd failed to launch: #{@shell.shell_cmd}")
|
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,11 @@ module Kameleon
|
|
26
27
|
@recipe.global[key] = build_recipe["global"][key]
|
27
28
|
end
|
28
29
|
end
|
29
|
-
@
|
30
|
-
@
|
31
|
-
@microstep_checkpoint = @options[:
|
30
|
+
@checkpointing = @options[:enable_checkpointing]
|
31
|
+
@checkpointing = true unless @options[:from_checkpoint].nil?
|
32
|
+
@microstep_checkpoint = @options[:microstep_checkpoints]
|
32
33
|
# Check if the recipe have checkpoint entry
|
33
|
-
if @
|
34
|
+
if @checkpointing && @recipe.checkpoint.nil?
|
34
35
|
fail BuildError, "Checkpoint is unavailable for this recipe"
|
35
36
|
end
|
36
37
|
|
@@ -78,7 +79,7 @@ module Kameleon
|
|
78
79
|
end
|
79
80
|
unless @options[:no_create_build_dir]
|
80
81
|
begin
|
81
|
-
Kameleon.ui.info("Creating kameleon build directory
|
82
|
+
Kameleon.ui.info("Creating kameleon build directory: #{@cwd}")
|
82
83
|
FileUtils.mkdir_p @cwd
|
83
84
|
rescue
|
84
85
|
raise BuildError, "Failed to create build directory #{@cwd}"
|
@@ -145,7 +146,7 @@ module Kameleon
|
|
145
146
|
|
146
147
|
def create_checkpoint(microstep_id)
|
147
148
|
@recipe.checkpoint["create"].each do |cmd|
|
148
|
-
safe_exec_cmd(cmd.dup.gsub!("@microstep_id", microstep_id))
|
149
|
+
safe_exec_cmd(cmd.dup.gsub!("@microstep_id", microstep_id), :log_level => "warn")
|
149
150
|
end
|
150
151
|
end
|
151
152
|
|
@@ -202,15 +203,15 @@ module Kameleon
|
|
202
203
|
macrostep.sequence do |microstep|
|
203
204
|
microstep_time = Time.now.to_i
|
204
205
|
microstep_checkpoint_duration = 0
|
205
|
-
step_prefix = "Step #{ microstep.order }
|
206
|
+
step_prefix = "Step #{ microstep.order }: "
|
206
207
|
Kameleon.ui.info("#{step_prefix}#{ microstep.slug }")
|
207
|
-
if @
|
208
|
+
if @checkpointing
|
208
209
|
if microstep.on_checkpoint == "skip"
|
209
|
-
Kameleon.ui.msg("--> Skipped")
|
210
|
+
Kameleon.ui.msg("--> Skipped because checkpointing is enabled")
|
210
211
|
next
|
211
212
|
end
|
212
|
-
if microstep.in_cache
|
213
|
-
Kameleon.ui.msg("-->
|
213
|
+
if microstep.in_cache and microstep.on_checkpoint != "redo"
|
214
|
+
Kameleon.ui.msg("--> Checkpoint ahead, do nothing")
|
214
215
|
else
|
215
216
|
begin
|
216
217
|
Kameleon.ui.msg("--> Running the step...")
|
@@ -221,29 +222,38 @@ module Kameleon
|
|
221
222
|
reload_contexts
|
222
223
|
breakpoint(nil)
|
223
224
|
end
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
225
|
+
if checkpoint_enabled?
|
226
|
+
if (@microstep_checkpoint == "first" and checkpointed)
|
227
|
+
Kameleon.ui.msg("--> Do not create a checkpoint for this microstep: macrostep was already checkpointed once")
|
228
|
+
elsif microstep.on_checkpoint == "redo"
|
229
|
+
Kameleon.ui.msg("--> Do not create a checkpoint for this microstep: it must be redone everytime")
|
230
|
+
elsif microstep.on_checkpoint == "disabled"
|
231
|
+
Kameleon.ui.msg("--> Do not create a checkpoint for this microstep: it is disabled")
|
232
|
+
else
|
233
|
+
microstep_checkpoint_time = Time.now.to_i
|
234
|
+
Kameleon.ui.msg("--> Creating checkpoint: #{ microstep.identifier }")
|
235
|
+
create_checkpoint(microstep.identifier)
|
236
|
+
checkpointed = true
|
237
|
+
microstep_checkpoint_duration = Time.now.to_i - microstep_checkpoint_time
|
238
|
+
macrostep_checkpoint_duration += microstep_checkpoint_duration
|
239
|
+
Kameleon.ui.verbose("Checkpoint creation for MicroStep #{microstep.name} took: #{microstep_checkpoint_duration} secs")
|
235
240
|
end
|
236
241
|
end
|
237
242
|
end
|
238
243
|
else
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
244
|
+
if microstep.on_checkpoint == "only"
|
245
|
+
Kameleon.ui.msg("--> Skipped because checkpointing is not enabled")
|
246
|
+
next
|
247
|
+
else
|
248
|
+
begin
|
249
|
+
Kameleon.ui.msg("--> Running the step...")
|
250
|
+
microstep.commands.each do |cmd|
|
251
|
+
safe_exec_cmd(cmd)
|
252
|
+
end
|
253
|
+
rescue SystemExit, Interrupt
|
254
|
+
reload_contexts
|
255
|
+
breakpoint(nil)
|
256
|
+
end
|
247
257
|
end
|
248
258
|
end
|
249
259
|
Kameleon.ui.verbose("MicroStep #{microstep.name} took: #{Time.now.to_i - microstep_time - microstep_checkpoint_duration} secs")
|
@@ -278,7 +288,7 @@ module Kameleon
|
|
278
288
|
context = "exec_" + cmd.value
|
279
289
|
expected_names = map.keys.map { |k| k.gsub "exec_", "" }
|
280
290
|
unless map.keys.include? context
|
281
|
-
Kameleon.ui.error("Invalid context name arguments. Expected
|
291
|
+
Kameleon.ui.error("Invalid context name arguments. Expected: "\
|
282
292
|
"#{expected_names}")
|
283
293
|
fail ExecError
|
284
294
|
else
|
@@ -296,7 +306,7 @@ module Kameleon
|
|
296
306
|
execute = true
|
297
307
|
[first_cmd.key, second_cmd.key].each do |key|
|
298
308
|
unless expected_cmds.include?(key)
|
299
|
-
Kameleon.ui.error("Invalid pipe arguments. Expected
|
309
|
+
Kameleon.ui.error("Invalid pipe arguments. Expected: "\
|
300
310
|
"#{expected_cmds}")
|
301
311
|
fail ExecError
|
302
312
|
end
|
@@ -349,7 +359,7 @@ module Kameleon
|
|
349
359
|
exec_cmd(cmd, kwargs)
|
350
360
|
end
|
351
361
|
else
|
352
|
-
Kameleon.ui.warn("Unknown command
|
362
|
+
Kameleon.ui.warn("Unknown command: #{cmd.key}")
|
353
363
|
end
|
354
364
|
end
|
355
365
|
|
@@ -407,7 +417,7 @@ module Kameleon
|
|
407
417
|
end
|
408
418
|
|
409
419
|
def rescue_exec_error(cmd)
|
410
|
-
message = "Error occured when executing the following command
|
420
|
+
message = "Error occured when executing the following command:\n"
|
411
421
|
cmd.string_cmd.split( /\r?\n/ ).each {|m| message << "\n> #{m}" }
|
412
422
|
if Kameleon.env.script?
|
413
423
|
raise ExecError, message
|
@@ -423,7 +433,7 @@ module Kameleon
|
|
423
433
|
begin
|
424
434
|
exec_cmd(cmd, kwargs)
|
425
435
|
rescue
|
426
|
-
Kameleon.ui.warn("An error occurred while executing
|
436
|
+
Kameleon.ui.warn("An error occurred while executing: #{cmd.value}")
|
427
437
|
end
|
428
438
|
end
|
429
439
|
end
|
@@ -431,16 +441,20 @@ module Kameleon
|
|
431
441
|
next if @cleaned_sections.include?(section.name)
|
432
442
|
Kameleon.ui.info("Cleaning #{section.name} section")
|
433
443
|
section.clean_macrostep.sequence do |microstep|
|
434
|
-
if @
|
444
|
+
if @checkpointing
|
435
445
|
if microstep.on_checkpoint == "skip"
|
436
446
|
next
|
437
447
|
end
|
448
|
+
else
|
449
|
+
if microstep.on_checkpoint == "only"
|
450
|
+
next
|
451
|
+
end
|
438
452
|
end
|
439
453
|
microstep.commands.each do |cmd|
|
440
454
|
begin
|
441
455
|
exec_cmd(cmd, kwargs)
|
442
456
|
rescue
|
443
|
-
Kameleon.ui.warn("An error occurred while executing
|
457
|
+
Kameleon.ui.warn("An error occurred while executing: #{cmd.value}")
|
444
458
|
end
|
445
459
|
end
|
446
460
|
end
|
@@ -555,19 +569,19 @@ module Kameleon
|
|
555
569
|
end
|
556
570
|
|
557
571
|
def build
|
558
|
-
if @
|
572
|
+
if @checkpointing
|
559
573
|
@from_checkpoint = @options[:from_checkpoint]
|
560
574
|
if @from_checkpoint.nil? || @from_checkpoint == "last"
|
561
575
|
@from_checkpoint = list_checkpoints.last
|
562
576
|
else
|
563
577
|
unless list_checkpoints.include?@from_checkpoint
|
564
|
-
fail BuildError, "Unknown checkpoint hash
|
578
|
+
fail BuildError, "Unknown checkpoint hash: #{@from_checkpoint}." \
|
565
579
|
" Use checkpoints command to find a valid" \
|
566
580
|
" checkpoint"
|
567
581
|
end
|
568
582
|
end
|
569
583
|
unless @from_checkpoint.nil?
|
570
|
-
Kameleon.ui.info("Restoring last build from step
|
584
|
+
Kameleon.ui.info("Restoring last build from step: #{@from_checkpoint}")
|
571
585
|
apply_checkpoint @from_checkpoint
|
572
586
|
@recipe.microsteps.each do |microstep|
|
573
587
|
microstep.in_cache = true
|
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
|
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
|
|
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,75 @@
|
|
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
|
+
- MC2:
|
65
|
+
- on_checkpoint: only
|
66
|
+
- exec_local: echo MicroStepC2
|
67
|
+
- MC3:
|
68
|
+
- exec_local: echo MicroStepC3
|
69
|
+
- MD:
|
70
|
+
- MD1:
|
71
|
+
- on_checkpoint: use_cache
|
72
|
+
- exec_local: echo MicroStepD1
|
73
|
+
|
74
|
+
|
75
|
+
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.10
|
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-06-13 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
|