kameleon-builder 2.9.4 → 2.10.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 77bd099db84f2bcda3b7a494e19055fc1d16158f8e6cb52d3be3abad4ce61fe8
4
- data.tar.gz: 9cab43b3a49e340aab7e051659c3e51e6dccdf71dffa8df18e5257dae9353ffc
3
+ metadata.gz: 40bafaeccf66d6d3149f1af122656d69ca563488fc51cb358e67a607f813d407
4
+ data.tar.gz: 93d6c6c995fa330626a823c06026e9a3733c0dc72ee1cdc7feefc1d6f0db0362
5
5
  SHA512:
6
- metadata.gz: a343c26b0723fbc92015ea796eaf1846270013cbe07344c7c27ec24e15960fd461b8bcd66adf4743cadaa3173a2bc2adba2fbccf3630126c16ecca8d1fb4d155
7
- data.tar.gz: c7b7c1392ab8d9459a8aba07b9c3580e6ea7a3c46cb2d56b9befb194784c6268c7370f04316a77864c6951c0f8011fd36176f75744d83e55856025fdf92195a4
6
+ metadata.gz: 4ff5b417aced3f8736f9d5d7dbe1f45092310667fbb352903fa9075844222d6e667e86881dca443367d1088d9dee7269d8f185c715ad9615957cda60985b7d07
7
+ data.tar.gz: e69e617c0ee0eddf3d65dc2c2cef1b878222afbd9d0c7f392d57a93f164e84dd5cd217e8c4ac6f8b7673ad7ceb8355c7c0d60c57e555ba2141ed3211a6c2ca25
data/.bumpversion.cfg CHANGED
@@ -1,7 +1,7 @@
1
1
  [bumpversion]
2
2
  commit = True
3
3
  tag = True
4
- current_version = 2.9.4
4
+ current_version = 2.10.1
5
5
  parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(\.(?P<release>[a-z]+))?
6
6
  serialize =
7
7
  {major}.{minor}.{patch}.{release}
data/CHANGES CHANGED
@@ -1,10 +1,33 @@
1
1
  Kameleon CHANGELOG
2
2
  ==================
3
3
 
4
- Version 2.9.3.dev
5
- -----------------
4
+ Version 2.10.1
5
+ -------------
6
+
7
+ Released on March 21th 2020
8
+
9
+ - Fix regression in 2.10.0 with the build directory creation
10
+
11
+ Version 2.10.0
12
+ -------------
13
+
14
+ Released on March 21th 2020
15
+
16
+ - Rework usage (cosmetic fixes)
17
+ - Drop the `kameleon template repository` action (same as `kameleon repository`)
18
+ - Make `kameleon dag` and `kameleon dryrun` standalone actions instead of `kameleon info` options
19
+ - Add the `kamelon dag --recipes-only`
20
+ - Make `kameleon dag` show distincly the extended recipe among the ancestors
21
+ - Add the `kameleon export` action
22
+
23
+ Version 2.9.4
24
+ -------------
25
+
26
+ Released on December 12th 2018
27
+
28
+ - Minor fixes
29
+ - NB: the 2.9.3 version was lost in space...
6
30
 
7
- **unreleased**
8
31
 
9
32
  Version 2.9.2
10
33
  -------------
data/lib/kameleon/cli.rb CHANGED
@@ -11,10 +11,10 @@ module Kameleon
11
11
  class Repository < Thor
12
12
  include Thor::Actions
13
13
 
14
- desc "add [NAME] [URL]", "Adds a new named <name> repository at <url>."
14
+ desc "add <NAME> <GIT_URL>", "Adds a new repository named <NAME> cloned from at <GIT_URL>."
15
15
  method_option :branch, :type => :string ,
16
16
  :default => nil,
17
- :desc => "checkout <branch>",
17
+ :desc => "checkout <BRANCH>",
18
18
  :aliases => "-b"
19
19
  def add(name, url)
