Class BoxGrinder::Appliance
In: lib/boxgrinder-build/appliance.rb
lib/boxgrinder-build/appliance.rb
Parent: Object

Methods

Attributes

appliance_config  [R] 
appliance_config  [R] 
plugin_chain  [R] 
plugin_chain  [R] 

Public Class methods

[Source]

    # File lib/boxgrinder-build/appliance.rb, line 37
37:     def initialize(appliance_definition, config = Config.new, options = {})
38:       @appliance_definition = appliance_definition
39:       @config = config
40:       @log = options[:log] || LogHelper.new(:level => @config.log_level)
41:     end

[Source]

    # File lib/boxgrinder-build/appliance.rb, line 37
37:     def initialize(appliance_definition, config = Config.new, options = {})
38:       @appliance_definition = appliance_definition
39:       @config = config
40:       @log = options[:log] || LogHelper.new(:level => @config.log_level)
41:     end

Public Instance methods

This creates the appliance by executing the plugin chain.

Definition is read and validated. Afterwards a plugin chain is created and every plugin in the chain is initialized and validated. The next step is the execution of the plugin chain, step by step.

Below you can find the whole process of bootstrapping a plugin.

  Call            Scope
  ------------------------------------------
  initialize      required, internal
  init            required, internal
  after_init      optional, user implemented
  validate        optional, user implemented
  after_validate  optional, user implemented
  execute         required, user implemented
  after_execute   optional, user implemented

[Source]

     # File lib/boxgrinder-build/appliance.rb, line 152
152:     def create
153:       @log.debug "Launching new build..."
154:       @log.trace "Used configuration: #{@config.to_yaml.gsub(/(\S*(key|account|cert|username|host|password)\S*).*:(.*)/, '\1' + ": <REDACTED>")}"
155: 
156:       # Let's load all plugins first
157:       PluginHelper.new(@config, :log => @log).load_plugins
158:       read_definition
159:       validate_definition
160:       initialize_plugins
161: 
162:       remove_old_builds if @config.force
163: 
164:       execute_plugin_chain
165: 
166:       self
167:     end

This creates the appliance by executing the plugin chain.

Definition is read and validated. Afterwards a plugin chain is created and every plugin in the chain is initialized and validated. The next step is the execution of the plugin chain, step by step.

Below you can find the whole process of bootstrapping a plugin.

  Call            Scope
  ------------------------------------------
  initialize      required, internal
  init            required, internal
  after_init      optional, user implemented
  validate        optional, user implemented
  after_validate  optional, user implemented
  execute         required, user implemented
  after_execute   optional, user implemented

[Source]

     # File lib/boxgrinder-build/appliance.rb, line 152
152:     def create
153:       @log.debug "Launching new build..."
154:       @log.trace "Used configuration: #{@config.to_yaml.gsub(/(\S*(key|account|cert|username|host|password)\S*).*:(.*)/, '\1' + ": <REDACTED>")}"
155: 
156:       # Let's load all plugins first
157:       PluginHelper.new(@config, :log => @log).load_plugins
158:       read_definition
159:       validate_definition
160:       initialize_plugins
161: 
162:       remove_old_builds if @config.force
163: 
164:       execute_plugin_chain
165: 
166:       self
167:     end

[Source]

     # File lib/boxgrinder-build/appliance.rb, line 173
173:     def delivery_selected?
174:       !(@config.delivery == :none or @config.delivery.to_s.empty? == nil)
175:     end

[Source]

     # File lib/boxgrinder-build/appliance.rb, line 173
173:     def delivery_selected?
174:       !(@config.delivery == :none or @config.delivery.to_s.empty? == nil)
175:     end

[Source]

     # File lib/boxgrinder-build/appliance.rb, line 177
177:     def execute_plugin(plugin, param = nil)
178:       if plugin.deliverables_exists?
179:         @log.info "Deliverables for #{plugin.plugin_info[:name]} #{plugin.plugin_info[:type]} plugin exists, skipping."
180:       else
181:         @log.debug "Executing #{plugin.plugin_info[:type]} plugin..."
182: 
183:         # Actually run the plugin
184:         param.nil? ? plugin.run : plugin.run(param)
185: 
186:         # Run after_execute callback, if implemented
187:         plugin.after_execute if plugin.respond_to?(:after_execute)
188: 
189:         @log.debug "#{plugin.plugin_info[:type].to_s.capitalize} plugin executed."
190:       end
191:     end

[Source]

     # File lib/boxgrinder-build/appliance.rb, line 177
177:     def execute_plugin(plugin, param = nil)
178:       if plugin.deliverables_exists?
179:         @log.info "Deliverables for #{plugin.plugin_info[:name]} #{plugin.plugin_info[:type]} plugin exists, skipping."
180:       else
181:         @log.debug "Executing #{plugin.plugin_info[:type]} plugin..."
182: 
183:         # Actually run the plugin
184:         param.nil? ? plugin.run : plugin.run(param)
185: 
186:         # Run after_execute callback, if implemented
187:         plugin.after_execute if plugin.respond_to?(:after_execute)
188: 
189:         @log.debug "#{plugin.plugin_info[:type].to_s.capitalize} plugin executed."
190:       end
191:     end

