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.
Files changed (185) hide show
  1. data/.editorconfig +0 -0
  2. data/.env +2 -6
  3. data/CHANGELOG.rst +74 -1
  4. data/Gemfile +20 -2
  5. data/README.rst +35 -25
  6. data/Thorfile +29 -0
  7. data/contrib/kameleon_bashrc.sh +61 -0
  8. data/contrib/polipo_env.sh +3 -2
  9. data/kameleon-builder.gemspec +3 -10
  10. data/lib/kameleon.rb +10 -14
  11. data/lib/kameleon/cli.rb +92 -105
  12. data/lib/kameleon/context.rb +76 -43
  13. data/lib/kameleon/engine.rb +147 -103
  14. data/lib/kameleon/environment.rb +10 -5
  15. data/lib/kameleon/error.rb +1 -32
  16. data/lib/kameleon/persistent_cache.rb +127 -29
  17. data/lib/kameleon/recipe.rb +63 -106
  18. data/lib/kameleon/shell.rb +32 -17
  19. data/lib/kameleon/step.rb +18 -1
  20. data/lib/kameleon/ui.rb +141 -0
  21. data/lib/kameleon/utils.rb +9 -0
  22. data/templates/{debian7-chroot.yaml → chroot/debian7-amd64.yaml} +29 -21
  23. data/templates/{docker-debian7.yaml → docker/debian7.yaml} +5 -5
  24. data/templates/extend.erb +2 -2
  25. data/templates/{debian7-g5k.yaml → grid5000/debian7.yaml} +1 -1
  26. data/templates/{archlinux-desktop.yaml → qemu/archlinux-desktop-i686.yaml} +2 -2
  27. data/templates/qemu/archlinux-desktop-x86_64.yaml +25 -0
  28. data/templates/qemu/archlinux-i686.yaml +25 -0
  29. data/templates/{archlinux.yaml → qemu/archlinux-x86_64.yaml} +37 -34
  30. data/templates/qemu/centos6.5-x86_64.yaml +113 -0
  31. data/templates/qemu/centos7-x86_64.yaml +119 -0
  32. data/templates/{debian7.yaml → qemu/debian7-amd64.yaml} +45 -40
  33. data/templates/{debian7-desktop.yaml → qemu/debian7-desktop-amd64.yaml} +2 -3
  34. data/templates/{debian7-kameleon.yaml → qemu/debian7-kameleon-amd64.yaml} +3 -6
  35. data/templates/{debian7-oar-dev.yaml → qemu/debian7-oar-amd64.yaml} +2 -2
  36. data/templates/qemu/debian8-amd64.yaml +25 -0
  37. data/templates/{fedora20-desktop.yaml → qemu/fedora20-desktop-x86_64.yaml} +2 -2
  38. data/templates/qemu/fedora20-x86_64.yaml +116 -0
  39. data/templates/{ubuntu-12.04.yaml → qemu/ubuntu-12.04-amd64.yaml} +42 -38
  40. data/templates/{ubuntu-12.04-desktop.yaml → qemu/ubuntu-12.04-desktop-amd64.yaml} +3 -3
  41. data/templates/{ubuntu-14.04.yaml → qemu/ubuntu-14.04-amd64.yaml} +2 -2
  42. data/templates/{ubuntu-14.04-desktop.yaml → qemu/ubuntu-14.04-desktop-amd64.yaml} +2 -2
  43. data/templates/steps/aliases/defaults.yaml +19 -13
  44. data/templates/steps/bootstrap/archlinux/arch_bootstrap.yaml +11 -19
  45. data/templates/steps/bootstrap/debian/debootstrap.yaml +10 -11
  46. data/templates/steps/bootstrap/debian/debootstrap_arm.yaml +11 -19
  47. data/templates/steps/bootstrap/fedora/init_pxeboot.yaml +13 -0
  48. data/templates/steps/bootstrap/fedora/yum_bootstrap.yaml +45 -0
  49. data/templates/steps/bootstrap/initialize_disk.yaml +16 -0
  50. data/templates/steps/bootstrap/initialize_disk_chroot.yaml +10 -14
  51. data/templates/steps/bootstrap/install_requirements.yaml +3 -0
  52. data/templates/steps/bootstrap/prepare_docker.yaml +7 -7
  53. data/templates/steps/bootstrap/prepare_qemu.yaml +20 -26
  54. data/templates/steps/bootstrap/prepare_virtualbox.yaml +63 -0
  55. data/templates/steps/bootstrap/start_chroot.yaml +2 -13
  56. data/templates/steps/bootstrap/start_qemu.yaml +50 -53
  57. data/templates/steps/bootstrap/start_virtualbox.yaml +37 -0
  58. data/templates/steps/bootstrap/switch_context_qemu.yaml +64 -0
  59. data/templates/steps/bootstrap/switch_context_virtualbox.yaml +66 -0
  60. data/templates/steps/breakpoint.yaml +2 -1
  61. data/templates/steps/checkpoints/docker.yaml +14 -11
  62. data/templates/steps/checkpoints/qcow2.yaml +26 -24
  63. data/templates/steps/checkpoints/qemu.yaml +30 -36
  64. data/templates/steps/checkpoints/virtualbox.yaml +21 -0
  65. data/templates/steps/disable_checkpoint.yaml +3 -0
  66. data/templates/steps/enable_checkpoint.yaml +5 -0
  67. data/templates/steps/export/qemu_save_appliance.yaml +52 -0
  68. data/templates/steps/export/virtualbox_save_appliance.yaml +67 -0
  69. data/templates/steps/setup/archlinux/install_bootloader.yaml +23 -0
  70. data/templates/steps/setup/centos/6.5/configure_network.yaml +31 -0
  71. data/templates/steps/setup/centos/6.5/configure_system.yaml +27 -0
  72. data/templates/steps/setup/debian/configure_apt.yaml +1 -6
  73. data/templates/steps/setup/debian/configure_kernel.yaml +0 -5
  74. data/templates/steps/setup/debian/install_bootloader.yaml +36 -0
  75. data/templates/steps/setup/debian/setup_vagrant_box.yaml +48 -18
  76. data/templates/steps/setup/debian/upgrade_system.yaml +2 -7
  77. data/templates/steps/setup/fedora/configure_kernel.yaml +9 -0
  78. data/templates/steps/setup/fedora/configure_keyboard.yaml +12 -0
  79. data/templates/steps/setup/fedora/configure_network.yaml +9 -1
  80. data/templates/steps/setup/fedora/configure_system.yaml +20 -45
  81. data/templates/steps/setup/fedora/install_bootloader.yaml +58 -0
  82. data/templates/steps/setup/fedora/minimal_install.yaml +3 -0
  83. data/templates/steps/setup/fedora/update_system.yaml +13 -5
  84. data/templates/steps/setup/ubuntu/configure_apt.yaml +4 -9
  85. data/templates/vagrant/debian7-amd64.yaml +130 -0
  86. data/templates/virtualbox/archlinux-desktop-i686.yaml +25 -0
  87. data/templates/virtualbox/archlinux-desktop-x86_64.yaml +28 -0
  88. data/templates/virtualbox/archlinux-i686.yaml +28 -0
  89. data/templates/virtualbox/archlinux-x86_64.yaml +109 -0
  90. data/templates/virtualbox/centos6.5-i386.yaml +39 -0
  91. data/templates/virtualbox/centos6.5-x86_64.yaml +111 -0
  92. data/templates/virtualbox/centos7-x86_64.yaml +116 -0
  93. data/{docs/source/debian7.yaml → templates/virtualbox/debian7-amd64.yaml} +53 -52
  94. data/templates/virtualbox/debian7-desktop-amd64.yaml +25 -0
  95. data/templates/{fedora-rawhide.yaml → virtualbox/debian7-i386.yaml} +12 -11
  96. data/templates/virtualbox/debian7-kameleon-amd64.yaml +38 -0
  97. data/templates/virtualbox/debian7-oar-amd64.yaml +51 -0
  98. data/templates/{debian-testing.yaml → virtualbox/debian8-amd64.yaml} +3 -3
  99. data/templates/virtualbox/debian8-i386.yaml +31 -0
  100. data/templates/virtualbox/fedora20-x86_64.yaml +116 -0
  101. data/templates/virtualbox/ubuntu-12.04-amd64.yaml +128 -0
  102. data/templates/virtualbox/ubuntu-12.04-desktop-amd64.yaml +25 -0
  103. data/templates/virtualbox/ubuntu-14.04-amd64.yaml +25 -0
  104. data/templates/virtualbox/ubuntu-14.04-desktop-amd64.yaml +27 -0
  105. data/version.txt +1 -1
  106. metadata +67 -212
  107. data/Rakefile +0 -24
  108. data/docs/.gitignore +0 -1
  109. data/docs/Makefile +0 -181
  110. data/docs/README.md +0 -17
  111. data/docs/make.bat +0 -242
  112. data/docs/source/_static/.gitignore +0 -0
  113. data/docs/source/_static/centos.png +0 -0
  114. data/docs/source/_static/debian.png +0 -0
  115. data/docs/source/_static/kameleon-logo.png +0 -0
  116. data/docs/source/_static/kameleon-logo.xcf +0 -0
  117. data/docs/source/_static/kameleon-long.png +0 -0
  118. data/docs/source/_static/ubuntu.png +0 -0
  119. data/docs/source/_themes/sphinx_rtd_theme/__init__.py +0 -17
  120. data/docs/source/_themes/sphinx_rtd_theme/breadcrumbs.html +0 -19
  121. data/docs/source/_themes/sphinx_rtd_theme/footer.html +0 -32
  122. data/docs/source/_themes/sphinx_rtd_theme/layout.html +0 -160
  123. data/docs/source/_themes/sphinx_rtd_theme/layout_old.html +0 -205
  124. data/docs/source/_themes/sphinx_rtd_theme/search.html +0 -50
  125. data/docs/source/_themes/sphinx_rtd_theme/searchbox.html +0 -7
  126. data/docs/source/_themes/sphinx_rtd_theme/static/css/badge_only.css +0 -1
  127. data/docs/source/_themes/sphinx_rtd_theme/static/css/theme.css +0 -4
  128. data/docs/source/_themes/sphinx_rtd_theme/static/fonts/FontAwesome.otf +0 -0
  129. data/docs/source/_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.eot +0 -0
  130. data/docs/source/_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.svg +0 -414
  131. data/docs/source/_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.ttf +0 -0
  132. data/docs/source/_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.woff +0 -0
  133. data/docs/source/_themes/sphinx_rtd_theme/static/js/theme.js +0 -47
  134. data/docs/source/_themes/sphinx_rtd_theme/theme.conf +0 -8
  135. data/docs/source/_themes/sphinx_rtd_theme/versions.html +0 -37
  136. data/docs/source/aliases.rst +0 -31
  137. data/docs/source/atlas_debian_g5k.yaml +0 -36
  138. data/docs/source/checkpoint.rst +0 -30
  139. data/docs/source/commands.rst +0 -63
  140. data/docs/source/conf.py +0 -262
  141. data/docs/source/context.rst +0 -47
  142. data/docs/source/debian_customized.yaml +0 -28
  143. data/docs/source/debian_customized_g5k.yaml +0 -21
  144. data/docs/source/faq.rst +0 -43
  145. data/docs/source/getting_started.rst +0 -260
  146. data/docs/source/grid5000_tutorial.rst +0 -525
  147. data/docs/source/index.rst +0 -53
  148. data/docs/source/install_atlas.yaml +0 -25
  149. data/docs/source/install_hpl.yaml +0 -24
  150. data/docs/source/installation.rst +0 -51
  151. data/docs/source/persistent_cache.rst +0 -34
  152. data/docs/source/recipe.rst +0 -177
  153. data/docs/source/tau_install.yaml +0 -19
  154. data/docs/source/tau_install_g5k.yaml +0 -25
  155. data/docs/source/use_cases.rst +0 -93
  156. data/docs/source/workspace.rst +0 -13
  157. data/lib/kameleon/logger.rb +0 -56
  158. data/omnibus/.gitignore +0 -11
  159. data/omnibus/.kitchen.yml +0 -25
  160. data/omnibus/Berksfile +0 -9
  161. data/omnibus/Berksfile.lock +0 -25
  162. data/omnibus/Gemfile +0 -12
  163. data/omnibus/README.md +0 -94
  164. data/omnibus/config/projects/kameleon.rb +0 -23
  165. data/omnibus/config/software/kameleon.rb +0 -24
  166. data/omnibus/config/software/polipo.rb +0 -30
  167. data/omnibus/config/software/ruby.rb +0 -158
  168. data/omnibus/files/mac_dmg/Resources/background.png +0 -0
  169. data/omnibus/files/mac_dmg/Resources/icon.png +0 -0
  170. data/omnibus/files/mac_pkg/Resources/background.png +0 -0
  171. data/omnibus/files/mac_pkg/Resources/license.html +0 -1
  172. data/omnibus/files/mac_pkg/Resources/welcome.html +0 -9
  173. data/omnibus/omnibus.rb +0 -27
  174. data/omnibus/package-scripts/kameleon/makeselfinst +0 -27
  175. data/omnibus/package-scripts/kameleon/postrm +0 -9
  176. data/templates/fedora20.yaml +0 -105
  177. data/templates/steps/bootstrap/archlinux/install_bootloader.yaml +0 -46
  178. data/templates/steps/bootstrap/archlinux/populate_disk.yaml +0 -39
  179. data/templates/steps/bootstrap/fedora/liveos_bootstrap.yaml +0 -123
  180. data/templates/steps/bootstrap/initialize_disk_qemu.yaml +0 -72
  181. data/templates/steps/bootstrap/install_bootloader.yaml +0 -42
  182. data/templates/steps/bootstrap/ubuntu/debootstrap.yaml +0 -27
  183. data/templates/steps/export/save_appliance.yaml +0 -58
  184. data/templates/steps/export/save_vagrant_box.yaml +0 -29
  185. data/templates/vagrant-debian7.yaml +0 -31