20
20
  Kameleon::Repository.add(name, url, options)
@@ -25,7 +25,7 @@ module Kameleon
25
25
  Kameleon::Repository.list
26
26
  end
27
27
 
28
- desc "update [NAME]", "Updates a named <name> repository"
28
+ desc "update <NAME>", "Updates repository named <NAME> repository"
29
29
  def update(name)
30
30
  Kameleon::Repository.update(name)
31
31
  end
@@ -37,7 +37,7 @@ module Kameleon
37
37
  class Template < Thor
38
38
  include Thor::Actions
39
39
 
40
- register CLI::Repository, 'repository', 'repository', 'Manages set of remote git repositories'
40
+ # register CLI::Repository, 'repository', 'repository', 'Manages set of remote git repositories'
41
41
 
42
42
  def self.source_root
43
43
  Kameleon.env.repositories_path
@@ -50,7 +50,7 @@ module Kameleon
50
50
  Utils.list_recipes(Kameleon.env.repositories_path)
51
51
  end
52
52
 
53
- desc "import [TEMPLATE_NAME]", "Imports the given template"
53
+ desc "import <TEMPLATE_NAME>", "Imports the given template"
54
54
  method_option :global, :type => :hash ,
55
55
  :default => {}, :aliases => "-g",
56
56
  :desc => "Set custom global variables."
@@ -81,7 +81,7 @@ module Kameleon
81
81
  end
82
82
  end
83
83
 
84
- desc "info [TEMPLATE_NAME]", "Display detailed information about a template"
84
+ desc "info <TEMPLATE_NAME>", "Display detailed information about a template"
85
85
  method_option :global, :type => :hash ,
86
86
  :default => {}, :aliases => "-g",
87
87
  :desc => "Set custom global variables."
@@ -108,7 +108,7 @@ module Kameleon
108
108
  class Main < Thor
109
109
  include Thor::Actions
110
110
 
111
- register CLI::Repository, 'repository', 'repository', 'Manages set of remote git repositories'
111
+ register CLI::Repository, 'repository', 'repository', 'Manages repositories of recipes'
112
112
  # register CLI::Recipe, 'recipe', 'recipe', 'Manages the local recipes'
113
113
  register CLI::Template, 'template', 'template', 'Lists and imports templates'
114
114
 
@@ -139,7 +139,7 @@ module Kameleon
139
139
  end
140
140
  map %w(ls) => :list
141
141
 
142
- desc "new [RECIPE_PATH] [TEMPLATE_NAME]", "Creates a new recipe"
142
+ desc "new <RECIPE_PATH> <TEMPLATE_NAME>", "Creates a new recipe from template <TEMPLATE_NAME>"
143
143
  method_option :global, :type => :hash ,
144
144
  :default => {}, :aliases => "-g",
145
145
  :desc => "Set custom global variables."
@@ -190,7 +190,7 @@ module Kameleon
190
190
  end
191
191
  end
192
192
 
193
- desc "info [RECIPE_PATH]", "Display detailed information about a recipe"
193
+ desc "info <RECIPE_PATH>", "Display detailed information about a recipe"
194
194
  method_option :global, :type => :hash ,
195
195
  :default => {}, :aliases => "-g",
196
196
  :desc => "Set custom global variables."
@@ -200,9 +200,35 @@ module Kameleon
200
200
  method_option :dryrun, :type => :boolean ,
201
201
  :default => false,
202
202
  :desc => "Show the build sequence but do not actually build"
203
- method_option :dag, :type => :boolean ,
203
+ method_option :relative, :type => :boolean ,
204
204
  :default => false,