[Source]

     # File lib/boxgrinder-build/appliance.rb, line 122
122:     def execute_plugin_chain
123:       @log.info "Building '#{@appliance_config.name}' appliance for #{@appliance_config.hardware.arch} architecture."
124: 
125:       @plugin_chain.each do |p|
126:         if @config.change_to_user
127:           execute_with_userchange(p)
128:         else
129:           execute_without_userchange(p)
130:         end
131:       end
132:     end

[Source]

     # File lib/boxgrinder-build/appliance.rb, line 122
122:     def execute_plugin_chain
123:       @log.info "Building '#{@appliance_config.name}' appliance for #{@appliance_config.hardware.arch} architecture."
124: 
125:       @plugin_chain.each do |p|
126:         if @config.change_to_user
127:           execute_with_userchange(p)
128:         else
129:           execute_without_userchange(p)
130:         end
131:       end
132:     end

Initializes the plugin by executing init, after_init, validate and after_validate methods.

We can be sure only for init method because it is implemented internally in base-plugin.rb, for all other methods we need to check if they exist.

[Source]

     # File lib/boxgrinder-build/appliance.rb, line 88
 88:     def initialize_plugin(plugin, plugin_info, options = {})
 89:       options = {
 90:         :log => @log
 91:       }.merge(options)
 92: 
 93:       unless @plugin_chain.empty?
 94:         options.merge!(:previous_plugin => @plugin_chain.last[:plugin])
 95:       end
 96: 
 97:       plugin.init(@config, @appliance_config, plugin_info, options)
 98: 
 99:       # Execute callbacks if implemented
100:       #
101:       # Order is very important
102:       [:after_init, :validate, :after_validate].each do |callback|
103:         plugin.send(callback) if plugin.respond_to?(callback)
104:       end
105: 
106:       param = nil
107: 
108:       # For operating system plugins we need to inject appliance definition.
109:       if plugin_info[:type] == :os
110:         param = @appliance_definition
111:       end
112: 
113:       @plugin_chain << {:plugin => plugin, :param => param}
114:     end

Initializes the plugin by executing init, after_init, validate and after_validate methods.

We can be sure only for init method because it is implemented internally in base-plugin.rb, for all other methods we need to check if they exist.

[Source]

     # File lib/boxgrinder-build/appliance.rb, line 88
 88:     def initialize_plugin(plugin, plugin_info, options = {})
 89:       options = {
 90:         :log => @log
 91:       }.merge(options)
 92: 
 93:       unless @plugin_chain.empty?
 94:         options.merge!(:previous_plugin => @plugin_chain.last[:plugin])
 95:       end
 96: 
 97:       plugin.init(@config, @appliance_config, plugin_info, options)
 98: 
 99:       # Execute callbacks if implemented
100:       #
101:       # Order is very important
102:       [:after_init, :validate, :after_validate].each do |callback|
103:         plugin.send(callback) if plugin.respond_to?(callback)
104:       end
105: 
106:       param = nil
107: 
108:       # For operating system plugins we need to inject appliance definition.
109:       if plugin_info[:type] == :os
110:         param = @appliance_definition
111:       end
112: 
113:       @plugin_chain << {:plugin => plugin, :param => param}
114:     end

Here we initialize all required plugins and create a plugin chain. Initialization involves also plugin configuration validation for specified plugin type.

[Source]

    # File lib/boxgrinder-build/appliance.rb, line 65
65:     def initialize_plugins
66:       @plugin_chain = []
67: 
68:       os_plugin, os_plugin_info = PluginManager.instance.initialize_plugin(:os, @appliance_config.os.name.to_sym)
69:       initialize_plugin(os_plugin, os_plugin_info)
70: 
71:       if platform_selected?
72:         platform_plugin, platform_plugin_info = PluginManager.instance.initialize_plugin(:platform, @config.platform)
73:         initialize_plugin(platform_plugin, platform_plugin_info)
74:       end
75: 
76:       if delivery_selected?
77:         delivery_plugin, delivery_plugin_info = PluginManager.instance.initialize_plugin(:delivery, @config.delivery)
78:         # Here we need to specify additionally the type of the plugin, as some delivery plugins
79:         # can have multiple types of delivery implemented. See s3-plugin.rb for example.
80:         initialize_plugin(delivery_plugin, delivery_plugin_info, :type => @config.delivery)
81:       end
82:     end

Here we initialize all required plugins and create a plugin chain. Initialization involves also plugin configuration validation for specified plugin type.

[Source]

    # File lib/boxgrinder-build/appliance.rb, line 65
