kameleon-builder 2.10.1 → 2.10.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.bumpversion.cfg +2 -2
- data/CHANGES +39 -0
- data/bin/kameleon +1 -1
- data/completion/kameleon.bash +15 -4
- data/erb/extend.yaml.erb +24 -0
- data/erb/{userconf.erb → userconf.yaml.erb} +1 -0
- data/kameleon-builder.gemspec +5 -4
- data/lib/kameleon.rb +9 -3
- data/lib/kameleon/cli.rb +118 -59
- data/lib/kameleon/error.rb +1 -0
- data/lib/kameleon/recipe.rb +2 -2
- data/lib/kameleon/repository.rb +42 -2
- data/lib/kameleon/shell.rb +10 -5
- data/lib/kameleon/utils.rb +40 -8
- data/lib/kameleon/version.rb +1 -2
- metadata +22 -9
- data/erb/extend.erb +0 -33
- data/version.txt +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aeb30622025baa485ebc09845773b1e39db3b701494c01e6a3ac32b94d9f4faa
|
4
|
+
data.tar.gz: ea307b68b21479e3f930ffdd53536d9616332037524efca18b25804cb02e616b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4cd740a9d6156e3e6c0ab480e103b8cf4b2d4cb67634c599c2a3fa4f99553d8b067bd00eee821b49a66cec4816450c59cf021298117f413f07b1796e2c0c682e
|
7
|
+
data.tar.gz: ea1d8fa490900e1263c9603008df2b174422f6026ae5d8b31b21d71ad56daf4330bc18ade35a9488c12ab3665b468604d1b56baa944553fc95299596107f44a5
|
data/.bumpversion.cfg
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
[bumpversion]
|
2
2
|
commit = True
|
3
3
|
tag = True
|
4
|
-
current_version = 2.10.
|
4
|
+
current_version = 2.10.5
|
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.
|
10
|
+
[bumpversion:file:lib/kameleon/version.rb]
|
11
11
|
|
12
12
|
[bumpversion:part:release]
|
13
13
|
optional_value = gamma
|
data/CHANGES
CHANGED
@@ -1,6 +1,45 @@
|
|
1
1
|
Kameleon CHANGELOG
|
2
2
|
==================
|
3
3
|
|
4
|
+
Version 2.10.5
|
5
|
+
--------------
|
6
|
+
|
7
|
+
Released on July 29th 2021
|
8
|
+
|
9
|
+
- Remove polipo from the software dependencies as it is not maintained anymore. This breaks the caching feature.
|
10
|
+
- Some changes to allow a debian packaging.
|
11
|
+
- Update authors.
|
12
|
+
- Change the version information file and update scripts accordingly.
|
13
|
+
|
14
|
+
Version 2.10.4
|
15
|
+
--------------
|
16
|
+
|
17
|
+
Released on May 11th 2020
|
18
|
+
|
19
|
+
- Fix support for extend ERB
|
20
|
+
- Add the `kameleon template erb` command
|
21
|
+
- Fix bash completion
|
22
|
+
- Cosmetic code fixes
|
23
|
+
|
24
|
+
Version 2.10.3
|
25
|
+
--------------
|
26
|
+
|
27
|
+
Released on April 10th 2020
|
28
|
+
|
29
|
+
- Rework kameleon template list: add color add progress bar
|
30
|
+
- Make bash completion understand the subcommands
|
31
|
+
- Fix the command help -> `kameleon <command> -h`
|
32
|
+
- Add support for custom extend erb templates
|
33
|
+
|
34
|
+
Version 2.10.2
|
35
|
+
--------------
|
36
|
+
|
37
|
+
Released on April 09th 2020
|
38
|
+
|
39
|
+
- Fix cli help for the repository and template sub-commands
|
40
|
+
- Add the git remote url and branch to kameleon repo list
|
41
|
+
- Add the 'kameleon repository remove' command
|
42
|
+
|
4
43
|
Version 2.10.1
|
5
44
|
-------------
|
6
45
|
|
data/bin/kameleon
CHANGED
data/completion/kameleon.bash
CHANGED
@@ -2,12 +2,23 @@
|
|
2
2
|
|
3
3
|
_kameleon() {
|
4
4
|
COMPREPLY=()
|
5
|
-
local
|
6
|
-
|
7
|
-
|
8
|
-
|
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
|
data/erb/extend.yaml.erb
ADDED
@@ -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] %>
|
data/kameleon-builder.gemspec
CHANGED
@@ -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
|
16
|
-
'michael.mercier@
|
17
|
-
'
|
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
|
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.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
|
-
|
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
|
|
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
|
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"
|
@@ -21,37 +21,53 @@ module Kameleon
|
|
21
21
|
end
|
22
22
|
|
23
23
|
desc "list", "Lists available repositories."
|
24
|
+
method_option :git, :type => :boolean,
|
25
|
+
:default => true,
|
26
|
+
:desc => "show the git repository and branch each repository comes from"
|
24
27
|
def list
|
25
|
-
Kameleon::Repository.list
|
28
|
+
Kameleon::Repository.list(options)
|
26
29
|
end
|
27
30
|
|
28
|
-
desc "update <NAME>", "Updates repository named <NAME>
|
31
|
+
desc "update <NAME>", "Updates repository named <NAME> from git"
|
29
32
|
def update(name)
|
30
33
|
Kameleon::Repository.update(name)
|
31
34
|
end
|
32
|
-
|
35
|
+
|
36
|
+
desc "remove <NAME>", "Remove repository named <NAME>"
|
37
|
+
def remove(name)
|
38
|
+
Kameleon::Repository.remove(name)
|
39
|
+
end
|
40
|
+
|
41
|
+
desc "commands", "Lists all available commands", :hide => true
|
42
|
+
def commands
|
43
|
+
puts Repository.all_commands.keys - ["commands"]
|
44
|
+
end
|
45
|
+
|
33
46
|
map %w(ls) => :list
|
47
|
+
map %w(rm) => :remove
|
48
|
+
map %w(completions) => :commands
|
34
49
|
end
|
35
50
|
|
36
51
|
|
37
52
|
class Template < Thor
|
38
53
|
include Thor::Actions
|
39
54
|
|
40
|
-
# register CLI::Repository, 'repository', 'repository', 'Manages set of remote git repositories'
|
41
|
-
|
42
55
|
def self.source_root
|
43
56
|
Kameleon.env.repositories_path
|
44
57
|
end
|
45
58
|
|
46
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"
|
47
63
|
def list
|
48
|
-
Kameleon.ui.
|
49
|
-
|
50
|
-
Utils.list_recipes(Kameleon.env.repositories_path)
|
64
|
+
Kameleon.ui.shell.say "Recipe templates available in: ", :red, false
|
65
|
+
Kameleon.ui.shell.say Kameleon.env.repositories_path.to_s, :yellow
|
66
|
+
Utils.list_recipes(Kameleon.env.repositories_path, options[:progress], true)
|
51
67
|
end
|
52
68
|
|
53
69
|
desc "import <TEMPLATE_NAME>", "Imports the given template"
|
54
|
-
method_option :global, :type => :hash
|
70
|
+
method_option :global, :type => :hash,
|
55
71
|
:default => {}, :aliases => "-g",
|
56
72
|
:desc => "Set custom global variables."
|
57
73
|
def import(template_name)
|
@@ -82,7 +98,7 @@ module Kameleon
|
|
82
98
|
end
|
83
99
|
|
84
100
|
desc "info <TEMPLATE_NAME>", "Display detailed information about a template"
|
85
|
-
method_option :global, :type => :hash
|
101
|
+
method_option :global, :type => :hash,
|
86
102
|
:default => {}, :aliases => "-g",
|
87
103
|
:desc => "Set custom global variables."
|
88
104
|
def info(template_name)
|
@@ -99,8 +115,27 @@ module Kameleon
|
|
99
115
|
tpl.resolve! :strict => false
|
100
116
|
tpl.display_info(false)
|
101
117
|
end
|
102
|
-
|
118
|
+
|
119
|
+
desc "erb <PATH>", "Create a extend recipe ERB file"
|
120
|
+
def erb(path)
|
121
|
+
if File.directory?(path)
|
122
|
+
erb_file = Pathname.new(path).join(Kameleon.default_values[:extend_yaml_erb])
|
123
|
+
elsif File.file?(path) and path.end_with?(".yaml")
|
124
|
+
erb_file = Pathname.new(path.gsub(%r{^(.+?/)?([^/]+?)(\.yaml)?$},'\1.\2') + Kameleon.default_values[:extend_yaml_erb])
|
125
|
+
else
|
126
|
+
fail KameleonError, "Invalid path '#{path}', please give a path to a yaml file or a directory"
|
127
|
+
end
|
128
|
+
Kameleon.ui.verbose("Create extend recipe ERB '#{erb_file}'")
|
129
|
+
copy_file(Pathname.new(Kameleon.erb_dirpath).join("extend.yaml.erb"), erb_file)
|
130
|
+
end
|
131
|
+
|
132
|
+
desc "commands", "Lists all available commands", :hide => true
|
133
|
+
def commands
|
134
|
+
puts Template.all_commands.keys - ["commands"]
|
135
|
+
end
|
136
|
+
|
103
137
|
map %w(ls) => :list
|
138
|
+
map %w(completions) => :commands
|
104
139
|
end
|
105
140
|
end
|
106
141
|
|
@@ -108,9 +143,10 @@ module Kameleon
|
|
108
143
|
class Main < Thor
|
109
144
|
include Thor::Actions
|
110
145
|
|
111
|
-
|
112
|
-
|
113
|
-
|
146
|
+
desc 'repository <SUBCOMMAND>', 'Manages repositories of recipes'
|
147
|
+
subcommand 'repository', CLI::Repository
|
148
|
+
desc 'template <SUBCOMMAND>', 'Lists and imports templates'
|
149
|
+
subcommand 'template', CLI::Template
|
114
150
|
|
115
151
|
class_option :color, :type => :boolean, :default => Kameleon.default_values[:color],
|
116
152
|
:desc => "Enables colorization in output"
|
@@ -121,26 +157,27 @@ module Kameleon
|
|
121
157
|
class_option :script, :type => :boolean, :default => Kameleon.default_values[:script],
|
122
158
|
:desc => "Never prompts for user intervention",
|
123
159
|
:aliases => "-s"
|
124
|
-
map %w(-h --help) => :help
|
125
160
|
|
126
161
|
desc "version", "Prints the Kameleon's version information"
|
127
162
|
def version
|
128
163
|
puts "Kameleon version #{Kameleon::VERSION}"
|
129
164
|
end
|
130
|
-
map %w(-v --version) => :version
|
131
165
|
|
132
166
|
def self.source_root
|
133
167
|
Kameleon.env.repositories_path
|
134
168
|
end
|
135
169
|
|
136
170
|
desc "list", "Lists all defined recipes in the current directory"
|
171
|
+
method_option :progress, :type => :boolean, :default => false,
|
172
|
+
:desc => "Show progress bar while resolving templates",
|
173
|
+
:aliases => "-p"
|
137
174
|
def list
|
138
|
-
|
175
|
+
Kameleon.ui.shell.say "Workspace recipes:", :red
|
176
|
+
Utils.list_recipes(Kameleon.env.workspace, options[:progress])
|
139
177
|
end
|
140
|
-
map %w(ls) => :list
|
141
178
|
|
142
179
|
desc "new <RECIPE_PATH> <TEMPLATE_NAME>", "Creates a new recipe from template <TEMPLATE_NAME>"
|
143
|
-
method_option :global, :type => :hash
|
180
|
+
method_option :global, :type => :hash,
|
144
181
|
:default => {}, :aliases => "-g",
|
145
182
|
:desc => "Set custom global variables."
|
146
183
|
def new(recipe_name, template_name)
|
@@ -180,9 +217,19 @@ module Kameleon
|
|
180
217
|
recipe_temp = File.join(tmp_dir, File.basename(recipe_path))
|
181
218
|
## copying recipe
|
182
219
|
File.open(recipe_temp, 'w+') do |file|
|
183
|
-
|
184
|
-
|
185
|
-
|
220
|
+
message="Try and use extend recipe ERB: "
|
221
|
+
extend_yaml_erb_list = Pathname.new(template_name).dirname.ascend.to_a.map do |p|
|
222
|
+
Kameleon.env.repositories_path.join(p, Kameleon.default_values[:extend_yaml_erb])
|
223
|
+
end
|
224
|
+
extend_yaml_erb_list.unshift(Kameleon.env.repositories_path.join(template_name.gsub(%r{^(.+?/)?([^/]+?)(\.yaml)?$},'\1.\2') + Kameleon.default_values[:extend_yaml_erb]))
|
225
|
+
extend_yaml_erb_list.push(Pathname.new(Kameleon.erb_dirpath).join("extend.yaml.erb"))
|
226
|
+
extend_yaml_erb = extend_yaml_erb_list.find do |f|
|
227
|
+
Kameleon.ui.verbose(message + f.to_s)
|
228
|
+
message = "-> Not found, fallback: "
|
229
|
+
File.readable?(f)
|
230
|
+
end
|
231
|
+
Kameleon.ui.debug("Open ERB file: '#{extend_yaml_erb}'")
|
232
|
+
result = ERB.new(File.open(extend_yaml_erb, 'rb') { |f| f.read }).result(binding)
|
186
233
|
file.write(result)
|
187
234
|
end
|
188
235
|
copy_file(recipe_temp, recipe_path)
|
@@ -191,16 +238,13 @@ module Kameleon
|
|
191
238
|
end
|
192
239
|
|
193
240
|
desc "info <RECIPE_PATH>", "Display detailed information about a recipe"
|
194
|
-
method_option :global, :type => :hash
|
241
|
+
method_option :global, :type => :hash,
|
195
242
|
:default => {}, :aliases => "-g",
|
196
243
|
:desc => "Set custom global variables."
|
197
|
-
method_option :from_cache, :type => :string
|
244
|
+
method_option :from_cache, :type => :string,
|
198
245
|
:default => nil,
|
199
246
|
:desc => "Get info from a persistent cache tar file (ignore recipe path)"
|
200
|
-
method_option :
|
201
|
-
:default => false,
|
202
|
-
:desc => "Show the build sequence but do not actually build"
|
203
|
-
method_option :relative, :type => :boolean ,
|
247
|
+
method_option :relative, :type => :boolean,
|
204
248
|
:default => false,
|
205
249
|
:desc => "Make pathnames relative to the current working directory"
|
206
250
|
def info(*recipe_paths)
|
@@ -226,18 +270,18 @@ module Kameleon
|
|
226
270
|
end
|
227
271
|
|
228
272
|
desc "dag <RECIPE_PATH> [<RECIPE_PATH> [<...>]]", "Draw a DAG of the steps to build one or more recipes"
|
229
|
-
method_option :global, :type => :hash
|
273
|
+
method_option :global, :type => :hash,
|
230
274
|
:default => {}, :aliases => "-g",
|
231
275
|
:desc => "Set custom global variables."
|
232
|
-
method_option :file, :type => :string
|
276
|
+
method_option :file, :type => :string,
|
233
277
|
:default => "/tmp/kameleon.dag",
|
234
278
|
:desc => "DAG output filename"
|
235
|
-
method_option :format, :type => :string
|
279
|
+
method_option :format, :type => :string,
|
236
280
|
:desc => "DAG GraphViz format"
|
237
|
-
method_option :relative, :type => :boolean
|
281
|
+
method_option :relative, :type => :boolean,
|
238
282
|
:default => false,
|
239
283
|
:desc => "Make pathnames relative to the current working directory"
|
240
|
-
method_option :recipes_only, :type => :boolean
|
284
|
+
method_option :recipes_only, :type => :boolean,
|
241
285
|
:default => false,
|
242
286
|
:desc => "Show recipes only (mostly useful to display multiple recipes inheritance)"
|
243
287
|
def dag(*recipe_paths)
|
@@ -268,10 +312,10 @@ module Kameleon
|
|
268
312
|
end
|
269
313
|
|
270
314
|
desc "dryrun <RECIPE_PATH>", "Show the steps the build would process"
|
271
|
-
method_option :global, :type => :hash
|
315
|
+
method_option :global, :type => :hash,
|
272
316
|
:default => {}, :aliases => "-g",
|
273
317
|
:desc => "Set custom global variables."
|
274
|
-
method_option :relative, :type => :boolean
|
318
|
+
method_option :relative, :type => :boolean,
|
275
319
|
:default => false,
|
276
320
|
:desc => "Make pathnames relative to the current working directory"
|
277
321
|
def dryrun(*recipe_paths)
|
@@ -283,10 +327,10 @@ module Kameleon
|
|
283
327
|
end
|
284
328
|
|
285
329
|
desc "export <RECIPE_PATH> <EXPORT_PATH>", "Export the given recipe with its steps and data to a given directory"
|
286
|
-
method_option :global, :type => :hash
|
330
|
+
method_option :global, :type => :hash,
|
287
331
|
:default => {}, :aliases => "-g",
|
288
332
|
:desc => "Set custom global variables."
|
289
|
-
method_option :add, :type => :boolean
|
333
|
+
method_option :add, :type => :boolean,
|
290
334
|
:default => false, :aliases => "-A",
|
291
335
|
:desc => "export recipe and steps to an existing directory (this may overwrite some existing files)"
|
292
336
|
def export(recipe_path,dest_path)
|
@@ -326,36 +370,36 @@ module Kameleon
|
|
326
370
|
end
|
327
371
|
|
328
372
|
desc "build <RECIPE_PATH>", "Builds the appliance from the given recipe"
|
329
|
-
method_option :build_path, :type => :string
|
373
|
+
method_option :build_path, :type => :string,
|
330
374
|
:default => nil, :aliases => "-b",
|
331
375
|
:desc => "Sets the build directory path"
|
332
|
-
method_option :clean, :type => :boolean
|
376
|
+
method_option :clean, :type => :boolean,
|
333
377
|
:default => false,
|
334
378
|
:desc => "Runs the command `kameleon clean` first"
|
335
|
-
method_option :from_checkpoint, :type => :string
|
379
|
+
method_option :from_checkpoint, :type => :string,
|
336
380
|
:default => nil,
|
337
381
|
:desc => "Uses specific checkpoint to build the image. " \
|
338
382
|
"Default value is the last checkpoint."
|
339
|
-
method_option :enable_checkpoint, :type => :boolean
|
383
|
+
method_option :enable_checkpoint, :type => :boolean,
|
340
384
|
:default => false,
|
341
385
|
:desc => "Enables checkpoint [experimental]"
|
342
|
-
method_option :list_checkpoints, :type => :boolean
|
386
|
+
method_option :list_checkpoints, :type => :boolean, :aliases => "--checkpoints",
|
343
387
|
:default => false,
|
344
388
|
:desc => "Lists all availables checkpoints"
|
345
389
|
method_option :enable_cache, :type => :boolean,
|
346
390
|
:default => false,
|
347
391
|
:desc => "Generates a persistent cache for the appliance."
|
348
|
-
method_option :cache_path, :type => :string
|
392
|
+
method_option :cache_path, :type => :string,
|
349
393
|
:default => nil,
|
350
394
|
:desc => "Sets the cache directory path"
|
351
|
-
method_option :from_cache, :type => :string
|
395
|
+
method_option :from_cache, :type => :string,
|
352
396
|
:default => nil,
|
353
397
|
:desc => "Uses a persistent cache tar file to build the image."
|
354
|
-
method_option :cache_archive_compression, :type => :string
|
398
|
+
method_option :cache_archive_compression, :type => :string,
|
355
399
|
:enum => ["none", "gzip", "bz2", "xz"],
|
356
400
|
:default => "gzip",
|
357
401
|
:desc => "Set the persistent cache tar file compression."
|
358
|
-
method_option :polipo_path, :type => :string
|
402
|
+
method_option :polipo_path, :type => :string,
|
359
403
|
:default => nil,
|
360
404
|
:desc => "Full path of the polipo binary to use for the persistent cache."
|
361
405
|
method_option :proxy, :type => :string, :default => "",
|
@@ -365,7 +409,7 @@ module Kameleon
|
|
365
409
|
:desc => "Specifies the username and password if the parent "\
|
366
410
|
"proxy requires authorisation it should have the "\
|
367
411
|
"form 'username:password'"
|
368
|
-
method_option :proxy_offline, :type => :boolean
|
412
|
+
method_option :proxy_offline, :type => :boolean,
|
369
413
|
:default => false, :aliases => "--offline",
|
370
414
|
:desc => "Prevents Polipo from contacting remote servers"
|
371
415
|
method_option :global, :type => :hash,
|
@@ -407,8 +451,16 @@ module Kameleon
|
|
407
451
|
end
|
408
452
|
|
409
453
|
desc "commands", "Lists all available commands", :hide => true
|
410
|
-
def commands
|
411
|
-
|
454
|
+
def commands(context="main")
|
455
|
+
Kameleon.ui.debug("Commands for '#{context}':")
|
456
|
+
case context
|
457
|
+
when "main"
|
458
|
+
puts Main.all_commands.keys - ["commands"]
|
459
|
+
when "repository"
|
460
|
+
invoke CLI::Repository, "commands", [], []
|
461
|
+
when "template"
|
462
|
+
invoke CLI::Template, "commands", [], []
|
463
|
+
end
|
412
464
|
end
|
413
465
|
|
414
466
|
desc "source_root", "Prints the kameleon directory path", :hide => true
|
@@ -416,6 +468,10 @@ module Kameleon
|
|
416
468
|
puts Kameleon.source_root
|
417
469
|
end
|
418
470
|
|
471
|
+
map %w(-v --version) => :version
|
472
|
+
map %w(ls) => :list
|
473
|
+
map %w(completions) => :commands
|
474
|
+
|
419
475
|
def initialize(*args)
|
420
476
|
super
|
421
477
|
self.options ||= {}
|
@@ -431,16 +487,19 @@ module Kameleon
|
|
431
487
|
Kameleon.ui.level = "verbose"
|
432
488
|
end
|
433
489
|
Kameleon.ui.verbose("The level of output is set to #{Kameleon.ui.level}")
|
434
|
-
|
435
|
-
opts = args[1]
|
436
|
-
cmd_name = args[2][:current_command].name
|
437
|
-
if opts.include? "--help" or opts.include? "-h"
|
438
|
-
Main.command_help(Kameleon.ui.shell, cmd_name)
|
439
|
-
raise Kameleon::Exit
|
440
|
-
end
|
441
490
|
end
|
442
491
|
|
443
|
-
def self.start(*)
|
492
|
+
def self.start(*args)
|
493
|
+
# `kameleon build -h` does not work without the following, except for subcommands...
|
494
|
+
# Ref: https://stackoverflow.com/a/49044225/6431461
|
495
|
+
if (Thor::HELP_MAPPINGS & ARGV).any? and subcommands.grep(/^#{ARGV[0]}/).empty?
|
496
|
+
Kameleon.ui.debug("Apply workaround to handle the help command in #{ARGV}")
|
497
|
+
Thor::HELP_MAPPINGS.each do |cmd|
|
498
|
+
if match = ARGV.delete(cmd)
|
499
|
+
ARGV.unshift match
|
500
|
+
end
|
501
|
+
end
|
502
|
+
end
|
444
503
|
super
|
445
504
|
rescue Exception => e
|
446
505
|
Kameleon.ui = Kameleon::UI::Shell.new
|
data/lib/kameleon/error.rb
CHANGED
data/lib/kameleon/recipe.rb
CHANGED
@@ -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
|
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
|
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
|
data/lib/kameleon/repository.rb
CHANGED
@@ -28,6 +28,7 @@ module Kameleon
|
|
28
28
|
def self.update(name)
|
29
29
|
check_git_binary
|
30
30
|
git_repo = File.join(Kameleon.env.repositories_path, name)
|
31
|
+
raise RepositoryError, "Repository not found '#{name}'" if not File.directory?(git_repo)
|
31
32
|
cmd = ["git", "--git-dir", File.join(git_repo, ".git"), "--work-tree",
|
32
33
|
git_repo, "pull", "--verbose"]
|
33
34
|
process = ChildProcess.build(*cmd)
|
@@ -37,10 +38,49 @@ module Kameleon
|
|
37
38
|
process.stop
|
38
39
|
end
|
39
40
|
|
40
|
-
def self.list
|
41
|
+
def self.list(kwargs = {})
|
41
42
|
Dir["#{Kameleon.env.repositories_path}/*"].each do |repo_path|
|
42
|
-
|
43
|
+
if kwargs[:git]
|
44
|
+
show_git_repository(repo_path)
|
45
|
+
else
|
46
|
+
Kameleon.ui.info File.basename(repo_path)
|
47
|
+
end
|
43
48
|
end
|
44
49
|
end
|
50
|
+
|
51
|
+
def self.remove(name)
|
52
|
+
repo_path = File.join(Kameleon.env.repositories_path, name)
|
53
|
+
raise RepositoryError, "Repository not found '#{name}'" if not File.directory?(repo_path)
|
54
|
+
Kameleon.ui.shell.say "Removing: ", :red, false
|
55
|
+
show_git_repository(repo_path)
|
56
|
+
FileUtils.rm_rf(repo_path)
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.show_git_repository(repo_path)
|
60
|
+
cmd = ["git", "remote", "-v"]
|
61
|
+
r, w = IO.pipe
|
62
|
+
process = ChildProcess.build(*cmd)
|
63
|
+
process.io.stdout = w
|
64
|
+
process.cwd = repo_path
|
65
|
+
process.start
|
66
|
+
w.close
|
67
|
+
url = r.readline.split[1]
|
68
|
+
process.wait
|
69
|
+
process.stop
|
70
|
+
cmd = ["git", "rev-parse", "--abbrev-ref", "HEAD"]
|
71
|
+
r, w = IO.pipe
|
72
|
+
process = ChildProcess.build(*cmd)
|
73
|
+
process.io.stdout = w
|
74
|
+
process.cwd = repo_path
|
75
|
+
process.start
|
76
|
+
w.close
|
77
|
+
branch = r.readline.chomp
|
78
|
+
process.wait
|
79
|
+
process.stop
|
80
|
+
Kameleon.ui.shell.say "#{File.basename("#{repo_path}")}", nil, false
|
81
|
+
Kameleon.ui.shell.say " <-", :magenta, false
|
82
|
+
Kameleon.ui.shell.say " #{url}", :cyan, false
|
83
|
+
Kameleon.ui.shell.say " (#{branch})", :yellow
|
84
|
+
end
|
45
85
|
end
|
46
86
|
end
|
data/lib/kameleon/shell.rb
CHANGED
@@ -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
|
-
|
29
|
-
|
30
|
-
|
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(
|
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
|
data/lib/kameleon/utils.rb
CHANGED
@@ -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(
|
127
|
-
Kameleon.env.root_dir =
|
128
|
+
def self.list_recipes(recipes_path, 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(
|
132
|
+
recipes_files = get_recipes(recipes_path)
|
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(
|
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
|
-
|
151
|
-
|
152
|
-
|
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)
|
data/lib/kameleon/version.rb
CHANGED
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.
|
4
|
+
version: 2.10.5
|
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:
|
15
|
+
date: 2021-07-29 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
|
102
|
-
- michael.mercier@
|
103
|
-
-
|
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:
|
@@ -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
|
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/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.1
|