boxgrinder-build 0.4.1 → 0.5.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.
Files changed (71) hide show
  1. data/CHANGELOG +7 -0
  2. data/Manifest +0 -0
  3. data/Rakefile +11 -0
  4. data/bin/boxgrinder-build +33 -27
  5. data/boxgrinder-build.gemspec +38 -0
  6. data/lib/boxgrinder-build/appliance.rb +32 -41
  7. data/lib/boxgrinder-build/helpers/appliance-customize-helper.rb +3 -48
  8. data/lib/boxgrinder-build/helpers/guestfs-helper.rb +98 -12
  9. data/lib/boxgrinder-build/helpers/linux-helper.rb +69 -0
  10. data/lib/boxgrinder-build/helpers/package-helper.rb +20 -11
  11. data/lib/boxgrinder-build/helpers/plugin-helper.rb +32 -32
  12. data/lib/boxgrinder-build/managers/plugin-manager.rb +98 -0
  13. data/lib/boxgrinder-build/plugins/base-plugin.rb +70 -17
  14. data/spec/Rakefile +13 -0
  15. data/spec/appliance-spec.rb +195 -0
  16. data/spec/helpers/appliance-customize-helper-spec.rb +30 -0
  17. data/spec/helpers/guestfs-helper-spec.rb +129 -0
  18. data/spec/helpers/linux-helper-spec.rb +50 -0
  19. data/spec/helpers/package-helper-spec.rb +6 -0
  20. data/spec/helpers/plugin-helper-spec.rb +63 -0
  21. data/spec/managers/plugin-manager-spec.rb +27 -0
  22. data/spec/plugins/base-plugin-spec.rb +89 -0
  23. data/spec/rspec/src/appliances/jeos-f13.appl +27 -0
  24. metadata +60 -157
  25. data/docs/examples/appliances/appliances.appl +0 -5
  26. data/docs/examples/appliances/minimal.appl +0 -9
  27. data/docs/examples/appliances/mix.appl +0 -8
  28. data/docs/examples/appliances/packages.appl +0 -13
  29. data/docs/node-info/pom.xml +0 -31
  30. data/docs/node-info/src/main/webapp/META-INF/MANIFEST.MF +0 -3
  31. data/docs/node-info/src/main/webapp/WEB-INF/web.xml +0 -7
  32. data/docs/node-info/src/main/webapp/index.jsp +0 -70
  33. data/lib/boxgrinder-build/helpers/rake-helper.rb +0 -71
  34. data/lib/boxgrinder-build/managers/base-plugin-manager.rb +0 -62
  35. data/lib/boxgrinder-build/managers/delivery-plugin-manager.rb +0 -39
  36. data/lib/boxgrinder-build/managers/operating-system-plugin-manager.rb +0 -6
  37. data/lib/boxgrinder-build/managers/platform-plugin-manager.rb +0 -26
  38. data/lib/boxgrinder-build/plugins/delivery/base/base-delivery-plugin.rb +0 -43
  39. data/lib/boxgrinder-build/plugins/delivery/local/local-plugin.rb +0 -57
  40. data/lib/boxgrinder-build/plugins/delivery/s3/aws-helper.rb +0 -64
  41. data/lib/boxgrinder-build/plugins/delivery/s3/s3-plugin.rb +0 -190
  42. data/lib/boxgrinder-build/plugins/delivery/sftp/sftp-plugin.rb +0 -159
  43. data/lib/boxgrinder-build/plugins/os/base/kickstart.rb +0 -148
  44. data/lib/boxgrinder-build/plugins/os/base/rhel-based-os-plugin.rb +0 -51
  45. data/lib/boxgrinder-build/plugins/os/base/rpm-based-os-plugin.rb +0 -134
  46. data/lib/boxgrinder-build/plugins/os/base/src/appliance.ks.erb +0 -41
  47. data/lib/boxgrinder-build/plugins/os/base/src/base.repo +0 -4
  48. data/lib/boxgrinder-build/plugins/os/base/src/motd.init +0 -21
  49. data/lib/boxgrinder-build/plugins/os/base/validators/rpm-dependency-validator.rb +0 -162
  50. data/lib/boxgrinder-build/plugins/os/base-operating-system-plugin.rb +0 -37
  51. data/lib/boxgrinder-build/plugins/os/centos/centos-plugin.rb +0 -52
  52. data/lib/boxgrinder-build/plugins/os/fedora/fedora-plugin.rb +0 -74
  53. data/lib/boxgrinder-build/plugins/os/rhel/rhel-plugin.rb +0 -40
  54. data/lib/boxgrinder-build/plugins/platform/base-platform-plugin.rb +0 -37
  55. data/lib/boxgrinder-build/plugins/platform/ec2/ec2-plugin.rb +0 -332
  56. data/lib/boxgrinder-build/plugins/platform/ec2/src/f12/yum.conf +0 -24
  57. data/lib/boxgrinder-build/plugins/platform/ec2/src/f12-i386-boxgrinder.repo +0 -11
  58. data/lib/boxgrinder-build/plugins/platform/ec2/src/f12-x86_64-boxgrinder.repo +0 -11
  59. data/lib/boxgrinder-build/plugins/platform/ec2/src/fstab_32bit +0 -8
  60. data/lib/boxgrinder-build/plugins/platform/ec2/src/fstab_64bit +0 -8
  61. data/lib/boxgrinder-build/plugins/platform/ec2/src/ifcfg-eth0 +0 -7
  62. data/lib/boxgrinder-build/plugins/platform/ec2/src/rc_local +0 -29
  63. data/lib/boxgrinder-build/plugins/platform/vmware/src/README +0 -42
  64. data/lib/boxgrinder-build/plugins/platform/vmware/src/base.vmdk +0 -19
  65. data/lib/boxgrinder-build/plugins/platform/vmware/src/base.vmx +0 -45
  66. data/lib/boxgrinder-build/plugins/platform/vmware/vmware-plugin.rb +0 -181
  67. data/lib/boxgrinder-build/validators/appliance-config-parameter-validator.rb +0 -37
  68. data/lib/boxgrinder-build/validators/appliance-validator.rb +0 -84
  69. data/lib/boxgrinder-build/validators/config-validator.rb +0 -48
  70. data/lib/boxgrinder-build/validators/ssh-validator.rb +0 -35
  71. data/lib/boxgrinder-build/validators/validator.rb +0 -91
