class OVIRT::VM

Attributes

clone[R]
cluster[R]
comment[RW]
cores[R]
creation_time[R]
description[R]
display[R]
ha[R]
ha_priority[R]
host[R]
instance_type[R]
interfaces[RW]
ips[R]
memory[R]
os[R]
profile[R]
quota[R]
status[R]
storage[R]
template[R]
vnc[R]
volumes[RW]

Public Class Methods

cloudinit(opts={}) click to toggle source
    # File lib/ovirt/vm.rb
151 def self.cloudinit(opts={})
152   hostname            = opts[:hostname]
153   ip                  = opts[:ip]
154   netmask             = opts[:netmask]
155   dns                 = opts[:dns]
156   gateway             = opts[:gateway]
157   domain              = opts[:domain]
158   nicname             = opts[:nicname]
159   nicsdef             = opts[:nicsdef]
160   user                = opts[:user] || 'root'
161   password            = opts[:password]
162   ssh_authorized_keys = opts[:ssh_authorized_keys]
163   fileslist           = opts[:files]
164   runcmd              = opts[:runcmd]
165   cluster_major, cluster_minor = opts[:cluster_version]
166   api_major,api_minor, api_build, api_revision = opts[:api_version]
167   extracmd            = opts[:custom_script]
168   unless opts[:phone_home].nil?
169     phone_home = \
170     "phone_home:\n" \
171     "  url: #{opts[:phone_home]['url']}\n" \
172     "  post: #{opts[:phone_home]['post']}\n"
173     extracmd = "#{extracmd}#{phone_home}"
174   end
175   cmdlist = 'runcmd:'
176   unless runcmd.nil?
177     runcmd.each do |cmd|
178       cmdlist = \
179       "#{cmdlist}\n" \
180       "- |\n"\
181       "  #{cmd.lines.join("  ")}\n"
182     end
183     extracmd   = "#{extracmd}#{cmdlist}"
184   end
185   builder   = Nokogiri::XML::Builder.new do
186     action {
187       # An API has changed in version 3.5.5. Make sure
188       # <use_cloud_init>true</use_cloud_init> is used only if the endpoint
189       # if of that version or higher and the cluster the VM is provisioned
190       # to is of version 3.5 or higher.
191       # NOTE: RHEV-m/OVirt versions prior to 3.6.0 contain a bug
192       # (https://bugzilla.redhat.com/show_bug.cgi?id=1206068) which causes
193       # that build and revision parameters ov API version are set to 0.
194       # This may have an impact on conditional inclusion of <use_cloud_init>
195       # and thus leaving the guest unconfigured.
196       # You can either upgrade to RHEV-m/OVirt 3.6+ or work this around by
197       # manually forcing the ovirt engine to report an appropriate version:
198       # % rhevm-config -s VdcVersion=<major>.<minor>.<build>.<revision>
199       # % service ovirt-engine restart
200       # Please replace the placeholders with appropriate values.
201       if api_major > 3 || (api_major == 3 && api_minor > 5) || (api_major == 3 && api_minor == 5 && api_build >= 5)
202         use_cloud_init true if cluster_major > 3 || (cluster_major == 3 && cluster_minor >= 5)
203       end
204       vm {
205         initialization {
206           custom_script extracmd if extracmd
207           cloud_init {
208             unless hostname.nil?
209               host { address hostname  }
210             end
211             unless password.nil?
212               users { 
213                 user {  
214                   user_name user
215                   password password
216                 }
217               }
218             end
219             unless ssh_authorized_keys.nil?
220               authorized_keys {
221                 authorized_key {
222                   user { user_name user }
223                   ssh_authorized_keys.each do |sshkey|
224                     key sshkey    
225                   end
226                 }
227               }
228             end
229             network_configuration {
230               if !nicname.nil?
231                 nics {
232                   nic {
233                     name_ nicname
234                     unless ip.nil? || netmask.nil? || gateway.nil?
235                       network { ip(:'address'=> ip , :'netmask'=> netmask, :'gateway'=> gateway ) }
236                       boot_protocol 'STATIC'
237                       on_boot 'true'
238                     end 
239                   }
240                 }
241               elsif nicsdef.is_a?(Array) && !nicsdef.empty? && nicsdef.all? { |n| n.is_a?(Hash) }
242                 nics {
243                   nicsdef.each do |n|
244                     nic {
245                       name_(n[:nicname])
246                       boot_protocol_(n[:boot_protocol] || 'NONE') # Defaults to NONE boot proto
247                       on_boot_(n[:on_boot] || 'true') # Defaults to 'true'
248                       unless n[:ip].nil? || n[:netmask].nil?
249                         network_ {
250                           n[:gateway].nil? ?
251                           ip_(:address => n[:ip], :netmask => n[:netmask]) :
252                           ip_(:address => n[:ip], :netmask => n[:netmask], :gateway => n[:gateway])
253                         }
254                       end
255                     }
256                   end
257                 }
258               end
259               dns { 
260                 if dns.is_a?(String)
261                   servers { host { address dns }}
262                 elsif dns.is_a?(Array) && dns.all? {|n| n.is_a?(String) }
263                   servers { host { address dns.join(' ') }}
264                 end
265                 if domain.is_a?(String)
266                   search_domains { host {  address domain }}
267                 elsif domain.is_a?(Array) && domain.all? {|n| n.is_a?(String) }
268                   search_domains { host { address domain.join(' ')}}
269                 end
270               }
271             }
272           regenerate_ssh_keys 'true'
273           files {
274             unless extracmd.nil?
275               file_ {
276                 name_   'ignored'
277                 content extracmd
278                 type    'PLAINTEXT'
279                }
280             end
281             unless fileslist.nil?
282               fileslist.each do |fileentry|
283                 file {
284                   name_   fileentry['path']
285                   content fileentry['content']
286                   type    'PLAINTEXT'
287                 }
288               end
289             end
290           }
291          }
292         }
293       }
294     }
295   end
296   Nokogiri::XML(builder.to_xml).root.to_xml
297 end
new(client, xml) click to toggle source
Calls superclass method OVIRT::BaseObject::new
   # File lib/ovirt/vm.rb
