fog-libvirt 0.11.0 → 0.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 478f04152afea3fd1b8ea8e6aa2d8a2bcdc83fc121f2e9cf61925c64a69c483b
4
- data.tar.gz: 364dcd8e9c09434b872d06b2c0d8bfce4c2f9320a57ee8d0f954223628797814
3
+ metadata.gz: 12e7867890312a401d0733ed3bd058c7bfba0488d32748569d6de134e516a752
4
+ data.tar.gz: 1e37605f3bd9fee08a79d18d4383bcb68f38d88675f12ead62b6366afc1c0a60
5
5
  SHA512:
6
- metadata.gz: b65c110f9d40bc749f967da511d7c534852dd4004d39b410cc07125eac26a0ebbece4fbbe7a38de1026142d5fe6d4457abba0f472a2769ef900c31af1e98d939
7
- data.tar.gz: 5e2508a3aeef1041963995a594b6c3788c9bda9638f5ff73f2a5fd2c12fbd1e18556c46a983b3ae6de07e96a08d3fd15c6b037fb1f2f845194587a69d844b360
6
+ metadata.gz: 6c5a173e6974eaa247bad12a3d3cacd10a43a1679dba49a361eb179e6a2a5d58ed12dacdab08b25c24ea49d05024f26b6c9564a2fb8fbf95be3e0500af6447c5
7
+ data.tar.gz: cb7536c410f12da3549d328e19dd6f997f0a3ae4795a90d6eea576bcca8e79a0c7a086ec8dc6b85c84e860d93ba70109d13cd3a0684769eec4991ff0c5311592
data/Gemfile CHANGED
@@ -6,4 +6,7 @@ group :development, :test do
6
6
  gem "octokit", :require => false
7
7
  end
8
8
 
9
+ # 0.8.3 breaks our tests
10
+ gem "ruby-libvirt", ">= 0.7.0", "< 0.8.3"
11
+
9
12
  gemspec
data/fog-libvirt.gemspec CHANGED
@@ -33,7 +33,6 @@ Gem::Specification.new do |s|
33
33
 
34
34
  s.add_development_dependency("net-ssh")
35
35
  s.add_development_dependency("minitest", "~> 5.0")
36
- s.add_development_dependency("minitest-stub-const")
37
36
  s.add_development_dependency("pry")
38
37
  s.add_development_dependency("rake")
39
38
  s.add_development_dependency("rubocop")
@@ -90,12 +90,13 @@ module Fog
90
90
  volumes.first.path if volumes and volumes.first
91
91
  end
92
92
 
93
- def destroy(options={ :destroy_volumes => false, :flags => 0 })
93
+ def destroy(options={ :destroy_volumes => false, :flags => ::Libvirt::Domain::UNDEFINE_NVRAM })
94
94
  poweroff unless stopped?
95
- if options.fetch(:flags, 0).zero?
95
+ flags = options.fetch(:flags, ::Libvirt::Domain::UNDEFINE_NVRAM)
96
+ if flags.zero?
96
97
  service.vm_action(uuid, :undefine)
97
98
  else
98
- service.vm_action(uuid, :undefine, options[:flags])
99
+ service.vm_action(uuid, :undefine, flags)
99
100
  end
100
101
  volumes.each { |vol| vol.destroy } if options[:destroy_volumes]
101
102
  true
@@ -147,7 +148,7 @@ module Fog
147
148
 
148
149
  def volumes
149
150
  # lazy loading of volumes
150
- @volumes ||= (@volumes_path || []).map{|path| service.volumes.all(:path => path).first }
151
+ @volumes ||= (@volumes_path || []).map{ |path| service.volumes.all(:path => path).first }.compact
151
152
  end
152
153
 
153
154
  def private_ip_address
@@ -267,9 +268,179 @@ module Fog
267
268
  "#{name}-cloud-init.iso"
268
269
  end
269
270
 