205
- :desc => "Show a DAG of the build sequence"
205
+ :desc => "Make pathnames relative to the current working directory"
206
+ def info(*recipe_paths)
207
+ if recipe_paths.empty?
208
+ if options[:from_cache].nil?
209
+ raise ArgumentError
210
+ else
211
+ unless File.file?(options[:from_cache])
212
+ raise CacheError, "The specified cache file "\
213
+ "\"#{options[:from_cache]}\" do not exists"
214
+ end
215
+ Kameleon.ui.info("Using the cached recipe")
216
+ @cache = Kameleon::Persistent_cache.instance
217
+ @cache.cache_path = options[:from_cache]
218
+ end
219
+ else
220
+ recipe_paths.each do |path|
221
+ recipe = Kameleon::Recipe.new(path)
222
+ recipe.resolve!
223
+ recipe.display_info(options[:relative])
224
+ end
225
+ end
226
+ end
227
+
228
+ desc "dag <RECIPE_PATH> [<RECIPE_PATH> [<...>]]", "Draw a DAG of the steps to build one or more recipes"
229
+ method_option :global, :type => :hash ,
230
+ :default => {}, :aliases => "-g",
231
+ :desc => "Set custom global variables."
206
232
  method_option :file, :type => :string ,
207
233
  :default => "/tmp/kameleon.dag",
208
234
  :desc => "DAG output filename"
@@ -211,52 +237,95 @@ module Kameleon
211
237
  method_option :relative, :type => :boolean ,
212
238
  :default => false,
213
239
  :desc => "Make pathnames relative to the current working directory"
214
-
215
- def info(*recipe_paths)
216
- if recipe_paths.length == 0 && !options[:from_cache].nil?
217
- unless File.file?(options[:from_cache])
218
- raise CacheError, "The specified cache file "\
219
- "\"#{options[:from_cache]}\" do not exists"
220
- end
221
- Kameleon.ui.info("Using the cached recipe")
222
- @cache = Kameleon::Persistent_cache.instance
223
- @cache.cache_path = options[:from_cache]
224
- end
225
- dag = nil
240
+ method_option :recipes_only, :type => :boolean ,
241
+ :default => false,
242
+ :desc => "Show recipes only (mostly useful to display multiple recipes inheritance)"
243
+ def dag(*recipe_paths)
244
+ raise ArgumentError if recipe_paths.empty?
226
245
  color = 0
246
+ recipes_dag = nil
227
247
  recipe_paths.each do |path|
228
248
  recipe = Kameleon::Recipe.new(path)
229
- if options[:dryrun]
230
- Kameleon::Engine.new(recipe, options).dryrun
231
- elsif options[:dag]
232
- dag = Kameleon::Engine.new(recipe, options).dag(dag, color)
233
- color += 1
249
+ recipes_dag = Kameleon::Engine.new(recipe, options.dup.merge({no_create_build_dir: true}).freeze).dag(recipes_dag, color, options[:recipes_only])
250
+ color += 1
251
+ end
252
+ format = "canon"
253
+ if options[:format]
254
+ if GraphViz::Constants::FORMATS.include?(options[:format])
255
+ format = options[:format]
234
256
  else
235
- recipe.resolve!
236
- recipe.display_info(options[:relative])
257
+ Kameleon.ui.warn("Unknown GraphViz format #{options[:format]}, fall back to #{format}")
237
258
  end
238
- end
239
- if options[:dag]
240
- format = "canon"
241
- if options[:format]
242
- if GraphViz::Constants::FORMATS.include?(options[:format])
243
- format = options[:format]
244
- else
245
- Kameleon.ui.warn("Unknown GraphViz format #{options[:format]}, fall back to #{format}")
259
+ else
260
+ options[:file].match(/^.+\.([^\.]+)$/) do |f|
261
+ if GraphViz::Constants::FORMATS.include?(f[1])
262
+ format = f[1]
246
263
  end