11 def initialize(client, xml)
12   super(client, xml[:id], xml[:href], (xml/'name').first.text)
13   parse_xml_attributes!(xml)
14 end
ticket(options={}) click to toggle source
   # File lib/ovirt/vm.rb
42 def self.ticket options={}
43   builder = Nokogiri::XML::Builder.new do
44     action_{ ticket_{ expiry_(options[:expiry] || 120) } }
45   end
46   Nokogiri::XML(builder.to_xml).root.to_s
47 end
to_xml(opts={}) click to toggle source
    # File lib/ovirt/vm.rb
 49 def self.to_xml(opts={})
 50   builder = Nokogiri::XML::Builder.new do
 51     vm{
 52       name_ opts[:name] || "i-#{Time.now.to_i}"
 53       description_ opts[:description] || ""
 54       if opts[:comment]
 55         comment_ opts[:comment]
 56       end
 57       if opts[:template] && !opts[:template].empty?
 58         template_ :id => (opts[:template])
 59       elsif opts[:template_name] && !opts[:template_name].empty?
 60         template_{ name_(opts[:template_name])}
 61       else
 62         template_{name_('Blank')}
 63       end
 64       if opts[:instance_type] && !opts[:instance_type].empty?
 65         instance_type( :id => opts[:instance_type])
 66       end
 67       if opts[:quota]
 68         quota_( :id => opts[:quota])
 69       end
 70       if opts[:cluster]
 71         cluster_( :id => opts[:cluster])
 72       elsif opts[:cluster_name]
 73         cluster_{ name_(opts[:cluster_name])}
 74       end
 75       type_ opts[:hwp_id] || 'Server'
 76       if opts[:memory]
 77           memory opts[:memory]
 78       end
 79       if opts[:cores] || opts[:sockets]
 80          cpu {
 81            topology( :cores => (opts[:cores] || '1'), :sockets => (opts[:sockets] || '1') )
 82          }
 83       end
 84       # os element must not be sent when template is present (RHBZ 1104235)
 85       if opts[:template].nil? || opts[:template].empty?
 86         os_opts = opts[:os] ? opts[:os].dup : {}
 87         os_opts[:type] ||= opts[:os_type] || 'unassigned'
 88         os_opts[:boot] ||= [opts.fetch(:boot_dev1, 'network'), opts.fetch(:boot_dev2, 'hd')]
 89         os_opts[:kernel] ||= opts[:os_kernel]
 90         os_opts[:initrd] ||= opts[:os_initrd]
 91         os_opts[:cmdline] ||= opts[:os_cmdline]
 92         if opts[:first_boot_dev]
 93           os_opts[:boot] = os_opts[:boot].sort_by.with_index do |device, index|
 94             device == opts[:first_boot_dev] ? -1 : index
 95           end
 96         end
 97         os(:type => os_opts[:type]) do
 98           os_opts[:boot].each { |device| boot(:dev => device) }
 99           kernel os_opts[:kernel]
100           initrd os_opts[:initrd]
101           cmdline os_opts[:cmdline]
102         end
103       end
104       if !opts[:ha].nil? || !opts[:ha_priority].nil?
105         high_availability_{
106           enabled_(opts[:ha]) unless opts[:ha].nil?
107           priority_(opts[:ha_priority]) unless opts[:ha_priority].nil?
108         }
109       end
110       disks_ {
111         clone_(opts[:clone]) if opts[:clone]
112         if opts[:disks]
113           opts[:disks].each do |d|
114             disk(:id => d[:id]) {
115               storage_domains { storage_domain(:id => d[:storagedomain]) }
116               format_(d[:format]) if d[:format]
117               sparse_(d[:sparse]) if d[:sparse]
118             }
119           end
120         end
121       }
122       display_{
123         type_(opts[:display][:type])
124       } if opts[:display]
125       custom_properties {
126         custom_property({
127           :name => "floppyinject",
128           :value => "#{opts[:fileinject_path] || OVIRT::FILEINJECT_PATH}:#{opts[:user_data]}",
129           :regexp => "^([^:]+):(.*)$"})
130       } if(opts[:user_data_method] && opts[:user_data_method] == :custom_property)
131       payloads {
132         payload(:type => 'floppy') {
133           file(:name => "#{opts[:fileinject_path] || OVIRT::FILEINJECT_PATH}") { content(Base64::decode64(opts[:user_data])) }
134         }
135       } if(opts[:user_data_method] && opts[:user_data_method] == :payload)
136       payloads {
137         payload(:type => 'floppy') {
138           files {
139             file {
140               name_ "#{opts[:fileinject_path] || OVIRT::FILEINJECT_PATH}"
141               content Base64::decode64(opts[:user_data])
142             }
143           }
144         }
145       } if(opts[:user_data_method] && opts[:user_data_method] == :payload_v3_3)
146     }
147   end
148   Nokogiri::XML(builder.to_xml).root.to_s
149 end

