@@ -267,9 +267,166 @@ def cloud_init_volume_name
267
267
"#{ name } -cloud-init.iso"
268
268
end
269
269
270
+ # rubocop:disable Metrics
271
+ def to_xml
272
+ builder = Nokogiri ::XML ::Builder . new do |xml |
273
+ xml . domain ( :type => domain_type ) do
274
+ xml . name ( name )
275
+ xml . memory ( memory_size )
276
+
277
+ if hugepages
278
+ xml . memoryBacking do
279
+ xml . hugepages
280
+ end
281
+ end
282
+
283
+ xml . vcpu ( cpus )
284
+ xml . os do
285
+ xml . type ( os_type , :arch => arch )
286
+
287
+ boot_order . each do |dev |
288
+ xml . boot ( :dev => dev )
289
+ end
290
+ end
291
+ xml . features do
292
+ xml . acpi
293
+ xml . apic
294
+ xml . pae
295
+ end
296
+
297
+ unless cpu . empty?
298
+ if cpu [ :mode ]
299
+ xml . cpu ( :mode => cpu [ :mode ] )
300
+ else
301
+ xml . cpu do
302
+ xml . model ( cpu . dig ( :model , :name ) , :fallback => cpu . dig ( :model , :fallback ) || "allow" )
303
+ end
304
+ end
305
+ end
306
+
307
+ xml . clock ( :offset => "utc" )
308
+
309
+ xml . devices do
310
+ ceph_args = read_ceph_args
311
+
312
+ volumes . each_with_index do |volume , index |
313
+ target_device = "vd#{ ( 'a' ..'z' ) . to_a [ index ] } "
314
+ if ceph_args && volume . pool_name . include? ( ceph_args [ "libvirt_ceph_pool" ] )
315
+ xml . disk ( :type => "network" , :device => "disk" ) do
316
+ xml . driver ( :name => "qemu" , :type => volume . format_type , :cache => "writeback" , :discard => "unmap" )
317
+ xml . source ( :protocol => "rbd" , :name => volume . path )
318
+
319
+ ceph_args [ "monitor" ] &.split ( "," ) &.each do |monitor |
320
+ xml . host ( :name => monitor , :port => ceph_args [ "port" ] )
321
+ end
322
+
323
+ xml . auth ( :username => ceph_args [ "auth_username" ] ) do
324
+ if ceph_args . key? ( "auth_uuid" )
325
+ xml . secret ( :type => "ceph" , :uuid => ceph_args [ "auth_uuid" ] )
326
+ else
327
+ xml . secret ( :type => "ceph" , :usage => ceph_args [ "auth_usage" ] )
328
+ end
329
+ end
330
+
331
+ xml . target ( :dev => target_device , :bus => args [ "bus_type" ] == "virtio" ? "virtio" : "scsi" )
332
+ end
333
+ else
334
+ xml . disk ( :type => "file" , :device => "disk" ) do
335
+ xml . driver ( :name => "qemu" , :type => volume . format_type )
336
+ xml . source ( :file => volume . path )
337
+ xml . target ( :dev => target_device , :bus => "virtio" )
338
+ end
339
+ end
340
+ end
341
+
342
+ if iso_file
343
+ xml . disk ( :type => "file" , :device => "cdrom" ) do
344
+ xml . driver ( :name => "qemu" , :type => "raw" )
345
+ xml . source ( :file => "#{ iso_dir } /#{ iso_file } " )
346
+ xml . target ( :dev => "hdc" , :bus => "ide" )
347
+ xml . readonly
348
+ xml . address ( :type => "drive" , :controller => 0 , :bus => 1 , :unit => 0 )
349
+ end
350
+ end
351
+
352
+ nics . each do |nic |
353
+ xml . interface ( :type => nic . type ) do
354
+ if nic . type == "bridge"
355
+ xml . source ( :bridge => nic . bridge )
356
+ else
357
+ xml . source ( :network => nic . network )
358
+ end
359
+ xml . model ( :type => nic . model )
360
+ end
361
+ end
362
+
363
+ if guest_agent
364
+ xml . channel ( :type => "unix" ) do
365
+ xml . target ( :type => "virtio" , :name => "org.qemu.guest_agent.0" )
366
+ end
367
+ end
368
+
369
+ xml . rng ( :model => "virtio" ) do
370
+ xml . backend ( virtio_rng [ :backend_path ] , :model => virtio_rng . fetch ( :backend_model , "random" ) )
371
+ end
372
+
373
+ if arch == "s390x"
374
+ xml . controller ( :type => "scsi" , :index => "0" , :model => "virtio-scsi" )
375
+ xml . console ( :type => "pty" ) do
376
+ xml . target ( :type => "sclp" )
377
+ end
378
+ xml . memballoon ( :model => "virtio" )
379
+ else
380
+ xml . serial ( :type => "pty" ) do
381
+ xml . target ( :port => 0 )
382
+ end
383
+ xml . console ( :type => "pty" ) do
384
+ xml . target ( :port => 0 )
385
+ end
386
+ xml . input ( :type => "tablet" , :bus => "usb" )
387
+ xml . input ( :type => "mouse" , :bus => "ps2" )
388
+
389
+ graphics = xml . graphics ( :type => display [ :type ] )
390
+ if display [ :port ] . empty?
391
+ graphics . port = display [ :port ]
392
+ graphics . autoport = "no"
393
+ else
394
+ graphics . port = -1
395
+ graphics . autoport = "yes"
396
+ end
397
+ graphics . listen = display [ :listen ] unless display [ :listen ] . empty?
398
+ graphics . password = display [ :password ] unless display [ :password ] . empty?
399
+
400
+ xml . video do
401
+ xml . model ( :type => "cirrus" , :vram => 9216 , :heads => 1 )
402
+ end
403
+ end
404
+ end
405
+ end
406
+ end
407
+
408
+ builder . to_xml
409
+ end
410
+ # rubocop:enable Metrics
411
+
270
412
private
271
413
attr_accessor :volumes_path
272
414
415
+ def read_ceph_args ( path = "/etc/foreman/ceph.conf" )
416
+ return unless File . file? ( path )
417
+
418
+ args = { }
419
+
420
+ File . readlines ( path ) . each do |line |
421
+ pair = line . strip . split ( "=" )
422
+ key = pair [ 0 ]
423
+ value = pair [ 1 ]
424
+ args [ key ] = value
425
+ end
426
+
427
+ args
428
+ end
429
+
273
430
# This tests the library version before redefining the address
274
431
# method for this instance to use a method compatible with
275
432
# earlier libvirt libraries, or uses the dhcp method from more
0 commit comments