247
- else
248
- options[:file].match(/^.+\.([^\.]+)$/) do |f|
249
- if GraphViz::Constants::FORMATS.include?(f[1])
250
- format = f[1]
251
- end
264
+ end
265
+ end
266
+ recipes_dag.output( :"#{format}" => options[:file] )
267
+ Kameleon.ui.info("Generated GraphViz #{format} file: #{options[:file]}")
268
+ end
269
+
270
+ desc "dryrun <RECIPE_PATH>", "Show the steps the build would process"
271
+ method_option :global, :type => :hash ,
272
+ :default => {}, :aliases => "-g",
273
+ :desc => "Set custom global variables."
274
+ method_option :relative, :type => :boolean ,
275
+ :default => false,
276
+ :desc => "Make pathnames relative to the current working directory"
277
+ def dryrun(*recipe_paths)
278
+ raise ArgumentError if recipe_paths.empty?
279
+ recipe_paths.each do |path|
280
+ recipe = Kameleon::Recipe.new(path)
281
+ Kameleon::Engine.new(recipe, options.dup.merge({no_create_build_dir: true}).freeze).dryrun
282
+ end
283
+ end
284
+
285
+ desc "export <RECIPE_PATH> <EXPORT_PATH>", "Export the given recipe with its steps and data to a given directory"
286
+ method_option :global, :type => :hash ,
287
+ :default => {}, :aliases => "-g",
288
+ :desc => "Set custom global variables."
289
+ method_option :add, :type => :boolean ,
290
+ :default => false, :aliases => "-A",
291
+ :desc => "export recipe and steps to an existing directory (this may overwrite some existing files)"
292
+ def export(recipe_path,dest_path)
293
+ unless recipe_path.end_with? '.yaml'
294
+ recipe_path = recipe_path + '.yaml'
295
+ end
296
+ # Manage global as it is not passed to env by default
297
+ if options[:global]
298
+ Kameleon.env.global.merge!(options[:global])
299
+ end
300
+ recipe = Recipe.new(recipe_path)
301
+ recipe.resolve! :strict => false
302
+ recipe.all_files.uniq.each do |path|
303
+ relative_path = path.relative_path_from(Kameleon.env.workspace)
304
+ if relative_path.fnmatch("../*")
305
+ raise if Kameleon.ui.level("verbose")
306
+ raise ExportError, "Recipe '#{recipe_path}' depends on a file" \
307
+ " outside of the current directory: '#{relative_path.to_s}'"
252
308
  end
309
+ end
310
+ Kameleon.ui.info("Export recipe #{recipe_path} to directory: #{dest_path}")
311
+ if File.exists?(dest_path)
312
+ unless options[:add]
313
+ raise if Kameleon.ui.level("verbose")
314
+ raise ExportError, "Target export directory '#{dest_path}' already "\
315
+ "exists, use the --add option if you really want to export the "\
316
+ "recipe files to it (this may overwrite some existing files)"
253
317
  end
254
- dag.output( :"#{format}" => options[:file] )
255
- Kameleon.ui.info("Generated GraphViz #{format} file: #{options[:file]}")
318
+ else
319
+ FileUtils.mkdir_p(dest_path)
320
+ end
321
+ recipe.all_files.uniq.each do |path|
322
+ relative_path = path.relative_path_from(Kameleon.env.workspace)
323
+ dst = File.join(dest_path, relative_path)
324
+ copy_file(path, dst)
256
325
  end
257
326
  end
258
327
 
259
- desc "build [RECIPE_PATH]", "Builds the appliance from the given recipe"
328
+ desc "build <RECIPE_PATH>", "Builds the appliance from the given recipe"
260
329
  method_option :build_path, :type => :string ,
261
330
  :default => nil, :aliases => "-b",
262
331
  :desc => "Sets the build directory path"
@@ -75,7 +75,7 @@ module Kameleon
75
75
  if @options[:enable_cache] || @options[:from_cache] then
76
76
  @cache.recipe_files = @recipe.all_files
77
77
  end
78
- unless @options[:dryrun] or @options[:dag]
78
+ unless @options[:no_create_build_dir]
79
79
  begin