65:     def initialize_plugins
66:       @plugin_chain = []
67: 
68:       os_plugin, os_plugin_info = PluginManager.instance.initialize_plugin(:os, @appliance_config.os.name.to_sym)
69:       initialize_plugin(os_plugin, os_plugin_info)
70: 
71:       if platform_selected?
72:         platform_plugin, platform_plugin_info = PluginManager.instance.initialize_plugin(:platform, @config.platform)
73:         initialize_plugin(platform_plugin, platform_plugin_info)
74:       end
75: 
76:       if delivery_selected?
77:         delivery_plugin, delivery_plugin_info = PluginManager.instance.initialize_plugin(:delivery, @config.delivery)
78:         # Here we need to specify additionally the type of the plugin, as some delivery plugins
79:         # can have multiple types of delivery implemented. See s3-plugin.rb for example.
80:         initialize_plugin(delivery_plugin, delivery_plugin_info, :type => @config.delivery)
81:       end
82:     end

[Source]

     # File lib/boxgrinder-build/appliance.rb, line 169
169:     def platform_selected?
170:       !(@config.platform == :none or @config.platform.to_s.empty? == nil)
171:     end

[Source]

     # File lib/boxgrinder-build/appliance.rb, line 169
169:     def platform_selected?
170:       !(@config.platform == :none or @config.platform.to_s.empty? == nil)
171:     end

[Source]

    # File lib/boxgrinder-build/appliance.rb, line 43
43:     def read_definition
44:       appliance_helper = ApplianceDefinitionHelper.new(:log => @log)
45:       appliance_helper.read_definitions(@appliance_definition)
46: 
47:       appliance_configs = appliance_helper.appliance_configs
48:       appliance_config = appliance_configs.first
49: 
50:       raise ValidationError, "Ensure your appliance definition file has a '.appl' extension: #{File.basename(@appliance_definition)}." if appliance_config.nil?
51: 
52:       appliance_config_helper = ApplianceConfigHelper.new(appliance_configs)
53:       @appliance_config = appliance_config_helper.merge(appliance_config.clone.init_arch).initialize_paths
54:     end

[Source]

    # File lib/boxgrinder-build/appliance.rb, line 43
43:     def read_definition
44:       appliance_helper = ApplianceDefinitionHelper.new(:log => @log)
45:       appliance_helper.read_definitions(@appliance_definition)
46: 
47:       appliance_configs = appliance_helper.appliance_configs
48:       appliance_config = appliance_configs.first
49: 
50:       raise ValidationError, "Ensure your appliance definition file has a '.appl' extension: #{File.basename(@appliance_definition)}." if appliance_config.nil?
51: 
52:       appliance_config_helper = ApplianceConfigHelper.new(appliance_configs)
53:       @appliance_config = appliance_config_helper.merge(appliance_config.clone.init_arch).initialize_paths
54:     end

[Source]

     # File lib/boxgrinder-build/appliance.rb, line 116
116:     def remove_old_builds
117:       @log.info "Removing previous builds for #{@appliance_config.name} appliance..."
118:       FileUtils.rm_rf(@appliance_config.path.build)
119:       @log.debug "Previous builds removed."
120:     end

[Source]

     # File lib/boxgrinder-build/appliance.rb, line 116
116:     def remove_old_builds
117:       @log.info "Removing previous builds for #{@appliance_config.name} appliance..."
118:       FileUtils.rm_rf(@appliance_config.path.build)
119:       @log.debug "Previous builds removed."
120:     end

[Source]

    # File lib/boxgrinder-build/appliance.rb, line 56
56:     def validate_definition
57:       os_plugin = PluginManager.instance.plugins[:os][@appliance_config.os.name.to_sym]
58: 
59:       raise "Unsupported operating system selected: #{@appliance_config.os.name}. Make sure you have installed right operating system plugin, see http://boxgrinder.org/tutorials/boxgrinder-build-plugins/#Operating_system_plugins. Supported OSes are: #{PluginManager.instance.plugins[:os].keys.join(", ")}" if os_plugin.nil?
60:       raise "Unsupported operating system version selected: #{@appliance_config.os.version}. Supported versions are: #{os_plugin[:versions].join(", ")}" unless @appliance_config.os.version.nil? or os_plugin[:versions].include?(@appliance_config.os.version)
61:     end

[Source]

    # File lib/boxgrinder-build/appliance.rb, line 56
56:     def validate_definition
57:       os_plugin = PluginManager.instance.plugins[:os][@appliance_config.os.name.to_sym]
58: 
59:       raise "Unsupported operating system selected: #{@appliance_config.os.name}. Make sure you have installed right operating system plugin, see http://boxgrinder.org/tutorials/boxgrinder-build-plugins/#Operating_system_plugins. Supported OSes are: #{PluginManager.instance.plugins[:os].keys.join(", ")}" if os_plugin.nil?
60:       raise "Unsupported operating system version selected: #{@appliance_config.os.version}. Supported versions are: #{os_plugin[:versions].join(", ")}" unless @appliance_config.os.version.nil? or os_plugin[:versions].include?(@appliance_config.os.version)
61:     end

[Validate]