data/CHANGELOG ADDED
@@ -0,0 +1,7 @@
1
+
2
+ v0.5.0
3
+
4
+ * Plugins externalized from BoxGrinder Build
5
+ * TODO
6
+
7
+ v0.4.0
data/Manifest ADDED
File without changes
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require 'echoe'
2
+
3
+ Echoe.new("boxgrinder-build") do |p|
4
+ p.project = "BoxGrinder Build"
5
+ p.author = "Marek Goldmann"
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"
8
+ p.email = "info@boxgrinder.org"
9
+ p.ignore_pattern = /^(pkg|doc)|\.svn|CVS|\.bzr|\.DS|\.git|\.log/
10
+ p.runtime_dependencies = ["commander >=4.0.3", "boxgrinder-core >=0.0.20"]
11
+ end
data/bin/boxgrinder-build CHANGED
@@ -21,45 +21,46 @@
21
21
  # 02110-1301 USA, or see the FSF site: http://www.fsf.org.
22
22
 
23
23
  require 'rubygems'
24
- require 'commander/import'
25
24
  require 'boxgrinder-core/helpers/log-helper'
25
+ require 'boxgrinder-build/managers/plugin-manager'
26
26
  require 'boxgrinder-build/helpers/plugin-helper'
27
27
  require 'boxgrinder-build/appliance'
28
28
 
29
- gem 'boxgrinder-core', '>= 0.0.11'
30
- gem 'aws-s3', '>= 0.6.2'
31
- gem 'amazon-ec2', '>= 0.9.6'
32
- gem 'net-sftp', '>= 2.0.4'
33
- gem 'net-ssh', '>= 2.0.20'
34
- gem 'rake', '>= 0.8.7'
35
- gem 'progressbar', '>= 0.9.0'
29
+ gem 'boxgrinder-core', '>= 0.0.20'
36
30
  gem 'commander', '>= 4.0.3'
37
31
 
38
- # :name is optional, otherwise uses the basename of this executable
32
+ #$stderr.reopen($stdout)
39
33
 