80
80
  Kameleon.ui.info("Creating kameleon build directory : #{@cwd}")
81
81
  FileUtils.mkdir_p @cwd
@@ -466,7 +466,7 @@ module Kameleon
466
466
  Kameleon.ui.shell.say ""
467
467
  end
468
468
 
469
- def dag(graph, color)
469
+ def dag(graph, color, recipes_only)
470
470
  if graph.nil?
471
471
  graph = GraphViz::new( "G" )
472
472
  end
@@ -482,47 +482,61 @@ module Kameleon
482
482
  n_recipe['colorscheme'] = colorscheme
483
483
  n_recipe['color'] = color
484
484
  (@recipe.base_recipes_files - [@recipe.path]).uniq.each do |base_recipe_path|
485
- n_base_recipe = g_recipes.add_nodes(base_recipe_path.relative_path_from(Pathname(Dir.pwd)).to_s)
486
- n_base_recipe['shape'] = 'Mdiamond'
487
- edge = graph.add_edges(n_base_recipe, n_recipe)
485
+ Kameleon.ui.debug("Dag add node #{base_recipe_path}")
486
+ n_base_recipe = g_recipes.add_nodes(base_recipe_path.relative_path_from(Pathname(Dir.pwd)).to_s)
487
+ n_base_recipe['shape'] = 'Mdiamond'
488
+ edge = graph.add_edges(n_base_recipe, n_recipe)
489
+ if base_recipe_path == @recipe.extended_recipe_file
490
+ Kameleon.ui.debug("This is the extended recipe")
491
+ edge['colorscheme'] = colorscheme
492
+ edge['color'] = color
493
+ else
488
494
  edge['style'] = 'dashed'
495
+ end
489
496
  end
490
497
  n_prev = n_recipe
