kameleon-builder 2.10.2 → 2.10.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5ba36ddda8ead18d06bc94412de565662a2cbed76a2ce71e4994e4f5ee665477
4
- data.tar.gz: 8a1e67a68923b413654682b87e14e6c91102b57dc9fd4ed45164f0827b1483cb
3
+ metadata.gz: e3fd959d36bbd756d9a632b39e1d9bdd1bcaa5a0c4fd8104187041473dbd4ae0
4
+ data.tar.gz: 3d36533205a0a55d3e2622ff1f713f4c2432f6cd48c34afc9bd35006855e9302
5
5
  SHA512:
6
- metadata.gz: 6993ca5f73661525c8a44133eb715d383144b75d5e4c9cc66f73aab1896643d9db09165ddc9af46e1474c2a82b856f1dc8a894582fb398f8d25ec472019878f1
7
- data.tar.gz: 205ac5b41d50af596f7428196bfc1c1c6633e6408d5643e3d4e71f323f5117755e863e98432febcca98f0461b421d40a6a3ec08634da50a66f1afe101c38eba8
6
+ metadata.gz: 2915fa5554adacbbeda1d03655bf995ab8191e9396649adc2cd158a386926b00f991da040144bb35b5d15ca37e127222400749f3d82c6e00fe934cce4bf851f2
7
+ data.tar.gz: c0c5754fcffb10f0c1d80b5523accf99768facc1468190ffd3991842d05edeacdedfef9d0b5651dc844b90dddc8c535234de2214f1d47177c42fbeada596531c
data/.bumpversion.cfg CHANGED
@@ -1,13 +1,13 @@
1
1
  [bumpversion]
2
2
  commit = True
3
3
  tag = True
4
- current_version = 2.10.2
4
+ current_version = 2.10.6
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}
8
8
  {major}.{minor}.{patch}
9
9
 
10
- [bumpversion:file:version.txt]
10
+ [bumpversion:file:lib/kameleon/version.rb]
11
11
 
12
12
  [bumpversion:part:release]
13
13
  optional_value = gamma
data/CHANGES CHANGED
@@ -1,10 +1,49 @@
1
1
  Kameleon CHANGELOG
2
2
  ==================
3
3
 
4
+ Version 2.10.6
5
+ --------------
6
+
7
+ Released on November 24th 2021
8
+
9
+ - Add the option filter for the template and recipe listings
10
+ - Preserve permission of files when importing template
11
+
12
+ Version 2.10.5
13
+ --------------
14
+
15
+ Released on July 29th 2021
16
+
17
+ - Remove polipo from the software dependencies as it is not maintained anymore. This breaks the caching feature.
18
+ - Some changes to allow a debian packaging.
19
+ - Update authors.
20
+ - Change the version information file and update scripts accordingly.
21
+
22
+ Version 2.10.4
23
+ --------------
24
+
25
+ Released on May 11th 2020
26
+
27
+ - Fix support for extend ERB
28
+ - Add the `kameleon template erb` command
29
+ - Fix bash completion
30
+ - Cosmetic code fixes
31
+
32
+ Version 2.10.3
33
+ --------------
34
+
35
+ Released on April 10th 2020
36
+
37
+ - Rework kameleon template list: add color add progress bar
38
+ - Make bash completion understand the subcommands
39
+ - Fix the command help -> `kameleon <command> -h`
40
+ - Add support for custom extend erb templates
41
+
4
42
  Version 2.10.2
5
43
  --------------
6
44
 
7
45
  Released on April 09th 2020
46
+
8
47
  - Fix cli help for the repository and template sub-commands
9
48
  - Add the git remote url and branch to kameleon repo list
10
49
  - Add the 'kameleon repository remove' command
data/RELEASING.md ADDED
@@ -0,0 +1,69 @@
1
+ About releases:
2
+ ===============
3
+ You can use the script ``./scripts/bumpversion.py`` which will handle
4
+ everything (incrementation, git tag creation, changelog update).
5
+ First you need to install bumpversion using pip::
6
+ ```
7
+ sudo pip install bumpversion
8
+ ```
9
+ Assuming work is done in the devel branch.
10
+
11
+ For stable releases:
12
+ --------------------
13
+
14
+ ## Merge devel into master:
15
+ ```
16
+ git checkout master
17
+ git merge devel
18
+ ```
19
+
20
+ ## Fix anything needed
21
+ Should be no conflict but...
22
+ Make sure changelog is up to date.
23
+
24
+ ## Bump version
25
+ ***Warning*** Make sure that there is no dirty file (not committed) before the following.
26
+ ```
27
+ ./scripts/bumpversion.py release # will do 2.7.0.dev -> 2.7.0 + git tag + changelog
28
+ git push
29
+ ```
30
+
31
+ ## Build gem
32
+ ```
33
+ gem build kameleon-builder.gemspec
34
+ ```
35
+
36
+ ## Push to Ruby gem repository
37
+ ```
38
+ gem push kameleon-builder-2.7.0.gem
39
+ ```
40
+
41
+ Note: You need a rubygem account and the owner has to give you permissions so that you can push.
42
+ To do so, create an account on https://rubygems.org/ and ask an owner to do
43
+ the following command::
44
+
45
+ ```
46
+ gem owner kameleon-builder -a your@email.com
47
+ ```
48
+
49
+ That's all :)
50
+
51
+ For devel releases:
52
+ -------------------
53
+
54
+ ## Move to the devel branch and rebase on master
55
+ ```
56
+ git checkout devel
57
+ git rebase master
58
+ ```
59
+
60
+ ## Prepare the new version
61
+ Create the new devel version (e.g. 2.7.0 dev)
62
+ ```
63
+ ./scripts/bumpversion.py newversion patch # 2.6.7 -> 2.7.0.dev
64
+ ```
65
+
66
+ At this point, do work, commit, and so on.
67
+ And same as above to build "devel" gem and use them locally, or push them if really wanted.
68
+
69
+ Up to the time to build a new stable version.
data/bin/kameleon CHANGED
@@ -17,7 +17,7 @@ begin
17
17
  Kameleon.init_userconf