40
- #$stderr.reopen('/dev/null')
34
+ if Process.uid != 0
35
+ puts "This program must be executed with root privileges. Try 'sudo boxgrinder-build'"
36
+ abort
37
+ end
38
+
39
+ require 'commander/import'
41
40
 
42
41
  program :name, 'BoxGrinder Build'
43
- program :version, '0.4.1'
44
- program :description, 'A tool for building VM images from simple definition files.'
42
+ program :version, '0.5.0'
43
+ 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'
45
+ program :help, 'Documentation', 'http://community.jboss.org/docs/DOC-14358'
46
+ program :help, 'Examples', "Run 'boxgrinder-build -h build' for more info about syntax."
45
47
  default_command :build
46
48
 
47
- $verbose = false
49
+ $log_level = :info
48
50
 
49
- global_option('-V', '--verbose', TrueClass, "Prints verbose information while building. Default: false.") { $verbose = true}
51
+ 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}
50
53
 
51
54
  module BoxGrinder
52
- log = LogHelper.new
53
-
54
- PluginHelper.new( :log => log ).load_plugins
55
-
56
55
  command :build do |c|
57
56
  c.syntax = 'build appliance_definition.appl [options]'
58
- c.description = 'Creates a base image for selected appliance definition.'
57
+ c.description = 'Creates an image from selected appliance definition for selected platform.'
58
+ c.examples = "boxgrinder-build test.appl -p vmware\nboxgrinder-build test.appl -p ec2 -d ami\nboxgrinder-build test.appl -d sftp"
59
59
 
60
- c.option '-p STRING', '--platform STRING', String, "The type of platform. Valid types are: #{PlatformPluginManager.instance.plugins.keys.join(', ')}. Default: none."
61
- c.option '-d STRING', '--delivery STRING', String, "The delivery type for selected image. Valid types are: #{DeliveryPluginManager.instance.types.keys.join(', ')}. Default: none."
62
- c.option '-f', '--force', TrueClass, "Force image creation - removes all previous builds for selected appliance. Default: false."
60
+ c.option '-p STRING', '--platform STRING', String, "The type of platform. Default: none." # Valid types are: #{PlatformPluginManager.instance.plugins.keys.join(', ')}. Default: none."
61
+ c.option '-d STRING', '--delivery STRING', String, "The delivery type for selected image. Default: none." # Valid types are: #{DeliveryPluginManager.instance.types.keys.join(', ')}. Default: none."
62
+ c.option '-f STRING', '--force', TrueClass, "Force image creation - removes all previous builds for selected appliance. Default: false."
63
+ c.option '-l STRING', '--plugins STRING', String, "Comma separated list of plugins. Default: default plugins will be available."
63
64
 
64
65
  c.action do |args, options|
65
66
  options.default :platform => :none
@@ -69,17 +70,22 @@ module BoxGrinder
69
70
  options.name = program(:name)
70
71
  options.version = program(:version)
71
72
 
72
- options.verbose = $verbose
73
73
  options.platform = options.platform.to_s.downcase.to_sym
74
74
  options.delivery = options.delivery.to_s.downcase.to_sym
75
75
 
76
- appliance_definition_file = args.shift or raise('Appliance definition file is required. Run boxgrinder-build -h for more info')
76
+ appliance_definition_file = args.shift or raise("You need to specify appliance definition file. Run 'boxgrinder-build -h' for more info")
77
77
 
78
78
  raise "Appliance definition file '#{appliance_definition_file}' could not be found" unless File.exists?( appliance_definition_file )
79
- raise "Not known platform: #{options.platform}. Available platforms: #{PlatformPluginManager.instance.plugins.keys.join(', ')}." if PlatformPluginManager.instance.plugins[options.platform].nil? and options.platform != :none
80
- raise "Not known delivery type: #{options.delivery}. Available types: #{DeliveryPluginManager.instance.types.keys.join(', ')}." if DeliveryPluginManager.instance.types.keys.include?(options.delivery).nil? and options.delivery != :none
81
79
 
82
- Appliance.new( appliance_definition_file, :options => options, :log => LogHelper.new( :threshold => $verbose ? :debug : :info ) ).create
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
83
89
  end
84
90
  end
85
91
  end