@@ -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
- @shell = Kameleon::Shell.new(@name, @cmd, @workdir, @local_workdir)
17
- @logger.debug("Initialize new ctx (#{name})")
18
- @log_on_progress = false
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
- @logger.debug(" #{v} = #{instance_variable_get(v)}")
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
- if @log_on_progress
29
- log_progress(log_level, out)
30
- @log_on_progress = false if out.match(/\n$/)
31
- else
32
- if out.match(/\n$/)
33
- out.split( /\r?\n/ ).each {|m| log(log_level, m) }
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
- @log_on_progress = true
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
- @logger.progress_info msg if log_level == "info"
49
- @logger.progress_error msg if log_level == "error"
50
- @logger.debug msg if log_level == "debug"
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
- lazyload_shell
68
+ load_shell
55
69
  cmd_with_prefix = "#{@exec_prefix} #{cmd}"
56
- cmd_with_prefix.split( /\r?\n/ ).each {|m| @logger.debug "+ #{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
- @logger.debug("Exit status : #{exit_status}")
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
- @logger.debug("Shell cmd failed to launch: #{@shell.shell_cmd}")
66
- raise ShellError, e.message + ". Check the cmd argument of the '#{@name}_context'."
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
- tmp = Tempfile.new("pipe-#{ Kameleon::Utils.generate_slug(cmd)[0..20] }")
71
- @logger.debug("Running piped commands")
72
- @logger.debug("Saving STDOUT from #{@name}_ctx to local file #{tmp.path}")
73
- execute(cmd, :stdout => tmp)
74
- tmp.close
75
- @logger.debug("Forwarding #{tmp.path} to STDIN of #{other_ctx.name}_ctx")
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 lazyload_shell()
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
- raise
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
- lazyload_shell
96
- @logger.info("Starting interactive shell")
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| @logger.error 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 reopen
111
- @shell.restart
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)
@@ -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 = !@recipe.checkpoint.nil? if @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
- #saving_steps_files
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
- @logger.notice("Creating kameleon working directory : #{@cwd}")
54
+ Kameleon.ui.info("Creating kameleon build directory : #{@cwd}")
49
55
  FileUtils.mkdir_p @cwd