491
- ["bootstrap", "setup", "export"].each do |section_name|
492
- section = @recipe.sections.fetch(section_name)
493
- g_section = graph.add_graph( "cluster S:#{ section_name }" )
494
- g_section['label'] = section_name.capitalize
495
- section.sequence do |macrostep|
496
- if macrostep.path.nil?
497
- macrostep_name = macrostep.name
498
- else
499
- macrostep_name = macrostep.path.relative_path_from(Pathname(Dir.pwd)).to_s
500
- macrostep_name.chomp!(".yaml")
501
- macrostep_name.sub!(/^steps\//, "")
502
- end
503
- g_macrostep = g_section.add_graph( "cluster M:#{ macrostep_name }")
504
- g_macrostep['label'] = macrostep_name
505
- g_macrostep['style'] = 'filled'
506
- g_macrostep['color'] = 'gray'
507
- macrostep.sequence do |microstep|
508
- n_microstep = g_macrostep.add_nodes("m:#{macrostep_name}/#{microstep.name}")
509
- n_microstep['label'] = microstep.name
510
- n_microstep['style'] = 'filled'
511
- n_microstep['color'] = 'white'
512
- edge = graph.add_edges(n_prev, n_microstep)
513
- edge['colorscheme'] = colorscheme
514
- edge['color'] = color
515
- n_prev = n_microstep
498
+ if recipes_only
499
+ Kameleon.ui.debug("As requested, only show recipes")
500
+ else
501
+ ["bootstrap", "setup", "export"].each do |section_name|
502
+ Kameleon.ui.debug("Dag add section #{section_name}")
503
+ section = @recipe.sections.fetch(section_name)
504
+ g_section = graph.add_graph( "cluster S:#{ section_name }" )
505
+ g_section['label'] = section_name.capitalize
506
+ section.sequence do |macrostep|
507
+ Kameleon.ui.debug("Dag add macrostep #{macrostep.name}")
508
+ if macrostep.path.nil?
509
+ macrostep_name = macrostep.name
510
+ else
511
+ macrostep_name = macrostep.path.relative_path_from(Pathname(Dir.pwd)).to_s
512
+ macrostep_name.chomp!(".yaml")
513
+ macrostep_name.sub!(/^steps\//, "")
514
+ end
515
+ g_macrostep = g_section.add_graph( "cluster M:#{ macrostep_name }")
516
+ g_macrostep['label'] = macrostep_name
517
+ g_macrostep['style'] = 'filled'
518
+ g_macrostep['color'] = 'gray'
519
+ macrostep.sequence do |microstep|
520
+ Kameleon.ui.debug("Dag add microstep #{microstep.name}")
521
+ n_microstep = g_macrostep.add_nodes("m:#{macrostep_name}/#{microstep.name}")
522
+ n_microstep['label'] = microstep.name
523
+ n_microstep['style'] = 'filled'
524
+ n_microstep['color'] = 'white'
525
+ edge = graph.add_edges(n_prev, n_microstep)
526
+ edge['colorscheme'] = colorscheme
527
+ edge['color'] = color
528
+ n_prev = n_microstep
529
+ end
516
530
  end
517
531
  end
532
+ n_end = graph.add_nodes('end')
533
+ n_end['label'] = 'END'
534
+ n_end['shape'] = 'Msquare'
535
+ edge = graph.add_edges(n_prev, n_end)
536
+ edge['colorscheme'] = colorscheme
537
+ edge['color'] = color
518
538
  end
519
- n_end = graph.add_nodes('end')
520
- n_end['label'] = 'END'
521
- n_end['shape'] = 'Msquare'
522
- edge = graph.add_edges(n_prev, n_end)
523
- edge['colorscheme'] = colorscheme
524
- edge['color'] = color
525
- Kameleon.ui.info "-> Drawn DAG for #{recipe_path}"
539
+ Kameleon.ui.info "-> Draw DAG for #{recipe_path}"
526
540
  return graph
527
541
  end
528
542
 
@@ -26,4 +26,5 @@ module Kameleon
26
26
  class AbortError < Error; status_code(8) ; end
27
27
  class TemplateNotFound < Error; status_code(9) ; end
28
28
  class CacheError < Error; status_code(10) ; end
29
+ class ExportError < Error; status_code(11) ; end
29
30
  end
@@ -14,6 +14,7 @@ module Kameleon
14
14
  attr_accessor :checkpoint_path
15
15
  attr_accessor :metainfo
16
16
  attr_accessor :files
17
+ attr_accessor :extended_recipe_file
17
18
  attr_accessor :base_recipes_files
18
19
  attr_accessor :data_files
19
20
  attr_accessor :env_files
@@ -97,6 +98,12 @@ module Kameleon
97
98
 
98
99
  update_steps_dirs()
99
100
 
101
+ extended_recipe_name = yaml_recipe.fetch("extend", "")
102
+ unless extended_recipe_name.nil?
103
+ extended_recipe_name << ".yaml" unless extended_recipe_name.end_with? ".yaml"
104
+ @extended_recipe_file = Pathname.new(File.expand_path(File.join(File.dirname(path), extended_recipe_name)))
105
+ end
106
+
100
107
  # Load extended recipe variables
101
108
  yaml_recipe = load_base_recipe(yaml_recipe, @path)
102
109
  yaml_recipe.delete("extend")
data/version.txt CHANGED
@@ -1 +1 @@
1
- 2.9.4
1
+ 2.10.1
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.9.4
4
+ version: 2.10.1
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: 2018-12-12 00:00:00.000000000 Z
15
+ date: 2020-03-21 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: childprocess
@@ -223,7 +223,7 @@ requirements:
223
223
  - polipo 1.0.3, or greater
224
224
  - graphviz 2.38.0 or greater
225
225
  rubyforge_project:
226
- rubygems_version: 2.7.7
226
+ rubygems_version: 2.7.6.2
227
227
  signing_key:
228
228
  specification_version: 4
229
229
  summary: Kameleon is a tool to build virtual machines from scratch