@@ -0,0 +1,38 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{boxgrinder-build}
5
+ s.version = "0.5.0"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Marek Goldmann"]
9
+ s.date = %q{2010-07-21}
10
+ s.default_executable = %q{boxgrinder-build}
11
+ s.description = %q{A tool for creating appliances from simple plain text files for various virtual environments.}
12
+ s.email = %q{info@boxgrinder.org}
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/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/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/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}
17
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Boxgrinder-build", "--main", "README"]
18
+ s.require_paths = ["lib"]
19
+ s.rubyforge_project = %q{BoxGrinder Build}
20
+ s.rubygems_version = %q{1.3.6}
21
+ s.summary = %q{A tool for creating appliances from simple plain text files for various virtual environments.}
22
+
23
+ if s.respond_to? :specification_version then
24
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
25
+ s.specification_version = 3
26
+
27
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
28
+ s.add_runtime_dependency(%q<commander>, [">= 4.0.3"])
29
+ s.add_runtime_dependency(%q<boxgrinder-core>, [">= 0.0.20"])
30
+ else
31
+ s.add_dependency(%q<commander>, [">= 4.0.3"])
32
+ s.add_dependency(%q<boxgrinder-core>, [">= 0.0.20"])
33
+ end
34
+ else
35
+ s.add_dependency(%q<commander>, [">= 4.0.3"])
36
+ s.add_dependency(%q<boxgrinder-core>, [">= 0.0.20"])
37
+ end
38
+ end
@@ -18,7 +18,6 @@
18
18
  # Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19
19
  # 02110-1301 USA, or see the FSF site: http://www.fsf.org.
20
20
 
21
- require 'rake/tasklib'
22
21
  require 'boxgrinder-core/models/appliance-config'
23
22
  require 'boxgrinder-core/models/config'
24
23
  require 'boxgrinder-core/helpers/appliance-helper'
@@ -26,7 +25,7 @@ require 'boxgrinder-core/helpers/appliance-config-helper'
26
25
  require 'boxgrinder-core/validators/appliance-config-validator'
27
26
 
28
27
  module BoxGrinder
29
- class Appliance < Rake::TaskLib
28
+ class Appliance
30
29
 
31
30
  def initialize( appliance_definition_file, options = {} )
32
31
  @config = Config.new
@@ -45,79 +44,71 @@ module BoxGrinder
45
44
 
46
45
  @appliance_config = appliance_config_helper.merge(appliance_config.clone.init_arch).initialize_paths
47
46
 
48
- ApplianceConfigValidator.new( @appliance_config, :os_plugins => OperatingSystemPluginManager.instance.plugins ).validate
47
+ ApplianceConfigValidator.new( @appliance_config, :os_plugins => PluginManager.instance.plugins[:os] ).validate
49
48
 
50
49
  if @options.force
51
50
  @log.info "Removing previous builds for #{@appliance_config.name} appliance..."
52
- FileUtils.rm_rf( @appliance_config.path.dir.build )
51
+ FileUtils.rm_rf( @appliance_config.path.build )
53
52
  @log.debug "Previous builds removed."
54
53
  end
55
54
 
56
- base_deliverables = execute_os_plugin
57
- platform_deliverables = execute_platform_plugin( base_deliverables )
55
+ base_plugin_output = execute_os_plugin
56
+ platform_plugin_output = execute_platform_plugin( base_plugin_output )
58
57
 
59
- execute_delivery_plugin( platform_deliverables )
58
+ execute_delivery_plugin( platform_plugin_output )
60
59
  end
61
60
 
62
61
  def execute_os_plugin
63
- os_plugin = OperatingSystemPluginManager.instance.plugins[@appliance_config.os.name.to_sym]
64
- os_plugin.init( @config, @appliance_config, :log => @log )
62
+ os_plugin, os_plugin_info = PluginManager.instance.initialize_plugin(:os, @appliance_config.os.name.to_sym )
63
+ os_plugin.init( @config, @appliance_config, :log => @log, :plugin_info => os_plugin_info )
65
64
 
