foreman_kubevirt 0.4.2 → 0.5.0
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 +4 -4
- data/app/models/foreman_kubevirt/kubevirt.rb +42 -13
- data/app/views/compute_resources/form/_kubevirt.html.erb +1 -1
- data/app/views/images/form/_kubevirt.html.erb +1 -1
- data/lib/foreman_kubevirt/version.rb +1 -1
- data/test/models/compute_resources/kubevirt_test.rb +67 -11
- data/test/unit/foreman_kubevirt_test.rb +3 -13
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c3f29a8f48b11e762c608eb0214c101a9bca7e87e8abc43419f5b04d538461a8
|
|
4
|
+
data.tar.gz: f6d536736bc4b8589ac3edb77ad28c85370bc3408bad137674e6ead7017076e1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1497af24453af9057568e04f1106e11e0e1b9fab1d460d9007baebb64b5165db2fb2b549ef6a5c432ce8393f60dac11cf60533ce2c4908cc9c64a6b4eae65b47
|
|
7
|
+
data.tar.gz: 32ee5c20e2a13e59fe10fef1186db415ca4f06da8fbf22e24d64df7f366f9e5b9775d33eb7618fbc4bc3e6b5553fe2830910a50e295c35e0c95143c83f49e38b
|
|
@@ -183,13 +183,14 @@ module ForemanKubevirt
|
|
|
183
183
|
user_data = { "userData" => options[:user_data] } if options[:user_data].present?
|
|
184
184
|
|
|
185
185
|
begin
|
|
186
|
-
volumes = create_volumes_for_vm(options)
|
|
186
|
+
volumes, volume_templates = create_volumes_for_vm(options)
|
|
187
187
|
interfaces, networks = create_network_devices_for_vm(options, volumes)
|
|
188
188
|
client.vms.create(:vm_name => options[:name],
|
|
189
189
|
:cpus => options[:cpu_cores].to_i,
|
|
190
190
|
:memory_size => convert_memory(options[:memory] + "b", :mi).to_s,
|
|
191
191
|
:memory_unit => "Mi",
|
|
192
192
|
:volumes => volumes,
|
|
193
|
+
:volume_templates => volume_templates,
|
|
193
194
|
:cloudinit => user_data,
|
|
194
195
|
:networks => networks,
|
|
195
196
|
:interfaces => interfaces)
|
|
@@ -221,7 +222,8 @@ module ForemanKubevirt
|
|
|
221
222
|
def vm_instance_defaults
|
|
222
223
|
{
|
|
223
224
|
:memory => 1024.megabytes.to_s,
|
|
224
|
-
:cpu_cores => '1'
|
|
225
|
+
:cpu_cores => '1',
|
|
226
|
+
:volumes => [new_volume].compact,
|
|
225
227
|
}
|
|
226
228
|
end
|
|
227
229
|
|
|
@@ -344,7 +346,7 @@ module ForemanKubevirt
|
|
|
344
346
|
:kubevirt_namespace => namespace,
|
|
345
347
|
:kubevirt_token => token,
|
|
346
348
|
:kubevirt_log => logger,
|
|
347
|
-
:kubevirt_verify_ssl =>
|
|
349
|
+
:kubevirt_verify_ssl => true,
|
|
348
350
|
:kubevirt_ca_cert => ca_cert,
|
|
349
351
|
:kubevirt_version => "v1alpha3"
|
|
350
352
|
)
|
|
@@ -376,22 +378,42 @@ module ForemanKubevirt
|
|
|
376
378
|
(volumes_attributes.present? || image)
|
|
377
379
|
end
|
|
378
380
|
|
|
379
|
-
def
|
|
380
|
-
|
|
381
|
-
|
|
381
|
+
def add_volume_for_image_provision(options)
|
|
382
|
+
volume = Fog::Kubevirt::Compute::Volume.new
|
|
383
|
+
volume.config = { name: rootdisk_name(options) }
|
|
384
|
+
volume.boot_order = 1
|
|
385
|
+
volume.name = 'rootdisk'
|
|
386
|
+
volume.type = 'dataVolume'
|
|
387
|
+
volume
|
|
382
388
|
end
|
|
383
389
|
|
|
384
|
-
def
|
|
390
|
+
def add_volume_template_for_image_provision(options)
|
|
385
391
|
image = options[:image_id]
|
|
386
392
|
raise ::Foreman::Exception.new _('VM should be created based on an image') unless image
|
|
387
393
|
|
|
388
|
-
|
|
394
|
+
namespace, name = image.split('/', 2)
|
|
395
|
+
if name.nil?
|
|
396
|
+
name = namespace
|
|
397
|
+
namespace = nil
|
|
398
|
+
end
|
|
389
399
|
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
400
|
+
volumes_attributes = options.fetch(:volumes_attributes, {})
|
|
401
|
+
_, boot_volume = volumes_attributes.find { |_, vol| vol[:bootable] == 'true' }
|
|
402
|
+
raise ::Foreman::Exception.new _('A bootable volume is required as a target for the image') unless boot_volume
|
|
403
|
+
capacity = boot_volume[:capacity]
|
|
404
|
+
capacity += "G" unless capacity.end_with? "G"
|
|
405
|
+
storage_class = boot_volume[:storage_class]
|
|
406
|
+
storage = { resources: { requests: { storage: capacity } } }
|
|
407
|
+
storage[:storageClassName] = storage_class if storage_class.present?
|
|
408
|
+
|
|
409
|
+
source_ref = { kind: 'DataSource', name: name, namespace: namespace }.compact
|
|
410
|
+
metadata = { name: rootdisk_name(options) }
|
|
411
|
+
{ kind: 'DataVolume', metadata: metadata, spec: { sourceRef: source_ref, storage: storage } }
|
|
412
|
+
end
|
|
413
|
+
|
|
414
|
+
def rootdisk_name(options)
|
|
415
|
+
vm_name = options[:name].parameterize
|
|
416
|
+
"#{vm_name}-root"
|
|
395
417
|
end
|
|
396
418
|
|
|
397
419
|
def validate_volume_capacity(volumes_attributes)
|
|
@@ -443,6 +465,8 @@ module ForemanKubevirt
|
|
|
443
465
|
volumes = []
|
|
444
466
|
vm_name = options[:name].gsub(/[._]+/, '-')
|
|
445
467
|
volumes_attributes.each_with_index do |(_, v), index|
|
|
468
|
+
# skip if this is a boot volume for image provisioning
|
|
469
|
+
next if image_provision && v[:bootable]
|
|
446
470
|
# Add PVC as volumes to the virtual machine
|
|
447
471
|
pvc_name = vm_name + "-claim-" + (index + 1).to_s
|
|
448
472
|
capacity = v[:capacity]
|
|
@@ -465,10 +489,15 @@ module ForemanKubevirt
|
|
|
465
489
|
|
|
466
490
|
# Add image as volume to the virtual machine
|
|
467
491
|
volumes = []
|
|
492
|
+
volume_templates = []
|
|
468
493
|
image_provision = options[:provision_method] == "image"
|
|
469
494
|
|
|
470
495
|
volumes << add_volume_for_image_provision(options) if image_provision
|
|
471
496
|
volumes.concat(add_volumes_based_on_pvcs(options, image_provision))
|
|
497
|
+
|
|
498
|
+
volume_templates << add_volume_template_for_image_provision(options) if image_provision
|
|
499
|
+
|
|
500
|
+
[volumes, volume_templates]
|
|
472
501
|
end
|
|
473
502
|
|
|
474
503
|
def create_pod_network_element
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
%>
|
|
10
10
|
|
|
11
11
|
<%= textarea_f f, :ca_cert, :label => _("X509 Certification Authorities"),
|
|
12
|
-
:placeholder => _("Optionally provide a CA, or a correctly ordered CA chain or a path to a file.
|
|
12
|
+
:placeholder => _("Optionally provide a CA, or a correctly ordered CA chain or a path to a file.") %>
|
|
13
13
|
|
|
14
14
|
<div class="col-md-offset-2">
|
|
15
15
|
<%= test_connection_button_f(f, f.object.connection_valid?) %>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
<%= text_f f, :username, :value => @image.username || "root", :help_inline => _("The user that is used to ssh into the instance, normally cloud-user, ec2-user, ubuntu, root etc") %>
|
|
2
2
|
<%= password_f f, :password, :help_inline => _("Password to authenticate with - used for SSH finish step.") %>
|
|
3
3
|
<%= checkbox_f f, :user_data, :help_inline => _("Does this image support user data input (e.g. via cloud-init)?") %>
|
|
4
|
-
<%= image_field(f, :label => _("Image"), :help_inline => _("The name of the image in
|
|
4
|
+
<%= image_field(f, :label => _("Image"), :help_inline => _("The name of the DataSource that contains the image. Use namespace/name notation to use a DataSource in a different namespace.")) %>
|
|
@@ -9,6 +9,23 @@ class ForemanKubevirtTest < ActiveSupport::TestCase
|
|
|
9
9
|
::FactoryBot.build(:compute_resource_kubevirt)
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
+
def mocked_client
|
|
13
|
+
vms = stub
|
|
14
|
+
pvcs = stub
|
|
15
|
+
pvcs.stubs(:create)
|
|
16
|
+
pvcs.stubs(:delete)
|
|
17
|
+
servers = stub
|
|
18
|
+
servers.stubs(:get)
|
|
19
|
+
storageclasses = stub
|
|
20
|
+
storageclasses.stubs(:all).returns([{ 'name': 'local' }])
|
|
21
|
+
client = stub
|
|
22
|
+
client.stubs(:vms).returns(vms)
|
|
23
|
+
client.stubs(:pvcs).returns(pvcs)
|
|
24
|
+
client.stubs(:servers).returns(servers)
|
|
25
|
+
client.stubs(:storageclasses).returns(storageclasses)
|
|
26
|
+
client
|
|
27
|
+
end
|
|
28
|
+
|
|
12
29
|
test "host_interfaces_attrs" do
|
|
13
30
|
record = new_kubevirt_vcr
|
|
14
31
|
host = ::FactoryBot.build(:host_kubevirt, :with_interfaces)
|
|
@@ -23,26 +40,65 @@ class ForemanKubevirtTest < ActiveSupport::TestCase
|
|
|
23
40
|
|
|
24
41
|
describe "create_vm" do
|
|
25
42
|
test "uses sanitized NIC names" do
|
|
26
|
-
vms = stub
|
|
27
|
-
pvcs = stub
|
|
28
|
-
pvcs.stubs(:create)
|
|
29
|
-
pvcs.stubs(:delete)
|
|
30
|
-
servers = stub
|
|
31
|
-
servers.stubs(:get)
|
|
32
|
-
client = stub
|
|
33
|
-
client.stubs(:vms).returns(vms)
|
|
34
|
-
client.stubs(:pvcs).returns(pvcs)
|
|
35
|
-
client.stubs(:servers).returns(servers)
|
|
36
43
|
record = new_kubevirt_vcr
|
|
44
|
+
client = mocked_client
|
|
37
45
|
record.stubs(:client).returns(client)
|
|
38
46
|
|
|
39
47
|
expected_networks = [{ :name => "default-network", :multus => { :networkName => "default/network" } }]
|
|
40
48
|
expected_interfaces = [{ :bridge => {}, :name => "default-network" }]
|
|
41
49
|
|
|
42
|
-
vms.expects(:create).with
|
|
50
|
+
client.vms.expects(:create).with do |args|
|
|
51
|
+
assert_equal expected_networks, args[:networks]
|
|
52
|
+
assert_equal expected_interfaces, args[:interfaces]
|
|
53
|
+
end
|
|
43
54
|
|
|
44
55
|
record.create_vm({ :name => "test", :volumes_attributes => { 0 => { :capacity => "5" } }, :interfaces_attributes => { "0" => { "cni_provider" => "multus", "network" => "default/network" } } })
|
|
45
56
|
end
|
|
57
|
+
|
|
58
|
+
test "raises an error for image based provisioning without an explicit boot volume" do
|
|
59
|
+
record = new_kubevirt_vcr
|
|
60
|
+
|
|
61
|
+
error = assert_raises(Foreman::Exception) do
|
|
62
|
+
record.create_vm({ :name => "test", :provision_method => 'image', :image_id => "default/template", :volumes_attributes => {}, :interfaces_attributes => { "0" => { "cni_provider" => "multus", "network" => "default/network" } } })
|
|
63
|
+
end
|
|
64
|
+
assert_match(/A bootable volume is required as a target for the image/, error.message)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
test "uses dataVolume for image based provisioning with an explicit boot volume" do
|
|
68
|
+
record = new_kubevirt_vcr
|
|
69
|
+
client = mocked_client
|
|
70
|
+
record.stubs(:client).returns(client)
|
|
71
|
+
|
|
72
|
+
client.vms.expects(:create).with do |args|
|
|
73
|
+
assert_equal 1, args[:volumes].length
|
|
74
|
+
assert_equal 1, args[:volume_templates].length
|
|
75
|
+
|
|
76
|
+
volume = args[:volumes].first
|
|
77
|
+
assert_equal 'dataVolume', volume.type
|
|
78
|
+
assert_equal 'test-root', volume.config[:name]
|
|
79
|
+
assert_equal 'rootdisk', volume.name
|
|
80
|
+
assert_equal 1, volume.boot_order
|
|
81
|
+
|
|
82
|
+
volume_template = args[:volume_templates].first
|
|
83
|
+
assert_equal 'DataVolume', volume_template[:kind]
|
|
84
|
+
assert_equal 'test-root', volume_template[:metadata][:name]
|
|
85
|
+
assert_equal 'DataSource', volume_template[:spec][:sourceRef][:kind]
|
|
86
|
+
assert_equal 'default', volume_template[:spec][:sourceRef][:namespace]
|
|
87
|
+
assert_equal 'template', volume_template[:spec][:sourceRef][:name]
|
|
88
|
+
assert_equal '10G', volume_template[:spec][:storage][:resources][:requests][:storage]
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
record.create_vm({ :name => "test", :provision_method => 'image', :image_id => "default/template", :volumes_attributes => { "0" => { :capacity => "10", :bootable => "true" } }, :interfaces_attributes => { "0" => { "cni_provider" => "multus", "network" => "default/network" } } })
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
test "raises an error for image based provisioning with only an extra data volume" do
|
|
95
|
+
record = new_kubevirt_vcr
|
|
96
|
+
|
|
97
|
+
error = assert_raises(Foreman::Exception) do
|
|
98
|
+
record.create_vm({ :name => "test", :provision_method => 'image', :image_id => "default/template", :volumes_attributes => { "0" => { :capacity => "10" } }, :interfaces_attributes => { "0" => { "cni_provider" => "multus", "network" => "default/network" } } })
|
|
99
|
+
end
|
|
100
|
+
assert_match(/A bootable volume is required as a target for the image/, error.message)
|
|
101
|
+
end
|
|
46
102
|
end
|
|
47
103
|
|
|
48
104
|
describe "create_network_element" do
|
|
@@ -40,7 +40,7 @@ class ForemanKubevirtTest < ActiveSupport::TestCase
|
|
|
40
40
|
"memory" => "1073741824",
|
|
41
41
|
"start" => "1",
|
|
42
42
|
"volumes_attributes" => {
|
|
43
|
-
"0" => { "_delete" => "", "storage_class" => "local-storage", "capacity" => "1", "bootable" => "
|
|
43
|
+
"0" => { "_delete" => "", "storage_class" => "local-storage", "capacity" => "1", "bootable" => "true" }
|
|
44
44
|
},
|
|
45
45
|
"image_id" => "kubevirt/fedora-cloud-registry-disk-demo",
|
|
46
46
|
"name" => "olive-kempter.example.com",
|
|
@@ -73,26 +73,16 @@ class ForemanKubevirtTest < ActiveSupport::TestCase
|
|
|
73
73
|
assert_equal 1, server.interfaces.count
|
|
74
74
|
end
|
|
75
75
|
|
|
76
|
-
test "create_vm image based without additional volumes should
|
|
76
|
+
test "create_vm image based without additional volumes should fail" do
|
|
77
77
|
vm_args = IMAGE_BASED_VM_ARGS.deep_dup
|
|
78
78
|
vm_args.delete("volumes_attributes")
|
|
79
79
|
|
|
80
|
-
Fog.mock!
|
|
81
|
-
compute_resource = new_kubevirt_vcr
|
|
82
|
-
server = compute_resource.create_vm(vm_args)
|
|
83
|
-
|
|
84
|
-
assert_equal "olive-kempter.example.com", server.name
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
test "should fail when creating a VM with_bootable flag and image based" do
|
|
88
|
-
vm_args = IMAGE_BASED_VM_ARGS.deep_dup
|
|
89
|
-
vm_args["volumes_attributes"]["0"]["bootable"] = "true"
|
|
90
80
|
Fog.mock!
|
|
91
81
|
compute_resource = new_kubevirt_vcr
|
|
92
82
|
exception = assert_raise(Foreman::Exception) do
|
|
93
83
|
compute_resource.create_vm(vm_args)
|
|
94
84
|
end
|
|
95
|
-
assert_match(/
|
|
85
|
+
assert_match(/A bootable volume is required as a target for the image/, exception.message)
|
|
96
86
|
end
|
|
97
87
|
|
|
98
88
|
test "should fail when creating a VM without an image or pvc" do
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: foreman_kubevirt
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Moti Asayag
|
|
@@ -15,7 +15,7 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - ">="
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: 1.
|
|
18
|
+
version: 1.6.0
|
|
19
19
|
- - "<"
|
|
20
20
|
- !ruby/object:Gem::Version
|
|
21
21
|
version: '2'
|
|
@@ -25,7 +25,7 @@ dependencies:
|
|
|
25
25
|
requirements:
|
|
26
26
|
- - ">="
|
|
27
27
|
- !ruby/object:Gem::Version
|
|
28
|
-
version: 1.
|
|
28
|
+
version: 1.6.0
|
|
29
29
|
- - "<"
|
|
30
30
|
- !ruby/object:Gem::Version
|
|
31
31
|
version: '2'
|