kameleon-builder 2.6.7 → 2.7.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|