Public Instance Methods

ready?() click to toggle source

In oVirt 3.1 a vm can be marked down and not locked while its volumes are locked. This method indicates if it is safe to launch the vm.

   # File lib/ovirt/vm.rb
22 def ready?
23   return false unless @status =~ /down/i
24   volumes.each do |volume|
25     return false if volume.status =~ /locked/i
26   end
27   true
28 end
running?() click to toggle source
   # File lib/ovirt/vm.rb
16 def running?
17   !(@status =~ /down/i) && !(@status =~ /wait_for_launch/i)
18 end

Private Instance Methods

parse_xml_attributes!(xml) click to toggle source
    # File lib/ovirt/vm.rb
301 def parse_xml_attributes!(xml)
302   @description = ((xml/'description').first.text rescue '')
303   @comment = ((xml/'comment').first.text rescue '')
304   @status = ((xml/'status').first.text rescue 'unknown')
305   @memory = (xml/'memory').first.text
306   @profile = (xml/'type').first.text
307   @template = Link::new(@client, (xml/'template').first[:id], (xml/'template').first[:href])
308   @instance_type = Link::new(@client, (xml/'instance_type').first[:id], (xml/'instance_type').first[:href]) rescue nil
309   @host = Link::new(@client, (xml/'host').first[:id], (xml/'host').first[:href]) rescue nil
310   @cluster = Link::new(@client, (xml/'cluster').first[:id], (xml/'cluster').first[:href])
311   @display = {
312     :type => ((xml/'display/type').first.text rescue ''),
313     :address => ((xml/'display/address').first.text rescue nil),
314     :port => ((xml/'display/port').first.text rescue nil),
315     :secure_port => ((xml/'display/secure_port').first.text rescue nil),
316     :subject => ((xml/'display/certificate/subject').first.text rescue nil),
317     :monitors => ((xml/'display/monitors').first.text rescue 0)
318   }
319   @cores = (xml/'cpu/topology').first[:cores].to_i
320   @sockets = (xml/'cpu/topology').first[:sockets].to_i rescue nil
321   @storage = ((xml/'disks/disk/size').first.text rescue nil)
322   @creation_time = (xml/'creation_time').text
323   @ips = (xml/'guest_info/ips/ip').map { |ip| ip[:address] }
324   @vnc = {
325     :address => ((xml/'display/address').first.text rescue "127.0.0.1"),
326     :port => ((xml/'display/port').first.text rescue "5890")
327   } unless @ip
328   @os = {
329       :type => (xml/'os').first[:type],
330       :boot => (xml/'os/boot').collect {|boot| boot[:dev] }
331   }
332   @ha = ((xml/'high_availability/enabled').first.text rescue nil)
333   @ha_priority = ((xml/'high_availability/priority').first.text rescue nil)
334   @quota = ((xml/'quota').first[:id] rescue nil)
335 
336   disks = xml/'disks/disk'
337   @volumes = disks.length > 0 ? disks.collect {|disk| OVIRT::Volume::new(@client, disk)} : nil
338 
339   interfaces = xml/'nics/nic'
340   @interfaces = interfaces.length > 0 ? interfaces.collect {|nic| OVIRT::Interface::new(@client, nic)} : nil
341 
342   @clone = ((xml/'disks/clone').first.text rescue nil)
343 end