66
- if deliverables_exists( os_plugin.deliverables )
67
- @log.info "Deliverables for #{os_plugin.info[:name]} operating system plugin exists, skipping."
68
- return os_plugin.deliverables
65
+ if os_plugin.deliverables_exists?
66
+ @log.info "Deliverables for #{os_plugin_info[:name]} operating system plugin exists, skipping."
67
+ return { :deliverables => os_plugin.deliverables }
69
68
  end
70
69
 
71
70
  @log.debug "Executing operating system plugin for #{@appliance_config.os.name}..."
72
- os_plugin.execute
71
+ os_plugin.run
73
72
  @log.debug "Operating system plugin executed."
74
73
 
75
- os_plugin.deliverables
74
+ { :deliverables => os_plugin.deliverables, :plugin_info => os_plugin_info }
76
75
  end
77
76
 
78
- def execute_platform_plugin( deliverables )
79
- if @options.platform == :none
77
+ def execute_platform_plugin( previous_plugin_output )
78
+ if @options.platform == :none or @options.platform == nil
80
79
  @log.debug "No platform selected, skipping platform conversion."
81
- return deliverables
80
+ return previous_plugin_output
82
81
  end
83
82
 
84
- platform_plugin = PlatformPluginManager.instance.plugins[@options.platform]
85
- platform_plugin.init( @config, @appliance_config, :log => @log )
83
+ platform_plugin, platform_plugin_info = PluginManager.instance.initialize_plugin(:platform, @options.platform )
84
+ 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] )
86
85
 
87
- if deliverables_exists( platform_plugin.deliverables )
88
- @log.info "Deliverables for #{platform_plugin.info[:name]} platform plugin exists, skipping."
89
- return platform_plugin.deliverables
86
+ if platform_plugin.deliverables_exists?
87
+ @log.info "Deliverables for #{platform_plugin_info[:name]} platform plugin exists, skipping."
88
+ return { :deliverables => platform_plugin.deliverables, :plugin_info => platform_plugin_info }
90
89
  end
91
90
 
92
91
  @log.debug "Executing platform plugin for #{@options.platform}..."
93
- platform_plugin.execute( deliverables[:disk] )
92
+ platform_plugin.run
94
93
  @log.debug "Platform plugin executed."
95
94
 
96
- platform_plugin.deliverables
95
+ { :deliverables => platform_plugin.deliverables, :plugin_info => platform_plugin_info }
97
96
  end
98
97
 
99
- def execute_delivery_plugin( deliverables )
100
- if @options.delivery == :none
98
+ def execute_delivery_plugin( previous_plugin_output )
99
+ if @options.delivery == :none or @options.delivery == nil
101
100
  @log.debug "No delivery method selected, skipping delivering."
102
- return deliverables
101
+ return
103
102
  end
104
103
 
105
- delivery_plugin = DeliveryPluginManager.instance.types[@options.delivery]
106
- delivery_plugin.init( @config, @appliance_config, :log => @log )
107
- delivery_plugin.execute( deliverables, @options.delivery )
108
- end
109
-
110
- # TODO: move this to plugin (os,platform,delivery)
111
- def deliverables_exists( deliverables )
112
- return false unless File.exists?(deliverables[:disk])
104
+ delivery_plugin, delivery_plugin_info = PluginManager.instance.initialize_plugin(:delivery, @options.delivery )
105
+ 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] )
113
106
 
114
- [:metadata, :other].each do |deliverable_type|
115
- deliverables[deliverable_type].each_value do |file|
116
- return false unless File.exists?(file)
117
- end
107
+ if @options.delivery != delivery_plugin_info[:name]
108
+ delivery_plugin.run( @options.delivery )
109
+ else
110
+ delivery_plugin.run
118
111
  end
119
-
120
- true
121
112
  end
122
113
  end
123
114
  end
@@ -18,13 +18,13 @@
18
18
  # Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19
19
  # 02110-1301 USA, or see the FSF site: http://www.fsf.org.
20
20
 
21
- require 'rake/tasklib'
22
21
  require 'boxgrinder-core/validators/errors'
23
22
  require 'boxgrinder-build/helpers/guestfs-helper'
24
23
  require 'tempfile'
24
+ require 'logger'
25
25
 
26
26
  module BoxGrinder
27
- class ApplianceCustomizeHelper < Rake::TaskLib
27
+ class ApplianceCustomizeHelper
28
28
 
