fog-libvirt 0.11.0 → 0.12.1

Sign up to get free protection for your applications and to get access to all the features.
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>