18
18
  Kameleon::Main.start
19
19
  rescue Exception => e
20
- Kameleon.ui.error("Error : #{e}")
20
+ Kameleon.ui.error("Error: #{e}")
21
21
  if Kameleon.env.debug
22
22
  raise e
23
23
  else
@@ -2,12 +2,23 @@
2
2
 
3
3
  _kameleon() {
4
4
  COMPREPLY=()
5
- local word="${COMP_WORDS[COMP_CWORD]}"
6
-
7
- if [ "$COMP_CWORD" -eq 1 ]; then
8
- local commands="$(compgen -W "$(kameleon commands)" -- "$word")"
5
+ local i=1
6
+ while [ $i -le "$COMP_CWORD" -a "${COMP_WORDS[$i]:0:1}" == "-" ]; do
7
+ ((i++))
8
+ done
9
+ if [ "$COMP_CWORD" -eq $i ]; then
10
+ local commands="$(compgen -W "$(kameleon commands)" -- "${COMP_WORDS[$i]}")"
9
11
  COMPREPLY=( $commands $projects )
10
12
  fi
13
+ while [ $i -le "$COMP_CWORD" -a "${COMP_WORDS[$i]:0:1}" == "-" ]; do
14
+ ((i++))
15
+ done
16
+ if [ "$COMP_CWORD" -eq $((i+1)) ] && kameleon commands | grep -q "${COMP_WORDS[$i]}" ; then
17
+ if kameleon help | grep -qe "^ kameleon ${COMP_WORDS[$i]}[a-z]* <SUBCOMMAND>"; then
18
+ local commands="$(compgen -W "$(kameleon ${COMP_WORDS[$i]} commands)" -- "${COMP_WORDS[$((i+1))]}")"
19
+ COMPREPLY=( $commands $projects )
20
+ fi
21
+ fi
11
22
  }
12
23
 
13
24
  complete -o default -F _kameleon kameleon
@@ -0,0 +1,24 @@
1
+ #==============================================================================
2
+ # vim: softtabstop=2 shiftwidth=2 expandtab fenc=utf-8 cc=81 tw=80
3
+ #==============================================================================
4
+ #
5
+ # DESCRIPTION: <MY RECIPE DESCRIPTION>
6
+ #
7
+ #==============================================================================
8
+ # This recipe extends another. To look at the step involed, run:
9
+ # kameleon dryrun <%= recipe_name %>
10
+ # To see the variables that you can override, use the following command:
11
+ # kameleon info <%= recipe_name %>
12
+ ---
13
+ extend: <%= tpl.relative_path_from_recipe(recipe_path) %>
14
+
15
+ global:
16
+
17
+ bootstrap:
18
+ - "@base"
19
+
20
+ setup:
21
+ - "@base"
22
+
23
+ export:
24
+ - "@base"
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  repositories_path: <%= Kameleon.default_values[:repositories_path] %>
3
+ extend_yaml_erb: <%= Kameleon.default_values[:extend_yaml_erb] %>
3
4
  script: <%= Kameleon.default_values[:script] %>
4
5
  color: <%= Kameleon.default_values[:color] %>
5
6
  debug: <%= Kameleon.default_values[:debug] %>
@@ -12,13 +12,13 @@ Gem::Specification.new do |s|
12
12
  'Cristan Ruiz',
13
13
  'Pierre Neyron',
14
14
  'Bruno Bzeznik']
