boxgrinder-build 0.4.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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