29
29
  def initialize( config, appliance_config, disk, options = {} )
30
30
  @config = config
@@ -36,57 +36,12 @@ module BoxGrinder
36
36
  end
37
37
 
38
38
  def customize
39
- @guestfs_helper = GuestFSHelper.new( @disk, :log => @log )
39
+ @guestfs_helper = GuestFSHelper.new( @disk, :log => @log ).run
40
40
  @guestfs = @guestfs_helper.guestfs
41
41
 
42
42
  yield @guestfs, @guestfs_helper
43
43
 
44
44
  @guestfs_helper.clean_close
45
45
  end
46
-
47
- def validate_options( options )
48
- options = {
49
- :packages => {},
50
- :repos => []
51
- }.merge(options)
52
-
53
- options[:packages][:yum] = options[:packages][:yum] || []
54
- options[:packages][:yum_local] = options[:packages][:yum_local] || []
55
- options[:packages][:rpm] = options[:packages][:rpm] || []
56
-
57
- if ( options[:packages][:yum_local].size == 0 and options[:packages][:rpm].size == 0 and options[:packages][:yum].size == 0 and options[:repos].size == 0)
58
- @log.debug "No additional local or remote packages or gems to install, skipping..."
59
- return false
60
- end
61
-
62
- true
63
- end
64
-
65
- def install_packages( options = {} )
66
- # silent return, we don't have any packages to install
67
- return unless validate_options( options )
68
-
69
- @guestfs_helper.rebuild_rpm_database
70
-
71
- for repo in options[:repos]
72
- @log.debug "Installing repo file '#{repo}'..."
73
- @guestfs.sh( "rpm -Uvh #{repo}" )
74
- @log.debug "Repo file '#{repo}' installed."
75
- end unless options[:repos].nil?
76
-
77
- unless options[:packages].nil?
78
- for yum_package in options[:packages][:yum]
79
- @log.debug "Installing package '#{yum_package}'..."
80
- @guestfs.sh( "yum -y install #{yum_package}" )
81
- @log.debug "Package '#{yum_package}' installed."
82
- end unless options[:packages][:yum].nil?
83
-
84
- for package in options[:packages][:rpm]
85
- @log.debug "Installing package '#{package}'..."
86
- @guestfs.sh( "rpm -Uvh --force #{package}" )
87
- @log.debug "Package '#{package}' installed."
88
- end unless options[:packages][:rpm].nil?
89
- end
90
- end
91
46
  end
92
47
  end
@@ -19,6 +19,63 @@
19
19
  # 02110-1301 USA, or see the FSF site: http://www.fsf.org.
20
20
 
21
21
  require 'guestfs'
22
+ require 'logger'
23
+
24
+ module BoxGrinder
25
+ class SilencerProxy
26
+ def initialize( o, destination )
27
+ @o = o
28
+ @destination = destination
29
+ end
30
+
31
+ def method_missing( m, *args, &block )
32
+ begin
33
+ redirect_streams( @destination ) do
34
+ @o.send(m, *args, &block)
35
+ end
36
+ rescue
37
+ raise
38
+ end
39
+ end
40
+
41
+ def redirect_streams( destination )
42
+ old_stdout_stream = STDOUT.dup
43
+ old_stderr_stream = STDERR.dup
44
+
45
+ STDOUT.reopen( destination )
46
+ STDERR.reopen( destination )
47
+
48
+ STDOUT.sync = true
49
+ STDERR.sync = true
50
+
51
+ yield
52
+ ensure
53
+ STDOUT.reopen( old_stdout_stream )
54
+ STDERR.reopen( old_stderr_stream )
55
+ end
56
+ end
57
+ end
58
+
59
+ module Guestfs
60
+ class Guestfs
61
+ alias_method :sh_original, :sh
62
+
63
+ def sh( command )
64
+ begin
65
+ output = sh_original( command )
66
+ puts output
67
+ rescue => e
68
+ puts "Error occurred while executing above command. Appliance may not work properly."
69
+ end
70
+
71
+ output
72
+ end
73
+
74
+ def redirect( destination )
75
+ BoxGrinder::SilencerProxy.new( self, destination )
76
+ end
77
+ end
78
+ end
22
79
 
23
80
  module BoxGrinder
24
81
  class GuestFSHelper