50
56
  rescue
51
- raise BuildError, "Failed to create working directory #{@cwd}"
57
+ raise BuildError, "Failed to create build directory #{@cwd}"
52
58
  end
53
- @logger.notice("Building local context [local]")
54
- @local_context = Context.new("local", "bash", @cwd, "", @cwd)
55
- @logger.notice("Building external context [out]")
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
- @logger.notice("Building internal context [in]")
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
- if @options[:from_cache] then
68
- begin
69
- @cache.unpack(@options[:from_cache])
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
- @logger.notice("File #{file} loaded from the recipe")
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
- @logger.notice("Creating directory for cache #{step_name}")
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
- cmd = @recipe.checkpoint["create"].gsub("@microstep_id", microstep_id)
93
- create_cmd = Kameleon::Command.new({"exec_out" => cmd}, "checkpoint")
94
- safe_exec_cmd(create_cmd, :log_level => "debug")
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
- cmd = @recipe.checkpoint["apply"].gsub("@microstep_id", microstep_id)
99
- apply_cmd = Kameleon::Command.new({"exec_out" => cmd}, "checkpoint")
100
- safe_exec_cmd(apply_cmd, :log_level => "debug")
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
- cmd = Kameleon::Command.new({"exec_out" => @recipe.checkpoint['list']},
106
- "checkpoint")
107
- safe_exec_cmd(cmd, :stdout => list)
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) #unless @options[:from_cache]
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
- @logger.notice("Step #{ microstep.order } : #{ microstep.slug }")
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
- @logger.notice(" ---> Skipped")
165
+ Kameleon.ui.info("--> Skipped")
139
166
  next
