boxgrinder-build 0.5.1 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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.