kameleon-builder 2.3.5 → 2.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.env +1 -1
- data/CHANGELOG.rst +12 -0
- data/contrib/kameleon_bashrc.sh +7 -0
- data/contrib/kameleon_exec_cmd.sh +18 -0
- data/contrib/kameleon_exec_cmd_wrapper.sh +22 -0
- data/lib/kameleon.rb +1 -0
- data/lib/kameleon/cli.rb +16 -3
- data/lib/kameleon/engine.rb +2 -1
- data/lib/kameleon/environment.rb +1 -0
- data/lib/kameleon/persistent_cache.rb +0 -1
- data/lib/kameleon/recipe.rb +78 -23
- data/lib/kameleon/shell.rb +29 -17
- data/lib/kameleon/step.rb +5 -3
- data/lib/kameleon/utils.rb +22 -3
- data/version.txt +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 65da9e8e38e49cbcc45af782e207462e37e18ec1
|
4
|
+
data.tar.gz: 1ad935fc3207a7a26940bf46b5f43956389829ab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 238d2ddf1bc6b0c901837163cecdebb475a9e1ee680ce22197a43038bf49f6c27d9dcf518a0be2ac976331bf8449934bff637af82b71fae5b864cfafb504bfc4
|
7
|
+
data.tar.gz: ed9e26c4420b36ae280249a067157546ae1ee9695b1691da99c041acd3728d860a73c5d7bddf226d074680b5230b489ddc4d7ac20bb0da2bfd18cbf81e3fbaeb
|
data/.env
CHANGED
data/CHANGELOG.rst
CHANGED
@@ -1,6 +1,18 @@
|
|
1
1
|
Kameleon CHANGELOG
|
2
2
|
==================
|
3
3
|
|
4
|
+
version 2.4.0
|
5
|
+
-------------
|
6
|
+
|
7
|
+
Released on Dec 23rd 2014
|
8
|
+
|
9
|
+
- Supported recipe attached data
|
10
|
+
- Introduced a new shell command execution mechanism, to prevent kameleon from waiting forever if the command act weird (Fixed #39)
|
11
|
+
- Improved the customization of steps with inheritance
|
12
|
+
- Allowed to set global variables from cli during build using ``--global key:value ..``
|
13
|
+
- Moved repository command to the upper level (``kameleon repository``)
|
14
|
+
|
15
|
+
|
4
16
|
version 2.3.5
|
5
17
|
-------------
|
6
18
|
|
data/contrib/kameleon_bashrc.sh
CHANGED
@@ -8,6 +8,7 @@ export DEBIAN_FRONTEND=noninteractive
|
|
8
8
|
|
9
9
|
mkdir -p $(dirname <%= @bash_history_file %>) ; touch "<%= @bash_history_file %>"
|
10
10
|
mkdir -p $(dirname <%= @bash_env_file %>) ; touch "<%= @bash_env_file %>"
|
11
|
+
mkdir -p $(dirname <%= @bash_status_file %>) ; touch "<%= @bash_status_file %>"
|
11
12
|
|
12
13
|
source /etc/bash.bashrc 2> /dev/null
|
13
14
|
|
@@ -21,6 +22,8 @@ function fail {
|
|
21
22
|
false
|
22
23
|
}
|
23
24
|
|
25
|
+
export -f fail
|
26
|
+
|
24
27
|
## aliases
|
25
28
|
if [ -t 1 ] ; then
|
26
29
|
# restore previous env
|
@@ -186,6 +189,8 @@ print('\n')
|
|
186
189
|
fi
|
187
190
|
}
|
188
191
|
|
192
|
+
export -f __download
|
193
|
+
|
189
194
|
function __find_linux_boot_device() {
|
190
195
|
local PDEVICE=`stat -c %04D /boot`
|
191
196
|
for file in $(find /dev -type b 2>/dev/null) ; do
|
@@ -197,3 +202,5 @@ function __find_linux_boot_device() {
|
|
197
202
|
done
|
198
203
|
echo "$ROOTDEVICE"
|
199
204
|
}
|
205
|
+
|
206
|
+
export -f __find_linux_boot_device
|
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
ROOT_DIRECTORY=$(dirname $(readlink -f ${BASH_SOURCE[0]}))
|
4
|
+
|
5
|
+
function save_env {
|
6
|
+
# Save environment
|
7
|
+
(comm -3 <(declare | sort) <(declare -f | sort)) > "$ROOT_DIRECTORY/<%= File.basename(@bash_env_file) %>"
|
8
|
+
}
|
9
|
+
|
10
|
+
trap 'save_env' INT TERM EXIT
|
11
|
+
|
12
|
+
# Load environment
|
13
|
+
source "$ROOT_DIRECTORY/<%= File.basename(@bash_env_file) %>" 2> /dev/null || true
|
14
|
+
|
15
|
+
# Log cmd
|
16
|
+
echo <%= Shellwords.escape(cmd.value) %> >> "$ROOT_DIRECTORY/<%= File.basename(@bash_history_file) %>"
|
17
|
+
|
18
|
+
<%= cmd.value %>
|
@@ -0,0 +1,22 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
ROOT_DIRECTORY=$(dirname $(readlink -f ${BASH_SOURCE[0]}))
|
4
|
+
|
5
|
+
function post_exec_wrapper {
|
6
|
+
echo $? > "$ROOT_DIRECTORY/<%= File.basename(@bash_status_file) %>"
|
7
|
+
# Print end flags
|
8
|
+
echo -n <%= cmd.end_err %> 1>&2
|
9
|
+
echo -n <%= cmd.end_out %>
|
10
|
+
}
|
11
|
+
|
12
|
+
function pre_exec_wrapper {
|
13
|
+
# Print begin flags
|
14
|
+
echo -n <%= cmd.begin_err %> 1>&2
|
15
|
+
echo -n <%= cmd.begin_out %>
|
16
|
+
}
|
17
|
+
|
18
|
+
trap 'post_exec_wrapper' INT TERM EXIT
|
19
|
+
|
20
|
+
## Started
|
21
|
+
pre_exec_wrapper
|
22
|
+
bash --rcfile "<%= @bashrc_file %>" <%= File.join(@bash_scripts_dir, "#{cmd}.sh" ) %>
|
data/lib/kameleon.rb
CHANGED
data/lib/kameleon/cli.rb
CHANGED
@@ -56,12 +56,13 @@ module Kameleon
|
|
56
56
|
end
|
57
57
|
begin
|
58
58
|
tpl = RecipeTemplate.new(template_path)
|
59
|
+
tpl.resolve!
|
59
60
|
rescue
|
60
61
|
raise TemplateNotFound, "Template '#{template_name}' not found. " \
|
61
62
|
"To see all templates, run the command "\
|
62
63
|
"`kameleon template ls`"
|
63
64
|
else
|
64
|
-
files2copy = tpl.base_recipes_files + tpl.files
|
65
|
+
files2copy = tpl.base_recipes_files + tpl.files + tpl.data
|
65
66
|
files2copy.each do |path|
|
66
67
|
relative_path = path.relative_path_from(Kameleon.env.repositories_path)
|
67
68
|
dst = File.join(Kameleon.env.workspace, relative_path)
|
@@ -71,6 +72,9 @@ module Kameleon
|
|
71
72
|
end
|
72
73
|
|
73
74
|
desc "info [TEMPLATE_NAME]", "Display detailed information about a template"
|
75
|
+
method_option :global, :type => :hash ,
|
76
|
+
:default => {}, :aliases => "-g",
|
77
|
+
:desc => "Set custom global variables."
|
74
78
|
def info(template_name)
|
75
79
|
Kameleon.env.root_dir = Kameleon.env.repositories_path
|
76
80
|
template_path = File.join(Kameleon.env.repositories_path, template_name)
|
@@ -78,6 +82,7 @@ module Kameleon
|
|
78
82
|
template_path = template_path + '.yaml'
|
79
83
|
end
|
80
84
|
tpl = RecipeTemplate.new(template_path)
|
85
|
+
tpl.resolve!
|
81
86
|
tpl.display_info
|
82
87
|
end
|
83
88
|
map %w(-h --help) => :help
|
@@ -89,6 +94,7 @@ module Kameleon
|
|
89
94
|
class Main < Thor
|
90
95
|
include Thor::Actions
|
91
96
|
|
97
|
+
register CLI::Repository, 'repository', 'repository', 'Manages set of remote git repositories'
|
92
98
|
# register CLI::Recipe, 'recipe', 'recipe', 'Manages the local recipes'
|
93
99
|
register CLI::Template, 'template', 'template', 'Lists and imports templates'
|
94
100
|
|
@@ -138,12 +144,13 @@ module Kameleon
|
|
138
144
|
|
139
145
|
begin
|
140
146
|
tpl = Kameleon::RecipeTemplate.new(template_path)
|
147
|
+
tpl.resolve!
|
141
148
|
rescue
|
142
149
|
raise TemplateNotFound, "Template '#{template_name}' not found. " \
|
143
150
|
"To see all templates, run the command "\
|
144
151
|
"`kameleon templates`"
|
145
152
|
else
|
146
|
-
files2copy = tpl.base_recipes_files + tpl.files
|
153
|
+
files2copy = tpl.base_recipes_files + tpl.files + tpl.data
|
147
154
|
files2copy.each do |path|
|
148
155
|
relative_path = path.relative_path_from(Kameleon.env.repositories_path)
|
149
156
|
dst = File.join(Kameleon.env.workspace, relative_path)
|
@@ -164,8 +171,12 @@ module Kameleon
|
|
164
171
|
end
|
165
172
|
|
166
173
|
desc "info [RECIPE_PATH]", "Display detailed information about a recipe"
|
174
|
+
method_option :global, :type => :hash ,
|
175
|
+
:default => {}, :aliases => "-g",
|
176
|
+
:desc => "Set custom global variables."
|
167
177
|
def info(recipe_path)
|
168
178
|
recipe = Kameleon::Recipe.new(recipe_path)
|
179
|
+
recipe.resolve!
|
169
180
|
recipe.display_info
|
170
181
|
end
|
171
182
|
|
@@ -195,7 +206,9 @@ module Kameleon
|
|
195
206
|
method_option :proxy_path, :type => :string ,
|
196
207
|
:default => nil,
|
197
208
|
:desc => "Full path of the proxy binary to use for the persistent cache."
|
198
|
-
|
209
|
+
method_option :global, :type => :hash,
|
210
|
+
:default => {}, :aliases => "-g",
|
211
|
+
:desc => "Set custom global variables."
|
199
212
|
def build(recipe_path=nil)
|
200
213
|
if recipe_path.nil? && !options[:from_cache].nil?
|
201
214
|
Kameleon.ui.info("Using the cached recipe")
|
data/lib/kameleon/engine.rb
CHANGED
@@ -40,7 +40,8 @@ module Kameleon
|
|
40
40
|
@cache.name = @recipe.name
|
41
41
|
@cache.mode = @options[:enable_cache] ? :build : :from
|
42
42
|
@cache.cache_path = @options[:from_cache]
|
43
|
-
|
43
|
+
# I'm passing the Pathname objects
|
44
|
+
@cache.recipe_files = @recipe.files + @recipe.base_recipes_files + @recipe.data
|
44
45
|
@cache.recipe_path = @recipe.path
|
45
46
|
|
46
47
|
if @recipe.global["in_context"]["proxy_cache"].nil? then
|
data/lib/kameleon/environment.rb
CHANGED
@@ -23,6 +23,7 @@ module Kameleon
|
|
23
23
|
:cache_path => Pathname.new(cache_path),
|
24
24
|
:repositories_path => Pathname.new(repositories_path),
|
25
25
|
:root_dir => Pathname.new(workspace),
|
26
|
+
:global => options.fetch(:global, {}),
|
26
27
|
}
|
27
28
|
options = Kameleon.default_values.merge(options).merge(env_options)
|
28
29
|
Kameleon.ui.debug("Environment initialized (#{self})")
|
@@ -176,7 +176,6 @@ module Kameleon
|
|
176
176
|
all_files = @recipe_files.push(@recipe_path)
|
177
177
|
recipe_dir = Pathname.new(common_prefix(all_files))
|
178
178
|
cached_recipe_dir = Pathname.new(File.join(@cache_dir,"recipe"))
|
179
|
-
# binding.pry
|
180
179
|
Kameleon::Utils.copy_files(recipe_dir, cached_recipe_dir, all_files)
|
181
180
|
end
|
182
181
|
## Saving metadata information
|
data/lib/kameleon/recipe.rb
CHANGED
@@ -15,7 +15,7 @@ module Kameleon
|
|
15
15
|
attr_accessor :metainfo
|
16
16
|
attr_accessor :files
|
17
17
|
attr_accessor :base_recipes_files
|
18
|
-
|
18
|
+
attr_accessor :data
|
19
19
|
|
20
20
|
def initialize(path, kwargs = {})
|
21
21
|
@path = Pathname.new(File.expand_path(path))
|
@@ -26,6 +26,7 @@ module Kameleon
|
|
26
26
|
"setup" => Section.new("setup"),
|
27
27
|
"export" => Section.new("export"),
|
28
28
|
}
|
29
|
+
@cli_global = Kameleon.env.global.clone
|
29
30
|
@global = {
|
30
31
|
"kameleon_recipe_name" => @name,
|
31
32
|
"kameleon_recipe_dir" => File.dirname(@path),
|
@@ -38,6 +39,7 @@ module Kameleon
|
|
38
39
|
@files = []
|
39
40
|
Kameleon.ui.debug("Initialize new recipe (#{path})")
|
40
41
|
@base_recipes_files = [@path]
|
42
|
+
@data = []
|
41
43
|
@steps_dirs = []
|
42
44
|
load! :strict => false
|
43
45
|
end
|
@@ -84,8 +86,9 @@ module Kameleon
|
|
84
86
|
|
85
87
|
# Load Global variables
|
86
88
|
@global.merge!(yaml_recipe.fetch("global", {}))
|
89
|
+
@global.merge!(@cli_global)
|
87
90
|
# Resolve dynamically-defined variables !!
|
88
|
-
resolved_global = Utils.resolve_vars(@global.to_yaml, @path, @global, kwargs)
|
91
|
+
resolved_global = Utils.resolve_vars(@global.to_yaml, @path, @global, self, kwargs)
|
89
92
|
resolved_global = @global.merge YAML.load(resolved_global)
|
90
93
|
# Loads aliases
|
91
94
|
load_aliases(yaml_recipe)
|
@@ -111,10 +114,10 @@ module Kameleon
|
|
111
114
|
embedded_step = false
|
112
115
|
# Get macrostep name and arguments if available
|
113
116
|
if raw_macrostep.kind_of? String
|
114
|
-
name = raw_macrostep
|
117
|
+
name = Utils.resolve_vars(raw_macrostep, @path, @global, self, kwargs)
|
115
118
|
args = nil
|
116
119
|
elsif raw_macrostep.kind_of? Hash
|
117
|
-
name = raw_macrostep.keys[0]
|
120
|
+
name = Utils.resolve_vars(raw_macrostep.keys[0], @path, @global, self, kwargs)
|
118
121
|
args = raw_macrostep.values[0]
|
119
122
|
else
|
120
123
|
fail RecipeError, "Malformed yaml recipe in section: "\
|
@@ -132,7 +135,7 @@ module Kameleon
|
|
132
135
|
end
|
133
136
|
if embedded_step
|
134
137
|
Kameleon.ui.debug("Loading embedded macrostep #{name}")
|
135
|
-
macrostep = load_macrostep(nil, name, args)
|
138
|
+
macrostep = load_macrostep(nil, name, args, kwargs)
|
136
139
|
section.macrosteps.push(macrostep)
|
137
140
|
next
|
138
141
|
end
|
@@ -142,11 +145,11 @@ module Kameleon
|
|
142
145
|
macrostep_path = Pathname.new(File.join(dir, name + '.yaml'))
|
143
146
|
if File.file?(macrostep_path)
|
144
147
|
Kameleon.ui.debug("Loading macrostep #{macrostep_path}")
|
145
|
-
macrostep = load_macrostep(macrostep_path, name, args)
|
148
|
+
macrostep = load_macrostep(macrostep_path, name, args, kwargs)
|
146
149
|
section.macrosteps.push(macrostep)
|
147
150
|
@files.push(macrostep_path)
|
148
151
|
Kameleon.ui.debug("Macrostep '#{name}' found in this path: " \
|
149
|
-
|
152
|
+
"#{macrostep_path}")
|
150
153
|
loaded = true
|
151
154
|
break
|
152
155
|
else
|
@@ -214,24 +217,31 @@ module Kameleon
|
|
214
217
|
end
|
215
218
|
|
216
219
|
def load_aliases(yaml_recipe)
|
220
|
+
def load_aliases_file(aliases_file)
|
221
|
+
dir_search = @steps_dirs.map do |steps_dir|
|
222
|
+
File.join(steps_dir, "aliases")
|
223
|
+
end.flatten
|
224
|
+
dir_search.each do |dir_path|
|
225
|
+
path = Pathname.new(File.join(dir_path, aliases_file))
|
226
|
+
if File.file?(path)
|
227
|
+
Kameleon.ui.debug("Loading aliases #{path}")
|
228
|
+
@aliases.merge!(YAML.load_file(path))
|
229
|
+
@files.push(path)
|
230
|
+
return path
|
231
|
+
end
|
232
|
+
end
|
233
|
+
fail RecipeError, "Aliases file for recipe '#{path}' does not exists"
|
234
|
+
end
|
217
235
|
if yaml_recipe.keys.include? "aliases"
|
218
236
|
aliases = yaml_recipe.fetch("aliases")
|
219
237
|
if aliases.kind_of? Hash
|
220
238
|
@aliases = aliases
|
221
239
|
elsif aliases.kind_of? String
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
path = Pathname.new(File.join(dir_path, aliases))
|
227
|
-
if File.file?(path)
|
228
|
-
Kameleon.ui.debug("Loading aliases #{path}")
|
229
|
-
@aliases = YAML.load_file(path)
|
230
|
-
@files.push(path)
|
231
|
-
return path
|
232
|
-
end
|
240
|
+
load_aliases_file(aliases)
|
241
|
+
elsif aliases.kind_of? Array
|
242
|
+
aliases.each do |aliases_file|
|
243
|
+
load_aliases_file(aliases_file)
|
233
244
|
end
|
234
|
-
fail RecipeError, "Aliases file for recipe '#{path}' does not exists"
|
235
245
|
end
|
236
246
|
end
|
237
247
|
end
|
@@ -267,7 +277,7 @@ module Kameleon
|
|
267
277
|
end
|
268
278
|
end
|
269
279
|
|
270
|
-
def load_macrostep(step_path, name, args)
|
280
|
+
def load_macrostep(step_path, name, args, kwargs)
|
271
281
|
if step_path.nil?
|
272
282
|
macrostep_yaml = args
|
273
283
|
step_path = @path
|
@@ -322,6 +332,12 @@ module Kameleon
|
|
322
332
|
loaded_microsteps = strip_microsteps
|
323
333
|
end
|
324
334
|
end
|
335
|
+
# Resolved neested variables earlier
|
336
|
+
local_variables.each do |k, v|
|
337
|
+
if v.kind_of? String
|
338
|
+
local_variables[k] = Utils.resolve_vars(v, @path, @global, self, kwargs)
|
339
|
+
end
|
340
|
+
end
|
325
341
|
return Macrostep.new(name, loaded_microsteps, local_variables, step_path)
|
326
342
|
end
|
327
343
|
|
@@ -335,6 +351,23 @@ module Kameleon
|
|
335
351
|
return nil
|
336
352
|
end
|
337
353
|
|
354
|
+
def resolve_data_path(partial_path, step_path)
|
355
|
+
Kameleon.ui.debug("Looking for data '#{partial_path}'")
|
356
|
+
dir_search = @steps_dirs.map do |steps_dir|
|
357
|
+
File.join(steps_dir, "data")
|
358
|
+
end.flatten
|
359
|
+
dir_search.each do |dir_path|
|
360
|
+
real_path = Pathname.new(File.join(dir_path, partial_path)).cleanpath
|
361
|
+
if real_path.exist?
|
362
|
+
Kameleon.ui.debug("Register data #{real_path}")
|
363
|
+
@data.push(real_path) unless @data.include? real_path
|
364
|
+
return real_path
|
365
|
+
end
|
366
|
+
Kameleon.ui.debug("#{real_path} : nonexistent")
|
367
|
+
end
|
368
|
+
fail RecipeError, "Cannot found data '#{partial_path}' unsed in '#{step_path}'"
|
369
|
+
end
|
370
|
+
|
338
371
|
def resolve!
|
339
372
|
unless @global.keys.include? "kameleon_uuid"
|
340
373
|
kameleon_id = SecureRandom.uuid
|
@@ -342,7 +375,7 @@ module Kameleon
|
|
342
375
|
@global["kameleon_short_uuid"] = kameleon_id.split("-").last
|
343
376
|
end
|
344
377
|
# Resolve dynamically-defined variables !!
|
345
|
-
resolved_global = Utils.resolve_vars(@global.to_yaml, @path, @global)
|
378
|
+
resolved_global = Utils.resolve_vars(@global.to_yaml, @path, @global, self)
|
346
379
|
@global.merge! YAML.load(resolved_global)
|
347
380
|
|
348
381
|
consistency_check
|
@@ -367,7 +400,7 @@ module Kameleon
|
|
367
400
|
Kameleon.ui.info("Resolving variables")
|
368
401
|
@sections.values.each do |section|
|
369
402
|
section.macrosteps.each do |macrostep|
|
370
|
-
macrostep.resolve_variables!(@global)
|
403
|
+
macrostep.resolve_variables!(@global, self)
|
371
404
|
end
|
372
405
|
end
|
373
406
|
|
@@ -394,6 +427,7 @@ module Kameleon
|
|
394
427
|
end
|
395
428
|
end
|
396
429
|
calculate_step_identifiers
|
430
|
+
flatten_data
|
397
431
|
end
|
398
432
|
|
399
433
|
def consistency_check()
|
@@ -431,7 +465,8 @@ module Kameleon
|
|
431
465
|
@checkpoint[key].each do |cmd|
|
432
466
|
cmd.string_cmd = Utils.resolve_vars(cmd.string_cmd,
|
433
467
|
@checkpoint["path"],
|
434
|
-
@global
|
468
|
+
@global,
|
469
|
+
self)
|
435
470
|
end
|
436
471
|
end
|
437
472
|
end
|
@@ -554,6 +589,21 @@ module Kameleon
|
|
554
589
|
end
|
555
590
|
end
|
556
591
|
|
592
|
+
def flatten_data
|
593
|
+
files = []
|
594
|
+
@data.each do |d|
|
595
|
+
if d.directory?
|
596
|
+
Find.find("#{d}") do |f|
|
597
|
+
files.push(Pathname.new(f)) unless File.directory? f
|
598
|
+
end
|
599
|
+
else
|
600
|
+
files.push(d)
|
601
|
+
end
|
602
|
+
end
|
603
|
+
@data = files.uniq
|
604
|
+
end
|
605
|
+
|
606
|
+
|
557
607
|
def to_hash
|
558
608
|
recipe_hash = {
|
559
609
|
"name" => @name,
|
@@ -562,6 +612,7 @@ module Kameleon
|
|
562
612
|
"base_recipes_files" => @base_recipes_files.map {|p| p.to_s },
|
563
613
|
"global" => @global,
|
564
614
|
"aliases" => @aliases,
|
615
|
+
"data" => @data,
|
565
616
|
}
|
566
617
|
recipe_hash["checkpoint"] = @checkpoint unless @checkpoint.nil?
|
567
618
|
recipe_hash["steps"] = to_array
|
@@ -584,6 +635,10 @@ module Kameleon
|
|
584
635
|
@files.each do |step|
|
585
636
|
prefix ; Kameleon.ui.info("#{step}")
|
586
637
|
end
|
638
|
+
Kameleon.ui.info("Data:")
|
639
|
+
@data.each do |d|
|
640
|
+
prefix ; Kameleon.ui.info("#{d}")
|
641
|
+
end
|
587
642
|
Kameleon.ui.info("Variables:")
|
588
643
|
@global.each do |key, value|
|
589
644
|
prefix ; Kameleon.ui.info("#{key}: #{value}")
|
data/lib/kameleon/shell.rb
CHANGED
@@ -18,15 +18,25 @@ module Kameleon
|
|
18
18
|
@local_workdir = local_workdir
|
19
19
|
@shell_workdir = shell_workdir
|
20
20
|
@proxy_cache = proxy_cache
|
21
|
-
@
|
22
|
-
@
|
23
|
-
@
|
24
|
-
@
|
25
|
-
|
21
|
+
@bash_scripts_dir = File.join(".scripts", @context_name)
|
22
|
+
@bashrc_file = File.join(@bash_scripts_dir, "bash_rc")
|
23
|
+
@bash_history_file = File.join(@bash_scripts_dir, "bash_history")
|
24
|
+
@bash_env_file = File.join(@bash_scripts_dir, "bash_env")
|
25
|
+
@bash_status_file = File.join(@bash_scripts_dir, "bash_status")
|
26
|
+
@default_bashrc_file = File.join(Kameleon.source_root, "contrib", "kameleon_bashrc.sh")
|
27
|
+
@cmd_tpl = ERB.new(File.read(File.join(Kameleon.source_root,
|
28
|
+
"contrib",
|
29
|
+
"kameleon_exec_cmd.sh")))
|
30
|
+
@cmd_wrapper_tpl = ERB.new(File.read(File.join(Kameleon.source_root,
|
31
|
+
"contrib",
|
32
|
+
"kameleon_exec_cmd_wrapper.sh")))
|
33
|
+
|
26
34
|
if @shell_workdir
|
35
|
+
@bash_scripts_dir = File.join(@shell_workdir, @bash_scripts_dir)
|
27
36
|
@bashrc_file = File.join(@shell_workdir, @bashrc_file)
|
28
37
|
@bash_history_file = File.join(@shell_workdir, @bash_history_file)
|
29
38
|
@bash_env_file = File.join(@shell_workdir, @bash_env_file)
|
39
|
+
@bash_status_file = File.join(@shell_workdir, @bash_status_file)
|
30
40
|
end
|
31
41
|
|
32
42
|
## Changing the default bashrc if the cache is activated
|
@@ -118,7 +128,7 @@ module Kameleon
|
|
118
128
|
change_dir_cmd = Shellwords.escape(change_dir_cmd)
|
119
129
|
end
|
120
130
|
shell_cmd = "mkdir -p $(dirname #{@bashrc_file})\n"
|
121
|
-
shell_cmd << "
|
131
|
+
shell_cmd << "rm $(dirname #{@bashrc_file})/*\n"
|
122
132
|
shell_cmd << "echo #{bashrc} > #{@bashrc_file}\n"
|
123
133
|
unless change_dir_cmd.nil?
|
124
134
|
shell_cmd << "echo #{change_dir_cmd} >> #{@bashrc_file}\n"
|
@@ -130,19 +140,17 @@ module Kameleon
|
|
130
140
|
end
|
131
141
|
|
132
142
|
def send_command cmd
|
133
|
-
shell_cmd = "
|
134
|
-
shell_cmd << "#{ ECHO_CMD } -n #{ cmd.begin_out }\n"
|
143
|
+
shell_cmd = ""
|
135
144
|
unless @sent_first_cmd
|
136
145
|
shell_cmd << init_shell_cmd
|
137
146
|
@sent_first_cmd = true
|
138
147
|
end
|
139
|
-
|
140
|
-
|
141
|
-
shell_cmd << "#{ cmd.
|
142
|
-
shell_cmd << "#{
|
143
|
-
shell_cmd << "
|
144
|
-
shell_cmd << "#{
|
145
|
-
shell_cmd << "#{ ECHO_CMD } -n #{ cmd.end_out }\n"
|
148
|
+
cmd_content = Shellwords.escape(@cmd_tpl.result(binding))
|
149
|
+
cmd_wrapper_content = Shellwords.escape(@cmd_wrapper_tpl.result(binding))
|
150
|
+
shell_cmd << "mkdir -p $(dirname #{File.join(@bash_scripts_dir, "#{cmd}.sh" )})\n"
|
151
|
+
shell_cmd << "echo #{cmd_content} > #{File.join(@bash_scripts_dir, "#{cmd}.sh" )}\n"
|
152
|
+
shell_cmd << "echo #{cmd_wrapper_content} > #{File.join(@bash_scripts_dir, "#{cmd}_wrapper.sh" )}\n"
|
153
|
+
shell_cmd << "bash #{File.join(@bash_scripts_dir, "#{cmd}_wrapper.sh" )}\n"
|
146
154
|
@process.io.stdin.puts shell_cmd
|
147
155
|
@process.io.stdin.flush
|
148
156
|
end
|
@@ -222,7 +230,7 @@ module Kameleon
|
|
222
230
|
|
223
231
|
def get_status
|
224
232
|
var_name = "__exit_status__"
|
225
|
-
@process.io.stdin << "#{ ECHO_CMD } \"#{ var_name }=$
|
233
|
+
@process.io.stdin << "#{ ECHO_CMD } \"#{ var_name }=$(cat #{@bash_status_file})\"\n"
|
226
234
|
@process.io.stdin.flush
|
227
235
|
while((line = @stdout.gets))
|
228
236
|
if (m = %r/#{ var_name }\s*=\s*(.*)/.match line)
|
@@ -321,7 +329,7 @@ module Kameleon
|
|
321
329
|
@value = raw.to_s.strip
|
322
330
|
@number = self.class.counter
|
323
331
|
@slug = Kameleon::Utils.generate_slug(@value)[0...30]
|
324
|
-
@id = "%d_%d_%d" % [
|
332
|
+
@id = "%d_%d_%d" % [@number, $$, rand(Time.now.usec)]
|
325
333
|
@begin_out = "__CMD_OUT_%s_BEGIN__" % @id
|
326
334
|
@end_out = "__CMD_OUT_%s_END__" % @id
|
327
335
|
@begin_out_pat = %r/#{ Regexp.escape(@begin_out) }(.*)/m
|
@@ -332,6 +340,10 @@ module Kameleon
|
|
332
340
|
@end_err_pat = %r/(.*)#{ Regexp.escape(@end_err) }/m
|
333
341
|
self.class.counter += 1
|
334
342
|
end
|
343
|
+
|
344
|
+
def to_s
|
345
|
+
"%05d_#{@slug}" % @number
|
346
|
+
end
|
335
347
|
end
|
336
348
|
|
337
349
|
end
|
data/lib/kameleon/step.rb
CHANGED
@@ -168,14 +168,15 @@ module Kameleon
|
|
168
168
|
@init_microsteps = []
|
169
169
|
end
|
170
170
|
|
171
|
-
def resolve_variables!(global)
|
171
|
+
def resolve_variables!(global, recipe)
|
172
172
|
# Resolve dynamically-defined variables !!
|
173
173
|
tmp_resolved_vars = {}
|
174
174
|
@variables.clone.each do |key, value|
|
175
175
|
yaml_vars = { key => value }.to_yaml.chomp
|
176
176
|
yaml_resolved = Utils.resolve_vars(yaml_vars,
|
177
177
|
@path,
|
178
|
-
tmp_resolved_vars.merge(global)
|
178
|
+
tmp_resolved_vars.merge(global),
|
179
|
+
recipe)
|
179
180
|
tmp_resolved_vars.merge! YAML.load(yaml_resolved.chomp)
|
180
181
|
end
|
181
182
|
@variables.merge! tmp_resolved_vars
|
@@ -183,7 +184,8 @@ module Kameleon
|
|
183
184
|
m.commands.each do |cmd|
|
184
185
|
cmd.string_cmd = Utils.resolve_vars(cmd.string_cmd,
|
185
186
|
@path,
|
186
|
-
global.merge(@variables)
|
187
|
+
global.merge(@variables),
|
188
|
+
recipe)
|
187
189
|
end
|
188
190
|
end
|
189
191
|
end
|
data/lib/kameleon/utils.rb
CHANGED
@@ -1,7 +1,26 @@
|
|
1
1
|
module Kameleon
|
2
2
|
module Utils
|
3
3
|
|
4
|
-
|
4
|
+
|
5
|
+
def self.resolve_vars(raw, yaml_path, initial_variables, recipe, kwargs = {})
|
6
|
+
raw = resolve_data_dir_vars(raw, yaml_path, initial_variables, recipe, kwargs)
|
7
|
+
return resolve_simple_vars(raw, yaml_path, initial_variables, kwargs)
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.resolve_data_dir_vars(raw, yaml_path, initial_variables, recipe, kwargs)
|
11
|
+
reg = %r/\$\$kameleon\_data\_dir\/(.*)|\$\${kameleon\_data\_dir}\/(.*)/
|
12
|
+
matches = raw.to_enum(:scan, reg).map { Regexp.last_match }
|
13
|
+
matches.each do |m|
|
14
|
+
unless m.nil?
|
15
|
+
path = resolve_simple_vars(m[1], yaml_path, initial_variables, kwargs)
|
16
|
+
resolved_path = recipe.resolve_data_path(path, yaml_path)
|
17
|
+
raw.gsub!(m[0], "\"#{resolved_path}\"")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
return raw
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.resolve_simple_vars(raw, yaml_path, initial_variables, kwargs)
|
5
24
|
raw.to_s.gsub(/\$\$\{[a-zA-Z0-9\-_]+\}|\$\$[a-zA-Z0-9\-_]+/) do |var|
|
6
25
|
# remove the dollars
|
7
26
|
if var.include? "{"
|
@@ -17,7 +36,7 @@ module Kameleon
|
|
17
36
|
fail RecipeError, "#{yaml_path}: variable #{var} not found in local or global"
|
18
37
|
end
|
19
38
|
end
|
20
|
-
return $` +
|
39
|
+
return $` + resolve_simple_vars(value.to_s + $', yaml_path, initial_variables, kwargs)
|
21
40
|
end
|
22
41
|
end
|
23
42
|
|
@@ -29,7 +48,7 @@ module Kameleon
|
|
29
48
|
value.gsub!(/\s*[^A-Za-z0-9\.]\s*/, '_')
|
30
49
|
value.gsub!(/_+/, "_")
|
31
50
|
value.gsub!(/\A[_\.]+|[_\.]+\z/, "")
|
32
|
-
value
|
51
|
+
value.chomp("_")
|
33
52
|
end
|
34
53
|
|
35
54
|
def self.extract_meta_var(name, content)
|
data/version.txt
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.4.0
|
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.
|
4
|
+
version: 2.4.0
|
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: 2014-12-
|
15
|
+
date: 2014-12-23 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: childprocess
|
@@ -95,6 +95,8 @@ files:
|
|
95
95
|
- completion/kameleon.bash
|
96
96
|
- completion/kameleon.fish
|
97
97
|
- contrib/kameleon_bashrc.sh
|
98
|
+
- contrib/kameleon_exec_cmd.sh
|
99
|
+
- contrib/kameleon_exec_cmd_wrapper.sh
|
98
100
|
- contrib/polipo_env.sh
|
99
101
|
- contrib/scripts/VirtualBox_deploy.sh
|
100
102
|
- contrib/scripts/chroot_env
|