140
167
  end
141
168
  if microstep.in_cache && microstep.on_checkpoint == "use_cache"
142
- @logger.notice(" ---> Using cache this time")
169
+ Kameleon.ui.info("--> Using checkpoint")
143
170
  else
144
- @logger.notice(" ---> Running step")
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
- @logger.notice(" ---> Creating checkpoint : #{ microstep.identifier }")
150
- create_checkpoint(microstep.identifier)
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
- @logger.notice(" ---> Running step")
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
- @logger.error("Invalid pipe arguments. Expected "\
197
- "#{expected_cmds} commands")
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
- exec_cmd(second_cmd)
245
+ safe_exec_cmd(second_cmd)
213
246
  end
214
247
  else
215
- @logger.warn("Unknown command : #{cmd.key}")
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.split( /\r?\n/ ).each {|m| @logger.error "#{m}" }
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| @logger.notice "#{m}" }
237
- @logger.progress_notice "answer ? [" + responses.keys().join("/") + "]: "
238
- answer = $stdin.gets
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
- @logger.notice("User choice : [#{answer}] #{responses[answer]}")
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
- @logger.notice("Getting back to Kameleon...")
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
- @logger.notice("Retrying the previous command...")
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
- map = {"exec_in" => @in_context,
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
- unless map[cmd.key].closed?
285
- begin
286
- exec_cmd(cmd)
287
- rescue
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
- @logger.notice("Restoring last build from step : #{@from_checkpoint}")
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
- @logger.error("Aborted...")
385
+ Kameleon.ui.error("Aborted...")
340
386
  elsif e.is_a?(SystemExit) || e.is_a?(Interrupt)
341
- @logger.error("Interrupted...")
342
- @out_context.reopen
343
- @in_context.reopen
344
- @local_context.reopen
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
- @logger.fatal("fatal error...")
392
+ Kameleon.ui.error("fatal error...")
347
393
  end
348
- @logger.warn("Waiting for cleanup before exiting...")
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
- if @enable_checkpoint
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?