Class: BoxGrinder::LibvirtPlugin
- Inherits:
-
BasePlugin
- Object
- BasePlugin
- BoxGrinder::LibvirtPlugin
- Defined in:
- lib/boxgrinder-build/plugins/delivery/libvirt/libvirt-plugin.rb
Instance Attribute Summary
Attributes inherited from BasePlugin
Instance Method Summary collapse
-
#build_xml(opts = {}) ⇒ Object
Build the XML domain definition.
-
#determine_locally ⇒ Object
Make no external connections, just dump a basic XML skeleton and provide sensible defaults where user provided values are not given.
-
#determine_remotely ⇒ Object
Interact with a libvirtd, attempt to determine optimal settings where possible.
- #execute ⇒ Object
-
#generate_xml(guest) ⇒ Object
Preferentially choose user settings.
- #set_defaults ⇒ Object
-
#upload_image ⇒ Object
Upload an image via SFTP.
- #validate ⇒ Object
Methods inherited from BasePlugin
#current_platform, #deliverables_exists?, #init, #initialize, #is_supported_os?, #is_supported_platform?, #merge_plugin_config, #read_plugin_config, #register_deliverable, #register_supported_os, #register_supported_platform, #run, #set_default_config_value, #subtype, #supported_oses, #validate_plugin_config
Methods included from Plugins
Constructor Details
This class inherits a constructor from BoxGrinder::BasePlugin
Instance Method Details
#build_xml(opts = {}) ⇒ Object
Build the XML domain definition. If the user provides a script, it will be called after the basic definition has been constructed with the XML as the sole parameter. The output from stdout of the script will be used as the new domain definition.
237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 |
# File 'lib/boxgrinder-build/plugins/delivery/libvirt/libvirt-plugin.rb', line 237 def build_xml(opts = {}) opts = {:bus => @bus, :os_type => :hvm}.merge!(opts) builder = Builder::XmlMarkup.new(:indent => 2) xml = builder.domain(:type => opts[:domain_type].to_s) do |domain| domain.name(@appliance_name) domain.description(@appliance_config.summary) domain.memory(@appliance_config.hardware.memory * 1024) #KB domain.vcpu(@appliance_config.hardware.cpus) domain.os do |os| os.type(opts[:os_type].to_s, :arch => @appliance_config.hardware.arch) os.boot(:dev => 'hd') end domain.devices do |devices| devices.disk(:type => 'file', :device => 'disk') do |disk| disk.source(:file => "#{@libvirt_image_uri}/#{File.basename(@previous_deliverables.disk)}") disk.target(:dev => 'hda', :bus => opts[:bus].to_s) end devices.interface(:type => 'network') do |interface| interface.source(:network => @network) interface.mac(:address => @mac) if @mac end devices.console(:type => 'pty') unless @noautoconsole devices.graphics(:type => 'vnc', :port => -1) unless @novnc end domain.features do |features| features.pae if @appliance_config.os.pae end end @log.debug xml # Let the user modify the XML specification to their requirements if @script @log.info "Attempting to run user provided script for modifying libVirt XML..." xml = IO::popen("#{@script} --domain '#{xml}'").read @log.debug "Response was: #{xml}" end xml end |
#determine_locally ⇒ Object
Make no external connections, just dump a basic XML skeleton and provide sensible defaults where user provided values are not given.
201 202 203 204 205 206 207 208 |
# File 'lib/boxgrinder-build/plugins/delivery/libvirt/libvirt-plugin.rb', line 201 def determine_locally domain = @libvirt_capabilities.get_plugin(@previous_plugin_info).domain_rank.last generate_xml(OpenStruct.new({ :domain_type => domain.name, :os_type => domain.virt_rank.last, :bus => domain.bus })) end |
#determine_remotely ⇒ Object
Interact with a libvirtd, attempt to determine optimal settings where possible. Register the appliance as a new domain.
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 |
# File 'lib/boxgrinder-build/plugins/delivery/libvirt/libvirt-plugin.rb', line 160 def determine_remotely # Remove password field from URI, as libvirt doesn't support it directly. We can use it for passphrase if needed. lv_uri = URI::Generic.build(:scheme => @connection_uri.scheme, :userinfo => @connection_uri.user, :host => @connection_uri.host, :path => @connection_uri.path, :query => @connection_uri.query) # The authentication only pertains to libvirtd itself and _not_ the transport (e.g. SSH). conn = Libvirt::open_auth(lv_uri.to_s, [Libvirt::CRED_AUTHNAME, Libvirt::CRED_PASSPHRASE]) do |cred| case cred["type"] when Libvirt::CRED_AUTHNAME @connection_uri.user when Libvirt::CRED_PASSPHRASE @connection_uri.password end end if dom = get_existing_domain(conn, @appliance_name) unless @overwrite @log.fatal("A domain already exists with the name #{@appliance_name}. Set overwrite:true to automatically destroy and undefine it.") raise RuntimeError, "Domain '#{@appliance_name}' already exists" #Make better specific exception end @log.info("Undefining existing domain #{@appliance_name}") undefine_domain(dom) end guest = @libvirt_capabilities.determine_capabilities(conn, @previous_plugin_info) raise "Remote libvirt machine offered no viable guests!" if guest.nil? xml = generate_xml(guest) @log.info("Defining domain #{@appliance_name}") conn.define_domain_xml(xml) xml ensure if conn conn.close unless conn.closed? end end |
#execute ⇒ Object
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/boxgrinder-build/plugins/delivery/libvirt/libvirt-plugin.rb', line 139 def execute if @image_delivery_uri.scheme =~ /sftp/ @log.info("Transferring file via SFTP...") upload_image else @log.info("Copying disk #{@previous_deliverables.disk} to: #{@image_delivery_uri.path}...") FileUtils.cp(@previous_deliverables.disk, @image_delivery_uri.path) end if @xml_only @log.info("Determining locally only.") xml = determine_locally else @log.info("Determining remotely.") xml = determine_remotely end write_xml(xml) end |
#generate_xml(guest) ⇒ Object
Preferentially choose user settings
228 229 230 231 232 |
# File 'lib/boxgrinder-build/plugins/delivery/libvirt/libvirt-plugin.rb', line 228 def generate_xml(guest) build_xml(:domain_type => (@domain_type || guest.domain_type), :os_type => (@virt_type || guest.os_type), :bus => (@bus || guest.bus)) end |
#set_defaults ⇒ Object
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/boxgrinder-build/plugins/delivery/libvirt/libvirt-plugin.rb', line 97 def set_defaults set_default_config_value('connection_uri', '') set_default_config_value('script', false) set_default_config_value('image_delivery_uri', '/var/lib/libvirt/images') set_default_config_value('libvirt_image_uri', false) set_default_config_value('remote_no_verify', true) set_default_config_value('overwrite', false) set_default_config_value('default_permissions', 0770) set_default_config_value('xml_only', false) # Manual overrides set_default_config_value('appliance_name', [@appliance_config.name, @appliance_config.version, @appliance_config.release, @appliance_config.os.name, @appliance_config.os.version, @appliance_config.hardware.arch, current_platform].join("-")) set_default_config_value('domain_type', false) set_default_config_value('virt_type', false) set_default_config_value('bus', false) set_default_config_value('network', 'default') set_default_config_value('mac', false) set_default_config_value('noautoconsole', false) libvirt_code_patch end |
#upload_image ⇒ Object
Upload an image via SFTP
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/boxgrinder-build/plugins/delivery/libvirt/libvirt-plugin.rb', line 211 def upload_image uploader = SFTPHelper.new(:log => @log) #SFTP library automagically uses keys registered with the OS first before trying a password. uploader.connect(@image_delivery_uri.host, (@image_delivery_uri.user || Etc.getlogin), :password => @image_delivery_uri.password) uploader.upload_files(@image_delivery_uri.path, @default_permissions, @overwrite, File.basename(@previous_deliverables.disk) => @previous_deliverables.disk) ensure uploader.disconnect if uploader.connected? end |
#validate ⇒ Object
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/boxgrinder-build/plugins/delivery/libvirt/libvirt-plugin.rb', line 120 def validate set_defaults ['connection_uri', 'xml_only', 'network', 'domain_type', 'virt_type', 'script', 'bus', 'appliance_name', 'default_permissions', 'overwrite', 'noautoconsole', 'mac'].each do |v| self.instance_variable_set(:"@#{v}", @plugin_config[v]) end @libvirt_capabilities = LibvirtCapabilities.new(:log => @log) @image_delivery_uri = URI.parse(@plugin_config['image_delivery_uri']) @libvirt_image_uri = (@plugin_config['libvirt_image_uri'] || @image_delivery_uri.path) @remote_no_verify = @plugin_config['remote_no_verify'] ? 1 : 0 (@connection_uri.include?('?') ? '&' : '?') + "no_verify=#{@remote_no_verify}" @connection_uri = URI.parse(@plugin_config['connection_uri']) end |