15
- s.email = ['salem.harrache@inria.fr',
16
- 'michael.mercier@inria.fr',
17
- 'cristian.ruiz@imag.fr',
15
+ s.email = ['salem@harrache.info',
16
+ 'michael.mercier@libr.fr',
17
+ 'camilo1729@gmail.com',
18
18
  'pierre.neyron@imag.fr',
19
19
  'bruno.bzeznik@imag.fr']
20
20
  s.description = %q{The mindful appliance builder}
21
- s.summary = %q{Kameleon is a tool to build virtual machines from scratch}
21
+ s.summary = %q{Kameleon is a tool to build system appliances from scratch}
22
22
  s.homepage = 'http://kameleon.imag.fr/'
23
23
  s.license = 'GPL-2.0'
24
24
 
@@ -33,6 +33,7 @@ Gem::Specification.new do |s|
33
33
  s.add_dependency 'table_print', '~> 1.5'
34
34
  s.add_dependency 'psych', '~> 2.0'
35
35
  s.add_dependency 'ruby-graphviz', '~> 1.2'
36
+ s.add_dependency 'progressbar', '~> 1'
36
37
 
37
38
  s.requirements = ['polipo 1.0.3, or greater', 'graphviz 2.38.0 or greater']
38
39
  end
data/lib/kameleon/cli.rb CHANGED
@@ -11,8 +11,8 @@ module Kameleon
11
11
  class Repository < Thor
12
12
  include Thor::Actions
13
13
 
14
- desc "add <NAME> <GIT_URL>", "Adds a new repository named <NAME> cloned from at <GIT_URL>."
15
- method_option :branch, :type => :string ,
14
+ desc "add <NAME> <GIT_URL>", "Adds a new repository named <NAME> cloned from <GIT_URL>."
15
+ method_option :branch, :type => :string,
16
16
  :default => nil,
17
17
  :desc => "checkout <BRANCH>",
18
18
  :aliases => "-b"
@@ -32,37 +32,45 @@ module Kameleon
32
32
  def update(name)
33
33
  Kameleon::Repository.update(name)
34
34
  end
35
- map %w(-h --help) => :help
36
- map %w(ls) => :list
37
35
 
38
36
  desc "remove <NAME>", "Remove repository named <NAME>"
39
37
  def remove(name)
40
38
  Kameleon::Repository.remove(name)
41
39
  end
42
- map %w(-h --help) => :help
40
+
41
+ desc "commands", "Lists all available commands", :hide => true
42
+ def commands
43
+ puts Repository.all_commands.keys - ["commands"]
44
+ end
45
+
43
46
  map %w(ls) => :list
44
47
  map %w(rm) => :remove
48
+ map %w(completions) => :commands
45
49
  end
46
50
 
47
51
 
48
52
  class Template < Thor
49
53
  include Thor::Actions
50
54
 
51
- # register CLI::Repository, 'repository', 'repository', 'Manages set of remote git repositories'
52
-
53
55
  def self.source_root
54
56
  Kameleon.env.repositories_path
55
57
  end
56
58
 
57
59
  desc "list", "Lists all available templates"
60
+ method_option :progress, :type => :boolean, :default => true,
61
+ :desc => "Show progress bar while resolving templates",
62
+ :aliases => "-p"
63
+ method_option :filter, :type => :string, :default => '',
64
+ :desc => "Filter templates with the given regexp",
65
+ :aliases => "-f"
58
66
  def list
59
- Kameleon.ui.info "The following templates are available in " \
60
- "#{ Kameleon.env.repositories_path }:"
61
- Utils.list_recipes(Kameleon.env.repositories_path)
67
+ Kameleon.ui.shell.say "Recipe templates available in: ", :red, false
68
+ Kameleon.ui.shell.say Kameleon.env.repositories_path.to_s, :yellow
69
+ Utils.list_recipes(Kameleon.env.repositories_path, options[:filter], options[:progress], true)
62
70
  end
63
71
 
64
72
  desc "import <TEMPLATE_NAME>", "Imports the given template"
65
- method_option :global, :type => :hash ,
73
+ method_option :global, :type => :hash,
66
74
  :default => {}, :aliases => "-g",
67
75
  :desc => "Set custom global variables."
68
76
  def import(template_name)
@@ -88,12 +96,13 @@ module Kameleon
88
96
  relative_path = path.relative_path_from(Kameleon.env.repositories_path)
89
97
  dst = File.join(Kameleon.env.workspace, relative_path)
90
98
  copy_file(path, dst)
99
+ chmod(dst, File.stat(path).mode, {:verbose=>false})
91
100
  end
92
101
  end
93
102
  end
94
103
 
95
104
  desc "info <TEMPLATE_NAME>", "Display detailed information about a template"
96
- method_option :global, :type => :hash ,
105
+ method_option :global, :type => :hash,
97
106
  :default => {}, :aliases => "-g",
98
107
  :desc => "Set custom global variables."
99
108
  def info(template_name)
@@ -110,8 +119,27 @@ module Kameleon
110
119
  tpl.resolve! :strict => false
111
120
  tpl.display_info(false)
112
121
  end
113
- map %w(-h --help) => :help
122
+
123
+ desc "erb <PATH>", "Create a extend recipe ERB file"
124
+ def erb(path)
125
+ if File.directory?(path)
126
+ erb_file = Pathname.new(path).join(Kameleon.default_values[:extend_yaml_erb])
127
+ elsif File.file?(path) and path.end_with?(".yaml")
128
+ erb_file = Pathname.new(path.gsub(%r{^(.+?/)?([^/]+?)(\.yaml)?$},'\1.\2') + Kameleon.default_values[:extend_yaml_erb])
129
+ else
130
+ fail KameleonError, "Invalid path '#{path}', please give a path to a yaml file or a directory"
131
+ end
132
+ Kameleon.ui.verbose("Create extend recipe ERB '#{erb_file}'")
133
+ copy_file(Pathname.new(Kameleon.erb_dirpath).join("extend.yaml.erb"), erb_file)
134
+ end
135
+
136
+ desc "commands", "Lists all available commands", :hide => true
137
+ def commands
138
+ puts Template.all_commands.keys - ["commands"]
139
+ end
140
+
114
141
  map %w(ls) => :list
142
+ map %w(completions) => :commands
115
143
  end
116
144
  end
117
145
 
@@ -133,26 +161,30 @@ module Kameleon
133
161
  class_option :script, :type => :boolean, :default => Kameleon.default_values[:script],
134
162
  :desc => "Never prompts for user intervention",
135
163
  :aliases => "-s"
136
- map %w(-h --help) => :help
137
164
 
138
165
  desc "version", "Prints the Kameleon's version information"
139
166
  def version
140
167
  puts "Kameleon version #{Kameleon::VERSION}"
141
168
  end
142
- map %w(-v --version) => :version
143
169
 
144
170
  def self.source_root
145
171
  Kameleon.env.repositories_path
146
172
  end
147
173
 
148
174
  desc "list", "Lists all defined recipes in the current directory"
175
+ method_option :progress, :type => :boolean, :default => false,
176
+ :desc => "Show progress bar while resolving recipes",
177
+ :aliases => "-p"
178
+ method_option :filter, :type => :string, :default => '',
179
+ :desc => "Filter recipes with the given regexp",
180
+ :aliases => "-f"
149
181
  def list
150
- Utils.list_recipes(Kameleon.env.workspace)
182
+ Kameleon.ui.shell.say "Workspace recipes:", :red
183
+ Utils.list_recipes(Kameleon.env.workspace, options[:filter], options[:progress])
151
184
  end
152
- map %w(ls) => :list
153
185
 
154
186
  desc "new <RECIPE_PATH> <TEMPLATE_NAME>", "Creates a new recipe from template <TEMPLATE_NAME>"
155
- method_option :global, :type => :hash ,
187
+ method_option :global, :type => :hash,
156
188
  :default => {}, :aliases => "-g",
157
189
  :desc => "Set custom global variables."
158
190
  def new(recipe_name, template_name)
@@ -187,14 +219,25 @@ module Kameleon
187
219
  relative_path = path.relative_path_from(Kameleon.env.repositories_path)
188
220
  dst = File.join(Kameleon.env.workspace, relative_path)
189
221
  copy_file(path, dst)
222
+ chmod(dst, File.stat(path).mode, {:verbose=>false})
190
223
  end
191
224
  Dir::mktmpdir do |tmp_dir|
192
225
  recipe_temp = File.join(tmp_dir, File.basename(recipe_path))
193
226
  ## copying recipe
194
227
  File.open(recipe_temp, 'w+') do |file|
195
- extend_erb_tpl = File.join(Kameleon.erb_dirpath, "extend.erb")
196
- erb = ERB.new(File.open(extend_erb_tpl, 'rb') { |f| f.read })
197
- result = erb.result(binding)
228
+ message="Try and use extend recipe ERB: "
229
+ extend_yaml_erb_list = Pathname.new(template_name).dirname.ascend.to_a.map do |p|
230
+ Kameleon.env.repositories_path.join(p, Kameleon.default_values[:extend_yaml_erb])
231
+ end
232
+ extend_yaml_erb_list.unshift(Kameleon.env.repositories_path.join(template_name.gsub(%r{^(.+?/)?([^/]+?)(\.yaml)?$},'\1.\2') + Kameleon.default_values[:extend_yaml_erb]))
233
+ extend_yaml_erb_list.push(Pathname.new(Kameleon.erb_dirpath).join("extend.yaml.erb"))
234
+ extend_yaml_erb = extend_yaml_erb_list.find do |f|
235
+ Kameleon.ui.verbose(message + f.to_s)
236
+ message = "-> Not found, fallback: "
237
+ File.readable?(f)
238
+ end
239
+ Kameleon.ui.debug("Open ERB file: '#{extend_yaml_erb}'")
240
+ result = ERB.new(File.open(extend_yaml_erb, 'rb') { |f| f.read }).result(binding)
198
241
  file.write(result)
199
242
  end
200
243
  copy_file(recipe_temp, recipe_path)
@@ -203,16 +246,13 @@ module Kameleon
203
246
  end
204
247
 
205
248
  desc "info <RECIPE_PATH>", "Display detailed information about a recipe"
206
- method_option :global, :type => :hash ,
249
+ method_option :global, :type => :hash,
207
250
  :default => {}, :aliases => "-g",
208
251
  :desc => "Set custom global variables."
209
- method_option :from_cache, :type => :string ,
252
+ method_option :from_cache, :type => :string,
210
253
  :default => nil,
211
254
  :desc => "Get info from a persistent cache tar file (ignore recipe path)"
212
- method_option :dryrun, :type => :boolean ,
213
- :default => false,
214
- :desc => "Show the build sequence but do not actually build"
215
- method_option :relative, :type => :boolean ,
255
+ method_option :relative, :type => :boolean,
216
256
  :default => false,
217
257
  :desc => "Make pathnames relative to the current working directory"
218
258
  def info(*recipe_paths)
@@ -238,18 +278,18 @@ module Kameleon
238
278
  end
239
279
 
240
280
  desc "dag <RECIPE_PATH> [<RECIPE_PATH> [<...>]]", "Draw a DAG of the steps to build one or more recipes"
241
- method_option :global, :type => :hash ,
281
+ method_option :global, :type => :hash,
242
282
  :default => {}, :aliases => "-g",
243
283
  :desc => "Set custom global variables."
244
- method_option :file, :type => :string ,
284
+ method_option :file, :type => :string,
245
285
  :default => "/tmp/kameleon.dag",
246
286
  :desc => "DAG output filename"
247
- method_option :format, :type => :string ,
287
+ method_option :format, :type => :string,
248
288
  :desc => "DAG GraphViz format"
249
- method_option :relative, :type => :boolean ,
289
+ method_option :relative, :type => :boolean,
250
290
  :default => false,
251
291
  :desc => "Make pathnames relative to the current working directory"
252
- method_option :recipes_only, :type => :boolean ,
292
+ method_option :recipes_only, :type => :boolean,
253
293
  :default => false,
254
294
  :desc => "Show recipes only (mostly useful to display multiple recipes inheritance)"
255
295
  def dag(*recipe_paths)
@@ -280,10 +320,10 @@ module Kameleon
280
320
  end
281
321
 
282
322
  desc "dryrun <RECIPE_PATH>", "Show the steps the build would process"
283
- method_option :global, :type => :hash ,
323
+ method_option :global, :type => :hash,
284
324
  :default => {}, :aliases => "-g",
285
325
  :desc => "Set custom global variables."
286
- method_option :relative, :type => :boolean ,
326
+ method_option :relative, :type => :boolean,
287
327
  :default => false,
288
328
  :desc => "Make pathnames relative to the current working directory"
289
329
  def dryrun(*recipe_paths)
@@ -295,10 +335,10 @@ module Kameleon
295
335
  end
296
336
 
297
337
  desc "export <RECIPE_PATH> <EXPORT_PATH>", "Export the given recipe with its steps and data to a given directory"
298
- method_option :global, :type => :hash ,
338
+ method_option :global, :type => :hash,
299
339
  :default => {}, :aliases => "-g",
300
340
  :desc => "Set custom global variables."
301
- method_option :add, :type => :boolean ,
341
+ method_option :add, :type => :boolean,
302
342
  :default => false, :aliases => "-A",
303
343
  :desc => "export recipe and steps to an existing directory (this may overwrite some existing files)"
304
344
  def export(recipe_path,dest_path)
@@ -338,36 +378,36 @@ module Kameleon
338
378
  end
339
379
 
340
380
  desc "build <RECIPE_PATH>", "Builds the appliance from the given recipe"
341
- method_option :build_path, :type => :string ,
381
+ method_option :build_path, :type => :string,
342
382
  :default => nil, :aliases => "-b",
343
383
  :desc => "Sets the build directory path"
344
- method_option :clean, :type => :boolean ,
384
+ method_option :clean, :type => :boolean,
345
385
  :default => false,
346
386
  :desc => "Runs the command `kameleon clean` first"
347
- method_option :from_checkpoint, :type => :string ,
387
+ method_option :from_checkpoint, :type => :string,
348
388
  :default => nil,
349
389
  :desc => "Uses specific checkpoint to build the image. " \
350
390
  "Default value is the last checkpoint."
351
- method_option :enable_checkpoint, :type => :boolean ,
391
+ method_option :enable_checkpoint, :type => :boolean,
352
392
  :default => false,
353
393
  :desc => "Enables checkpoint [experimental]"
354
- method_option :list_checkpoints, :type => :boolean , :aliases => "--checkpoints",
394
+ method_option :list_checkpoints, :type => :boolean, :aliases => "--checkpoints",
355
395
  :default => false,
356
396
  :desc => "Lists all availables checkpoints"
357
397
  method_option :enable_cache, :type => :boolean,
358
398
  :default => false,
359
399
  :desc => "Generates a persistent cache for the appliance."
360
- method_option :cache_path, :type => :string ,
400
+ method_option :cache_path, :type => :string,
361
401
  :default => nil,
362
402
  :desc => "Sets the cache directory path"
363
- method_option :from_cache, :type => :string ,
403
+ method_option :from_cache, :type => :string,
364
404
  :default => nil,
365
405
  :desc => "Uses a persistent cache tar file to build the image."
366
- method_option :cache_archive_compression, :type => :string ,
406
+ method_option :cache_archive_compression, :type => :string,
367
407
  :enum => ["none", "gzip", "bz2", "xz"],
368
408
  :default => "gzip",
369
409
  :desc => "Set the persistent cache tar file compression."
370
- method_option :polipo_path, :type => :string ,
410
+ method_option :polipo_path, :type => :string,
371
411
  :default => nil,
372
412
  :desc => "Full path of the polipo binary to use for the persistent cache."
373
413
  method_option :proxy, :type => :string, :default => "",
@@ -377,7 +417,7 @@ module Kameleon
377
417
  :desc => "Specifies the username and password if the parent "\
378
418
  "proxy requires authorisation it should have the "\
379
419
  "form 'username:password'"
380
- method_option :proxy_offline, :type => :boolean ,
420
+ method_option :proxy_offline, :type => :boolean,
381
421
  :default => false, :aliases => "--offline",
382
422
  :desc => "Prevents Polipo from contacting remote servers"
383
423
  method_option :global, :type => :hash,
@@ -419,8 +459,16 @@ module Kameleon
419
459
  end
420
460
 
421
461
  desc "commands", "Lists all available commands", :hide => true
422
- def commands
423
- puts Main.all_commands.keys - ["commands", "completions"]
462
+ def commands(context="main")
463
+ Kameleon.ui.debug("Commands for '#{context}':")
464
+ case context
465
+ when "main"
466
+ puts Main.all_commands.keys - ["commands"]
467
+ when "repository"
468
+ invoke CLI::Repository, "commands", [], []
469
+ when "template"
470
+ invoke CLI::Template, "commands", [], []
471
+ end
424
472
  end
425
473
 
426
474
  desc "source_root", "Prints the kameleon directory path", :hide => true
@@ -428,6 +476,10 @@ module Kameleon
428
476
  puts Kameleon.source_root
429
477
  end
430
478
 
479
+ map %w(-v --version) => :version
480
+ map %w(ls) => :list
481
+ map %w(completions) => :commands
482
+
431
483
  def initialize(*args)
432
484
  super
433
485
  self.options ||= {}
@@ -445,7 +497,17 @@ module Kameleon
445
497
  Kameleon.ui.verbose("The level of output is set to #{Kameleon.ui.level}")
446
498
  end
447
499
 
448
- def self.start(*)
500
+ def self.start(*args)
501
+ # `kameleon build -h` does not work without the following, except for subcommands...
502
+ # Ref: https://stackoverflow.com/a/49044225/6431461
503
+ if (Thor::HELP_MAPPINGS & ARGV).any? and subcommands.grep(/^#{ARGV[0]}/).empty?
504
+ Kameleon.ui.debug("Apply workaround to handle the help command in #{ARGV}")
505
+ Thor::HELP_MAPPINGS.each do |cmd|
506
+ if match = ARGV.delete(cmd)
507
+ ARGV.unshift match
508
+ end
509
+ end
510
+ end
449
511
  super
450
512
  rescue Exception => e
451
513
  Kameleon.ui = Kameleon::UI::Shell.new
@@ -93,7 +93,7 @@ module Kameleon
93
93
  unless File.file? @path
94
94
  yaml_recipe = YAML.load_file @path
95
95
  unless yaml_recipe.kind_of? Hash
96
- fail RecipeError, "Invalid yaml error : #{@path}"
96
+ fail RecipeError, "Invalid yaml: #{@path}"
97
97
  end
98
98
 
99
99
  update_steps_dirs()
@@ -242,7 +242,7 @@ module Kameleon
242
242
  unless File.file? path
243
243
  base_yaml_recipe = YAML.load_file base_recipe_path
244
244
  unless yaml_recipe.kind_of? Hash
245
- fail RecipeError, "Invalid yaml error : #{base_yaml_recipe}"
245
+ fail RecipeError, "Invalid yaml: #{base_yaml_recipe}"
246
246
  end
247
247
  base_yaml_recipe.keys.each do |key|
248
248
  if ["export", "bootstrap", "setup"].include? key
@@ -25,12 +25,17 @@ module Kameleon
25
25
  @bash_history_file = File.join(@bash_scripts_dir, "bash_history")
26
26
  @bash_env_file = File.join(@bash_scripts_dir, "bash_env")
27
27
  @bash_status_file = File.join(@bash_scripts_dir, "bash_status")
28
- @default_bashrc_file = File.join(Kameleon.source_root, "contrib", "kameleon_bashrc.sh")
29
- @cmd_tpl = ERB.new(File.read(File.join(Kameleon.source_root,
30
- "contrib",
28
+ if File::directory?(f = File.join(Kameleon.source_root, "contrib"))
29
+ @contrib_dir = f
30
+ elsif File::directory?(f = '/usr/share/kameleon/contrib')
31
+ @contrib_dir = f
32
+ else
33
+ raise "Could not find contrib dir"
34
+ end
35
+ @default_bashrc_file = File.join(@contrib_dir, 'kameleon_bashrc.sh')
36
+ @cmd_tpl = ERB.new(File.read(File.join(@contrib_dir,
31
37
  "kameleon_exec_cmd.sh")))
32
- @cmd_wrapper_tpl = ERB.new(File.read(File.join(Kameleon.source_root,
33
- "contrib",
38
+ @cmd_wrapper_tpl = ERB.new(File.read(File.join(@contrib_dir,
34
39
  "kameleon_exec_cmd_wrapper.sh")))
35
40
 
36
41
  if @shell_workdir
@@ -1,3 +1,5 @@
1
+ require 'progressbar'
2
+
1
3
  module Kameleon
2
4
  module Utils
3
5
 
@@ -123,33 +125,63 @@ module Kameleon
123
125
  end
124
126
  end
125
127
 
126
- def self.list_recipes(repository_path, kwargs = {})
127
- Kameleon.env.root_dir = repository_path
128
+ def self.list_recipes(recipes_path, filter = '', do_progressbar = false, is_repository = false, kwargs = {})
129
+ Kameleon.env.root_dir = recipes_path
128
130
  catch_exception = kwargs.fetch(:catch_exception, true)
129
131
  recipes_hash = []
130
- recipes_files = get_recipes(repository_path)
132
+ recipes_files = get_recipes(recipes_path).select { |f| Regexp.new(filter).match(f.to_s.gsub(recipes_path.to_s + '/', '').chomp('.yaml')) }
133
+ if recipes_files.empty?
134
+ Kameleon.ui.shell.say " <None>", :cyan
135
+ return
136
+ end
137
+ if do_progressbar
138
+ progressbar = ProgressBar.create(:format => '%t (%p%%) %bᗧ%i',
139
+ :title => 'Resolving ' + if is_repository; 'templates' else 'recipes' end,
140
+ :progress_mark => '.',
141
+ :remainder_mark => '・',
142
+ :total => recipes_files.size + 10,
143
+ :starting_at => 10)
144
+ end
131
145
  recipes_files.each do |f|
132
146
  path = f.to_s
133
147
  begin
134
148
  recipe = RecipeTemplate.new(path)
135
- name = path.gsub(repository_path.to_s + '/', '').chomp('.yaml')
149
+ name = path.gsub(recipes_path.to_s + '/', '').chomp('.yaml')
136
150
  recipes_hash.push({
137
151
  "name" => name,
138
152
  "description" => recipe.metainfo['description'],
139
153
  })
154
+ progressbar.increment if do_progressbar
140
155
  rescue => e
141
156
  raise e if Kameleon.env.debug or not catch_exception
142
157
  end
143
158
  end
144
159
  unless recipes_hash.empty?
145
- recipes_hash = recipes_hash.sort_by{ |k| k["name"] }
146
160
  name_width = recipes_hash.map { |k| k['name'].size }.max
147
161
  desc_width = Kameleon.ui.shell.terminal_width - name_width - 3
148
162
  desc_width = (80 - name_width - 3) if desc_width < 0
149
163
  end
150
- tp(recipes_hash,
151
- {"name" => {:width => name_width}},
152
- { "description" => {:width => desc_width}})
164
+ repo_str_old = nil
165
+ recipes_hash.sort_by{ |k| k["name"] }.each do |r|
166
+ if is_repository
167
+ repo_str,recipe_dir_str,recipe_str = r["name"].match(%r{^([^/]+/)(.+/)?([^/]+)$}).to_a[1..3].map{|m| m.to_s}
168
+ else
169
+ repo_str,recipe_dir_str,recipe_str = r["name"].match(%r{^()(.+/)?([^/]+)$}).to_a[1..3].map{|m| m.to_s}
170
+ end
171
+ if not repo_str_old.nil? and repo_str_old != repo_str
172
+ Kameleon.ui.shell.say "#{'-' * name_width} | #{'-' * desc_width}"
173
+ end
174
+ repo_str_old = repo_str
175
+ Kameleon.ui.debug("#{r["name"]} -> repo=#{repo_str}, recipe_dir=#{recipe_dir_str}, recipee=#{recipe_str}")
176
+ Kameleon.ui.shell.say "#{repo_str}", :yellow, false
177
+ Kameleon.ui.shell.say "#{recipe_dir_str}", :cyan, false
178
+ Kameleon.ui.shell.say sprintf("%-#{name_width - repo_str.length - recipe_dir_str.length}s", recipe_str), :magenta, false
179
+ Kameleon.ui.shell.say " | ", nil, false
180
+ if r["description"].to_s.length > desc_width - 4
181
+ r["description"] = r["description"][0..(desc_width - 4)] + "..."
182
+ end
183
+ Kameleon.ui.shell.say sprintf("%-#{desc_width}s", r["description"]), :blue
184
+ end
153
185
  end
154
186
 
155
187
  def self.get_recipes(path)
@@ -1,4 +1,3 @@
1
1
  module Kameleon
2
- VERSION = File.read(
3
- File.expand_path("../../../version.txt", __FILE__)).chomp
2
+ VERSION = '2.10.6'
4
3
  end
data/lib/kameleon.rb CHANGED
@@ -30,7 +30,12 @@ module Kameleon
30
30
  end
31
31
 
32
32
  def erb_dirpath
33
- File.join(Kameleon.source_root, 'erb')
33
+ d = File.join(Kameleon.source_root, 'erb')
34
+ if File::directory?(d)
35
+ return d
36
+ elsif File::directory?(d = '/usr/share/kameleon/erb')
37
+ return d
38
+ end
34
39
  end
35
40
 
36
41
  def userdir
@@ -46,7 +51,7 @@ module Kameleon
46
51
  def init_userconf()
47
52
  if not File.exists?(Kameleon.userconf_path) or File.zero?(Kameleon.userconf_path)
48
53
  File.open(Kameleon.userconf_path, 'w+') do |file|
49
- userconf_erb = File.join(Kameleon.erb_dirpath, "userconf.erb")
54
+ userconf_erb = File.join(Kameleon.erb_dirpath, "userconf.yaml.erb")
50
55
  erb = ERB.new(File.open(userconf_erb, 'rb') { |f| f.read })
51
56
  result = erb.result(binding)
52
57
  file.write(result)
@@ -73,7 +78,8 @@ module Kameleon
73
78
  :debug => userconf.fetch("debug", false),
74
79
  :script => userconf.fetch("script", false),
75
80
  :repositories_path => userconf.fetch("repositories_path",
76
- File.join(userdir.to_s, 'repos')),
81
+ File.join(userdir.to_s, 'repos')),
82
+ :extend_yaml_erb => userconf.fetch("extend_yaml_erb", ".extend.yaml.erb")
77
83
  }
78
84
  end
79
85
 
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.2
4
+ version: 2.10.6
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: 2020-04-09 00:00:00.000000000 Z
15
+ date: 2021-11-24 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: childprocess
@@ -96,11 +96,25 @@ dependencies:
96
96
  - - "~>"
97
97
  - !ruby/object:Gem::Version
98
98
  version: '1.2'
99
+ - !ruby/object:Gem::Dependency
100
+ name: progressbar
101
+ requirement: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - "~>"
104
+ - !ruby/object:Gem::Version
105
+ version: '1'
106
+ type: :runtime
107
+ prerelease: false
108
+ version_requirements: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - "~>"
111
+ - !ruby/object:Gem::Version
112
+ version: '1'
99
113
  description: The mindful appliance builder
100
114
  email:
101
- - salem.harrache@inria.fr
102
- - michael.mercier@inria.fr
103
- - cristian.ruiz@imag.fr
115
+ - salem@harrache.info
116
+ - michael.mercier@libr.fr
117
+ - camilo1729@gmail.com
104
118
  - pierre.neyron@imag.fr
105
119
  - bruno.bzeznik@imag.fr
106
120
  executables:
@@ -117,7 +131,7 @@ files:
117
131
  - COPYING
118
132
  - Gemfile
119
133
  - README.rst
120
- - RELEASING.rst
134
+ - RELEASING.md
121
135
  - Vagrantfile
122
136
  - bin/kameleon
123
137
  - completion/_kameleon
@@ -157,8 +171,8 @@ files:
157
171
  - contrib/steps/setup/root_ssh_config.yaml
158
172
  - contrib/steps/setup/set_user_password.yaml
159
173
  - contrib/steps/setup/system_optimization.yaml
160
- - erb/extend.erb
161
- - erb/userconf.erb
174
+ - erb/extend.yaml.erb
175
+ - erb/userconf.yaml.erb
162
176
  - kameleon-builder.gemspec
163
177
  - lib/kameleon.rb
164
178
  - lib/kameleon/cli.rb
@@ -200,7 +214,6 @@ files:
200
214
  - tests/test_context.rb
201
215
  - tests/test_recipe.rb
202
216
  - tests/test_version.rb
203
- - version.txt
204
217
  homepage: http://kameleon.imag.fr/
205
218
  licenses:
206
219
  - GPL-2.0
@@ -226,7 +239,7 @@ rubyforge_project:
226
239
  rubygems_version: 2.7.6.2
227
240
  signing_key:
228
241
  specification_version: 4
229
- summary: Kameleon is a tool to build virtual machines from scratch
242
+ summary: Kameleon is a tool to build system appliances from scratch
230
243
  test_files:
231
244
  - tests/helper.rb
232
245
  - tests/issue76/fail.stdout
data/RELEASING.rst DELETED
@@ -1,29 +0,0 @@
1
- You can use the script ``./scripts/bumpversion.py`` which will handle
2
- everything (incrementation, git tag creation, changelog update).
3
- First you need to install bumpversion using pip::
4
-
5
- sudo pip2 install bumpversion
6
-
7
- Then for the actual releasing:
8
-
9
- 1) After each release, a new version has to be created (in this example, the 2.7.0 dev)::
10
-
11
- python2 ./scripts/bumpversion.py newversion minor # 2.6.7 -> 2.7.0.dev
12
-
13
- 2) [work/commit]
14
- 3) **Warning:** Be sure that there is no dirty file (not committed) before
15
- doing this.
16
-
17
- Releasing a new version::
18
-
19
- python2 ./scripts/bumpversion.py release # 2.7.0.dev -> 2.7.0 + git tag + changelog
20
- gem build kameleon-builder.gemspec
21
- gem push kameleon-builder-2.7.0.gem
22
-
23
- You need a rubygem account and I have to give you permissions so that you can push.
24
- To do so, create an account on https://rubygems.org/ and ask an owner to do
25
- the following command::
26
-
27
- gem owner kameleon-builder -a your@email.com
28
-
29
- And that's all :)
data/erb/extend.erb DELETED
@@ -1,33 +0,0 @@
1
- #==============================================================================
2
- # vim: softtabstop=2 shiftwidth=2 expandtab fenc=utf-8 cc=81 tw=80
3
- #==============================================================================
4
- #
5
- # DESCRIPTION: <MY RECIPE DESCRIPTION>
6
- #
7
- #==============================================================================
8
- ---
9
- extend: <%= tpl.relative_path_from_recipe(recipe_path) %>
10
-
11
- global:
12
- # This is the backend you have imported to switch to an other backend BCKD do:
13
- #
14
- # kameleon template import <%= tpl.relative_path_from_recipe(recipe_path) %> --global backend:BCKB
15
- #
16
- # Then, uncomment and update the following variable.
17
- <% if Kameleon.env.global["backend"] %>
18
- backend: <%= Kameleon.env.global["backend"] %>
19
- <% else %>
20
- # backend: qemu
21
- <% end %>
22
- # To see the variables that you can override, use the following command:
23
- #
24
- # kameleon info <%= recipe_name %>
25
-
26
- bootstrap:
27
- - "@base"
28
-
29
- setup:
30
- - "@base"
31
-
32
- export:
33
- - "@base"
data/version.txt DELETED
@@ -1 +0,0 @@
1
- 2.10.2