kameleon-builder 2.6.7 → 2.7.0
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.
- data/.bumpversion.cfg +1 -1
- data/CHANGES +18 -0
- data/RELEASING +16 -0
- data/completion/_kameleon +3 -0
- data/contrib/kameleon_exec_cmd.sh +1 -0
- data/lib/kameleon/cli.rb +5 -2
- data/lib/kameleon/engine.rb +8 -3
- data/lib/kameleon/persistent_cache.rb +26 -19
- data/lib/kameleon/recipe.rb +114 -8
- data/lib/kameleon/utils.rb +38 -5
- data/tests/recipes/test_recipe.yaml +3 -0
- data/tests/test2/test2.yaml +2 -1
- data/tests/test2/test3.yaml +2 -0
- data/version.txt +1 -1
- metadata +32 -21
- checksums.yaml +0 -7
data/.bumpversion.cfg
CHANGED
data/CHANGES
CHANGED
@@ -1,6 +1,24 @@
|
|
1
1
|
Kameleon CHANGELOG
|
2
2
|
==================
|
3
3
|
|
4
|
+
Version 2.7.0
|
5
|
+
-------------
|
6
|
+
|
7
|
+
Released on December 09th 2015
|
8
|
+
|
9
|
+
- Fixed variables overload when using inheritance
|
10
|
+
- Added support for including global options from a separate file (#57)
|
11
|
+
- Allowed kameleon to fail silently if some error occured during include
|
12
|
+
- Marked all bash variables for export
|
13
|
+
- Sorted variables in ``kameleon info`` dump
|
14
|
+
- Removed duplicate error messages
|
15
|
+
- Shutdown polipo cleanly (#54)
|
16
|
+
- Added offline mode to prevent Polipo from contacting remote servers
|
17
|
+
- Fixed polipo default options to avoid "206 partial responses" (#54)
|
18
|
+
- Made only one checkpoint per macrostep to improve performance
|
19
|
+
- Made polipo log file unique for each user to avoid "Permission denied" error
|
20
|
+
- Added new keyword in ZSH completion
|
21
|
+
|
4
22
|
Version 2.6.7
|
5
23
|
-------------
|
6
24
|
|
data/RELEASING
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
You can use the script ``./scripts/bumpversion.py`` which will handle
|
2
|
+
everything (incrementation, git tag creation, changelog update).
|
3
|
+
|
4
|
+
1) After each release, a new version has to be created (in this example, the 2.7.0 dev)
|
5
|
+
|
6
|
+
$ python2 ./scripts/bumpversion.py newversion minor # 2.6.7 -> 2.7.0.dev
|
7
|
+
|
8
|
+
[work/commit]
|
9
|
+
|
10
|
+
2) Releasing a new version
|
11
|
+
|
12
|
+
$ python2 ./scripts/bumpversion.py release # 2.7.0.dev -> 2.7.0 + git tag + changelog
|
13
|
+
$ gem build kameleon-builder.gemspec
|
14
|
+
$ gem push kameleon-builder-2.7.0.gem
|
15
|
+
|
16
|
+
You need a rubygem account and I have to give you permissions so that you can push
|
data/completion/_kameleon
CHANGED
@@ -147,6 +147,7 @@ _kameleon () {
|
|
147
147
|
_arguments -C \
|
148
148
|
'(--from-cache)1:Kameleon recipe path:_files' \
|
149
149
|
'(1)--from-cache=:Persistent cache tar file to build the image:_files' \
|
150
|
+
'--cache-archive-compression=:Select the persistent cache compression:(gzip xz bz2)' \
|
150
151
|
'(-b --build-path)'{-b,--build-path=}':Build directory path:_directories' \
|
151
152
|
'--clean[Runs the command `kameleon clean` first]' \
|
152
153
|
'--from-checkpoint=:Specify checkpoint to build the image' \
|
@@ -154,6 +155,8 @@ _kameleon () {
|
|
154
155
|
{--checkpoints,--list-checkpoints}'[Lists all availables checkpoints]' \
|
155
156
|
'--enable-cache[Generates a persistent cache for the appliance]' \
|
156
157
|
'--cache-path=:Cache directory path:_directories' \
|
158
|
+
'--proxy=:Specifies the hostname and port number of the parent HTTP proxy define as host\:port' \
|
159
|
+
'--proxy-credentials=:Specifies the username and password if the parent proxy requires authorisation define as username\:password' \
|
157
160
|
'*'{-g,--global}':Custom global variable define as key\:value' && ret=0
|
158
161
|
;;
|
159
162
|
(help)
|
data/lib/kameleon/cli.rb
CHANGED
@@ -60,7 +60,7 @@ module Kameleon
|
|
60
60
|
rescue
|
61
61
|
raise TemplateNotFound, "Template '#{template_name}' not found. " \
|
62
62
|
"To see all templates, run the command "\
|
63
|
-
"`kameleon template
|
63
|
+
"`kameleon template list`"
|
64
64
|
else
|
65
65
|
tpl.all_files.each do |path|
|
66
66
|
relative_path = path.relative_path_from(Kameleon.env.repositories_path)
|
@@ -149,7 +149,7 @@ module Kameleon
|
|
149
149
|
rescue
|
150
150
|
raise TemplateNotFound, "Template '#{template_name}' not found. " \
|
151
151
|
"To see all templates, run the command "\
|
152
|
-
"`kameleon
|
152
|
+
"`kameleon template list`"
|
153
153
|
else
|
154
154
|
tpl.all_files.each do |path|
|
155
155
|
relative_path = path.relative_path_from(Kameleon.env.repositories_path)
|
@@ -234,6 +234,9 @@ module Kameleon
|
|
234
234
|
:desc => "Specifies the username and password if the parent "\
|
235
235
|
"proxy requires authorisation it should have the "\
|
236
236
|
"form 'username:password'"
|
237
|
+
method_option :proxy_offline, :type => :boolean ,
|
238
|
+
:default => false, :aliases => "--offline",
|
239
|
+
:desc => "Prevents Polipo from contacting remote servers"
|
237
240
|
method_option :global, :type => :hash,
|
238
241
|
:default => {}, :aliases => "-g",
|
239
242
|
:desc => "Set custom global variables."
|
data/lib/kameleon/engine.rb
CHANGED
@@ -46,6 +46,7 @@ module Kameleon
|
|
46
46
|
@cache.polipo_path = @options[:polipo_path]
|
47
47
|
@cache.name = @recipe.name
|
48
48
|
@cache.mode = @options[:enable_cache] ? :build : :from
|
49
|
+
@cache.offline = @options[:proxy_offline]
|
49
50
|
@cache.cache_path = @options[:from_cache]
|
50
51
|
@cache.recipe_path = @recipe.path
|
51
52
|
@cache.archive_format = @options[:cache_archive_compression]
|
@@ -184,6 +185,7 @@ module Kameleon
|
|
184
185
|
def do_steps(section_name)
|
185
186
|
section = @recipe.sections.fetch(section_name)
|
186
187
|
section.sequence do |macrostep|
|
188
|
+
checkpointed = false
|
187
189
|
macrostep_time = Time.now.to_i
|
188
190
|
if @cache then
|
189
191
|
Kameleon.ui.debug("Starting proxy cache server for macrostep '#{macrostep.name}'...")
|
@@ -209,9 +211,12 @@ module Kameleon
|
|
209
211
|
safe_exec_cmd(cmd)
|
210
212
|
end
|
211
213
|
unless microstep.on_checkpoint == "redo"
|
212
|
-
|
213
|
-
|
214
|
-
|
214
|
+
unless checkpointed
|
215
|
+
if checkpoint_enabled?
|
216
|
+
Kameleon.ui.msg("--> Creating checkpoint : #{ microstep.identifier }")
|
217
|
+
create_checkpoint(microstep.identifier)
|
218
|
+
checkpointed = true
|
219
|
+
end
|
215
220
|
end
|
216
221
|
end
|
217
222
|
end
|
@@ -21,6 +21,7 @@ module Kameleon
|
|
21
21
|
attr_accessor :recipe_path
|
22
22
|
attr_accessor :archive_format
|
23
23
|
attr_accessor :polipo_cmd_options
|
24
|
+
attr_accessor :offline
|
24
25
|
|
25
26
|
def initialize()
|
26
27
|
## we must configure Polipo to be execute for the in and out context
|
@@ -29,18 +30,15 @@ module Kameleon
|
|
29
30
|
@polipo_process = nil
|
30
31
|
@polipo_port = find_unused_port
|
31
32
|
|
32
|
-
# :idleTime => "1",
|
33
33
|
@polipo_cmd_options = {:diskCacheRoot => "",
|
34
34
|
:maxDiskCacheEntrySize => "-1",
|
35
|
-
:
|
36
|
-
:disableServersList => "false",
|
35
|
+
:idleTime => "1",
|
37
36
|
:allowedClients => "0.0.0.0/0",
|
38
37
|
:proxyPort => @polipo_port,
|
39
|
-
:relaxTransparency =>"true",
|
40
38
|
:daemonise => false,
|
41
39
|
:proxyAddress => "0.0.0.0",
|
42
|
-
:logFile => File.join(Kameleon.env.build_path, '
|
43
|
-
:logLevel => "
|
40
|
+
:logFile => File.join(Kameleon.env.build_path, "polipo-#{ENV['USER']}.log"),
|
41
|
+
:logLevel => "0xFF",
|
44
42
|
}
|
45
43
|
|
46
44
|
@activated = false
|
@@ -56,6 +54,7 @@ module Kameleon
|
|
56
54
|
@recipe_file = nil
|
57
55
|
@steps_files = []
|
58
56
|
@cached_recipe_dir = nil
|
57
|
+
@offline = false
|
59
58
|
end
|
60
59
|
|
61
60
|
def find_unused_port
|
@@ -104,13 +103,16 @@ module Kameleon
|
|
104
103
|
def proxy_is_running?()
|
105
104
|
begin
|
106
105
|
res = Net::HTTP.get_response(URI("http://127.0.0.1:#{@polipo_port}/polipo/status"))
|
107
|
-
if not
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
106
|
+
if not @offline
|
107
|
+
if not res.body.include? "is on line"
|
108
|
+
Kameleon.ui.debug("The proxy is running but not responding. Server response: #{res.inspect}")
|
109
|
+
return false
|
110
|
+
else
|
111
|
+
Kameleon.ui.debug("The proxy is responding")
|
112
|
+
return true
|
113
|
+
end
|
112
114
|
end
|
113
|
-
return
|
115
|
+
return true
|
114
116
|
rescue Exception => e
|
115
117
|
Kameleon.ui.debug("The proxy is not responding. Server response: #{e.message}")
|
116
118
|
return false
|
@@ -141,8 +143,17 @@ module Kameleon
|
|
141
143
|
|
142
144
|
|
143
145
|
def stop_web_proxy
|
144
|
-
|
146
|
+
# http://www.pps.univ-paris-diderot.fr/~jch/software/polipo/manual/Stopping.html
|
145
147
|
Kameleon.ui.info("Stopping web proxy polipo")
|
148
|
+
unless (@polipo_process.nil? || @polipo_process.exited?)
|
149
|
+
Process.kill("USR1", @polipo_process.pid) # will write out all the in-memory data to disk
|
150
|
+
Process.kill("SIGINT", @polipo_process.pid) # will shut down cleanly
|
151
|
+
begin
|
152
|
+
@polipo_process.poll_for_exit(10)
|
153
|
+
rescue ChildProcess::TimeoutError
|
154
|
+
@polipo_process.stop # tries increasingly harsher methods to kill the process.
|
155
|
+
end
|
156
|
+
end
|
146
157
|
end
|
147
158
|
|
148
159
|
def pack()
|
@@ -198,12 +209,7 @@ module Kameleon
|
|
198
209
|
end
|
199
210
|
|
200
211
|
def stop()
|
201
|
-
|
202
|
-
@polipo_process.poll_for_exit(5)
|
203
|
-
rescue ChildProcess::TimeoutError
|
204
|
-
@polipo_process.stop # tries increasingly harsher methods to kill the process.
|
205
|
-
end
|
206
|
-
Kameleon.ui.info("Stopping web proxy polipo")
|
212
|
+
stop_web_proxy
|
207
213
|
Kameleon.ui.info("Finishing persistent cache with last files")
|
208
214
|
cache_metadata_dir = File.join(@cache_dir,"metadata")
|
209
215
|
if @mode == :build then
|
@@ -260,6 +266,7 @@ module Kameleon
|
|
260
266
|
FileUtils.mkdir_p File.join(@cache_dir,"recipe")
|
261
267
|
FileUtils.mkdir_p File.join(@cache_dir,"DATA")
|
262
268
|
FileUtils.mkdir_p File.join(@cache_dir,"metadata")
|
269
|
+
@polipo_cmd_options[:proxyOffline] = @offline
|
263
270
|
end
|
264
271
|
|
265
272
|
def get_recipe()
|
data/lib/kameleon/recipe.rb
CHANGED
@@ -50,6 +50,13 @@ module Kameleon
|
|
50
50
|
load! :strict => false
|
51
51
|
end
|
52
52
|
|
53
|
+
def update_steps_dirs()
|
54
|
+
# Where we can find steps
|
55
|
+
@steps_dirs = @base_recipes_files.map do |recipe_path|
|
56
|
+
get_steps_dirs(recipe_path)
|
57
|
+
end.flatten!
|
58
|
+
end
|
59
|
+
|
53
60
|
def get_steps_dirs(recipe_path)
|
54
61
|
relative_path = recipe_path.to_s.gsub(Kameleon.env.root_dir.to_s + '/', '')
|
55
62
|
if relative_path.eql? recipe_path.to_s
|
@@ -80,6 +87,9 @@ module Kameleon
|
|
80
87
|
unless yaml_recipe.kind_of? Hash
|
81
88
|
fail RecipeError, "Invalid yaml error : #{@path}"
|
82
89
|
end
|
90
|
+
|
91
|
+
update_steps_dirs()
|
92
|
+
|
83
93
|
# Load entended recipe variables
|
84
94
|
yaml_recipe = load_base_recipe(yaml_recipe, @path)
|
85
95
|
yaml_recipe.delete("extend")
|
@@ -92,7 +102,8 @@ module Kameleon
|
|
92
102
|
|
93
103
|
# Load Global variables
|
94
104
|
@global.merge!(yaml_recipe.fetch("global", {}))
|
95
|
-
|
105
|
+
# merge cli variable with recursive variable overload
|
106
|
+
@global = Utils.overload_merge(@global, @cli_global)
|
96
107
|
# Resolve dynamically-defined variables !!
|
97
108
|
resolved_global = Utils.resolve_vars(@global.to_yaml, @path, @global, self, kwargs)
|
98
109
|
resolved_global = @global.merge YAML.load(resolved_global)
|
@@ -176,6 +187,7 @@ module Kameleon
|
|
176
187
|
end
|
177
188
|
|
178
189
|
def load_base_recipe(yaml_recipe, path)
|
190
|
+
|
179
191
|
base_recipe_name = yaml_recipe.fetch("extend", "")
|
180
192
|
return yaml_recipe if base_recipe_name.empty?
|
181
193
|
|
@@ -186,6 +198,9 @@ module Kameleon
|
|
186
198
|
## check that the recipe has not already been loaded
|
187
199
|
return yaml_recipe if @base_recipes_files.include? base_recipe_path
|
188
200
|
|
201
|
+
@base_recipes_files.push(Pathname.new(File.expand_path(base_recipe_path)))
|
202
|
+
update_steps_dirs()
|
203
|
+
|
189
204
|
base_recipe_path << ".yaml" unless base_recipe_path.end_with? ".yaml"
|
190
205
|
fail RecipeError, "Could not find this following recipe : #{@recipe_path}" \
|
191
206
|
unless File.file? path
|
@@ -213,17 +228,107 @@ module Kameleon
|
|
213
228
|
end
|
214
229
|
base_yaml_recipe[key] = recipe_section
|
215
230
|
elsif ["global"].include? key
|
216
|
-
base_section = base_yaml_recipe
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
base_yaml_recipe[key] = base_section.merge(recipe_section)
|
231
|
+
base_section = load_global(base_yaml_recipe, base_recipe_path)
|
232
|
+
recipe_section = load_global(yaml_recipe, path)
|
233
|
+
# manage recursive variable overload
|
234
|
+
base_yaml_recipe[key] = Utils.overload_merge(base_section, recipe_section)
|
221
235
|
end
|
222
236
|
end
|
223
|
-
@base_recipes_files.push(Pathname.new(File.expand_path(base_recipe_path)))
|
224
237
|
return load_base_recipe(base_yaml_recipe, base_recipe_path)
|
225
238
|
end
|
226
239
|
|
240
|
+
def load_global(yaml_recipe, recipe_path)
|
241
|
+
global = {}
|
242
|
+
if yaml_recipe.keys.include? "global"
|
243
|
+
global_loaded = yaml_recipe.fetch("global", {})
|
244
|
+
global_loaded = {} if global_loaded.nil?
|
245
|
+
if global_loaded.kind_of? Hash
|
246
|
+
global_loaded.each do |key, value|
|
247
|
+
if key.eql? "include"
|
248
|
+
global_to_include = load_include_global(value, recipe_path)
|
249
|
+
global.merge!(global_to_include)
|
250
|
+
else
|
251
|
+
global[key] = value
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
256
|
+
return global
|
257
|
+
end
|
258
|
+
|
259
|
+
def load_include_global(yaml_include, recipe_path)
|
260
|
+
def load_global_file(global_file, recipe_path)
|
261
|
+
def try_to_load(absolute_path)
|
262
|
+
if File.file?(absolute_path)
|
263
|
+
global_to_include = YAML.load_file(absolute_path)
|
264
|
+
if global_to_include.kind_of? Hash
|
265
|
+
@step_files.push(absolute_path)
|
266
|
+
return global_to_include
|
267
|
+
else
|
268
|
+
fail RecipeError, "Global should be a Hash. (check #{absolute_path})"
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
## check that the recipe has not already been loaded
|
273
|
+
global_file << ".yaml" unless global_file.end_with? ".yaml"
|
274
|
+
|
275
|
+
dir_search = @steps_dirs.map do |steps_dir|
|
276
|
+
File.join(steps_dir, "global")
|
277
|
+
end.flatten
|
278
|
+
dir_search.unshift(File.join(File.dirname(recipe_path)))
|
279
|
+
# try relative/absolute path
|
280
|
+
if Pathname.new(global_file).absolute?
|
281
|
+
global_to_include = try_to_load(global_file)
|
282
|
+
unless global_to_include.nil?
|
283
|
+
return global_to_include
|
284
|
+
else
|
285
|
+
fail RecipeError, "File '#{global_file}' not found"
|
286
|
+
end
|
287
|
+
else
|
288
|
+
dir_search.each do |dir_path|
|
289
|
+
absolute_path = Pathname.new(File.join(dir_path, global_file))
|
290
|
+
global_to_include = try_to_load(absolute_path)
|
291
|
+
unless global_to_include.nil?
|
292
|
+
return global_to_include
|
293
|
+
end
|
294
|
+
end
|
295
|
+
end
|
296
|
+
rel_dir_search = dir_search.map do |steps_dir|
|
297
|
+
relative_path = Pathname.new(steps_dir).relative_path_from(Pathname(Dir.pwd)).to_s
|
298
|
+
end.flatten
|
299
|
+
fail RecipeError, "File '#{global_file}' not found here #{rel_dir_search}"
|
300
|
+
end
|
301
|
+
|
302
|
+
global_hash = {}
|
303
|
+
if yaml_include.kind_of? String
|
304
|
+
list_files = [yaml_include]
|
305
|
+
elsif yaml_include.kind_of? Array
|
306
|
+
list_files = []
|
307
|
+
yaml_include.each do |value|
|
308
|
+
if value.kind_of? String
|
309
|
+
list_files.push(value)
|
310
|
+
end
|
311
|
+
end
|
312
|
+
else
|
313
|
+
return global_hash
|
314
|
+
end
|
315
|
+
list_files.each do |includes_file|
|
316
|
+
filename = includes_file
|
317
|
+
if includes_file.start_with?("-")
|
318
|
+
filename = includes_file[1..-1]
|
319
|
+
end
|
320
|
+
begin
|
321
|
+
new_global = load_global_file(filename, recipe_path)
|
322
|
+
global_hash.merge!(new_global)
|
323
|
+
rescue
|
324
|
+
unless includes_file.start_with?("-")
|
325
|
+
raise
|
326
|
+
end
|
327
|
+
end
|
328
|
+
end
|
329
|
+
return global_hash
|
330
|
+
end
|
331
|
+
|
227
332
|
def load_aliases(yaml_recipe)
|
228
333
|
def load_aliases_file(aliases_file)
|
229
334
|
dir_search = @steps_dirs.map do |steps_dir|
|
@@ -681,7 +786,8 @@ module Kameleon
|
|
681
786
|
prefix ; Kameleon.ui.info("#{d}")
|
682
787
|
end
|
683
788
|
Kameleon.ui.info("Variables:")
|
684
|
-
@global.
|
789
|
+
@global.sort.map do |key, value|
|
790
|
+
value = "\n" if value.to_s.empty?
|
685
791
|
prefix ; Kameleon.ui.info("#{key}: #{value}")
|
686
792
|
end
|
687
793
|
end
|
data/lib/kameleon/utils.rb
CHANGED
@@ -4,7 +4,7 @@ module Kameleon
|
|
4
4
|
|
5
5
|
def self.resolve_vars(raw, yaml_path, initial_variables, recipe, kwargs = {})
|
6
6
|
raw = resolve_data_dir_vars(raw, yaml_path, initial_variables, recipe, kwargs)
|
7
|
-
return resolve_simple_vars(raw, yaml_path, initial_variables,
|
7
|
+
return resolve_simple_vars(raw, yaml_path, initial_variables, kwargs)
|
8
8
|
end
|
9
9
|
|
10
10
|
def self.resolve_data_dir_vars(raw, yaml_path, initial_variables, recipe, kwargs)
|
@@ -12,7 +12,7 @@ module Kameleon
|
|
12
12
|
matches = raw.to_enum(:scan, reg).map { Regexp.last_match }
|
13
13
|
matches.each do |m|
|
14
14
|
unless m.nil?
|
15
|
-
path = resolve_simple_vars(m[1], yaml_path, initial_variables,
|
15
|
+
path = resolve_simple_vars(m[1], yaml_path, initial_variables, kwargs)
|
16
16
|
resolved_path = recipe.resolve_data_path(path.chomp('"'), yaml_path)
|
17
17
|
raw.gsub!(m[0].chomp('"'), "#{resolved_path}")
|
18
18
|
end
|
@@ -20,8 +20,41 @@ module Kameleon
|
|
20
20
|
return raw
|
21
21
|
end
|
22
22
|
|
23
|
-
def self.
|
24
|
-
|
23
|
+
def self.resolve_simple_vars_once(raw, initial_variables)
|
24
|
+
raw.to_s.gsub(/\$\$\{[a-zA-Z0-9\-_]+\}|\$\$[a-zA-Z0-9\-_]+/) do |var|
|
25
|
+
# remove the dollars
|
26
|
+
if var.include? "{"
|
27
|
+
strip_var = var[3,(var.length - 4)]
|
28
|
+
else
|
29
|
+
strip_var = var[2,(var.length - 2)]
|
30
|
+
end
|
31
|
+
# check in local vars
|
32
|
+
if initial_variables.has_key? strip_var
|
33
|
+
value = initial_variables[strip_var]
|
34
|
+
end
|
35
|
+
return $` + value.to_s + $'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
# Variables are replaced correctly for recursive variable overload of
|
41
|
+
# the parent by the child:
|
42
|
+
# For example:
|
43
|
+
# Parent={var: 10}
|
44
|
+
# Child={var: $$var 11}
|
45
|
+
# => {var: 10 11}
|
46
|
+
def self.overload_merge(parent_dict, child_dict)
|
47
|
+
parent_dict.merge(child_dict){ |key, old_value, new_value|
|
48
|
+
if new_value.to_s.include?("$$" + key.to_s) or new_value.to_s.include?("$${" + key.to_s + "}")
|
49
|
+
Utils.resolve_simple_vars_once(new_value, {key => old_value})
|
50
|
+
else
|
51
|
+
new_value
|
52
|
+
end
|
53
|
+
}
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
def self.resolve_simple_vars(raw, yaml_path, initial_variables, kwargs)
|
25
58
|
raw.to_s.gsub(/\$\$\{[a-zA-Z0-9\-_]+\}|\$\$[a-zA-Z0-9\-_]+/) do |var|
|
26
59
|
# remove the dollars
|
27
60
|
if var.include? "{"
|
@@ -37,7 +70,7 @@ module Kameleon
|
|
37
70
|
fail RecipeError, "#{yaml_path}: variable #{var} not found in local or global"
|
38
71
|
end
|
39
72
|
end
|
40
|
-
return $` + resolve_simple_vars(value.to_s + $', yaml_path, initial_variables,
|
73
|
+
return $` + resolve_simple_vars(value.to_s + $', yaml_path, initial_variables, kwargs)
|
41
74
|
end
|
42
75
|
end
|
43
76
|
|
data/tests/test2/test2.yaml
CHANGED
data/version.txt
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.7.0
|
metadata
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kameleon-builder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.7.0
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
7
|
authors:
|
7
8
|
- Salem Harrache
|
@@ -12,60 +13,66 @@ authors:
|
|
12
13
|
autorequire:
|
13
14
|
bindir: bin
|
14
15
|
cert_chain: []
|
15
|
-
date: 2015-
|
16
|
+
date: 2015-12-09 00:00:00.000000000 Z
|
16
17
|
dependencies:
|
17
18
|
- !ruby/object:Gem::Dependency
|
18
19
|
name: childprocess
|
19
20
|
requirement: !ruby/object:Gem::Requirement
|
21
|
+
none: false
|
20
22
|
requirements:
|
21
|
-
- -
|
23
|
+
- - ~>
|
22
24
|
- !ruby/object:Gem::Version
|
23
25
|
version: 0.5.3
|
24
|
-
- -
|
26
|
+
- - ! '>='
|
25
27
|
- !ruby/object:Gem::Version
|
26
28
|
version: 0.3.0
|
27
29
|
type: :runtime
|
28
30
|
prerelease: false
|
29
31
|
version_requirements: !ruby/object:Gem::Requirement
|
32
|
+
none: false
|
30
33
|
requirements:
|
31
|
-
- -
|
34
|
+
- - ~>
|
32
35
|
- !ruby/object:Gem::Version
|
33
36
|
version: 0.5.3
|
34
|
-
- -
|
37
|
+
- - ! '>='
|
35
38
|
- !ruby/object:Gem::Version
|
36
39
|
version: 0.3.0
|
37
40
|
- !ruby/object:Gem::Dependency
|
38
41
|
name: thor
|
39
42
|
requirement: !ruby/object:Gem::Requirement
|
43
|
+
none: false
|
40
44
|
requirements:
|
41
|
-
- -
|
45
|
+
- - ~>
|
42
46
|
- !ruby/object:Gem::Version
|
43
47
|
version: '0.19'
|
44
|
-
- -
|
48
|
+
- - ! '>='
|
45
49
|
- !ruby/object:Gem::Version
|
46
50
|
version: 0.15.0
|
47
51
|
type: :runtime
|
48
52
|
prerelease: false
|
49
53
|
version_requirements: !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
50
55
|
requirements:
|
51
|
-
- -
|
56
|
+
- - ~>
|
52
57
|
- !ruby/object:Gem::Version
|
53
58
|
version: '0.19'
|
54
|
-
- -
|
59
|
+
- - ! '>='
|
55
60
|
- !ruby/object:Gem::Version
|
56
61
|
version: 0.15.0
|
57
62
|
- !ruby/object:Gem::Dependency
|
58
63
|
name: table_print
|
59
64
|
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
60
66
|
requirements:
|
61
|
-
- -
|
67
|
+
- - ~>
|
62
68
|
- !ruby/object:Gem::Version
|
63
69
|
version: 1.5.2
|
64
70
|
type: :runtime
|
65
71
|
prerelease: false
|
66
72
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
67
74
|
requirements:
|
68
|
-
- -
|
75
|
+
- - ~>
|
69
76
|
- !ruby/object:Gem::Version
|
70
77
|
version: 1.5.2
|
71
78
|
description: The mindful appliance builder
|
@@ -80,15 +87,16 @@ executables:
|
|
80
87
|
extensions: []
|
81
88
|
extra_rdoc_files: []
|
82
89
|
files:
|
83
|
-
-
|
84
|
-
-
|
85
|
-
-
|
86
|
-
-
|
90
|
+
- .bumpversion.cfg
|
91
|
+
- .editorconfig
|
92
|
+
- .env
|
93
|
+
- .gitignore
|
87
94
|
- AUTHORS
|
88
95
|
- CHANGES
|
89
96
|
- COPYING
|
90
97
|
- Gemfile
|
91
98
|
- README.rst
|
99
|
+
- RELEASING
|
92
100
|
- Vagrantfile
|
93
101
|
- bin/kameleon
|
94
102
|
- completion/_kameleon
|
@@ -156,6 +164,7 @@ files:
|
|
156
164
|
- tests/recipes/steps/setup/linux/software_install.yaml
|
157
165
|
- tests/recipes/test_recipe.yaml
|
158
166
|
- tests/test2/test2.yaml
|
167
|
+
- tests/test2/test3.yaml
|
159
168
|
- tests/test_context.rb
|
160
169
|
- tests/test_recipe.rb
|
161
170
|
- tests/test_version.rb
|
@@ -163,27 +172,28 @@ files:
|
|
163
172
|
homepage: http://kameleon.imag.fr/
|
164
173
|
licenses:
|
165
174
|
- GPL-2
|
166
|
-
metadata: {}
|
167
175
|
post_install_message:
|
168
176
|
rdoc_options: []
|
169
177
|
require_paths:
|
170
178
|
- lib
|
171
179
|
required_ruby_version: !ruby/object:Gem::Requirement
|
180
|
+
none: false
|
172
181
|
requirements:
|
173
|
-
- -
|
182
|
+
- - ! '>='
|
174
183
|
- !ruby/object:Gem::Version
|
175
184
|
version: '0'
|
176
185
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
186
|
+
none: false
|
177
187
|
requirements:
|
178
|
-
- -
|
188
|
+
- - ! '>='
|
179
189
|
- !ruby/object:Gem::Version
|
180
190
|
version: '0'
|
181
191
|
requirements:
|
182
192
|
- polipo 1.0.3, or greater
|
183
193
|
rubyforge_project:
|
184
|
-
rubygems_version:
|
194
|
+
rubygems_version: 1.8.23.2
|
185
195
|
signing_key:
|
186
|
-
specification_version:
|
196
|
+
specification_version: 3
|
187
197
|
summary: Kameleon is a tool to build virtual machines from scratch
|
188
198
|
test_files:
|
189
199
|
- tests/helper.rb
|
@@ -195,6 +205,7 @@ test_files:
|
|
195
205
|
- tests/recipes/steps/setup/linux/software_install.yaml
|
196
206
|
- tests/recipes/test_recipe.yaml
|
197
207
|
- tests/test2/test2.yaml
|
208
|
+
- tests/test2/test3.yaml
|
198
209
|
- tests/test_context.rb
|
199
210
|
- tests/test_recipe.rb
|
200
211
|
- tests/test_version.rb
|
checksums.yaml
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
---
|
2
|
-
SHA1:
|
3
|
-
metadata.gz: 41ec4253d5c8e1212274257dd0ef731fd911680c
|
4
|
-
data.tar.gz: 9f6a9adf0e0764e352d2968ade87478d8c9c82a5
|
5
|
-
SHA512:
|
6
|
-
metadata.gz: ecd9d831258ff4d46e034e740221c4dc3cf5a10b8e66e711bec447b9fbc417f3519b019e930d503ee2d9791ec5b2d14c412b357bf41cee617e3a7f52009c733b
|
7
|
-
data.tar.gz: 31575ddef96d63072c0d2d4a8ab391a989eaf871a2fce7e7d5bc89babe03febfb1059330fe5b6221bd94fd71c3952ff15ccec5a5e05bfa122d24edff3a2bce4c
|