@@ -27,31 +84,58 @@ module BoxGrinder
27
84
  @log = options[:log] || Logger.new(STDOUT)
28
85
 
29
86
  @partitions = {}
30
-
31
- launch
32
87
  end
33
88
 
34
89
  attr_reader :guestfs
35
90
 
36
- def launch
91
+ def customize
92
+ read_pipe, write_pipe = IO.pipe
93
+
94
+ fork do
95
+ read_pipe.each do |o|
96
+ if o.chomp.strip.eql?("<EOF>")
97
+ exit
98
+ else
99
+ @log.trace "GFS: #{o.chomp.strip}"
100
+ end
101
+ end
102
+ end
103
+
104
+ helper = execute( write_pipe )
105
+
106
+ yield @guestfs, helper
107
+
108
+ clean_close
109
+
110
+ write_pipe.puts "<EOF>"
111
+
112
+ Process.wait
113
+ end
114
+
115
+ def execute( pipe = nil )
37
116
  @log.debug "Preparing guestfs..."
38
- @guestfs = Guestfs::create
117
+
118
+ @guestfs = pipe.nil? ? Guestfs::create : Guestfs::create.redirect( pipe )
39
119
 
40
120
  # TODO remove this, https://bugzilla.redhat.com/show_bug.cgi?id=502058
41
121
  @guestfs.set_append( "noapic" )
42
122
 
123
+ @guestfs.set_verbose(1)
124
+ @guestfs.set_trace(1)
125
+
43
126
  # workaround for latest qemu
44
127
  # It'll only work if qemu-stable package is installed. It is installed by default on meta-appliance
45
128
  # TODO wait for stable qemu and remove this
129
+ # Looks like in F13 (qemu-img-0.12.3-8.fc13.i686) this is fixed
46
130
  qemu_wrapper = "/usr/share/qemu-stable/bin/qemu.wrapper"
47
131
 
48
132
  if File.exists?( qemu_wrapper )
49
133
  @guestfs.set_qemu( qemu_wrapper )
50
134
  end
51
135
 
52
- @log.debug "Adding drive '#{@raw_disk}'..."
136
+ @log.trace "Adding drive '#{@raw_disk}'..."
53
137
  @guestfs.add_drive( @raw_disk )
54
- @log.debug "Drive added."
138
+ @log.trace "Drive added."
55
139
 
56
140
  @log.debug "Launching guestfs..."
57
141
  @guestfs.launch
@@ -65,23 +149,25 @@ module BoxGrinder
65
149
  mount_partitions
66
150
  end
67
151
 
68
- @log.debug "Guestfs launched."
152
+ @log.trace "Guestfs launched."
153
+
154
+ self
69
155
  end
70
156
 
71
157
  def clean_close
72
- @log.debug "Closing guestfs..."
158
+ @log.trace "Closing guestfs..."
73
159
 
74
160
  @guestfs.sync
75
161
  @guestfs.umount_all
76
162
  @guestfs.close
77
163
 
78
- @log.debug "Guestfs closed."
164
+ @log.trace "Guestfs closed."
79
165
  end
80
166
 
81
167
  def mount_partition( part, mount_point )
82
- @log.debug "Mounting #{part} partition to #{mount_point}..."
168
+ @log.trace "Mounting #{part} partition to #{mount_point}..."
83
169
  @guestfs.mount_options( "", part, mount_point )
84
- @log.debug "Partition mounted."
170
+ @log.trace "Partition mounted."
85
171
  end
86
172
 
87
173
  # TODO this is shitty, I know... https://bugzilla.redhat.com/show_bug.cgi?id=507188
@@ -112,4 +198,4 @@ module BoxGrinder
112
198
  end
113
199
  end
114
200
  end