271
+ # rubocop:disable Metrics
272
+ def to_xml
273
+ builder = Nokogiri::XML::Builder.new do |xml|
274
+ xml.domain(:type => domain_type) do
275
+ xml.name(name)
276
+ xml.memory(memory_size)
277
+
278
+ if hugepages
279
+ xml.memoryBacking do
280
+ xml.hugepages
281
+ end
282
+ end
283
+
284
+ xml.vcpu(cpus)
285
+ xml.os do
286
+ type = xml.type(os_type, :arch => arch)
287
+ type[:machine] = "q35" if ["i686", "x86_64"].include?(arch)
288
+
289
+ boot_order.each do |dev|
290
+ xml.boot(:dev => dev)
291
+ end
292
+ end
293
+ xml.features do
294
+ xml.acpi
295
+ xml.apic
296
+ end
297
+
298
+ unless cpu.empty?
299
+ if cpu.dig(:model, :name)
300
+ xml.cpu do
301
+ xml.model(cpu.dig(:model, :name), :fallback => cpu.dig(:model, :fallback) || "allow")
302
+ end
303
+ else
304
+ xml.cpu(
305
+ :mode => cpu.dig(:model, :name) || "host-passthrough",
306
+ :check => cpu.fetch(:check, "none"),
307
+ :migratable => cpu.fetch(:migratable, "on")
308
+ )
309
+ end
310
+ end
311
+
312
+ xml.clock(:offset => "utc") do
313
+ xml.timer(:name => "rtc", :tickpolicy => "catchup")
314
+ xml.timer(:name => "pit", :tickpolicy => "delay")
315
+ xml.timer(:name => "hpet", :present => "no")
316
+ end
317
+
318
+ xml.devices do
319
+ ceph_args = read_ceph_args
320
+
321
+ volumes.each_with_index do |volume, index|
322
+ target_device = "vd#{('a'..'z').to_a[index]}"
323
+ if ceph_args && volume.pool_name.include?(ceph_args["libvirt_ceph_pool"])
324
+ xml.disk(:type => "network", :device => "disk") do
325
+ xml.driver(:name => "qemu", :type => volume.format_type, :cache => "writeback", :discard => "unmap")
326
+ xml.source(:protocol => "rbd", :name => volume.path)
327
+
328
+ ceph_args["monitor"]&.split(",")&.each do |monitor|
329
+ xml.host(:name => monitor, :port => ceph_args["port"])
330
+ end
331
+
332
+ xml.auth(:username => ceph_args["auth_username"]) do
333
+ if ceph_args.key?("auth_uuid")
334
+ xml.secret(:type => "ceph", :uuid => ceph_args["auth_uuid"])
335
+ else
336
+ xml.secret(:type => "ceph", :usage => ceph_args["auth_usage"])
337
+ end
338
+ end
339
+
340
+ xml.target(:dev => target_device, :bus => args["bus_type"] == "virtio" ? "virtio" : "scsi")
341
+ end
342
+ else
343
+ is_block = volume.path.start_with?("/dev/")
344
+ xml.disk(:type => is_block ? "block" : "file", :device => "disk") do
345
+ xml.driver(:name => "qemu", :type => volume.format_type)
346
+ if is_block
347
+ xml.source(:dev => volume.path)
348
+ else
349
+ xml.source(:file => volume.path)
350
+ end
351
+ xml.target(:dev => target_device, :bus => "virtio")
352
+ end
353
+ end
354
+ end
355
+
356
+ if iso_file
357
+ xml.disk(:type => "file", :device => "cdrom") do
358
+ xml.driver(:name => "qemu", :type => "raw")
359
+ xml.source(:file => "#{iso_dir}/#{iso_file}")
360
+ xml.target(:dev => "hdc", :bus => "ide")
361
+ xml.readonly
362
+ xml.address(:type => "drive", :controller => 0, :bus => 1, :unit => 0)
363
+ end
364
+ end
365
+
366
+ nics.each do |nic|
367
+ xml.interface(:type => nic.type) do
368
+ if nic.type == "bridge"
369
+ xml.source(:bridge => nic.bridge)
370
+ else
371
+ xml.source(:network => nic.network)
372
+ end
373
+ xml.model(:type => nic.model)
374
+ end
375
+ end
376
+
377
+ if guest_agent
378
+ xml.channel(:type => "unix") do
379
+ xml.target(:type => "virtio", :name => "org.qemu.guest_agent.0")
380
+ end
381
+ end
382
+
383
+ xml.rng(:model => "virtio") do
384
+ xml.backend(virtio_rng[:backend_path], :model => virtio_rng.fetch(:backend_model, "random"))
385
+ end
386
+
387
+ if arch == "s390x"
388
+ xml.controller(:type => "scsi", :index => "0", :model => "virtio-scsi")
389
+ xml.console(:type => "pty") do
390
+ xml.target(:type => "sclp")
391
+ end
392
+ xml.memballoon(:model => "virtio")
393
+ else
394
+ xml.serial(:type => "pty") do
395
+ xml.target(:port => 0)
396
+ end
397
+ xml.console(:type => "pty") do
398
+ xml.target(:port => 0)
399
+ end
400
+ xml.input(:type => "tablet", :bus => "usb")
401
+ xml.input(:type => "mouse", :bus => "ps2")
402
+
403
+ graphics = xml.graphics(:type => display[:type])
404
+ if display[:port].empty?
405
+ graphics.port = display[:port]
406
+ graphics.autoport = "no"
407
+ else
408
+ graphics.port = -1
409
+ graphics.autoport = "yes"
410
+ end
411
+ graphics.listen = display[:listen] unless display[:listen].empty?
412
+ graphics.passwd = display[:password] unless display[:password].empty?
413
+
414
+ xml.video do
415
+ xml.model(:type => "cirrus", :vram => 9216, :heads => 1)
416
+ end
417
+ end
418
+ end
419
+ end
420
+ end
421
+
422
+ builder.to_xml
423
+ end
424
+ # rubocop:enable Metrics
425
+
270
426
  private
