kameleon-builder 2.1.3 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.editorconfig +0 -0
- data/.env +2 -6
- data/CHANGELOG.rst +74 -1
- data/Gemfile +20 -2
- data/README.rst +35 -25
- data/Thorfile +29 -0
- data/contrib/kameleon_bashrc.sh +61 -0
- data/contrib/polipo_env.sh +3 -2
- data/kameleon-builder.gemspec +3 -10
- data/lib/kameleon.rb +10 -14
- data/lib/kameleon/cli.rb +92 -105
- data/lib/kameleon/context.rb +76 -43
- data/lib/kameleon/engine.rb +147 -103
- data/lib/kameleon/environment.rb +10 -5
- data/lib/kameleon/error.rb +1 -32
- data/lib/kameleon/persistent_cache.rb +127 -29
- data/lib/kameleon/recipe.rb +63 -106
- data/lib/kameleon/shell.rb +32 -17
- data/lib/kameleon/step.rb +18 -1
- data/lib/kameleon/ui.rb +141 -0
- data/lib/kameleon/utils.rb +9 -0
- data/templates/{debian7-chroot.yaml → chroot/debian7-amd64.yaml} +29 -21
- data/templates/{docker-debian7.yaml → docker/debian7.yaml} +5 -5
- data/templates/extend.erb +2 -2
- data/templates/{debian7-g5k.yaml → grid5000/debian7.yaml} +1 -1
- data/templates/{archlinux-desktop.yaml → qemu/archlinux-desktop-i686.yaml} +2 -2
- data/templates/qemu/archlinux-desktop-x86_64.yaml +25 -0
- data/templates/qemu/archlinux-i686.yaml +25 -0
- data/templates/{archlinux.yaml → qemu/archlinux-x86_64.yaml} +37 -34
- data/templates/qemu/centos6.5-x86_64.yaml +113 -0
- data/templates/qemu/centos7-x86_64.yaml +119 -0
- data/templates/{debian7.yaml → qemu/debian7-amd64.yaml} +45 -40
- data/templates/{debian7-desktop.yaml → qemu/debian7-desktop-amd64.yaml} +2 -3
- data/templates/{debian7-kameleon.yaml → qemu/debian7-kameleon-amd64.yaml} +3 -6
- data/templates/{debian7-oar-dev.yaml → qemu/debian7-oar-amd64.yaml} +2 -2
- data/templates/qemu/debian8-amd64.yaml +25 -0
- data/templates/{fedora20-desktop.yaml → qemu/fedora20-desktop-x86_64.yaml} +2 -2
- data/templates/qemu/fedora20-x86_64.yaml +116 -0
- data/templates/{ubuntu-12.04.yaml → qemu/ubuntu-12.04-amd64.yaml} +42 -38
- data/templates/{ubuntu-12.04-desktop.yaml → qemu/ubuntu-12.04-desktop-amd64.yaml} +3 -3
- data/templates/{ubuntu-14.04.yaml → qemu/ubuntu-14.04-amd64.yaml} +2 -2
- data/templates/{ubuntu-14.04-desktop.yaml → qemu/ubuntu-14.04-desktop-amd64.yaml} +2 -2
- data/templates/steps/aliases/defaults.yaml +19 -13
- data/templates/steps/bootstrap/archlinux/arch_bootstrap.yaml +11 -19
- data/templates/steps/bootstrap/debian/debootstrap.yaml +10 -11
- data/templates/steps/bootstrap/debian/debootstrap_arm.yaml +11 -19
- data/templates/steps/bootstrap/fedora/init_pxeboot.yaml +13 -0
- data/templates/steps/bootstrap/fedora/yum_bootstrap.yaml +45 -0
- data/templates/steps/bootstrap/initialize_disk.yaml +16 -0
- data/templates/steps/bootstrap/initialize_disk_chroot.yaml +10 -14
- data/templates/steps/bootstrap/install_requirements.yaml +3 -0
- data/templates/steps/bootstrap/prepare_docker.yaml +7 -7
- data/templates/steps/bootstrap/prepare_qemu.yaml +20 -26
- data/templates/steps/bootstrap/prepare_virtualbox.yaml +63 -0
- data/templates/steps/bootstrap/start_chroot.yaml +2 -13
- data/templates/steps/bootstrap/start_qemu.yaml +50 -53
- data/templates/steps/bootstrap/start_virtualbox.yaml +37 -0
- data/templates/steps/bootstrap/switch_context_qemu.yaml +64 -0
- data/templates/steps/bootstrap/switch_context_virtualbox.yaml +66 -0
- data/templates/steps/breakpoint.yaml +2 -1
- data/templates/steps/checkpoints/docker.yaml +14 -11
- data/templates/steps/checkpoints/qcow2.yaml +26 -24
- data/templates/steps/checkpoints/qemu.yaml +30 -36
- data/templates/steps/checkpoints/virtualbox.yaml +21 -0
- data/templates/steps/disable_checkpoint.yaml +3 -0
- data/templates/steps/enable_checkpoint.yaml +5 -0
- data/templates/steps/export/qemu_save_appliance.yaml +52 -0
- data/templates/steps/export/virtualbox_save_appliance.yaml +67 -0
- data/templates/steps/setup/archlinux/install_bootloader.yaml +23 -0
- data/templates/steps/setup/centos/6.5/configure_network.yaml +31 -0
- data/templates/steps/setup/centos/6.5/configure_system.yaml +27 -0
- data/templates/steps/setup/debian/configure_apt.yaml +1 -6
- data/templates/steps/setup/debian/configure_kernel.yaml +0 -5
- data/templates/steps/setup/debian/install_bootloader.yaml +36 -0
- data/templates/steps/setup/debian/setup_vagrant_box.yaml +48 -18
- data/templates/steps/setup/debian/upgrade_system.yaml +2 -7
- data/templates/steps/setup/fedora/configure_kernel.yaml +9 -0
- data/templates/steps/setup/fedora/configure_keyboard.yaml +12 -0
- data/templates/steps/setup/fedora/configure_network.yaml +9 -1
- data/templates/steps/setup/fedora/configure_system.yaml +20 -45
- data/templates/steps/setup/fedora/install_bootloader.yaml +58 -0
- data/templates/steps/setup/fedora/minimal_install.yaml +3 -0
- data/templates/steps/setup/fedora/update_system.yaml +13 -5
- data/templates/steps/setup/ubuntu/configure_apt.yaml +4 -9
- data/templates/vagrant/debian7-amd64.yaml +130 -0
- data/templates/virtualbox/archlinux-desktop-i686.yaml +25 -0
- data/templates/virtualbox/archlinux-desktop-x86_64.yaml +28 -0
- data/templates/virtualbox/archlinux-i686.yaml +28 -0
- data/templates/virtualbox/archlinux-x86_64.yaml +109 -0
- data/templates/virtualbox/centos6.5-i386.yaml +39 -0
- data/templates/virtualbox/centos6.5-x86_64.yaml +111 -0
- data/templates/virtualbox/centos7-x86_64.yaml +116 -0
- data/{docs/source/debian7.yaml → templates/virtualbox/debian7-amd64.yaml} +53 -52
- data/templates/virtualbox/debian7-desktop-amd64.yaml +25 -0
- data/templates/{fedora-rawhide.yaml → virtualbox/debian7-i386.yaml} +12 -11
- data/templates/virtualbox/debian7-kameleon-amd64.yaml +38 -0
- data/templates/virtualbox/debian7-oar-amd64.yaml +51 -0
- data/templates/{debian-testing.yaml → virtualbox/debian8-amd64.yaml} +3 -3
- data/templates/virtualbox/debian8-i386.yaml +31 -0
- data/templates/virtualbox/fedora20-x86_64.yaml +116 -0
- data/templates/virtualbox/ubuntu-12.04-amd64.yaml +128 -0
- data/templates/virtualbox/ubuntu-12.04-desktop-amd64.yaml +25 -0
- data/templates/virtualbox/ubuntu-14.04-amd64.yaml +25 -0
- data/templates/virtualbox/ubuntu-14.04-desktop-amd64.yaml +27 -0
- data/version.txt +1 -1
- metadata +67 -212
- data/Rakefile +0 -24
- data/docs/.gitignore +0 -1
- data/docs/Makefile +0 -181
- data/docs/README.md +0 -17
- data/docs/make.bat +0 -242
- data/docs/source/_static/.gitignore +0 -0
- data/docs/source/_static/centos.png +0 -0
- data/docs/source/_static/debian.png +0 -0
- data/docs/source/_static/kameleon-logo.png +0 -0
- data/docs/source/_static/kameleon-logo.xcf +0 -0
- data/docs/source/_static/kameleon-long.png +0 -0
- data/docs/source/_static/ubuntu.png +0 -0
- data/docs/source/_themes/sphinx_rtd_theme/__init__.py +0 -17
- data/docs/source/_themes/sphinx_rtd_theme/breadcrumbs.html +0 -19
- data/docs/source/_themes/sphinx_rtd_theme/footer.html +0 -32
- data/docs/source/_themes/sphinx_rtd_theme/layout.html +0 -160
- data/docs/source/_themes/sphinx_rtd_theme/layout_old.html +0 -205
- data/docs/source/_themes/sphinx_rtd_theme/search.html +0 -50
- data/docs/source/_themes/sphinx_rtd_theme/searchbox.html +0 -7
- data/docs/source/_themes/sphinx_rtd_theme/static/css/badge_only.css +0 -1
- data/docs/source/_themes/sphinx_rtd_theme/static/css/theme.css +0 -4
- data/docs/source/_themes/sphinx_rtd_theme/static/fonts/FontAwesome.otf +0 -0
- data/docs/source/_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.eot +0 -0
- data/docs/source/_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.svg +0 -414
- data/docs/source/_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.ttf +0 -0
- data/docs/source/_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.woff +0 -0
- data/docs/source/_themes/sphinx_rtd_theme/static/js/theme.js +0 -47
- data/docs/source/_themes/sphinx_rtd_theme/theme.conf +0 -8
- data/docs/source/_themes/sphinx_rtd_theme/versions.html +0 -37
- data/docs/source/aliases.rst +0 -31
- data/docs/source/atlas_debian_g5k.yaml +0 -36
- data/docs/source/checkpoint.rst +0 -30
- data/docs/source/commands.rst +0 -63
- data/docs/source/conf.py +0 -262
- data/docs/source/context.rst +0 -47
- data/docs/source/debian_customized.yaml +0 -28
- data/docs/source/debian_customized_g5k.yaml +0 -21
- data/docs/source/faq.rst +0 -43
- data/docs/source/getting_started.rst +0 -260
- data/docs/source/grid5000_tutorial.rst +0 -525
- data/docs/source/index.rst +0 -53
- data/docs/source/install_atlas.yaml +0 -25
- data/docs/source/install_hpl.yaml +0 -24
- data/docs/source/installation.rst +0 -51
- data/docs/source/persistent_cache.rst +0 -34
- data/docs/source/recipe.rst +0 -177
- data/docs/source/tau_install.yaml +0 -19
- data/docs/source/tau_install_g5k.yaml +0 -25
- data/docs/source/use_cases.rst +0 -93
- data/docs/source/workspace.rst +0 -13
- data/lib/kameleon/logger.rb +0 -56
- data/omnibus/.gitignore +0 -11
- data/omnibus/.kitchen.yml +0 -25
- data/omnibus/Berksfile +0 -9
- data/omnibus/Berksfile.lock +0 -25
- data/omnibus/Gemfile +0 -12
- data/omnibus/README.md +0 -94
- data/omnibus/config/projects/kameleon.rb +0 -23
- data/omnibus/config/software/kameleon.rb +0 -24
- data/omnibus/config/software/polipo.rb +0 -30
- data/omnibus/config/software/ruby.rb +0 -158
- data/omnibus/files/mac_dmg/Resources/background.png +0 -0
- data/omnibus/files/mac_dmg/Resources/icon.png +0 -0
- data/omnibus/files/mac_pkg/Resources/background.png +0 -0
- data/omnibus/files/mac_pkg/Resources/license.html +0 -1
- data/omnibus/files/mac_pkg/Resources/welcome.html +0 -9
- data/omnibus/omnibus.rb +0 -27
- data/omnibus/package-scripts/kameleon/makeselfinst +0 -27
- data/omnibus/package-scripts/kameleon/postrm +0 -9
- data/templates/fedora20.yaml +0 -105
- data/templates/steps/bootstrap/archlinux/install_bootloader.yaml +0 -46
- data/templates/steps/bootstrap/archlinux/populate_disk.yaml +0 -39
- data/templates/steps/bootstrap/fedora/liveos_bootstrap.yaml +0 -123
- data/templates/steps/bootstrap/initialize_disk_qemu.yaml +0 -72
- data/templates/steps/bootstrap/install_bootloader.yaml +0 -42
- data/templates/steps/bootstrap/ubuntu/debootstrap.yaml +0 -27
- data/templates/steps/export/save_appliance.yaml +0 -58
- data/templates/steps/export/save_vagrant_box.yaml +0 -29
- data/templates/vagrant-debian7.yaml +0 -31
data/lib/kameleon/context.rb
CHANGED
@@ -6,97 +6,125 @@ module Kameleon
|
|
6
6
|
attr_accessor :shell
|
7
7
|
attr_accessor :name
|
8
8
|
|
9
|
-
def initialize(name, cmd, workdir, exec_prefix, local_workdir)
|
9
|
+
def initialize(name, cmd, workdir, exec_prefix, local_workdir, kwargs = {})
|
10
10
|
@name = name.downcase
|
11
|
-
@logger = Log4r::Logger.new("kameleon::[#{@name}_ctx]")
|
12
11
|
@cmd = cmd
|
13
12
|
@workdir = workdir
|
14
13
|
@exec_prefix = exec_prefix
|
15
14
|
@local_workdir = local_workdir
|
16
|
-
@
|
17
|
-
@
|
18
|
-
@
|
15
|
+
@proxy_cache = kwargs[:proxy_cache]
|
16
|
+
@fail_silently = kwargs.fetch(:fail_silently, true)
|
17
|
+
@lazyload = kwargs.fetch(:lazyload, false)
|
18
|
+
@shell = Kameleon::Shell.new(@name,
|
19
|
+
@cmd,
|
20
|
+
@workdir,
|
21
|
+
@local_workdir,
|
22
|
+
@proxy_cache)
|
23
|
+
@already_loaded = false
|
24
|
+
Kameleon.ui.debug("Initialize new ctx (#{name})")
|
19
25
|
|
20
26
|
instance_variables.each do |v|
|
21
|
-
|
27
|
+
Kameleon.ui.debug(" #{v} = #{instance_variable_get(v)}")
|
22
28
|
end
|
23
29
|
|
24
30
|
@cache = Kameleon::Persistent_cache.instance
|
31
|
+
unless @lazyload
|
32
|
+
load_shell
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def already_loaded?
|
37
|
+
@already_loaded
|
25
38
|
end
|
26
39
|
|
27
40
|
def do_log(out, log_level)
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
if out.
|
33
|
-
|
41
|
+
prefix = "[#{@name}] "
|
42
|
+
out.gsub!("\r", "\r#{prefix}")
|
43
|
+
out.gsub!("\n", "\n#{prefix}")
|
44
|
+
if Kameleon.log_on_progress
|
45
|
+
if out.end_with?("#{prefix}")
|
46
|
+
Kameleon.log_on_progress = false
|
47
|
+
log_progress(log_level, out.chomp(prefix))
|
34
48
|
else
|
35
49
|
log_progress(log_level, out)
|
36
|
-
|
50
|
+
end
|
51
|
+
else
|
52
|
+
if out.end_with?("#{prefix}")
|
53
|
+
log_progress(log_level, prefix + out.chomp(prefix))
|
54
|
+
else
|
55
|
+
Kameleon.log_on_progress = true
|
56
|
+
log_progress(log_level, prefix + out)
|
37
57
|
end
|
38
58
|
end
|
39
59
|
end
|
40
60
|
|
41
|
-
def log(log_level, msg)
|
42
|
-
@logger.info msg if log_level == "info"
|
43
|
-
@logger.error msg if log_level == "error"
|
44
|
-
@logger.debug msg if log_level == "debug"
|
45
|
-
end
|
46
|
-
|
47
61
|
def log_progress(log_level, msg)
|
48
|
-
|
49
|
-
|
50
|
-
|
62
|
+
Kameleon.ui.confirm(msg, false) if log_level == "info"
|
63
|
+
Kameleon.ui.error(msg, false) if log_level == "error"
|
64
|
+
Kameleon.ui.debug msg if log_level == "debug"
|
51
65
|
end
|
52
66
|
|
53
67
|
def execute(cmd, kwargs = {})
|
54
|
-
|
68
|
+
load_shell
|
55
69
|
cmd_with_prefix = "#{@exec_prefix} #{cmd}"
|
56
|
-
cmd_with_prefix.split( /\r?\n/ ).each {|m|
|
70
|
+
cmd_with_prefix.split( /\r?\n/ ).each {|m| Kameleon.ui.debug "+ #{m}" }
|
57
71
|
log_level = kwargs.fetch(:log_level, "info")
|
58
72
|
exit_status = @shell.execute(cmd_with_prefix, kwargs) do |out, err|
|
59
73
|
do_log(out, log_level) unless out.nil?
|
60
74
|
do_log(err, "error") unless err.nil?
|
61
75
|
end
|
62
|
-
|
76
|
+
Kameleon.ui.debug("Exit status : #{exit_status}")
|
63
77
|
fail ExecError unless exit_status.eql? 0
|
64
78
|
rescue ShellError, Errno::EPIPE => e
|
65
|
-
|
66
|
-
raise
|
79
|
+
Kameleon.ui.debug("Shell cmd failed to launch: #{@shell.shell_cmd}")
|
80
|
+
raise ExecError, e.message + ". The '#{@name}_context' is inaccessible."
|
67
81
|
end
|
68
82
|
|
69
83
|
def pipe(cmd, other_cmd, other_ctx)
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
84
|
+
if @cache.mode == :from then
|
85
|
+
Kameleon.ui.info("Redirecting pipe into cache")
|
86
|
+
tmp = @cache.get_cache_cmd(cmd)
|
87
|
+
else
|
88
|
+
tmp = Tempfile.new("pipe-#{ Kameleon::Utils.generate_slug(cmd)[0..20] }")
|
89
|
+
Kameleon.ui.debug("Running piped commands")
|
90
|
+
Kameleon.ui.debug("Saving STDOUT from #{@name}_ctx to local file #{tmp.path}")
|
91
|
+
execute(cmd, :stdout => tmp)
|
92
|
+
tmp.close
|
93
|
+
end
|
94
|
+
## Saving one side of the pipe into the cache
|
95
|
+
if @cache.mode == :build then
|
96
|
+
@cache.cache_cmd(cmd,tmp.path)
|
97
|
+
end
|
98
|
+
|
99
|
+
Kameleon.ui.debug("Forwarding #{tmp.path} to STDIN of #{other_ctx.name}_ctx")
|
76
100
|
dest_pipe_path = "${KAMELEON_WORKDIR}/pipe-#{ Kameleon::Utils.generate_slug(other_cmd)[0..20] }"
|
77
101
|
other_ctx.send_file(tmp.path, dest_pipe_path)
|
78
102
|
other_cmd_with_pipe = "cat #{dest_pipe_path} | #{other_cmd} && rm #{dest_pipe_path}"
|
79
103
|
other_ctx.execute(other_cmd_with_pipe)
|
80
104
|
end
|
81
105
|
|
82
|
-
def
|
83
|
-
unless @shell.started?
|
106
|
+
def load_shell()
|
107
|
+
unless @shell.started? || @shell.exited?
|
84
108
|
@shell.restart
|
85
|
-
# Start the shell process
|
86
109
|
execute("echo The '#{name}_context' has been initialized", :log_level => "info")
|
110
|
+
@already_loaded = true
|
87
111
|
end
|
88
|
-
rescue
|
112
|
+
rescue Exception => e
|
89
113
|
@shell.stop
|
90
|
-
|
114
|
+
if @fail_silently
|
115
|
+
e.message.split( /\r?\n/ ).each {|m| Kameleon.ui.error m }
|
116
|
+
else
|
117
|
+
raise
|
118
|
+
end
|
91
119
|
end
|
92
120
|
|
93
121
|
def start_shell
|
94
122
|
#TODO: Load env and history
|
95
|
-
|
96
|
-
|
123
|
+
load_shell
|
124
|
+
Kameleon.ui.info("Starting interactive shell")
|
97
125
|
@shell.fork_and_wait
|
98
126
|
rescue ShellError => e
|
99
|
-
e.message.split( /\r?\n/ ).each {|m|
|
127
|
+
e.message.split( /\r?\n/ ).each {|m| Kameleon.ui.error m }
|
100
128
|
end
|
101
129
|
|
102
130
|
def closed?
|
@@ -107,8 +135,13 @@ module Kameleon
|
|
107
135
|
@shell.stop
|
108
136
|
end
|
109
137
|
|
110
|
-
def
|
111
|
-
@shell.
|
138
|
+
def reload
|
139
|
+
@shell = Kameleon::Shell.new(@name,
|
140
|
+
@cmd,
|
141
|
+
@workdir,
|
142
|
+
@local_workdir,
|
143
|
+
@proxy_cache)
|
144
|
+
@shell.start
|
112
145
|
end
|
113
146
|
|
114
147
|
def send_file(source_path, dest_path)
|
data/lib/kameleon/engine.rb
CHANGED
@@ -1,110 +1,137 @@
|
|
1
1
|
require 'kameleon/recipe'
|
2
2
|
require 'kameleon/context'
|
3
3
|
require 'kameleon/persistent_cache'
|
4
|
-
|
5
4
|
module Kameleon
|
6
5
|
|
7
6
|
class Engine
|
8
7
|
attr_accessor :recipe
|
9
8
|
attr_accessor :cwd
|
10
|
-
attr_accessor :build_recipe_path
|
11
|
-
attr_accessor :pretty_list_checkpoints
|
12
9
|
|
13
10
|
def initialize(recipe, options)
|
14
11
|
@options = options
|
15
|
-
@logger = Log4r::Logger.new("kameleon::[kameleon]")
|
16
12
|
@recipe = recipe
|
17
13
|
@cleaned_sections = []
|
18
14
|
@cwd = @recipe.global["kameleon_cwd"]
|
19
15
|
@build_recipe_path = File.join(@cwd, "kameleon_build_recipe.yaml")
|
20
16
|
|
17
|
+
@recipe.global["persistent_cache"] = @options[:cache] ? "true" : "false"
|
18
|
+
|
21
19
|
build_recipe = load_build_recipe
|
22
20
|
# restore previous build uuid
|
23
21
|
unless build_recipe.nil?
|
24
|
-
# binding.pry
|
25
22
|
%w(kameleon_uuid kameleon_short_uuid).each do |key|
|
26
23
|
@recipe.global[key] = build_recipe["global"][key]
|
27
24
|
end
|
28
25
|
end
|
29
|
-
|
30
|
-
@enable_checkpoint = !@options[:no_checkpoint]
|
26
|
+
@enable_checkpoint = @options[:checkpoint]
|
31
27
|
# Check if the recipe have checkpoint entry
|
32
|
-
@enable_checkpoint
|
28
|
+
if @enable_checkpoint && @recipe.checkpoint.nil?
|
29
|
+
fail BuildError, "Checkpoint is unavailable for this recipe"
|
30
|
+
end
|
33
31
|
|
34
32
|
@recipe.resolve!
|
35
33
|
|
36
34
|
if @options[:cache] || @options[:from_cache] then
|
37
35
|
@cache = Kameleon::Persistent_cache.instance
|
38
|
-
@cache.activated = true
|
39
36
|
@cache.cwd = @cwd
|
40
37
|
@cache.polipo_path = @options[:proxy_path]
|
41
|
-
@cache.check_polipo_binary
|
42
38
|
@cache.name = @recipe.name
|
43
|
-
|
39
|
+
@cache.mode = @options[:cache] ? :build : :from
|
40
|
+
@cache.cache_path = @options[:from_cache]
|
41
|
+
@cache.recipe_files = @recipe.files # I'm passing the Pathname objects
|
42
|
+
@cache.recipe_path = @recipe.path
|
43
|
+
|
44
|
+
if @recipe.global["in_context"]["proxy_cache"].nil? then
|
45
|
+
raise BuildError, "Missing varible for in context 'proxy_cache' when using the option --cache"
|
46
|
+
end
|
47
|
+
|
48
|
+
if @recipe.global["out_context"]["proxy_cache"].nil? then
|
49
|
+
raise BuildError, "Missing varible for out context 'proxy_cache' when using the option --cache"
|
50
|
+
end
|
44
51
|
end
|
45
52
|
|
46
|
-
@in_context = nil
|
47
53
|
begin
|
48
|
-
|
54
|
+
Kameleon.ui.info("Creating kameleon build directory : #{@cwd}")
|
49
55
|
FileUtils.mkdir_p @cwd
|
50
56
|
rescue
|
51
|
-
raise BuildError, "Failed to create
|
57
|
+
raise BuildError, "Failed to create build directory #{@cwd}"
|
52
58
|
end
|
53
|
-
@
|
54
|
-
|
55
|
-
|
59
|
+
@cache.start if @cache
|
60
|
+
build_contexts
|
61
|
+
end
|
62
|
+
|
63
|
+
def build_contexts
|
64
|
+
lazyload = @options.fetch(:lazyload, true)
|
65
|
+
fail_silently = @options.fetch(:fail_silently, false)
|
66
|
+
proxy_cache_out = @recipe.global["out_context"]["proxy_cache"]
|
67
|
+
proxy_cache_in = @recipe.global["in_context"]["proxy_cache"]
|
68
|
+
|
69
|
+
Kameleon.ui.debug("Building local context [local]")
|
70
|
+
@local_context = Context.new("local", "bash", @cwd, "", @cwd,
|
71
|
+
:proxy_cache => "localhost",
|
72
|
+
:lazyload => false,
|
73
|
+
:fail_silently => false)
|
74
|
+
Kameleon.ui.debug("Building external context [out]")
|
56
75
|
@out_context = Context.new("out",
|
57
76
|
@recipe.global["out_context"]["cmd"],
|
58
77
|
@recipe.global["out_context"]["workdir"],
|
59
78
|
@recipe.global["out_context"]["exec_prefix"],
|
60
|
-
@cwd
|
61
|
-
|
79
|
+
@cwd,
|
80
|
+
:proxy_cache => proxy_cache_out,
|
81
|
+
:lazyload => lazyload,
|
82
|
+
:fail_silently => fail_silently)
|
83
|
+
|
84
|
+
Kameleon.ui.debug("Building internal context [in]")
|
62
85
|
@in_context = Context.new("in",
|
63
86
|
@recipe.global["in_context"]["cmd"],
|
64
87
|
@recipe.global["in_context"]["workdir"],
|
65
88
|
@recipe.global["in_context"]["exec_prefix"],
|
66
|
-
@cwd
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
rescue
|
71
|
-
raise BuildError, "Failed to untar the persistent cache file"
|
72
|
-
end
|
73
|
-
end
|
89
|
+
@cwd,
|
90
|
+
:proxy_cache => proxy_cache_in,
|
91
|
+
:lazyload => lazyload,
|
92
|
+
:fail_silently => fail_silently)
|
74
93
|
end
|
75
94
|
|
76
95
|
def saving_steps_files
|
77
96
|
@recipe.files.each do |file|
|
78
|
-
|
79
|
-
sleep 1
|
97
|
+
Kameleon.ui.info("File #{file} loaded from the recipe")
|
80
98
|
end
|
81
99
|
|
82
100
|
end
|
83
101
|
|
84
102
|
def create_cache_directory(step_name)
|
85
|
-
|
103
|
+
Kameleon.ui.debug("Creating directory for cache #{step_name}")
|
86
104
|
directory_name = @cache.cache_dir + "/#{step_name}"
|
87
105
|
FileUtils.mkdir_p directory_name
|
88
106
|
directory_name
|
89
107
|
end
|
90
108
|
|
91
109
|
def create_checkpoint(microstep_id)
|
92
|
-
|
93
|
-
|
94
|
-
|
110
|
+
@recipe.checkpoint["create"].each do |cmd|
|
111
|
+
safe_exec_cmd(cmd.dup.gsub!("@microstep_id", microstep_id))
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def checkpoint_enabled?
|
116
|
+
@recipe.checkpoint["enabled?"].each do |cmd|
|
117
|
+
exec_cmd(cmd, :log_level => "debug")
|
118
|
+
end
|
119
|
+
return true
|
120
|
+
rescue ExecError
|
121
|
+
return false
|
95
122
|
end
|
96
123
|
|
97
124
|
def apply_checkpoint(microstep_id)
|
98
|
-
|
99
|
-
|
100
|
-
|
125
|
+
@recipe.checkpoint["apply"].each do |cmd|
|
126
|
+
safe_exec_cmd(cmd.dup.gsub!("@microstep_id", microstep_id))
|
127
|
+
end
|
101
128
|
end
|
102
129
|
|
103
130
|
def list_all_checkpoints
|
104
131
|
list = ""
|
105
|
-
|
106
|
-
|
107
|
-
|
132
|
+
@recipe.checkpoint["list"].each do |cmd|
|
133
|
+
safe_exec_cmd(cmd, :stdout => list)
|
134
|
+
end
|
108
135
|
return list.split(/\r?\n/)
|
109
136
|
end
|
110
137
|
|
@@ -124,34 +151,36 @@ module Kameleon
|
|
124
151
|
def do_steps(section_name)
|
125
152
|
section = @recipe.sections.fetch(section_name)
|
126
153
|
section.sequence do |macrostep|
|
127
|
-
|
128
154
|
if @cache then
|
155
|
+
Kameleon.ui.info("Starting proxy cache server for macrostep '#{macrostep.name}'...")
|
129
156
|
# the following function start a polipo web proxy and stops a previous run
|
130
|
-
dir_cache = @cache.create_cache_directory(macrostep.name)
|
157
|
+
dir_cache = @cache.create_cache_directory(macrostep.name)
|
131
158
|
@cache.start_web_proxy_in(dir_cache)
|
132
159
|
end
|
133
|
-
|
134
160
|
macrostep.sequence do |microstep|
|
135
|
-
|
161
|
+
step_prefix = "Step #{ microstep.order } : "
|
162
|
+
Kameleon.ui.info("#{step_prefix}#{ microstep.slug }")
|
136
163
|
if @enable_checkpoint
|
137
164
|
if microstep.on_checkpoint == "skip"
|
138
|
-
|
165
|
+
Kameleon.ui.info("--> Skipped")
|
139
166
|
next
|
140
167
|
end
|
141
168
|
if microstep.in_cache && microstep.on_checkpoint == "use_cache"
|
142
|
-
|
169
|
+
Kameleon.ui.info("--> Using checkpoint")
|
143
170
|
else
|
144
|
-
|
171
|
+
Kameleon.ui.info("--> Running the step...")
|
145
172
|
microstep.commands.each do |cmd|
|
146
173
|
safe_exec_cmd(cmd)
|
147
174
|
end
|
148
175
|
unless microstep.on_checkpoint == "redo"
|
149
|
-
|
150
|
-
|
176
|
+
if checkpoint_enabled?
|
177
|
+
Kameleon.ui.info("--> Creating checkpoint : #{ microstep.identifier }")
|
178
|
+
create_checkpoint(microstep.identifier)
|
179
|
+
end
|
151
180
|
end
|
152
181
|
end
|
153
182
|
else
|
154
|
-
|
183
|
+
Kameleon.ui.info("--> Running the step...")
|
155
184
|
microstep.commands.each do |cmd|
|
156
185
|
safe_exec_cmd(cmd)
|
157
186
|
end
|
@@ -159,12 +188,6 @@ module Kameleon
|
|
159
188
|
end
|
160
189
|
end
|
161
190
|
@cleaned_sections.push(section.name)
|
162
|
-
|
163
|
-
if @cache then
|
164
|
-
@cache.stop_web_proxy
|
165
|
-
@cache.pack unless @options[:from_cache]
|
166
|
-
end
|
167
|
-
|
168
191
|
end
|
169
192
|
|
170
193
|
def safe_exec_cmd(cmd, kwargs = {})
|
@@ -178,11 +201,23 @@ module Kameleon
|
|
178
201
|
end
|
179
202
|
|
180
203
|
def exec_cmd(cmd, kwargs = {})
|
204
|
+
map = {"exec_in" => @in_context,
|
205
|
+
"exec_out" => @out_context,
|
206
|
+
"exec_local" => @local_context}
|
181
207
|
case cmd.key
|
182
208
|
when "breakpoint"
|
183
209
|
breakpoint(cmd.value)
|
210
|
+
when "reload_context"
|
211
|
+
context = "exec_" + cmd.value
|
212
|
+
expected_names = map.keys.map { |k| k.gsub "exec_", "" }
|
213
|
+
unless map.keys.include? context
|
214
|
+
Kameleon.ui.error("Invalid context name arguments. Expected : "\
|
215
|
+
"#{expected_names}")
|
216
|
+
fail ExecError
|
217
|
+
else
|
218
|
+
map[context].reload
|
219
|
+
end
|
184
220
|
when "exec_in"
|
185
|
-
skip_alert(cmd) if @in_context.nil?
|
186
221
|
@in_context.execute(cmd.value, kwargs)
|
187
222
|
when "exec_out"
|
188
223
|
@out_context.execute(cmd.value, kwargs)
|
@@ -193,32 +228,31 @@ module Kameleon
|
|
193
228
|
expected_cmds = ["exec_in", "exec_out", "exec_local"]
|
194
229
|
[first_cmd.key, second_cmd.key].each do |key|
|
195
230
|
unless expected_cmds.include?(key)
|
196
|
-
|
197
|
-
|
231
|
+
Kameleon.ui.error("Invalid pipe arguments. Expected : "\
|
232
|
+
"#{expected_cmds}")
|
198
233
|
fail ExecError
|
199
234
|
end
|
200
235
|
end
|
201
|
-
map = {"exec_in" => @in_context,
|
202
|
-
"exec_out" => @out_context,
|
203
|
-
"exec_local" => @local_context,}
|
204
236
|
first_context = map[first_cmd.key]
|
205
237
|
second_context = map[second_cmd.key]
|
238
|
+
@cache.cache_cmd_id(cmd.identifier) if @cache
|
206
239
|
first_context.pipe(first_cmd.value, second_cmd.value, second_context)
|
207
240
|
when "rescue"
|
208
241
|
first_cmd, second_cmd = cmd.value
|
209
242
|
begin
|
210
243
|
exec_cmd(first_cmd)
|
211
244
|
rescue ExecError
|
212
|
-
|
245
|
+
safe_exec_cmd(second_cmd)
|
213
246
|
end
|
214
247
|
else
|
215
|
-
|
248
|
+
Kameleon.ui.warn("Unknown command : #{cmd.key}")
|
216
249
|
end
|
217
250
|
end
|
218
251
|
|
219
252
|
|
220
253
|
def breakpoint(message, kwargs = {})
|
221
|
-
message
|
254
|
+
message = "Kameleon breakpoint!" if message.nil?
|
255
|
+
message.split( /\r?\n/ ).each {|m| Kameleon.ui.error "#{m}" }
|
222
256
|
enable_retry = kwargs[:enable_retry]
|
223
257
|
msg = ""
|
224
258
|
msg << "Press [r] to retry\n" if enable_retry
|
@@ -233,13 +267,16 @@ module Kameleon
|
|
233
267
|
responses.merge!({"o" => "launch out_context"})
|
234
268
|
responses.merge!({"i" => "launch in_context"})
|
235
269
|
while true
|
236
|
-
msg.split( /\r?\n/ ).each {|m|
|
237
|
-
|
238
|
-
|
270
|
+
msg.split( /\r?\n/ ).each {|m| Kameleon.ui.info "#{m}" }
|
271
|
+
if Kameleon.env.script?
|
272
|
+
answer = "a"
|
273
|
+
else
|
274
|
+
answer = Kameleon.ui.ask "answer ? [" + responses.keys().join("/") + "]: "
|
275
|
+
end
|
239
276
|
raise AbortError, "Execution aborted..." if answer.nil?
|
240
277
|
answer.chomp!
|
241
278
|
if responses.keys.include?(answer)
|
242
|
-
|
279
|
+
Kameleon.ui.info("User choice : [#{answer}] #{responses[answer]}")
|
243
280
|
if ["o", "i", "l"].include?(answer)
|
244
281
|
if answer.eql? "l"
|
245
282
|
@local_context.start_shell
|
@@ -248,7 +285,7 @@ module Kameleon
|
|
248
285
|
else
|
249
286
|
@in_context.start_shell
|
250
287
|
end
|
251
|
-
|
288
|
+
Kameleon.ui.info("Getting back to Kameleon...")
|
252
289
|
elsif answer.eql? "a"
|
253
290
|
raise AbortError, "Execution aborted..."
|
254
291
|
elsif answer.eql? "c"
|
@@ -258,7 +295,7 @@ module Kameleon
|
|
258
295
|
@local_context.execute("true") unless @local_context.closed?
|
259
296
|
return true
|
260
297
|
elsif answer.eql? "r"
|
261
|
-
|
298
|
+
Kameleon.ui.info("Retrying the previous command...")
|
262
299
|
return false
|
263
300
|
end
|
264
301
|
end
|
@@ -268,25 +305,43 @@ module Kameleon
|
|
268
305
|
def rescue_exec_error(cmd)
|
269
306
|
message = "Error occured when executing the following command :\n"
|
270
307
|
cmd.string_cmd.split( /\r?\n/ ).each {|m| message << "\n> #{m}" }
|
308
|
+
if Kameleon.env.script?
|
309
|
+
raise ExecError, message
|
310
|
+
end
|
271
311
|
return breakpoint(message, :enable_retry => true)
|
272
312
|
end
|
273
313
|
|
274
|
-
def clean()
|
314
|
+
def clean(kwargs = {})
|
315
|
+
map = {"exec_in" => @in_context,
|
316
|
+
"exec_out" => @out_context,
|
317
|
+
"exec_local" => @local_context}
|
318
|
+
if kwargs.fetch(:with_checkpoint, false)
|
319
|
+
Kameleon.ui.info("Removing all checkpoints")
|
320
|
+
@recipe.checkpoint["clear"].each do |cmd|
|
321
|
+
if map.keys.include? cmd.key
|
322
|
+
begin
|
323
|
+
exec_cmd(cmd) unless map[cmd.key].closed?
|
324
|
+
rescue
|
325
|
+
Kameleon.ui.warn("An error occurred while executing : #{cmd.value}")
|
326
|
+
end
|
327
|
+
end
|
328
|
+
end
|
329
|
+
end
|
275
330
|
@recipe.sections.values.each do |section|
|
276
331
|
next if @cleaned_sections.include?(section.name)
|
277
|
-
|
278
|
-
"exec_out" => @out_context,
|
279
|
-
"exec_local" => @local_context}
|
280
|
-
@logger.notice("Cleaning #{section.name} section")
|
332
|
+
Kameleon.ui.info("Cleaning #{section.name} section")
|
281
333
|
section.clean_macrostep.sequence do |microstep|
|
334
|
+
if @enable_checkpoint
|
335
|
+
if microstep.on_checkpoint == "skip"
|
336
|
+
next
|
337
|
+
end
|
338
|
+
end
|
282
339
|
microstep.commands.each do |cmd|
|
283
340
|
if map.keys.include? cmd.key
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
@logger.warn("An error occurred while executing : #{cmd.value}")
|
289
|
-
end
|
341
|
+
begin
|
342
|
+
exec_cmd(cmd) unless map[cmd.key].closed?
|
343
|
+
rescue
|
344
|
+
Kameleon.ui.warn("An error occurred while executing : #{cmd.value}")
|
290
345
|
end
|
291
346
|
end
|
292
347
|
end
|
@@ -295,16 +350,6 @@ module Kameleon
|
|
295
350
|
@cache.stop_web_proxy if @options[:cache] ## stopping polipo
|
296
351
|
end
|
297
352
|
|
298
|
-
def clear
|
299
|
-
clean
|
300
|
-
unless @recipe.checkpoint.nil?
|
301
|
-
@logger.notice("Removing all old checkpoints")
|
302
|
-
cmd = @recipe.checkpoint["clear"]
|
303
|
-
clear_cmd = Kameleon::Command.new({"exec_out" => cmd}, "checkpoint")
|
304
|
-
safe_exec_cmd(clear_cmd, :log_level => "info")
|
305
|
-
end
|
306
|
-
end
|
307
|
-
|
308
353
|
def build
|
309
354
|
if @enable_checkpoint
|
310
355
|
@from_checkpoint = @options[:from_checkpoint]
|
@@ -318,7 +363,7 @@ module Kameleon
|
|
318
363
|
end
|
319
364
|
end
|
320
365
|
unless @from_checkpoint.nil?
|
321
|
-
|
366
|
+
Kameleon.ui.info("Restoring last build from step : #{@from_checkpoint}")
|
322
367
|
apply_checkpoint @from_checkpoint
|
323
368
|
@recipe.microsteps.each do |microstep|
|
324
369
|
microstep.in_cache = true
|
@@ -333,24 +378,25 @@ module Kameleon
|
|
333
378
|
["bootstrap", "setup", "export"].each do |section|
|
334
379
|
do_steps(section)
|
335
380
|
end
|
381
|
+
@cache.stop if @cache
|
336
382
|
clean
|
337
383
|
rescue Exception => e
|
338
384
|
if e.is_a?(AbortError)
|
339
|
-
|
385
|
+
Kameleon.ui.error("Aborted...")
|
340
386
|
elsif e.is_a?(SystemExit) || e.is_a?(Interrupt)
|
341
|
-
|
342
|
-
@out_context.
|
343
|
-
@in_context.
|
344
|
-
@local_context.
|
387
|
+
Kameleon.ui.error("Interrupted...")
|
388
|
+
@out_context.reload if @out_context.already_loaded?
|
389
|
+
@in_context.reload if @in_context.already_loaded?
|
390
|
+
@local_context.reload if @local_context.already_loaded?
|
345
391
|
else
|
346
|
-
|
392
|
+
Kameleon.ui.error("fatal error...")
|
347
393
|
end
|
348
|
-
|
394
|
+
Kameleon.ui.warn("Waiting for cleanup before exiting...")
|
349
395
|
clean
|
350
396
|
@out_context.close!
|
351
397
|
@in_context.close!
|
352
398
|
@local_context.close!
|
353
|
-
raise
|
399
|
+
raise e
|
354
400
|
end
|
355
401
|
end
|
356
402
|
|
@@ -369,15 +415,13 @@ module Kameleon
|
|
369
415
|
end
|
370
416
|
|
371
417
|
def pretty_checkpoints_list
|
372
|
-
|
373
|
-
|
374
418
|
def find_microstep_slug_by_id(id)
|
375
419
|
@recipe.microsteps.each do |m|
|
376
420
|
return m.slug if m.identifier == id
|
377
421
|
end
|
378
422
|
end
|
379
423
|
dict_checkpoints = []
|
380
|
-
|
424
|
+
unless @recipe.checkpoint.nil?
|
381
425
|
list_checkpoints.each do |id|
|
382
426
|
slug = find_microstep_slug_by_id id
|
383
427
|
unless slug.nil?
|