boxgrinder-build 0.5.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,4 +1,9 @@
1
1
 
2
+ v0.6.0
3
+
4
+ * [BGBUILD-52] Wrong post section inheritance
5
+ * [BGBUILD-46] Allow building 32 bit images on 64 bit arch
6
+
2
7
  v0.5.1
3
8
 
4
9
  * [BGBUILD-40] Fix for running Augeas in Libguestfs
data/Manifest CHANGED
@@ -1,26 +0,0 @@
1
- CHANGELOG
2
- LICENSE
3
- Manifest
4
- README
5
- Rakefile
6
- bin/boxgrinder-build
7
- lib/boxgrinder-build/appliance.rb
8
- lib/boxgrinder-build/helpers/appliance-customize-helper.rb
9
- lib/boxgrinder-build/helpers/augeas-helper.rb
10
- lib/boxgrinder-build/helpers/guestfs-helper.rb
11
- lib/boxgrinder-build/helpers/linux-helper.rb
12
- lib/boxgrinder-build/helpers/package-helper.rb
13
- lib/boxgrinder-build/helpers/plugin-helper.rb
14
- lib/boxgrinder-build/managers/plugin-manager.rb
15
- lib/boxgrinder-build/plugins/base-plugin.rb
16
- spec/Rakefile
17
- spec/appliance-spec.rb
18
- spec/helpers/appliance-customize-helper-spec.rb
19
- spec/helpers/augeas-helper-spec.rb
20
- spec/helpers/guestfs-helper-spec.rb
21
- spec/helpers/linux-helper-spec.rb
22
- spec/helpers/package-helper-spec.rb
23
- spec/helpers/plugin-helper-spec.rb
24
- spec/managers/plugin-manager-spec.rb
25
- spec/plugins/base-plugin-spec.rb
26
- spec/rspec/src/appliances/jeos-f13.appl
data/Rakefile CHANGED
@@ -4,8 +4,8 @@ Echoe.new("boxgrinder-build") do |p|
4
4
  p.project = "BoxGrinder Build"
5
5
  p.author = "Marek Goldmann"
6
6
  p.summary = "A tool for creating appliances from simple plain text files for various virtual environments."
7
- p.url = "http://www.jboss.org/stormgrind/projects/boxgrinder.html"
7
+ p.url = "http://www.jboss.org/boxgrinder"
8
8
  p.email = "info@boxgrinder.org"
9
9
  p.ignore_pattern = /^(pkg|doc)|\.svn|CVS|\.bzr|\.DS|\.git|\.log/
10
- p.runtime_dependencies = ["commander ~>4.0.3", "boxgrinder-core ~>0.0.22"]
11
- end
10
+ p.runtime_dependencies = ["commander ~>4.0.3", "boxgrinder-core ~>0.1.0"]
11
+ end
data/bin/boxgrinder-build CHANGED
@@ -21,14 +21,13 @@
21
21
  # 02110-1301 USA, or see the FSF site: http://www.fsf.org.
22
22
 
23
23
  require 'rubygems'
24
- require 'boxgrinder-core/helpers/log-helper'
25
- require 'boxgrinder-build/managers/plugin-manager'
26
- require 'boxgrinder-build/helpers/plugin-helper'
27
- require 'boxgrinder-build/appliance'
28
24
 
29
- gem 'boxgrinder-core', '>= 0.0.20'
25
+ gem 'boxgrinder-core', '>= 0.1.0'
30
26
  gem 'commander', '>= 4.0.3'
31
27
 
28
+ require 'boxgrinder-core/helpers/log-helper'
29
+ require 'boxgrinder-build/appliance'
30
+
32
31
  #$stderr.reopen($stdout)
33
32
 
34
33
  if Process.uid != 0
@@ -39,9 +38,9 @@ end
39
38
  require 'commander/import'
40
39
 
41
40
  program :name, 'BoxGrinder Build'
42
- program :version, '0.5.1'
41
+ program :version, '0.6.0'
43
42
  program :description, "A tool for building VM images from simple definition files."
44
- program :help, 'Hompepage', 'http://www.jboss.org/stormgrind/projects/boxgrinder/build.html'
43
+ program :help, 'Homepage', 'http://www.jboss.org/boxgrinder/build.html'
45
44
  program :help, 'Documentation', 'http://community.jboss.org/docs/DOC-14358'
46
45
  program :help, 'Examples', "Run 'boxgrinder-build -h build' for more info about syntax."
47
46
  default_command :build
@@ -49,7 +48,7 @@ default_command :build
49
48
  $log_level = :info
50
49
 
51
50
  global_option('-V', '--verbose', TrueClass, "Prints debug information while building. Default: false.") { $log_level = :debug}
52
- global_option('-W', '--veryverbose', TrueClass, "Prints trace information while building. Default: false.") { $log_level = :trace}
51
+ global_option('-W', '--very-verbose', TrueClass, "Prints trace information while building. Default: false.") { $log_level = :trace}
53
52
 
54
53
  module BoxGrinder
55
54
  command :build do |c|
@@ -77,15 +76,7 @@ module BoxGrinder
77
76
 
78
77
  raise "Appliance definition file '#{appliance_definition_file}' could not be found" unless File.exists?( appliance_definition_file )
79
78
 
80
- log = LogHelper.new( :threshold => $log_level )
81
-
82
- PluginHelper.new( :options => options, :log => log ).load_plugins
83
- PluginManager.instance.log = log
84
-
85
- raise "Not known platform: #{options.platform}. #{PluginManager.instance.plugins[:platform].empty? ? 'There are no platform plugins, please install one or more.' : "Available types: #{PluginManager.instance.plugin_types( :platform ).join(', ')}."}" if PluginManager.instance.plugins[:platform][options.platform].nil? and options.platform != :none
86
- raise "Not known delivery type: #{options.delivery}. #{PluginManager.instance.plugins[:delivery].empty? ? 'There are no delivery plugins, please install one or more.' : "Available types: #{PluginManager.instance.plugin_types( :delivery ).join(', ')}."}" if PluginManager.instance.plugin_types( :delivery ).include?(options.delivery).nil? and options.delivery != :none
87
-
88
- Appliance.new( appliance_definition_file, :options => options, :log => log ).create
79
+ Appliance.new( appliance_definition_file, :options => options, :log => LogHelper.new( :threshold => $log_level ) ).create
89
80
  end
90
81
  end
91
82
  end
@@ -2,37 +2,37 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{boxgrinder-build}
5
- s.version = "0.5.1"
5
+ s.version = "0.6.0"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Marek Goldmann"]
9
- s.date = %q{2010-08-23}
9
+ s.date = %q{2010-10-12}
10
10
  s.default_executable = %q{boxgrinder-build}
11
11
  s.description = %q{A tool for creating appliances from simple plain text files for various virtual environments.}
12
12
  s.email = %q{info@boxgrinder.org}
13
13
  s.executables = ["boxgrinder-build"]