271
427
  attr_accessor :volumes_path
272
428
 
429
+ def read_ceph_args(path = "/etc/foreman/ceph.conf")
430
+ return unless File.file?(path)
431
+
432
+ args = {}
433
+
434
+ File.readlines(path).each do |line|
435
+ pair = line.strip.split("=")
436
+ key = pair[0]
437
+ value = pair[1]
438
+ args[key] = value
439
+ end
440
+
441
+ args
442
+ end
443
+
273
444
  # This tests the library version before redefining the address
274
445
  # method for this instance to use a method compatible with
275
446
  # earlier libvirt libraries, or uses the dhcp method from more
@@ -479,7 +650,7 @@ module Fog
479
650
  {
480
651
  :persistent => true,
481
652
  :cpus => 1,
482
- :memory_size => 256 *1024,
653
+ :memory_size => 256 * 1024,
483
654
  :name => randomized_name,
484
655
  :os_type => "hvm",
485
656
  :arch => "x86_64",
@@ -109,7 +109,7 @@ module Fog
109
109
  :memory_size => 6,
110
110
  :cpus => 5,
111
111
  :autostart => false,
112
- :os_type => "RHEL6",
112
+ :os_type => "hvm",
113
113
  :active => false,
114
114
  :vnc_port => 5910,
115
115
  :boot_order => boot_order(xml),
@@ -1,5 +1,5 @@
1
1
  module Fog
2
2
  module Libvirt
3
- VERSION = '0.11.0'
3
+ VERSION = '0.12.1'
4
4
  end
5
5
  end
@@ -36,8 +36,8 @@ class ServerTest < Minitest::Test
36
36
  end
37
37
 
38
38
  def test_ssh_ip_command_success
39
- fog_ssh = MiniTest::Mock.new
40
- result = MiniTest::Mock.new
39
+ fog_ssh = Minitest::Mock.new
40
+ result = Minitest::Mock.new
41
41
  result.expect(:status, 0)
42
42
  result.expect(:stdout, "any_ip")
43
43
  fog_ssh.expect(:run, [result], [String])
@@ -49,10 +49,10 @@ class ServerTest < Minitest::Test
49
49
  end
50
50
 
51
51
  def test_local_ip_command_success
52
- proc_info = MiniTest::Mock.new
52
+ proc_info = Minitest::Mock.new
53
53
  proc_info.expect(:each_line, "127.0.0.1")
54
54
  proc_info.expect(:pid, 0)
55
- status = MiniTest::Mock.new
55
+ status = Minitest::Mock.new
56
56
  status.expect(:exitstatus, 0)
57
57
  Process.stubs(:waitpid2).returns([0, status])
58
58
  IO.stub(:popen, true, proc_info) do
@@ -59,5 +59,25 @@ Shindo.tests('Fog::Compute[:libvirt] | server model', ['libvirt']) do
59
59
  end
60
60
  end
61
61
  test('be a kind of Fog::Libvirt::Compute::Server') { server.kind_of? Fog::Libvirt::Compute::Server }
62
+ tests("serializes to xml") do
63
+ test("with memory") { server.to_xml.match?(%r{<memory>\d+</memory>}) }
64
+ test("with disk of type file") do
65
+ xml = server.to_xml
66
+ xml.match?(/<disk type="file" device="disk">/) && xml.match?(%r{<source file="path/to/disk"/>})
67
+ end
68
+ test("with disk of type block") do
69
+ server = Fog::Libvirt::Compute::Server.new(
70
+ {
71
+ :nics => [],
72
+ :volumes => [
73
+ Fog::Libvirt::Compute::Volume.new({ :path => "/dev/sda", :pool_name => "dummy" })
74
+ ]
75
+ }
76
+ )
77
+ xml = server.to_xml
78
+ xml.match?(/<disk type="block" device="disk">/) && xml.match?(%r{<source dev="/dev/sda"/>})
79
+ end
80
+ test("with q35 machine type on x86_64") { server.to_xml.match?(%r{<type arch="x86_64" machine="q35">hvm</type>}) }
81
+ end
62
82
  end
63
83
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fog-libvirt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.0
4
+ version: 0.12.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - geemus (Wesley Beary)
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-12-12 00:00:00.000000000 Z
11
+ date: 2024-07-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fog-core
@@ -108,20 +108,6 @@ dependencies:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
110
  version: '5.0'
111
- - !ruby/object:Gem::Dependency
112
- name: minitest-stub-const
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - ">="
116
- - !ruby/object:Gem::Version
117
- version: '0'
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - ">="
123
- - !ruby/object:Gem::Version
124
- version: '0'
125
111
  - !ruby/object:Gem::Dependency
126
112
  name: pry
127
113
  requirement: !ruby/object:Gem::Requirement
@@ -258,7 +244,6 @@ files:
258
244
  - lib/fog/libvirt/models/compute/servers.rb
259
245
  - lib/fog/libvirt/models/compute/templates/network.xml.erb
260
246
  - lib/fog/libvirt/models/compute/templates/pool.xml.erb
261
- - lib/fog/libvirt/models/compute/templates/server.xml.erb
262
247
  - lib/fog/libvirt/models/compute/templates/volume.xml.erb
263
248
  - lib/fog/libvirt/models/compute/util/uri.rb
264
249
  - lib/fog/libvirt/models/compute/util/util.rb
@@ -335,7 +320,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
335
320
  - !ruby/object:Gem::Version
336
321
  version: '0'
337
322
  requirements: []
338
- rubygems_version: 3.3.7
323
+ rubygems_version: 3.4.19
339
324
  signing_key:
340
325
  specification_version: 2
341
326
  summary: Module for the 'fog' gem to support libvirt
@@ -1,155 +0,0 @@
1
- <domain type='<%= domain_type %>'>
2
- <name><%= name %></name>
3
- <memory><%= memory_size %></memory>
4
- <% if hugepages -%>
5
- <memoryBacking>
6
- <hugepages/>
7
- </memoryBacking>
8
- <% end -%>
9
- <vcpu><%= cpus %></vcpu>
10
- <os>
11
- <type arch='<%= arch %>'><%= os_type %></type>
12
- <% boot_order.each do |dev| -%>
13
- <boot dev='<%= dev %>'/>
14
- <% end -%>
15
- </os>
16
- <features>
17
- <acpi/>
18
- <apic/>
19
- <pae/>
20
- </features>
21
- <% if !cpu.empty? -%>
22
- <% if cpu[:mode] -%>
23
- <cpu mode='<%= cpu[:mode] %>'>
24
- <% else -%>
25
- <cpu>
26
- <% end -%>
27
- <%
28
- fallback = 'allow'
29
- model = ''
30
- if cpu[:model]
31
- fallback = cpu[:model][:fallback] if cpu[:model][:fallback]
32
- model = cpu[:model][:name] if cpu[:model][:name]
33
- end
34
- -%>
35
- <model fallback='<%= fallback %>'><%= model %></model>
36
- </cpu>
37
- <% end -%>
38
- <clock offset='utc'/>
39
- <devices>
40
- <% args = {}
41
- if File.file?('/etc/foreman/ceph.conf')
42
- File.readlines('/etc/foreman/ceph.conf').each do |line|
43
- pair = line.strip.split("=")
44
- key = pair[0]
45
- value = pair[1]
46
- args[key] = value
47
- end
48
- end
49
- %>
50
- <% volumes.each do |vol| -%>
51
- <% if File.file?('/etc/foreman/ceph.conf') && vol.pool_name.include?(args["libvirt_ceph_pool"]) %>
52
- <disk type='network' device='disk'>
53
- <driver name='qemu' type='<%= vol.format_type %>' cache='writeback' discard='unmap'/>
54
- <source protocol='rbd' name='<%= vol.path %>'>
55
- <% if args.key?("monitor") -%>
56
- <% args["monitor"].split(",").each do |mon| %>
57
- <host name='<%= mon %>' port='<%= args["port"] %>'/>
58
- <% end %>
59
- <% end %>
60
- </source>
61
- <auth username='<%= args["auth_username"] %>'>
62
- <% if args.key?("auth_uuid") -%>
63
- <secret type='ceph' uuid='<%= args["auth_uuid"] %>'/>
64
- <% else -%>
65
- <secret type='ceph' usage='<%= args["auth_usage"] %>'/>
66
- <% end -%>
67
- </auth>
68
- <% if args['bus_type'] == 'virtio' %>
69
- <target dev='vd<%= ('a'..'z').to_a[volumes.index(vol)] %>' bus='virtio'/>
70
- <% else %>
71
- <target dev='sd<%= ('a'..'z').to_a[volumes.index(vol)] %>' bus='scsi'/>
72
- <% end %>
73
- </disk>
74
- <% else %>
75
- <disk type='file' device='disk'>
76
- <driver name='qemu' type='<%= vol.format_type %>'/>
77
- <source file='<%= vol.path %>'/>
78
- <%# we need to ensure a unique target dev -%>
79
- <target dev='vd<%= ('a'..'z').to_a[volumes.index(vol)] %>' bus='virtio'/>
80
- </disk>
81
- <% end %>
82
- <% end -%>
83
- <% if iso_file -%>
84
- <disk type='file' device='cdrom'>
85
- <driver name='qemu' type='raw'/>
86
- <source file='<%= "#{iso_dir}/#{iso_file}" %>'/>
87
- <target dev='hdc' bus='ide'/>
88
- <readonly/>
89
- <address type='drive' controller='0' bus='1' unit='0'/>
90
- </disk>
91
- <% end -%>
92
- <% nics.each do |nic| -%>
93
- <interface type='<%= nic.type %>'>
94
- <source <%= nic.type == 'bridge' ? "bridge='#{nic.bridge}'" : "network='#{nic.network}'" %> />
95
- <model type='<%= nic.model %>'/>
96
- </interface>
97
- <% end -%>
98
- <% if guest_agent -%>
99
- <channel type='unix'>
100
- <target type='virtio' name='org.qemu.guest_agent.0'/>
101
- </channel>
102
- <% end -%>
103
- <rng model='virtio'>
104
- <%
105
- rng_backend_model = virtio_rng[:backend_model] ? virtio_rng[:backend_model] : 'random'
106
- -%>
107
- <% if virtio_rng[:backend_path] -%>
108
- <backend model='<%= rng_backend_model %>'><%= virtio_rng[:backend_path] %></backend>
109
- <% else -%>
110
- <backend model='<%= rng_backend_model %>'/>
111
- <% end -%>
112
- </rng>
113
- <% if arch == "s390x" -%>
114
- <controller type="scsi" index="0" model="virtio-scsi"/>
115
- <console type="pty">
116
- <target type="sclp"/>
117
- </console>
118
- <memballoon model="virtio"/>
119
- <% else -%>
120
- <serial type='pty'>
121
- <target port='0'/>
122
- </serial>
123
- <console type='pty'>
124
- <target port='0'/>
125
- </console>
126
- <input type='tablet' bus='usb'/>
127
- <input type='mouse' bus='ps2'/>
128
- <% end -%>
129
- <%
130
- display_type = display[:type]
131
-
132
- if display[:port].empty?
133
- display_port = display[:port]
134
- autoport = 'no'
135
- else
136
- display_port = '-1'
137
- autoport = 'yes'
138
- end
139
-
140
- unless display[:listen].empty?
141
- display_listen = "listen='#{display[:listen]}'"
142
- end
143
-
144
- unless display[:password].empty?
145
- display_password = "passwd='#{display[:password]}'"
146
- end
147
- -%>
148
- <% if arch != "s390x" -%>
149
- <graphics type='<%= display_type %>' port='<%= display_port %>' autoport='<%= autoport %>' <%= display_listen %> <%= display_password %> />
150
- <video>
151
- <model type='cirrus' vram='9216' heads='1'/>
152
- </video>
153
- <% end -%>
154
- </devices>
155
- </domain>