115
- end
201
+ end
@@ -0,0 +1,69 @@
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 'logger'
22
+
23
+ module BoxGrinder
24
+ class LinuxHelper
25
+ def initialize( options = {} )
26
+ @log = options[:log] || Logger.new(STDOUT)
27
+ end
28
+
29
+ def kernel_version( guestfs )
30
+ kernel_versions = guestfs.ls("/lib/modules")
31
+ version = kernel_versions.last
32
+
33
+ if kernel_versions.size > 1
34
+ kernel_versions.each do |v|
35
+ if v.match(/PAE$/)
36
+ version = v
37
+ break
38
+ end
39
+ end
40
+ end
41
+
42
+ version
43
+ end
44
+
45
+ def kernel_image_name( guestfs )
46
+ guestfs.sh("ls -1 /boot | grep initramfs | wc -l").chomp.strip.to_i > 0 ? "initramfs" : "initrd"
47
+ end
48
+
49
+ def recreate_kernel_image( guestfs, modules = [] )
50
+ kernel_version = kernel_version( guestfs )
51
+ kernel_image_name = kernel_image_name( guestfs )
52
+
53
+ if guestfs.exists("/sbin/dracut") != 0
54
+ command = "/sbin/dracut -f -v --add-drivers #{modules.join(' ')}"
55
+ else
56
+ drivers_argument = ""
57
+ modules.each { |mod| drivers_argument << " --preload=#{mod}" }
58
+
59
+ command = "/sbin/mkinitrd -f -v#{drivers_argument}"
60
+ end
61
+
62
+ @log.trace "Additional modules to preload in kernel: #{modules.join(', ')}"
63
+
64
+ @log.debug "Recreating kernel image for #{kernel_version} kernel..."
65
+ guestfs.sh( "#{command} /boot/#{kernel_image_name}-#{kernel_version}.img #{kernel_version}" )
66
+ @log.debug "Kernel image recreated."
67
+ end
68
+ end
69
+ end
@@ -20,35 +20,44 @@
20
20
 
21
21
  module BoxGrinder
22
22
  class PackageHelper
23
- def initialize(config, appliance_config, options = {})
23
+ def initialize(config, appliance_config, dir, options = {})
24
24
  @config = config
25
25
  @appliance_config = appliance_config
26
+ @dir = dir
26
27
 
27
28
  @log = options[:log] || Logger.new(STDOUT)
28
29
  @exec_helper = options[:exec_helper] || ExecHelper.new({:log => @log})
29
30
  end
30
31
 
31
- def package(deliverables, type = :tar)
32
- files = []
33
- files << File.basename(deliverables[:disk])
32
+ def package(deliverables, options = {})
33
+ type = options[:type] || :tar
34
+ plugin_info = options[:plugin_info]
35
+
36
+ platform = 'raw'
34
37
 
35
- [:metadata, :other].each do |deliverable_type|
36
- deliverables[deliverable_type].each_value do |file|
37
- files << File.basename(file)
38
+ unless plugin_info.nil?
39
+ if plugin_info[:type] == :platform
40
+ platform = plugin_info[:name].to_s
38
41
  end
39
42
  end
40
43
 
41
- deliverable_platform = deliverables[:platform].nil? ? "" : deliverables[:platform]
42
- package_path = "#{@appliance_config.path.dir.packages}/#{@appliance_config.name}-#{@appliance_config.version}.#{@appliance_config.release}-#{@appliance_config.hardware.arch}-#{deliverable_platform}.tgz"
44
+ files = []
45
+
46
+ deliverables.each_value do |file|
47
+ files << File.basename(file)
48
+ end
49
+
50
+ #TODO rewrite this to use deliverables and previous_deliverables
51
+ package_path = "#{@dir.tmp}/#{@appliance_config.name}-#{@appliance_config.version}.#{@appliance_config.release}-#{@appliance_config.os.name}-#{@appliance_config.os.version}-#{@appliance_config.hardware.arch}-#{platform}.tgz"
43
52
 
44
53
  if File.exists?(package_path)
45
- @log.info "Package of #{type} type for #{@appliance_config.name} appliance and #{deliverable_platform} platform already exists, skipping."
54
+ @log.info "Package of #{type} type for #{@appliance_config.name} appliance and #{platform} platform already exists, skipping."
46
55
  return package_path
47
56
  end
48
57
 
49
58
  FileUtils.mkdir_p(File.dirname(package_path))
50
59
 
51
- @log.info "Packaging #{@appliance_config.name} appliance for #{deliverable_platform} platform to #{type}..."
60
+ @log.info "Packaging #{@appliance_config.name} appliance for #{platform} platform to #{type}..."
52
61
 
53
62
  case type
54
63
  when :tar