14
- s.extra_rdoc_files = ["CHANGELOG", "LICENSE", "README", "bin/boxgrinder-build", "lib/boxgrinder-build/appliance.rb", "lib/boxgrinder-build/helpers/appliance-customize-helper.rb", "lib/boxgrinder-build/helpers/augeas-helper.rb", "lib/boxgrinder-build/helpers/guestfs-helper.rb", "lib/boxgrinder-build/helpers/linux-helper.rb", "lib/boxgrinder-build/helpers/package-helper.rb", "lib/boxgrinder-build/helpers/plugin-helper.rb", "lib/boxgrinder-build/managers/plugin-manager.rb", "lib/boxgrinder-build/plugins/base-plugin.rb"]
15
- s.files = ["CHANGELOG", "LICENSE", "Manifest", "README", "Rakefile", "bin/boxgrinder-build", "lib/boxgrinder-build/appliance.rb", "lib/boxgrinder-build/helpers/appliance-customize-helper.rb", "lib/boxgrinder-build/helpers/augeas-helper.rb", "lib/boxgrinder-build/helpers/guestfs-helper.rb", "lib/boxgrinder-build/helpers/linux-helper.rb", "lib/boxgrinder-build/helpers/package-helper.rb", "lib/boxgrinder-build/helpers/plugin-helper.rb", "lib/boxgrinder-build/managers/plugin-manager.rb", "lib/boxgrinder-build/plugins/base-plugin.rb", "spec/Rakefile", "spec/appliance-spec.rb", "spec/helpers/appliance-customize-helper-spec.rb", "spec/helpers/augeas-helper-spec.rb", "spec/helpers/guestfs-helper-spec.rb", "spec/helpers/linux-helper-spec.rb", "spec/helpers/package-helper-spec.rb", "spec/helpers/plugin-helper-spec.rb", "spec/managers/plugin-manager-spec.rb", "spec/plugins/base-plugin-spec.rb", "spec/rspec/src/appliances/jeos-f13.appl", "boxgrinder-build.gemspec"]
16
- s.homepage = %q{http://www.jboss.org/stormgrind/projects/boxgrinder.html}
14
+ s.extra_rdoc_files = ["CHANGELOG", "LICENSE", "README", "bin/boxgrinder-build", "lib/boxgrinder-build/appliance.rb", "lib/boxgrinder-build/helpers/appliance-customize-helper.rb", "lib/boxgrinder-build/helpers/augeas-helper.rb", "lib/boxgrinder-build/helpers/guestfs-helper.rb", "lib/boxgrinder-build/helpers/image-helper.rb", "lib/boxgrinder-build/helpers/linux-helper.rb", "lib/boxgrinder-build/helpers/package-helper.rb", "lib/boxgrinder-build/helpers/plugin-helper.rb", "lib/boxgrinder-build/managers/plugin-manager.rb", "lib/boxgrinder-build/plugins/base-plugin.rb"]
15
+ s.files = ["CHANGELOG", "LICENSE", "Manifest", "README", "Rakefile", "bin/boxgrinder-build", "lib/boxgrinder-build/appliance.rb", "lib/boxgrinder-build/helpers/appliance-customize-helper.rb", "lib/boxgrinder-build/helpers/augeas-helper.rb", "lib/boxgrinder-build/helpers/guestfs-helper.rb", "lib/boxgrinder-build/helpers/image-helper.rb", "lib/boxgrinder-build/helpers/linux-helper.rb", "lib/boxgrinder-build/helpers/package-helper.rb", "lib/boxgrinder-build/helpers/plugin-helper.rb", "lib/boxgrinder-build/managers/plugin-manager.rb", "lib/boxgrinder-build/plugins/base-plugin.rb", "spec/Rakefile", "spec/appliance-spec.rb", "spec/helpers/appliance-customize-helper-spec.rb", "spec/helpers/augeas-helper-spec.rb", "spec/helpers/guestfs-helper-spec.rb", "spec/helpers/image-helper-spec.rb", "spec/helpers/linux-helper-spec.rb", "spec/helpers/package-helper-spec.rb", "spec/helpers/plugin-helper-spec.rb", "spec/managers/plugin-manager-spec.rb", "spec/plugins/base-plugin-spec.rb", "spec/rspec/src/appliances/jeos-f13.appl", "boxgrinder-build.gemspec"]
16
+ s.homepage = %q{http://www.jboss.org/boxgrinder}
17
17
  s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Boxgrinder-build", "--main", "README"]
18
18
  s.require_paths = ["lib"]
19
19
  s.rubyforge_project = %q{BoxGrinder Build}
20
- s.rubygems_version = %q{1.3.6}
20
+ s.rubygems_version = %q{1.3.7}
21
21
  s.summary = %q{A tool for creating appliances from simple plain text files for various virtual environments.}
22
22
 
23
23
  if s.respond_to? :specification_version then
24
24
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
25
25
  s.specification_version = 3
26
26
 
27
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
27
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
28
28
  s.add_runtime_dependency(%q<commander>, ["~> 4.0.3"])
29
- s.add_runtime_dependency(%q<boxgrinder-core>, ["~> 0.0.22"])
29
+ s.add_runtime_dependency(%q<boxgrinder-core>, ["~> 0.1.0"])
30
30
  else
31
31
  s.add_dependency(%q<commander>, ["~> 4.0.3"])
32
- s.add_dependency(%q<boxgrinder-core>, ["~> 0.0.22"])
32
+ s.add_dependency(%q<boxgrinder-core>, ["~> 0.1.0"])
33
33
  end
34
34
  else
35
35
  s.add_dependency(%q<commander>, ["~> 4.0.3"])
36
- s.add_dependency(%q<boxgrinder-core>, ["~> 0.0.22"])
36
+ s.add_dependency(%q<boxgrinder-core>, ["~> 0.1.0"])
37
37
  end
38
38
  end
@@ -22,6 +22,8 @@ require 'boxgrinder-core/models/appliance-config'
22
22
  require 'boxgrinder-core/models/config'
23
23
  require 'boxgrinder-core/helpers/appliance-helper'
24
24
  require 'boxgrinder-core/helpers/appliance-config-helper'
25
+ require 'boxgrinder-build/helpers/plugin-helper'
26
+ require 'boxgrinder-build/managers/plugin-manager'
25
27
  require 'boxgrinder-core/validators/appliance-config-validator'
26
28
 
27
29
  module BoxGrinder
@@ -38,19 +40,23 @@ module BoxGrinder
38
40
  @config.version.release = nil
39
41
  end
40
42
 
41
- def create
43
+ def read_and_validate_definition
42
44
  appliance_configs, appliance_config = ApplianceHelper.new( :log => @log ).read_definitions( @appliance_definition_file )
43
45
  appliance_config_helper = ApplianceConfigHelper.new( appliance_configs )
44
46
 
45
47
  @appliance_config = appliance_config_helper.merge(appliance_config.clone.init_arch).initialize_paths
46
48
 
47
- ApplianceConfigValidator.new( @appliance_config, :os_plugins => PluginManager.instance.plugins[:os] ).validate
49
+ ApplianceConfigValidator.new( @appliance_config ).validate
50
+ end
48
51
 
49
- if @options.force
50
- @log.info "Removing previous builds for #{@appliance_config.name} appliance..."
51
- FileUtils.rm_rf( @appliance_config.path.build )
52
- @log.debug "Previous builds removed."
53
- end
52
+ def remove_old_builds
53
+ @log.info "Removing previous builds for #{@appliance_config.name} appliance..."
54
+ FileUtils.rm_rf( @appliance_config.path.build )
55
+ @log.debug "Previous builds removed."
56
+ end
57
+
58
+ def execute_plugin_chain
59
+ @log.info "Building '#{@appliance_config.name}' appliance for #{@appliance_config.hardware.arch} architecture."
54
60
 
55
61
  base_plugin_output = execute_os_plugin
56
62
  platform_plugin_output = execute_platform_plugin( base_plugin_output )
@@ -58,7 +64,17 @@ module BoxGrinder
58
64
  execute_delivery_plugin( platform_plugin_output )
59
65
  end
60
66
 
67
+ def create
68
+ PluginHelper.new( :options => @options, :log => @log ).load_plugins
69
+
70
+ read_and_validate_definition
71
+ remove_old_builds if @options.force
72
+ execute_plugin_chain
73
+ end
74
+
61
75
  def execute_os_plugin
76
+ raise "No operating system plugins installed. Install one or more operating system plugin. See http://community.jboss.org/docs/DOC-15081 and http://community.jboss.org/docs/DOC-15214 for more info" if PluginManager.instance.plugins[:os].empty?
77
+
62
78
  os_plugin, os_plugin_info = PluginManager.instance.initialize_plugin(:os, @appliance_config.os.name.to_sym )
63
79
  os_plugin.init( @config, @appliance_config, :log => @log, :plugin_info => os_plugin_info )
64
80
 
@@ -80,6 +96,8 @@ module BoxGrinder
80
96
  return previous_plugin_output
81
97
  end
82
98
 
99
+ raise "No platform plugins installed. Install one or more platform plugin. See http://community.jboss.org/docs/DOC-15081 and http://community.jboss.org/docs/DOC-15214 for more info" if PluginManager.instance.plugins[:platform].empty?
100
+
83
101
  platform_plugin, platform_plugin_info = PluginManager.instance.initialize_plugin(:platform, @options.platform )
84
102
  platform_plugin.init( @config, @appliance_config, :log => @log, :plugin_info => platform_plugin_info, :previous_plugin_info => previous_plugin_output[:plugin_info], :previous_deliverables => previous_plugin_output[:deliverables] )
85
103
 
@@ -101,6 +119,8 @@ module BoxGrinder
101
119
  return
102
120
  end
103
121
 
122
+ raise "No delivery plugins installed. Install one or more delivery plugin. See http://community.jboss.org/docs/DOC-15081 and http://community.jboss.org/docs/DOC-15214 for more info" if PluginManager.instance.plugins[:delivery].empty?
123
+
104
124
  delivery_plugin, delivery_plugin_info = PluginManager.instance.initialize_plugin(:delivery, @options.delivery )
105
125
  delivery_plugin.init( @config, @appliance_config, :log => @log, :plugin_info => delivery_plugin_info, :previous_plugin_info => previous_plugin_output[:plugin_info], :previous_deliverables => previous_plugin_output[:deliverables] )
106
126
 
@@ -0,0 +1,123 @@
1
+ # JBoss, Home of Professional Open Source
2
+ # Copyright 2009, Red Hat Middleware LLC, and individual contributors
3
+ # by the @authors tag. See the copyright.txt in the distribution for a
4
+ # full listing of individual contributors.
5
+ #
6
+ # This is free software; you can redistribute it and/or modify it
7
+ # under the terms of the GNU Lesser General Public License as
8
+ # published by the Free Software Foundation; either version 2.1 of
9
+ # the License, or (at your option) any later version.
10
+ #
11
+ # This software is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
+ # Lesser General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Lesser General Public
17
+ # License along with this software; if not, write to the Free
18
+ # Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19
+ # 02110-1301 USA, or see the FSF site: http://www.fsf.org.
20
+
21
+ require 'fileutils'
22
+ require 'boxgrinder-build/helpers/guestfs-helper'
23
+
24
+ module BoxGrinder
25
+ class ImageHelper
26
+ def initialize(options = {})
27
+ @log = options[:log] || Logger.new(STDOUT)
28
+ @exec_helper = options[:exec_helper] || ExecHelper.new(:log => @log)
29
+ end
30
+
31
+ def mount_image(disk, mount_dir)
32
+ offsets = calculate_disk_offsets(disk)
33
+
34
+ @log.debug "Mounting image #{File.basename(disk)} in #{mount_dir}..."
35
+ FileUtils.mkdir_p(mount_dir)
36
+
37
+ mounts = {}
38
+
39
+ offsets.each do |offset|
40
+ loop_device = get_loop_device
41
+ @exec_helper.execute("losetup -o #{offset.to_s} #{loop_device} #{disk}")
42
+ label = @exec_helper.execute("e2label #{loop_device}").strip.chomp.gsub('_', '')
43
+ label = '/' if label == ''
44
+ mounts[label] = loop_device
45
+ end
46
+
47
+ @exec_helper.execute("mount #{mounts['/']} -t #{get_filesystem_type(mounts['/'])} #{mount_dir}")
48
+
49
+ mounts.reject { |key, value| key == '/' }.each do |mount_point, loop_device|
50
+ @exec_helper.execute("mount #{loop_device} -t #{get_filesystem_type(loop_device)} #{mount_dir}#{mount_point}")
51
+ end
52
+
53
+ @log.trace "Mounts:\n#{mounts}"
54
+
55
+ mounts
56
+ end
57
+
58
+ def get_filesystem_type(device, default_type = 'ext3')
59
+ fs_type = @exec_helper.execute("df -T #{device} | tail -1 | awk '{print $2}'")
60
+ return default_type if fs_type.empty? or fs_type == '-'
61
+ fs_type
62
+ end
63
+
64
+ def umount_image(disk, mount_dir, mounts)
65
+ @log.debug "Unmounting image '#{File.basename(disk)}'..."
66
+
67
+ mounts.each { |mount_point, loop_device| @exec_helper.execute("umount -d #{loop_device}") unless mount_point == '/' }
68
+
69
+ @exec_helper.execute("umount -d #{mounts['/']}")
70
+
71
+ FileUtils.rm_rf(mount_dir)
72
+ end
73
+
74
+ def get_loop_device
75
+ begin
76
+ loop_device = @exec_helper.execute("losetup -f 2>&1").strip
77
+ rescue
78
+ raise "No free loop devices available, please free at least one. See 'losetup -d' command."
79
+ end
80
+
81
+ loop_device
82
+ end
83
+
84
+ def calculate_disk_offsets(disk)
85
+ @log.debug "Calculating offsets for '#{File.basename(disk)}' disk..."
86
+ loop_device = get_loop_device
87
+
88
+ @exec_helper.execute("losetup #{loop_device} #{disk}")
89
+ offsets = @exec_helper.execute("parted #{loop_device} 'unit B print' | grep -e '^ [0-9]' | awk '{ print $2 }'").scan(/\d+/)
90
+ @exec_helper.execute("losetup -d #{loop_device}")
91
+
92
+ @log.trace "Offsets:\n#{offsets}"
93
+
94
+ offsets
95
+ end
96
+
97
+ def create_disk(disk, size)
98
+ @log.trace "Preparing disk..."
99
+ @exec_helper.execute "dd if=/dev/zero of=#{disk} bs=1 count=0 seek=#{size * 1024}M"
100
+ @log.trace "Disk prepared"
101
+ end
102
+
103
+ def create_filesystem(disk, options = {})
104
+ options = {:type => 'ext3', :label => '/'}.merge(options)
105
+
106
+ @log.trace "Creating filesystem..."
107
+ @exec_helper.execute "mke2fs -T #{options[:type]} -L '#{options[:label]}' -F #{disk}"
108
+ @log.trace "Filesystem created"
109
+ end
110
+
111
+ def sync_files(from_dir, to_dir)
112
+ @log.debug "Syncing files between #{from_dir} and #{to_dir}..."
113
+ @exec_helper.execute "rsync -u -r -a #{from_dir}/* #{to_dir}"
114
+ @log.debug "Sync finished."
115
+ end
116
+
117
+ def customize(disk_path)
118
+ GuestFSHelper.new(disk_path, :log => @log).customize do |guestfs, guestfs_helper|
119
+ yield guestfs, guestfs_helper
120
+ end
121
+ end
122
+ end
123
+ end
@@ -54,7 +54,7 @@ module BoxGrinder
54
54
  end
55
55
 
56
56
  def read_and_require
57
- plugins = %w(boxgrinder-build-fedora-os-plugin boxgrinder-build-rhel-os-plugin boxgrinder-build-centos-os-plugin boxgrinder-build-ec2-platform-plugin boxgrinder-build-vmware-platform-plugin boxgrinder-build-s3-delivery-plugin boxgrinder-build-sftp-delivery-plugin boxgrinder-build-local-delivery-plugin) + parse_plugin_list
57
+ plugins = %w(boxgrinder-build-fedora-os-plugin boxgrinder-build-rhel-os-plugin boxgrinder-build-centos-os-plugin boxgrinder-build-ec2-platform-plugin boxgrinder-build-vmware-platform-plugin boxgrinder-build-s3-delivery-plugin boxgrinder-build-sftp-delivery-plugin boxgrinder-build-local-delivery-plugin boxgrinder-build-ebs-delivery-plugin) + parse_plugin_list
58
58
 
59
59
  plugins.flatten.each do |plugin|
60
60
  @log.trace "Requiring plugin '#{plugin}'..."
@@ -93,6 +93,5 @@ module BoxGrinder
93
93
  end
94
94
 
95
95
  attr_reader :plugins
96
- attr_accessor :log
97
96
  end
98
97
  end
@@ -19,7 +19,7 @@
19
19
  # 02110-1301 USA, or see the FSF site: http://www.fsf.org.
20
20
 
21
21
  require 'boxgrinder-core/helpers/exec-helper'
22
- require 'boxgrinder-build/helpers/guestfs-helper'
22
+ require 'boxgrinder-build/helpers/image-helper'
23
23
  require 'ostruct'
24
24
  require 'openhash/openhash'
25
25
  require 'fileutils'
@@ -34,6 +34,7 @@ module BoxGrinder
34
34
 
35
35
  @log = options[:log] || Logger.new(STDOUT)
36
36
  @exec_helper = options[:exec_helper] || ExecHelper.new( :log => @log )
37
+ @image_helper = options[:image_helper] || ImageHelper.new( :log => @log )
37
38
 
38
39
  @plugin_info = options[:plugin_info]
39
40
  @previous_plugin_info = options[:previous_plugin_info]
@@ -42,6 +43,7 @@ module BoxGrinder
42
43
  @plugin_config = {}
43
44
 
44
45
  @deliverables = OpenHash.new
46
+ @supported_oses = OpenHash.new
45
47
  @target_deliverables = OpenHash.new
46
48
  @dir = OpenHash.new
47
49
 
@@ -69,6 +71,29 @@ module BoxGrinder
69
71
  end
70
72
  end
71
73
 
74
+ def register_supported_os( name, versions )
75
+ raise "You can register supported operating system only after the plugin is initialized, please initialize the plugin using init method." if @initialized.nil?
76
+
77
+ @supported_oses[name] = OpenHash.new if @supported_oses[name].nil?
78
+ @supported_oses[name] = versions
79
+ end
80
+
81
+ def is_supported_os?
82
+ return false unless !@supported_oses[@appliance_config.os.name].nil? and @supported_oses[@appliance_config.os.name].include?(@appliance_config.os.version)
83
+ true
84
+ end
85
+
86
+ def supported_oses
87
+ supported = ""
88
+
89
+ @supported_oses.each do |name, versions|
90
+ supported << ", " unless supported.empty?
91
+ supported << "#{name} (versions: #{versions.join(", ")})"
92
+ end
93
+
94
+ supported
95
+ end
96
+
72
97
  def validate_plugin_config(fields = [], doc = nil)
73
98
  more_info = doc.nil? ? '' : "See #{doc} for more info"
74
99
 
@@ -135,16 +160,7 @@ module BoxGrinder
135
160
  begin
136
161
  @plugin_config = YAML.load_file(@config_file)
137
162
  rescue
138
- raise "An error occurred while reading configuration file #{@config_file} for #{self.class.name}. Is it a valid YAML file?"
139
- end
140
- end
141
-
142
- # TODO consider removing this from BasePlugin and moving to another base class
143
- def customize( disk_path )
144
- raise "Customizing cannot be started until the plugin isn't initialized" if @initialized.nil?
145
-
146
- GuestFSHelper.new( disk_path, :log => @log ).customize do |guestfs, guestfs_helper|
147
- yield guestfs, guestfs_helper
163
+ raise "An error occurred while reading configuration file '#{@config_file}' for #{self.class.name}. Is it a valid YAML file?"
148
164
  end
149
165
  end
150
166
  end
@@ -1,6 +1,5 @@
1
1
  require 'boxgrinder-build/appliance'
2
2
  require 'rspec/rspec-config-helper'
3
- require 'rbconfig'
4
3
  require 'ostruct'
5
4
 
6
5
  module BoxGrinder
@@ -8,188 +7,185 @@ module BoxGrinder
8
7
  include RSpecConfigHelper
9
8
 
10
9
  before(:all) do
11
- @arch = RbConfig::CONFIG['host_cpu']
10
+ @arch = `uname -m`.chomp.strip
12
11
  end
13
12
 
14
13
  def prepare_appliance( options = OpenStruct.new )
15
14
  options.name = 'boxgrinder'
16
15
  options.version = '1.0'
17
16
 
18
- @appliance = Appliance.new( "#{File.dirname( __FILE__ )}/rspec/src/appliances/jeos-f13.appl", :log => Logger.new('/dev/null'), :options => options )
17
+ @options = options
18
+ @log = Logger.new('/dev/null')
19
+
20
+ @plugin_manager = mock( PluginManager )
21
+
22
+ PluginManager.stub!(:instance).and_return( @plugin_manager )
23
+
24
+ @appliance = Appliance.new( "#{File.dirname( __FILE__ )}/rspec/src/appliances/jeos-f13.appl", :log => @log, :options => @options )
19
25
  end
20
26
 
21
27
  before(:each) do
22
28
  prepare_appliance
23
29
  end
24
30
 
25
- it "should create only base image" do
26
- validator = mock(ApplianceConfigValidator)
27
- validator.should_receive(:validate)
28
-
29
- ApplianceConfigValidator.should_receive(:new).with(any_args).and_return(validator)
30
-
31
- plugin_manager_first_call = mock('PluginManagerOne')
32
- plugin_manager_first_call.should_receive(:plugins).and_return({})
31
+ it "should prepare appliance to build" do
32
+ plugin_helper = mock(PluginHelper)
33
+ plugin_helper.should_receive(:load_plugins)
33
34
 
34
- PluginManager.should_receive(:instance).and_return(plugin_manager_first_call)
35
-
36
- os_plugin = mock('OS Plugin')
37
- os_plugin.should_receive(:init)
38
- os_plugin.should_receive(:deliverables_exists?).and_return(false)
39
- os_plugin.should_receive(:run)
40
- os_plugin.should_receive(:deliverables).and_return({ :disk => 'abc'})
35
+ PluginHelper.should_receive( :new ).with( :options => @options, :log => @log ).and_return( plugin_helper )
41
36
 
42
- plugin_manager_second_call = mock('PluginManagerTwo')
43
- plugin_manager_second_call.should_receive(:initialize_plugin).with(:os, :fedora).and_return([ os_plugin, {:class => Appliance, :type => :os, :name => :fedora, :full_name => "Fedora", :versions => ["11", "12", "13", "rawhide"] } ] )
44
-
45
- PluginManager.should_receive(:instance).and_return(plugin_manager_second_call)
37
+ @appliance.should_receive(:read_and_validate_definition)
38
+ @appliance.should_not_receive(:remove_old_builds)
39
+ @appliance.should_receive(:execute_plugin_chain)
46
40
 
47
41
  @appliance.create
48
42
  end
49
43
 
50
- it "should build appliance and convert it to VMware format" do
51
- prepare_appliance( OpenStruct.new({ :platform => :vmware }) )
52
-
53
- validator = mock(ApplianceConfigValidator)
54
- validator.should_receive(:validate)
55
-
56
- ApplianceConfigValidator.should_receive(:new).with(any_args).and_return(validator)
57
-
58
- os_plugin_output = {}
59
-
60
- @appliance.should_receive(:execute_os_plugin).and_return(os_plugin_output)
61
-
62
- plugin_manager_first_call = mock('PluginManagerOne')
63
- plugin_manager_first_call.should_receive(:plugins).and_return({})
64
-
65
- PluginManager.should_receive(:instance).and_return(plugin_manager_first_call)
44
+ it "should prepare appliance to build with removing old files" do
45
+ prepare_appliance( OpenStruct.new( :force => true ) )
66
46
 
67
- platform_plugin = mock('VMware Plugin')
68
- platform_plugin.should_receive(:init)
69
- platform_plugin.should_receive(:deliverables_exists?).and_return(false)
70
- platform_plugin.should_receive(:run)
71
- platform_plugin.should_receive(:deliverables).and_return({ :disk => 'abc'})
47
+ plugin_helper = mock(PluginHelper)
48
+ plugin_helper.should_receive(:load_plugins)
72
49
 
73
- plugin_manager_second_call = mock('PluginManagerTwo')
74
- plugin_manager_second_call.should_receive(:initialize_plugin).with(:platform, :vmware).and_return([ platform_plugin, {:class => Appliance, :type => :platform, :name => :vmware, :full_name => "VMware"} ] )
50
+ PluginHelper.should_receive( :new ).with( :options => @options, :log => @log ).and_return( plugin_helper )
75
51
 
76
- PluginManager.should_receive(:instance).and_return(plugin_manager_second_call)
52
+ @appliance.should_receive(:read_and_validate_definition)
53
+ @appliance.should_receive(:remove_old_builds)
54
+ @appliance.should_receive(:execute_plugin_chain)
77
55
 
78
56
  @appliance.create
79
57
  end
80
58
 
81
- it "should build appliance, convert it to EC2 format and deliver it using S3 ami type" do
82
- prepare_appliance( OpenStruct.new({ :platform => :ec2, :delivery => :ami }) )
59
+ it "should read and validate definition" do
60
+ appliance_config = ApplianceConfig.new
83
61
 
84
- validator = mock(ApplianceConfigValidator)
85
- validator.should_receive(:validate)
62
+ appliance_helper = mock(ApplianceHelper)
63
+ appliance_helper.should_receive(:read_definitions).with( "#{File.dirname( __FILE__ )}/rspec/src/appliances/jeos-f13.appl" ).and_return([{}, appliance_config])
86
64
 
87
- ApplianceConfigValidator.should_receive(:new).with(any_args).and_return(validator)
65
+ ApplianceHelper.should_receive(:new).with( :log => @log ).and_return(appliance_helper)
88
66
 
89
- os_plugin_output = { :abc => 'def'}
90
- platform_plugin_output = { :abc => 'def'}
67
+ appliance_config_helper = mock(ApplianceConfigHelper)
91
68
 
92
- @appliance.should_receive(:execute_os_plugin).and_return(os_plugin_output)
93
- @appliance.should_receive(:execute_platform_plugin).and_return(platform_plugin_output)
69
+ appliance_config.should_receive(:clone).and_return(appliance_config)
70
+ appliance_config.should_receive(:init_arch).and_return(appliance_config)
71
+ appliance_config.should_receive(:initialize_paths).and_return(appliance_config)
94
72
 
95
- plugin_manager_first_call = mock('PluginManagerOne')
96
- plugin_manager_first_call.should_receive(:plugins).and_return({})
73
+ appliance_config_helper.should_receive(:merge).with( appliance_config ).and_return( appliance_config )
97
74
 
98
- PluginManager.should_receive(:instance).and_return(plugin_manager_first_call)
99
-
100
- delivery_plugin = mock('S3 Plugin')
101
- delivery_plugin.should_receive(:init)
102
- delivery_plugin.should_receive(:run).with(:ami)
75
+ ApplianceConfigHelper.should_receive(:new).with( {} ).and_return( appliance_config_helper )
103
76
 
104
- plugin_manager_second_call = mock('PluginManagerTwo')
105
- plugin_manager_second_call.should_receive(:initialize_plugin).with(:delivery, :ami).and_return([ delivery_plugin, {:class => Appliance, :type => :delivery, :name => :s3, :full_name => "Amazon Simple Storage Service (Amazon S3)", :types => [:s3, :cloudfront, :ami]} ] )
77
+ appliance_config_validator = mock(ApplianceConfigValidator)
78
+ appliance_config_validator.should_receive(:validate)
106
79
 
107
- PluginManager.should_receive(:instance).and_return(plugin_manager_second_call)
80
+ ApplianceConfigValidator.should_receive(:new).with( appliance_config ).and_return(appliance_config_validator)
108
81
 
109
- @appliance.create
82
+ @appliance.read_and_validate_definition
110
83
  end
111
- it "should build appliance, convert it to vmware format and deliver it using sftp ami type" do
112
- prepare_appliance( OpenStruct.new({ :platform => :vmware, :delivery => :sftp }) )
113
84
 
114
- validator = mock(ApplianceConfigValidator)
115
- validator.should_receive(:validate)
116
-
117
- ApplianceConfigValidator.should_receive(:new).with(any_args).and_return(validator)
85
+ it "should remove old builds" do
86
+ @appliance.instance_variable_set(:@appliance_config, generate_appliance_config )
87
+ FileUtils.should_receive(:rm_rf).with("build/appliances/#{@arch}/fedora/11/full")
88
+ @appliance.remove_old_builds
89
+ end
118
90
 
119
- os_plugin_output = { :abc => 'def'}
120
- platform_plugin_output = { :abc => 'def'}
91
+ it "should build base appliance" do
92
+ @appliance.instance_variable_set(:@appliance_config, generate_appliance_config )
121
93
 
122
- @appliance.should_receive(:execute_os_plugin).and_return(os_plugin_output)
123
- @appliance.should_receive(:execute_platform_plugin).and_return(platform_plugin_output)
94
+ os_plugin = mock('FedoraPlugin')
95
+ os_plugin.should_receive(:init)
96
+ os_plugin.should_receive(:deliverables_exists?).and_return(false)
97
+ os_plugin.should_receive(:run)
98
+ os_plugin.should_receive(:deliverables).and_return({ :disk => 'abc'})
124
99
 
125
- plugin_manager_first_call = mock('PluginManagerOne')
126
- plugin_manager_first_call.should_receive(:plugins).and_return({})
100
+ @plugin_manager.should_receive(:plugins).and_return( { :os => "something" } )
101
+ @plugin_manager.should_receive(:initialize_plugin).once.with(:os, :fedora).and_return([ os_plugin, {:class => Appliance, :type => :os, :name => :fedora, :full_name => "Fedora", :versions => ["11", "12", "13", "rawhide"] } ] )
127
102
 
128
- PluginManager.should_receive(:instance).and_return(plugin_manager_first_call)
103
+ @appliance.execute_plugin_chain
104
+ end
129
105
 
130
- delivery_plugin = mock('S3 Plugin')
131
- delivery_plugin.should_receive(:init)
132
- delivery_plugin.should_receive(:run).with(no_args)
106
+ it "should not build base appliance because deliverable already exists" do
107
+ @appliance.instance_variable_set(:@appliance_config, generate_appliance_config )
133
108
 
134
- plugin_manager_second_call = mock('PluginManagerTwo')
135
- plugin_manager_second_call.should_receive(:initialize_plugin).with(:delivery, :sftp).and_return([ delivery_plugin, {:class => Appliance, :type => :delivery, :name => :sftp, :full_name => "SSH File Transfer Protocol"} ] )
109
+ os_plugin = mock('FedoraPlugin')
110
+ os_plugin.should_receive(:init)
111
+ os_plugin.should_receive(:deliverables_exists?).and_return(true)
112
+ os_plugin.should_not_receive(:run)
113
+ os_plugin.should_receive(:deliverables).and_return({ :disk => 'abc'})
136
114
 
137
- PluginManager.should_receive(:instance).and_return(plugin_manager_second_call)
115
+ @plugin_manager.should_receive(:plugins).and_return( { :os => "something" } )
116
+ @plugin_manager.should_receive(:initialize_plugin).once.with(:os, :fedora).and_return([ os_plugin, {:class => Appliance, :type => :os, :name => :fedora, :full_name => "Fedora", :versions => ["11", "12", "13", "rawhide"] } ] )
138
117
 
139
- @appliance.create
118
+ @appliance.execute_plugin_chain
140
119
  end
141
120
 
142
- it "should remove previous build when force is specified" do
143
- prepare_appliance( OpenStruct.new( :force => true ) )
144
-
145
- validator = mock(ApplianceConfigValidator)
146
- validator.should_receive(:validate)
121
+ it "should build appliance and convert it to VMware format" do
122
+ prepare_appliance( OpenStruct.new({ :platform => :vmware }) )
147
123
 
148
- ApplianceConfigValidator.should_receive(:new).with(any_args).and_return(validator)
124
+ @appliance.instance_variable_set(:@appliance_config, generate_appliance_config )
125
+ @appliance.should_receive( :execute_os_plugin ).and_return( {} )
149
126
 
150
- @appliance.should_receive(:execute_os_plugin).and_return(nil)
151
- @appliance.should_receive(:execute_platform_plugin).and_return(nil)
152
- @appliance.should_receive(:execute_delivery_plugin).and_return(nil)
127
+ platform_plugin = mock('VMware Plugin')
128
+ platform_plugin.should_receive(:init)
129
+ platform_plugin.should_receive(:deliverables_exists?).and_return(false)
130
+ platform_plugin.should_receive(:run)
131
+ platform_plugin.should_receive(:deliverables).and_return({ :disk => 'abc' })
153
132
 
154
- FileUtils.should_receive(:rm_rf).with("build/appliances/#{@arch}/fedora/13/jeos-f13")
133
+ @plugin_manager.should_receive(:plugins).and_return( { :platform => "something" } )
134
+ @plugin_manager.should_receive(:initialize_plugin).once.with(:platform, :vmware).and_return([ platform_plugin, {:class => Appliance, :type => :platform, :name => :vmware, :full_name => "VMware"} ] )
155
135
 
156
- @appliance.create
136
+ @appliance.execute_plugin_chain
157
137
  end
158
138
 
159
- it "should not execute plugins when deliverables exists" do
139
+ it "should build appliance and convert it to VMware format because deliverable already exists" do
160
140
  prepare_appliance( OpenStruct.new({ :platform => :vmware }) )
161
141
 
162
- validator = mock(ApplianceConfigValidator)
163
- validator.should_receive(:validate)
142
+ @appliance.instance_variable_set(:@appliance_config, generate_appliance_config )
143
+ @appliance.should_receive( :execute_os_plugin ).and_return( {} )
164
144
 
165
- ApplianceConfigValidator.should_receive(:new).with(any_args).and_return(validator)
145
+ platform_plugin = mock('VMware Plugin')
146
+ platform_plugin.should_receive(:init)
147
+ platform_plugin.should_receive(:deliverables_exists?).and_return(true)
148
+ platform_plugin.should_not_receive(:run)
149
+ platform_plugin.should_receive(:deliverables).and_return({ :disk => 'abc' })
166
150
 
167
- os_plugin = mock('OS Plugin')
168
- os_plugin.should_receive(:init)
169
- os_plugin.should_receive(:deliverables_exists?).and_return(true)
170
- os_plugin.should_receive(:deliverables).and_return({ :disk => 'abc'})
151
+ @plugin_manager.should_receive(:plugins).and_return( { :platform => "something" } )
152
+ @plugin_manager.should_receive(:initialize_plugin).once.with(:platform, :vmware).and_return([ platform_plugin, {:class => Appliance, :type => :platform, :name => :vmware, :full_name => "VMware"} ] )
153
+
154
+ @appliance.execute_plugin_chain
155
+ end
156
+
157
+ it "should build appliance, convert it to EC2 format and deliver it using S3 ami type" do
158
+ prepare_appliance( OpenStruct.new({ :platform => :ec2, :delivery => :ami }) )
159
+
160
+ @appliance.instance_variable_set(:@appliance_config, generate_appliance_config )
161
+ @appliance.should_receive( :execute_os_plugin ).and_return( { :abc => 'def'} )
162
+ @appliance.should_receive( :execute_platform_plugin ).with( { :abc => 'def'} ).and_return( { :def => 'ghi'} )
171
163
 
172
- plugin_manager_first_call = mock('PluginManagerOne')
173
- plugin_manager_first_call.should_receive(:plugins).and_return({})
164
+ delivery_plugin = mock('S3 Plugin')
165
+ delivery_plugin.should_receive(:init)
166
+ delivery_plugin.should_receive(:run).with(:ami)
174
167
 
175
- PluginManager.should_receive(:instance).and_return(plugin_manager_first_call)
168
+ @plugin_manager.should_receive(:plugins).and_return( { :delivery => "something" } )
169
+ @plugin_manager.should_receive(:initialize_plugin).with(:delivery, :ami).and_return([ delivery_plugin, {:class => Appliance, :type => :delivery, :name => :s3, :full_name => "Amazon Simple Storage Service (Amazon S3)", :types => [:s3, :cloudfront, :ami]} ] )
176
170
 
177
- plugin_manager_second_call = mock('PluginManagerTwo')
178
- plugin_manager_second_call.should_receive(:initialize_plugin).with(:os, :fedora).and_return([ os_plugin, {:class => Appliance, :type => :os, :name => :fedora, :full_name => "Fedora", :versions => ["11", "12", "13", "rawhide"] } ] )
171
+ @appliance.execute_plugin_chain
172
+ end
179
173
 
180
- PluginManager.should_receive(:instance).and_return(plugin_manager_second_call)
174
+ it "should build appliance, convert it to EC2 format and deliver it using delivery plugin with only one delivery type" do
175
+ prepare_appliance( OpenStruct.new({ :platform => :ec2, :delivery => :same }) )
181
176
 
182
- platform_plugin = mock('Platform Plugin')
183
- platform_plugin.should_receive(:init)
184
- platform_plugin.should_receive(:deliverables_exists?).and_return(true)
185
- platform_plugin.should_receive(:deliverables).and_return({ :disk => 'def'})
177
+ @appliance.instance_variable_set(:@appliance_config, generate_appliance_config )
178
+ @appliance.should_receive( :execute_os_plugin ).and_return( { :abc => 'def'} )
179
+ @appliance.should_receive( :execute_platform_plugin ).with( { :abc => 'def'} ).and_return( { :def => 'ghi'} )
186
180
 
187
- platform_plugin_manager_second_call = mock('PlatformPluginManagerOne')
188
- platform_plugin_manager_second_call.should_receive(:initialize_plugin).with(:platform, :vmware).and_return([ platform_plugin, {:class => Appliance, :type => :platform, :name => :vmware, :full_name => "VMware"} ] )
181
+ delivery_plugin = mock('S3 Plugin')
182
+ delivery_plugin.should_receive(:init)
183
+ delivery_plugin.should_receive(:run).with(no_args())
189
184
 
190
- PluginManager.should_receive(:instance).and_return(platform_plugin_manager_second_call)
185
+ @plugin_manager.should_receive(:plugins).and_return( { :delivery => "something" } )
186
+ @plugin_manager.should_receive(:initialize_plugin).with(:delivery, :same).and_return([ delivery_plugin, {:class => Appliance, :type => :delivery, :name => :same, :full_name => "A plugin"} ] )
191
187
 
192
- @appliance.create
188
+ @appliance.execute_plugin_chain
193
189
  end
194
190
  end
195
191
  end
@@ -0,0 +1,144 @@
1
+ #
2
+ # Copyright 2010 Red Hat, Inc.
3
+ #
4
+ # This is free software; you can redistribute it and/or modify it
5
+ # under the terms of the GNU Lesser General Public License as
6
+ # published by the Free Software Foundation; either version 3 of
7
+ # the License, or (at your option) any later version.
8
+ #
9
+ # This software is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ # Lesser General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU Lesser General Public
15
+ # License along with this software; if not, write to the Free
16
+ # Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
17
+ # 02110-1301 USA, or see the FSF site: http://www.fsf.org.
18
+
19
+ require 'boxgrinder-build/helpers/image-helper'
20
+
21
+ module BoxGrinder
22
+ describe ImageHelper do
23
+
24
+ before(:each) do
25
+ @helper = ImageHelper.new(:log => Logger.new('/dev/null'))
26
+
27
+ @log = @helper.instance_variable_get(:@log)
28
+ @exec_helper = @helper.instance_variable_get(:@exec_helper)
29
+ end
30
+
31
+ it "should mount image with one root partition" do
32
+ @helper.should_receive(:calculate_disk_offsets).with('disk.raw').and_return(['0'])
33
+ FileUtils.should_receive(:mkdir_p).with('mount_dir')
34
+ @helper.should_receive(:get_loop_device).and_return('/dev/loop0')
35
+ @exec_helper.should_receive(:execute).with('losetup -o 0 /dev/loop0 disk.raw')
36
+ @exec_helper.should_receive(:execute).with('e2label /dev/loop0').and_return('/')
37
+ @exec_helper.should_receive(:execute).with("df -T /dev/loop0 | tail -1 | awk '{print $2}'").and_return('ext3')
38
+ @exec_helper.should_receive(:execute).with('mount /dev/loop0 -t ext3 mount_dir')
39
+
40
+ @helper.mount_image('disk.raw', 'mount_dir').should == {"/"=>"/dev/loop0"}
41
+ end
42
+
43
+ it "should mount image with two partitions with support for new livecd-tools partitions labels starting with '_'" do
44
+ @helper.should_receive(:calculate_disk_offsets).with('disk.raw').and_return(['322', '562'])
45
+ FileUtils.should_receive(:mkdir_p).with('mount_dir')
46
+ @helper.should_receive(:get_loop_device).and_return('/dev/loop0')
47
+ @exec_helper.should_receive(:execute).with('losetup -o 322 /dev/loop0 disk.raw')
48
+ @exec_helper.should_receive(:execute).with('e2label /dev/loop0').and_return('_/home')
49
+ @helper.should_receive(:get_loop_device).and_return('/dev/loop1')
50
+ @exec_helper.should_receive(:execute).with('losetup -o 562 /dev/loop1 disk.raw')
51
+ @exec_helper.should_receive(:execute).with('e2label /dev/loop1').and_return('_/')
52
+
53
+ @exec_helper.should_receive(:execute).with("df -T /dev/loop1 | tail -1 | awk '{print $2}'").and_return('ext3')
54
+ @exec_helper.should_receive(:execute).with("df -T /dev/loop0 | tail -1 | awk '{print $2}'").and_return('ext4')
55
+
56
+ @exec_helper.should_receive(:execute).with('mount /dev/loop1 -t ext3 mount_dir')
57
+ @exec_helper.should_receive(:execute).with('mount /dev/loop0 -t ext4 mount_dir/home')
58
+
59
+ @helper.mount_image('disk.raw', 'mount_dir').should == {"/"=>"/dev/loop1", "/home"=>"/dev/loop0"}
60
+ end
61
+
62
+ it "should umount the image" do
63
+ @exec_helper.should_receive(:execute).ordered.with('umount -d /dev/loop0')
64
+ @exec_helper.should_receive(:execute).ordered.with('umount -d /dev/loop1')
65
+ FileUtils.should_receive(:rm_rf).with('mount_dir')
66
+
67
+ @helper.umount_image('disk.raw', 'mount_dir', {"/"=>"/dev/loop1", "/home"=>"/dev/loop0"})
68
+ end
69
+
70
+ it "should get free loop device" do
71
+ @exec_helper.should_receive(:execute).with('losetup -f 2>&1').and_return("/dev/loop0\n")
72
+
73
+ @helper.get_loop_device.should == '/dev/loop0'
74
+ end
75
+
76
+ it "shouldn't get free loop device because there are no free loop devices left" do
77
+ @exec_helper.should_receive(:execute).with('losetup -f 2>&1').and_raise('boom')
78
+
79
+ begin
80
+ @helper.get_loop_device
81
+ raise "Shouldn't raise"
82
+ rescue => e
83
+ e.message.should == "No free loop devices available, please free at least one. See 'losetup -d' command."
84
+ end
85
+ end
86
+
87
+ it "should calculate disks offsets" do
88
+ @helper.should_receive(:get_loop_device).and_return('/dev/loop0')
89
+ @exec_helper.should_receive(:execute).ordered.with('losetup /dev/loop0 disk.raw')
90
+ @exec_helper.should_receive(:execute).ordered.with("parted /dev/loop0 'unit B print' | grep -e '^ [0-9]' | awk '{ print $2 }'").and_return("0B\n1234B\n")
91
+ @exec_helper.should_receive(:execute).ordered.with('losetup -d /dev/loop0')
92
+
93
+ @helper.calculate_disk_offsets('disk.raw').should == ["0", "1234"]
94
+ end
95
+
96
+ it "should create a new empty disk image" do
97
+ @exec_helper.should_receive(:execute).with('dd if=/dev/zero of=disk.raw bs=1 count=0 seek=10240M')
98
+
99
+ @helper.create_disk('disk.raw', 10)
100
+ end
101
+
102
+ it "should create default filesystem on selected device" do
103
+ @exec_helper.should_receive(:execute).with("mke2fs -T ext3 -L '/' -F /dev/loop0")
104
+
105
+ @helper.create_filesystem('/dev/loop0')
106
+ end
107
+
108
+ it "should create ext4 filesystem on selected device" do
109
+ @exec_helper.should_receive(:execute).with("mke2fs -T ext4 -L '/' -F /dev/loop0")
110
+
111
+ @helper.create_filesystem('/dev/loop0', :type => 'ext4')
112
+ end
113
+
114
+ it "should create ext4 filesystem on selected device with a label" do
115
+ @exec_helper.should_receive(:execute).with("mke2fs -T ext4 -L '/home' -F /dev/loop0")
116
+
117
+ @helper.create_filesystem('/dev/loop0', :type => 'ext4', :label => '/home')
118
+ end
119
+
120
+
121
+ it "should sync files" do
122
+ @exec_helper.should_receive(:execute).with("rsync -u -r -a from_dir/* to_dir")
123
+
124
+ @helper.sync_files('from_dir', 'to_dir')
125
+ end
126
+
127
+ it "should customize the disk image suing GuestFS" do
128
+ guestfs = mock('GuestFS')
129
+ guestfs.should_receive(:abc)
130
+
131
+ guestfs_helper = mock(GuestFSHelper)
132
+ guestfs_helper.should_receive(:customize).ordered.and_yield(guestfs, guestfs_helper)
133
+ guestfs_helper.should_receive(:def)
134
+
135
+ GuestFSHelper.should_receive(:new).with('disk.raw', :log => @log).and_return(guestfs_helper)
136
+
137
+ @helper.customize('disk.raw') do |guestfs, guestfs_helper|
138
+ guestfs.abc
139
+ guestfs_helper.def
140
+ end
141
+ end
142
+ end
143
+ end
144
+
@@ -8,7 +8,7 @@ module BoxGrinder
8
8
 
9
9
  before(:all) do
10
10
  @current_arch = (-1.size) == 8 ? "x86_64" : "i386"
11
- @plugin_array = %w(boxgrinder-build-fedora-os-plugin boxgrinder-build-rhel-os-plugin boxgrinder-build-centos-os-plugin boxgrinder-build-ec2-platform-plugin boxgrinder-build-vmware-platform-plugin boxgrinder-build-s3-delivery-plugin boxgrinder-build-sftp-delivery-plugin boxgrinder-build-local-delivery-plugin)
11
+ @plugin_array = %w(boxgrinder-build-fedora-os-plugin boxgrinder-build-rhel-os-plugin boxgrinder-build-centos-os-plugin boxgrinder-build-ec2-platform-plugin boxgrinder-build-vmware-platform-plugin boxgrinder-build-s3-delivery-plugin boxgrinder-build-sftp-delivery-plugin boxgrinder-build-local-delivery-plugin boxgrinder-build-ebs-delivery-plugin)
12
12
  end
13
13
 
14
14
  before(:each) do
@@ -1,18 +1,17 @@
1
1
  require 'boxgrinder-build/plugins/base-plugin'
2
2
  require 'rspec/rspec-config-helper'
3
- require 'rbconfig'
4
3
 
5
4
  module BoxGrinder
6
5
  describe BasePlugin do
7
6
  include RSpecConfigHelper
8
7
 
9
8
  before(:all) do
10
- @arch = RbConfig::CONFIG['host_cpu']
9
+ @arch = `uname -m`.chomp.strip
11
10
  end
12
11
 
13
12
  before(:each) do
14
13
  @plugin = BasePlugin.new
15
- @plugin.init( generate_config, generate_appliance_config, :plugin_info => { :name => :plugin_name })
14
+ @plugin.init(generate_config, generate_appliance_config, :plugin_info => {:name => :plugin_name}, :log => Logger.new('/dev/null'))
16
15
  end
17
16
 
18
17
  it "should be initialized after running init method" do
@@ -78,12 +77,78 @@ module BoxGrinder
78
77
  FileUtils.should_receive(:rm_rf).with("build/appliances/#{@arch}/fedora/11/full/plugin_name-plugin/tmp")
79
78
  FileUtils.should_receive(:mkdir_p).with("build/appliances/#{@arch}/fedora/11/full/plugin_name-plugin/tmp")
80
79
 
81
- @plugin.should_receive( :execute ).with('a', 3)
80
+ @plugin.should_receive(:execute).with('a', 3)
82
81
 
83
82
  FileUtils.should_receive(:mv).with("build/appliances/#{@arch}/fedora/11/full/plugin_name-plugin/tmp/disk", "build/appliances/#{@arch}/fedora/11/full/plugin_name-plugin/disk")
84
83
  FileUtils.should_receive(:rm_rf).with("build/appliances/#{@arch}/fedora/11/full/plugin_name-plugin/tmp")
85
84
 
86
85
  @plugin.run('a', 3)
87
86
  end
87
+
88
+ it "should register a supported os" do
89
+ @plugin.register_supported_os('fedora', ['12', '13'])
90
+
91
+ oses = @plugin.instance_variable_get(:@supported_oses)
92
+
93
+ oses.size.should == 1
94
+ oses['fedora'].size.should == 2
95
+ oses['fedora'].should == ['12', '13']
96
+ end
97
+
98
+ it "should return that the OS is supported" do
99
+ @plugin.register_supported_os('fedora', ['12', '13'])
100
+
101
+ @plugin.instance_variable_get(:@appliance_config).os.name = 'fedora'
102
+ @plugin.instance_variable_get(:@appliance_config).os.version = '12'
103
+
104
+ @plugin.is_supported_os?.should == true
105
+ end
106
+
107
+ it "should return that the OS is not supported" do
108
+ @plugin.register_supported_os('fedora', ['1223'])
109
+
110
+ @plugin.instance_variable_get(:@appliance_config).os.name = 'fedora'
111
+ @plugin.instance_variable_get(:@appliance_config).os.version = '12'
112
+
113
+ @plugin.is_supported_os?.should == false
114
+ end
115
+
116
+ it "should return supported os string" do
117
+ @plugin.register_supported_os('fedora', ['12', '13'])
118
+ @plugin.register_supported_os('centos', ['5'])
119
+
120
+ @plugin.supported_oses.should == "fedora (versions: 12, 13), centos (versions: 5)"
121
+ end
122
+
123
+ it "should set default config value" do
124
+ @plugin.set_default_config_value('key', 'avalue')
125
+
126
+ @plugin.instance_variable_get(:@plugin_config)['key'].should == 'avalue'
127
+ end
128
+
129
+ it "should read plugin config" do
130
+ @plugin.instance_variable_set(:@config_file, "configfile")
131
+
132
+ File.should_receive(:exists?).with('configfile').and_return(true)
133
+ YAML.should_receive(:load_file).with('configfile').and_return('abcdef')
134
+
135
+ @plugin.read_plugin_config
136
+
137
+ @plugin.instance_variable_get(:@plugin_config).should == 'abcdef'
138
+ end
139
+
140
+ it "should read plugin config and raise an exception" do
141
+ @plugin.instance_variable_set(:@config_file, "configfile")
142
+
143
+ File.should_receive(:exists?).with('configfile').and_return(true)
144
+ YAML.should_receive(:load_file).with('configfile').and_raise('something')
145
+
146
+ begin
147
+ @plugin.read_plugin_config
148
+ raise "Should raise"
149
+ rescue => e
150
+ e.message.should == "An error occurred while reading configuration file 'configfile' for BoxGrinder::BasePlugin. Is it a valid YAML file?"
151
+ end
152
+ end
88
153
  end
89
154
  end
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: boxgrinder-build
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 7
4
5
  prerelease: false
5
6
  segments:
6
7
  - 0
7
- - 5
8
- - 1
9
- version: 0.5.1
8
+ - 6
9
+ - 0
10
+ version: 0.6.0
10
11
  platform: ruby
11
12
  authors:
12
13
  - Marek Goldmann
@@ -14,16 +15,18 @@ autorequire:
14
15
  bindir: bin
15
16
  cert_chain: []
16
17
 
17
- date: 2010-08-23 00:00:00 +02:00
18
+ date: 2010-10-12 00:00:00 +02:00
18
19
  default_executable:
19
20
  dependencies:
20
21
  - !ruby/object:Gem::Dependency
21
22
  name: commander
22
23
  prerelease: false
23
24
  requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
24
26
  requirements:
25
27
  - - ~>
26
28
  - !ruby/object:Gem::Version
29
+ hash: 57
27
30
  segments:
28
31
  - 4
29
32
  - 0
@@ -35,14 +38,16 @@ dependencies:
35
38
  name: boxgrinder-core
36
39
  prerelease: false
37
40
  requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
38
42
  requirements:
39
43
  - - ~>
40
44
  - !ruby/object:Gem::Version
45
+ hash: 27
41
46
  segments:
42
47
  - 0
48
+ - 1
43
49
  - 0
44
- - 22
45
- version: 0.0.22
50
+ version: 0.1.0
46
51
  type: :runtime
47
52
  version_requirements: *id002
48
53
  description: A tool for creating appliances from simple plain text files for various virtual environments.
@@ -60,6 +65,7 @@ extra_rdoc_files:
60
65
  - lib/boxgrinder-build/helpers/appliance-customize-helper.rb
61
66
  - lib/boxgrinder-build/helpers/augeas-helper.rb
62
67
  - lib/boxgrinder-build/helpers/guestfs-helper.rb
68
+ - lib/boxgrinder-build/helpers/image-helper.rb
63
69
  - lib/boxgrinder-build/helpers/linux-helper.rb
64
70
  - lib/boxgrinder-build/helpers/package-helper.rb
65
71
  - lib/boxgrinder-build/helpers/plugin-helper.rb
@@ -76,6 +82,7 @@ files:
76
82
  - lib/boxgrinder-build/helpers/appliance-customize-helper.rb
77
83
  - lib/boxgrinder-build/helpers/augeas-helper.rb
78
84
  - lib/boxgrinder-build/helpers/guestfs-helper.rb
85
+ - lib/boxgrinder-build/helpers/image-helper.rb
79
86
  - lib/boxgrinder-build/helpers/linux-helper.rb
80
87
  - lib/boxgrinder-build/helpers/package-helper.rb
81
88
  - lib/boxgrinder-build/helpers/plugin-helper.rb
@@ -86,6 +93,7 @@ files:
86
93
  - spec/helpers/appliance-customize-helper-spec.rb
87
94
  - spec/helpers/augeas-helper-spec.rb
88
95
  - spec/helpers/guestfs-helper-spec.rb
96
+ - spec/helpers/image-helper-spec.rb
89
97
  - spec/helpers/linux-helper-spec.rb
90
98
  - spec/helpers/package-helper-spec.rb
91
99
  - spec/helpers/plugin-helper-spec.rb
@@ -94,7 +102,7 @@ files:
94
102
  - spec/rspec/src/appliances/jeos-f13.appl
95
103
  - boxgrinder-build.gemspec
96
104
  has_rdoc: true
97
- homepage: http://www.jboss.org/stormgrind/projects/boxgrinder.html
105
+ homepage: http://www.jboss.org/boxgrinder
98
106
  licenses: []
99
107
 
100
108
  post_install_message:
@@ -108,16 +116,20 @@ rdoc_options:
108
116
  require_paths:
109
117
  - lib
110
118
  required_ruby_version: !ruby/object:Gem::Requirement
119
+ none: false
111
120
  requirements:
112
121
  - - ">="
113
122
  - !ruby/object:Gem::Version
123
+ hash: 3
114
124
  segments:
115
125
  - 0
116
126
  version: "0"
117
127
  required_rubygems_version: !ruby/object:Gem::Requirement
128
+ none: false
118
129
  requirements:
119
130
  - - ">="
120
131
  - !ruby/object:Gem::Version
132
+ hash: 11
121
133
  segments:
122
134
  - 1
123
135
  - 2
@@ -125,7 +137,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
125
137
  requirements: []
126
138
 
127
139
  rubyforge_project: BoxGrinder Build
128
- rubygems_version: 1.3.6
140
+ rubygems_version: 1.3.7
129
141
  signing_key:
130
142
  specification_version: 3
131
143
  summary: A tool for creating appliances from simple plain text files for various virtual environments.