fog-kubevirt 1.2.5 → 1.3.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/lib/fog/kubevirt.rb +3 -2
- data/lib/fog/kubevirt/compute/compute.rb +5 -148
- data/lib/fog/kubevirt/compute/models/persistentvolume.rb +9 -9
- data/lib/fog/kubevirt/compute/models/persistentvolumes.rb +6 -1
- data/lib/fog/kubevirt/compute/models/pvcs.rb +3 -1
- data/lib/fog/kubevirt/compute/models/storageclass.rb +8 -2
- data/lib/fog/kubevirt/compute/models/template.rb +6 -0
- data/lib/fog/kubevirt/compute/models/vm.rb +1 -0
- data/lib/fog/kubevirt/compute/models/vminstances.rb +1 -1
- data/lib/fog/kubevirt/compute/models/vms.rb +12 -3
- data/lib/fog/kubevirt/compute/requests/create_networkattachmentdef.rb +0 -3
- data/lib/fog/kubevirt/compute/requests/create_persistentvolume.rb +0 -3
- data/lib/fog/kubevirt/compute/requests/create_pvc.rb +0 -3
- data/lib/fog/kubevirt/compute/requests/create_service.rb +0 -3
- data/lib/fog/kubevirt/compute/requests/create_storageclass.rb +0 -3
- data/lib/fog/kubevirt/compute/requests/create_vm.rb +0 -3
- data/lib/fog/kubevirt/compute/requests/create_vminstance.rb +0 -3
- data/lib/fog/kubevirt/compute/utils/exception_wrapper.rb +43 -0
- data/lib/fog/kubevirt/compute/utils/unit_converter.rb +115 -0
- data/lib/fog/kubevirt/version.rb +1 -1
- data/spec/integration/mac_vmi_spec.rb +135 -0
- data/spec/integration/net-attach-def_spec.rb +43 -0
- data/spec/integration/pvcs_spec.rb +3 -2
- data/spec/integration/shared_context.rb +11 -4
- data/spec/integration/volumes_spec.rb +45 -0
- data/spec/unit/create_vm_spec.rb +4 -3
- data/spec/unit/unit_converter_spec.rb +4 -2
- metadata +10 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b8646bec0df5d890b6c7aca5738a39596c982146
|
4
|
+
data.tar.gz: aa9d02efd6cd353248becb936f2365b25765ea03
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8bbe31efac532a38857e420fd847d878c0653eb64b75266506b03c7bd5b8fe918a908d99a71a391bf44e8b16d2ca3d5f157bc7a9787170fadb8bde99751eae3c
|
7
|
+
data.tar.gz: d72fa662e0dbf84869a8e66e7f30ea96062bc8365415733c4eef0fb7ea6c55851440b27cd94b27e1482cbea5f25a8b8b10fe4d0662f45ac0bd72c7445dcbdd69
|
data/lib/fog/kubevirt.rb
CHANGED
@@ -7,9 +7,10 @@ module Fog
|
|
7
7
|
|
8
8
|
module Errors
|
9
9
|
class ServiceError < Fog::Errors::Error; end
|
10
|
-
class AlreadyExistsError < Fog::Errors::Error; end
|
11
10
|
class ClientError < Fog::Errors::Error; end
|
12
|
-
class
|
11
|
+
class AlreadyExistsError < ClientError; end
|
12
|
+
class NotFoundError < ClientError; end
|
13
|
+
class ValidationError < ClientError; end
|
13
14
|
end
|
14
15
|
|
15
16
|
service(:compute, 'Compute')
|
@@ -2,7 +2,8 @@ require 'delegate'
|
|
2
2
|
require 'json'
|
3
3
|
require 'rest-client'
|
4
4
|
|
5
|
-
require
|
5
|
+
require 'fog/core'
|
6
|
+
require 'fog/kubevirt/compute/utils/exception_wrapper'
|
6
7
|
|
7
8
|
module Fog
|
8
9
|
module Kubevirt
|
@@ -84,150 +85,6 @@ module Fog
|
|
84
85
|
end
|
85
86
|
end
|
86
87
|
|
87
|
-
class ExceptionWrapper
|
88
|
-
def initialize(client, version)
|
89
|
-
@client = client
|
90
|
-
@version = version
|
91
|
-
end
|
92
|
-
|
93
|
-
def method_missing(symbol, *args)
|
94
|
-
super unless @client.respond_to?(symbol)
|
95
|
-
|
96
|
-
if block_given?
|
97
|
-
@client.__send__(symbol, *args) do |*block_args|
|
98
|
-
yield(*block_args)
|
99
|
-
end
|
100
|
-
else
|
101
|
-
@client.__send__(symbol, *args)
|
102
|
-
end
|
103
|
-
rescue KubeException => e
|
104
|
-
raise ::Fog::Kubevirt::Errors::ClientError, e
|
105
|
-
end
|
106
|
-
|
107
|
-
def respond_to_missing?(method_name, include_private = false)
|
108
|
-
@client.respond_to?(symbol, include_all) || super
|
109
|
-
end
|
110
|
-
|
111
|
-
def version
|
112
|
-
@version
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
#
|
117
|
-
# This class contains functions performing unit calculations.
|
118
|
-
# Originally implemented for manageiq-providers-kubevirt project
|
119
|
-
#
|
120
|
-
class UnitConverter
|
121
|
-
#
|
122
|
-
# Converts a value containing an optional unit to another unit. For example, if the value is
|
123
|
-
# `2 MiB` and the unit is `KiB` the result will be 2048.
|
124
|
-
#
|
125
|
-
# @param value [String] The value to convert, with an optional unit suffix.
|
126
|
-
# @param to [Symbol] (:b) The name of the unit to convert to, for example `:gib`.
|
127
|
-
# @return [BigDecimal] The converted value.
|
128
|
-
#
|
129
|
-
def self.convert(value, to)
|
130
|
-
# Return nil if no value is given:
|
131
|
-
return nil unless value
|
132
|
-
|
133
|
-
match = validate(value)
|
134
|
-
value = match[:value]
|
135
|
-
from = match[:suffix]
|
136
|
-
|
137
|
-
# Convert the value from string to big decimal to make sure that we don't loose precission:
|
138
|
-
value = BigDecimal(value)
|
139
|
-
|
140
|
-
# Do the conversion:
|
141
|
-
from_factor = scale_factor(from)
|
142
|
-
to_factor = scale_factor(to)
|
143
|
-
value * from_factor / to_factor
|
144
|
-
end
|
145
|
-
|
146
|
-
#
|
147
|
-
# Validates and extracts the numeric value and the unit
|
148
|
-
#
|
149
|
-
# @param value [String] The value to validate with optional unit suffix.
|
150
|
-
# @return [MatchData] describing the match, or ValidationError is raised if no match.
|
151
|
-
#
|
152
|
-
def self.validate(value)
|
153
|
-
match = VALUE_RE.match(value)
|
154
|
-
raise ::Fog::Kubevirt::Errors::ValidationError, "The value '#{value}' isn't a valid unit" unless match
|
155
|
-
|
156
|
-
match
|
157
|
-
end
|
158
|
-
|
159
|
-
#
|
160
|
-
# Regular expression used to match values and to separate them into the numeric value and the
|
161
|
-
# optional unit suffix.
|
162
|
-
#
|
163
|
-
VALUE_RE = /^\s*(?<value>[[:digit:]]+)\s*(?<suffix>[[:alpha:]]+)?\s*$/i
|
164
|
-
private_constant :VALUE_RE
|
165
|
-
|
166
|
-
#
|
167
|
-
# Scale factors associated to the different unit suffixes.
|
168
|
-
#
|
169
|
-
SCALE_FACTORS = {
|
170
|
-
:b => 1,
|
171
|
-
|
172
|
-
:k => 10**3,
|
173
|
-
:m => 10**6,
|
174
|
-
:g => 10**9,
|
175
|
-
:t => 10**12,
|
176
|
-
:p => 10**15,
|
177
|
-
:e => 10**18,
|
178
|
-
:z => 10**21,
|
179
|
-
:y => 10**24,
|
180
|
-
|
181
|
-
:kb => 10**3,
|
182
|
-
:mb => 10**6,
|
183
|
-
:gb => 10**9,
|
184
|
-
:tb => 10**12,
|
185
|
-
:pb => 10**15,
|
186
|
-
:eb => 10**18,
|
187
|
-
:zb => 10**21,
|
188
|
-
:yb => 10**24,
|
189
|
-
|
190
|
-
:ki => 2**10,
|
191
|
-
:mi => 2**20,
|
192
|
-
:gi => 2**30,
|
193
|
-
:ti => 2**40,
|
194
|
-
:pi => 2**50,
|
195
|
-
:ei => 2**60,
|
196
|
-
:zi => 2**70,
|
197
|
-
:yi => 2**80,
|
198
|
-
|
199
|
-
:kib => 2**10,
|
200
|
-
:mib => 2**20,
|
201
|
-
:gib => 2**30,
|
202
|
-
:tib => 2**40,
|
203
|
-
:pib => 2**50,
|
204
|
-
:eib => 2**60,
|
205
|
-
:zib => 2**70,
|
206
|
-
:yib => 2**80
|
207
|
-
}.freeze
|
208
|
-
private_constant :SCALE_FACTORS
|
209
|
-
|
210
|
-
#
|
211
|
-
# Finds the scale factor that matches the given unit suffix.
|
212
|
-
#
|
213
|
-
# @param sufix [Symbol, String] The unit suffix, as symbol or string. For example `MiB` or `:mib`.
|
214
|
-
# @return [Integer] The scale factor corresponding to that unit.
|
215
|
-
#
|
216
|
-
def self.scale_factor(suffix)
|
217
|
-
suffix = suffix.downcase.to_sym if suffix.kind_of?(String)
|
218
|
-
factor = SCALE_FACTORS[suffix]
|
219
|
-
raise ::Fog::Kubevirt::Errors::ValidationError, "The value '#{suffix}' isn't a valid unit suffix" unless factor
|
220
|
-
factor
|
221
|
-
end
|
222
|
-
private_class_method :scale_factor
|
223
|
-
end
|
224
|
-
|
225
|
-
#
|
226
|
-
# Label name which identifies operation system information
|
227
|
-
#
|
228
|
-
OS_LABEL = 'kubevirt.io/os'.freeze
|
229
|
-
OS_LABEL_SYMBOL = :'kubevirt.io/os'
|
230
|
-
|
231
88
|
# converts kubeclient objects into hash for fog to consume
|
232
89
|
def object_to_hash(object)
|
233
90
|
result = object
|
@@ -382,7 +239,7 @@ module Fog
|
|
382
239
|
#
|
383
240
|
def watch_vms(opts = {})
|
384
241
|
mapper = Proc.new do |notice|
|
385
|
-
vm = OpenStruct.new(Vm.parse(notice.object)) if notice.object.kind == 'VirtualMachine'
|
242
|
+
vm = OpenStruct.new(Vm.parse(object_to_hash(notice.object))) if notice.object.kind == 'VirtualMachine'
|
386
243
|
vm ||= OpenStruct.new
|
387
244
|
|
388
245
|
populate_notice_attributes(vm, notice)
|
@@ -401,7 +258,7 @@ module Fog
|
|
401
258
|
#
|
402
259
|
def watch_vminstances(opts = {})
|
403
260
|
mapper = Proc.new do |notice|
|
404
|
-
vminstance = OpenStruct.new(Vminstance.parse(notice.object)) if notice.object.kind == 'VirtualMachineInstance'
|
261
|
+
vminstance = OpenStruct.new(Vminstance.parse(object_to_hash(notice.object))) if notice.object.kind == 'VirtualMachineInstance'
|
405
262
|
vminstance ||= OpenStruct.new
|
406
263
|
|
407
264
|
populate_notice_attributes(vminstance, notice)
|
@@ -538,7 +395,7 @@ module Fog
|
|
538
395
|
end
|
539
396
|
|
540
397
|
def wrap_client(client, version, key)
|
541
|
-
wrapped_client = ExceptionWrapper.new(client, version)
|
398
|
+
wrapped_client = ::Fog::Kubevirt::Utils::ExceptionWrapper.new(client, version, @log)
|
542
399
|
@clients[key] = wrapped_client
|
543
400
|
|
544
401
|
wrapped_client
|
@@ -8,17 +8,17 @@ module Fog
|
|
8
8
|
attribute :uid, :aliases => 'metadata_uid'
|
9
9
|
attribute :annotations, :aliases => 'metadata_annotations'
|
10
10
|
attribute :labels, :aliases => 'metadata_labels'
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
attribute :access_modes, :aliases => 'spec_access_modes'
|
12
|
+
attribute :mount_options, :aliases => 'spec_mount_options'
|
13
|
+
attribute :reclaim_policy, :aliases => 'spec_reclaim_policy'
|
14
|
+
attribute :storage_class, :aliases => 'spec_storage_class'
|
15
15
|
attribute :capacity, :aliases => 'spec_capacity'
|
16
16
|
attribute :claim_ref, :aliases => 'spec_claim_ref'
|
17
|
-
attribute :type,
|
18
|
-
attribute :config,
|
17
|
+
attribute :type, :aliases => 'spec_type'
|
18
|
+
attribute :config, :aliases => 'spec_config'
|
19
19
|
attribute :phase, :aliases => 'status_phase'
|
20
|
-
attribute :reason,
|
21
|
-
attribute :message,
|
20
|
+
attribute :reason, :aliases => 'status_reason'
|
21
|
+
attribute :message, :aliases => 'status_message'
|
22
22
|
|
23
23
|
def self.parse(object)
|
24
24
|
metadata = object[:metadata]
|
@@ -35,7 +35,7 @@ module Fog
|
|
35
35
|
:access_modes => spec[:accessModes],
|
36
36
|
:mount_options => spec[:mountOptions],
|
37
37
|
:reclaim_policy => spec[:persistentVolumeReclaimPolicy],
|
38
|
-
|
38
|
+
:storage_class => spec[:storageClassName],
|
39
39
|
:capacity => spec.dig(:capacity, :storage),
|
40
40
|
:claim_ref => spec[:claimRef],
|
41
41
|
:type => type,
|
@@ -35,6 +35,11 @@ module Fog
|
|
35
35
|
name = args[:name]
|
36
36
|
labels = args[:labels]
|
37
37
|
|
38
|
+
# type is required
|
39
|
+
if args[:type].nil? || args[:type].empty?
|
40
|
+
raise ::Fog::Kubevirt::Errors::ValidationError "Type of storage can not be empty"
|
41
|
+
end
|
42
|
+
|
38
43
|
volume = {
|
39
44
|
:apiVersion => "v1",
|
40
45
|
:kind => "PersistentVolume",
|
@@ -52,7 +57,7 @@ module Fog
|
|
52
57
|
} if args[:capacity]
|
53
58
|
|
54
59
|
volume[:spec][:accessModes] = args[:access_modes] if args[:access_modes]
|
55
|
-
volume[:spec][args[:type].to_sym] = args[:config]
|
60
|
+
volume[:spec][args[:type].to_sym] = args[:config]
|
56
61
|
|
57
62
|
service.create_persistentvolume(volume)
|
58
63
|
end
|
@@ -1,10 +1,12 @@
|
|
1
1
|
require 'fog/core/collection'
|
2
2
|
require 'fog/kubevirt/compute/models/pvc'
|
3
|
+
require 'fog/kubevirt/compute/utils/unit_converter'
|
3
4
|
|
4
5
|
module Fog
|
5
6
|
module Kubevirt
|
6
7
|
class Compute
|
7
8
|
class Pvcs < Fog::Collection
|
9
|
+
|
8
10
|
attr_reader :kind, :resource_version
|
9
11
|
|
10
12
|
model Fog::Kubevirt::Compute::Pvc
|
@@ -82,7 +84,7 @@ module Fog
|
|
82
84
|
private
|
83
85
|
|
84
86
|
def check_size(value)
|
85
|
-
::Fog::Kubevirt::
|
87
|
+
::Fog::Kubevirt::Utils::UnitConverter.validate(value[:storage])
|
86
88
|
end
|
87
89
|
end
|
88
90
|
end
|
@@ -2,10 +2,13 @@ module Fog
|
|
2
2
|
module Kubevirt
|
3
3
|
class Compute
|
4
4
|
class Storageclass < Fog::Model
|
5
|
+
IS_DEFAULT = 'storageclass.kubernetes.io/is-default-class'.freeze
|
6
|
+
|
5
7
|
# Metadata
|
6
8
|
identity :name
|
7
9
|
attribute :resource_version, :aliases => 'metadata_resource_version'
|
8
10
|
attribute :uid, :aliases => 'metadata_uid'
|
11
|
+
attribute :default
|
9
12
|
|
10
13
|
attribute :mount_options
|
11
14
|
attribute :parameters
|
@@ -15,17 +18,20 @@ module Fog
|
|
15
18
|
|
16
19
|
def self.parse(object)
|
17
20
|
metadata = object[:metadata]
|
18
|
-
|
21
|
+
annotations = metadata[:annotations]
|
22
|
+
sc = {
|
19
23
|
:name => metadata[:name],
|
20
24
|
:resource_version => metadata[:resourceVersion],
|
21
25
|
:uid => metadata[:uid],
|
22
|
-
|
23
26
|
:parameters => object[:parameters],
|
24
27
|
:mount_options => object[:mountOptions],
|
25
28
|
:provisioner => object[:provisioner],
|
26
29
|
:reclaim_policy => object[:reclaimPolicy],
|
27
30
|
:volume_binding_mode => object[:volumeBindingMode]
|
28
31
|
}
|
32
|
+
|
33
|
+
sc[:default] = annotations[IS_DEFAULT.to_sym] unless annotations.nil?
|
34
|
+
sc
|
29
35
|
end
|
30
36
|
end
|
31
37
|
end
|
@@ -15,6 +15,12 @@ module Fog
|
|
15
15
|
attribute :objects
|
16
16
|
attribute :parameters
|
17
17
|
|
18
|
+
#
|
19
|
+
# Label name which identifies operation system information
|
20
|
+
#
|
21
|
+
OS_LABEL = 'kubevirt.io/os'.freeze
|
22
|
+
OS_LABEL_SYMBOL = :'kubevirt.io/os'
|
23
|
+
|
18
24
|
def clone(options = {})
|
19
25
|
params = values(options)
|
20
26
|
|
@@ -44,6 +44,7 @@ module Fog
|
|
44
44
|
# :vm_name [String] - name of a vm
|
45
45
|
# :cpus [String] - number of cpus
|
46
46
|
# :memory_size [String] - amount of memory
|
47
|
+
# :memory_unit [String] - memory unit to use, default to 'M'
|
47
48
|
# :image [String] - name of a container disk
|
48
49
|
# :pvc [String] - name of a persistent volume claim
|
49
50
|
# :cloudinit [Hash] - number of items needed to configure cloud-init
|
@@ -71,6 +72,7 @@ module Fog
|
|
71
72
|
vm_name = args.fetch(:vm_name)
|
72
73
|
cpus = args.fetch(:cpus, nil)
|
73
74
|
memory_size = args.fetch(:memory_size)
|
75
|
+
memory_unit = args.fetch(:memory_unit, "M")
|
74
76
|
init = args.fetch(:cloudinit, {})
|
75
77
|
networks = args.fetch(:networks, nil)
|
76
78
|
interfaces = args.fetch(:interfaces, nil)
|
@@ -80,6 +82,8 @@ module Fog
|
|
80
82
|
raise ::Fog::Kubevirt::Errors::ValidationError
|
81
83
|
end
|
82
84
|
|
85
|
+
memory = "#{memory_size}#{memory_unit}"
|
86
|
+
::Fog::Kubevirt::Utils::UnitConverter.validate(memory)
|
83
87
|
volumes, disks = add_vm_storage(vm_name, vm_volumes)
|
84
88
|
|
85
89
|
unless init.empty?
|
@@ -114,7 +118,7 @@ module Fog
|
|
114
118
|
},
|
115
119
|
:resources => {
|
116
120
|
:requests => {
|
117
|
-
:memory =>
|
121
|
+
:memory => memory
|
118
122
|
}
|
119
123
|
}
|
120
124
|
},
|
@@ -173,10 +177,9 @@ module Fog
|
|
173
177
|
end
|
174
178
|
|
175
179
|
def add_vm_storage(vm_name, vm_volumes)
|
176
|
-
normalized_vm_name = vm_name.gsub(/[._]+/,'-')
|
177
180
|
volumes, disks = [], []
|
178
181
|
vm_volumes.each_with_index do |v, idx|
|
179
|
-
volume_name = v.name
|
182
|
+
volume_name = v.name.nil? ? normalized_name(vm_name) + "-disk-0" + idx.to_s : normalized_name(v.name)
|
180
183
|
disk = {
|
181
184
|
:name => volume_name,
|
182
185
|
:disk => {}
|
@@ -209,6 +212,12 @@ module Fog
|
|
209
212
|
|
210
213
|
return volumes, disks
|
211
214
|
end
|
215
|
+
|
216
|
+
private
|
217
|
+
|
218
|
+
def normalized_name(name)
|
219
|
+
name.gsub(/[._]+/,'-')
|
220
|
+
end
|
212
221
|
end
|
213
222
|
end
|
214
223
|
end
|
@@ -22,9 +22,6 @@ module Fog
|
|
22
22
|
net_att = deep_merge!(net_att, metadata: { namespace: @namespace })
|
23
23
|
end
|
24
24
|
kube_net_client.create_network_attachment_definition(net_att)
|
25
|
-
rescue ::Fog::Kubevirt::Errors::ClientError => err
|
26
|
-
log.warn(err)
|
27
|
-
raise ::Fog::Kubevirt::Errors::AlreadyExistsError
|
28
25
|
end
|
29
26
|
end
|
30
27
|
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Fog
|
2
|
+
module Kubevirt
|
3
|
+
module Utils
|
4
|
+
class ExceptionWrapper
|
5
|
+
def initialize(client, version, log)
|
6
|
+
@client = client
|
7
|
+
@version = version
|
8
|
+
@log = log
|
9
|
+
end
|
10
|
+
|
11
|
+
def method_missing(symbol, *args)
|
12
|
+
super unless @client.respond_to?(symbol)
|
13
|
+
|
14
|
+
if block_given?
|
15
|
+
@client.__send__(symbol, *args) do |*block_args|
|
16
|
+
yield(*block_args)
|
17
|
+
end
|
18
|
+
else
|
19
|
+
@client.__send__(symbol, *args)
|
20
|
+
end
|
21
|
+
rescue KubeException => e
|
22
|
+
if e.error_code == 409
|
23
|
+
@log.warn(e)
|
24
|
+
raise ::Fog::Kubevirt::Errors::AlreadyExistsError, e
|
25
|
+
elsif e.error_code == 404
|
26
|
+
raise ::Fog::Kubevirt::Errors::NotFoundError, e
|
27
|
+
else
|
28
|
+
@log.warn(e)
|
29
|
+
raise ::Fog::Kubevirt::Errors::ClientError, e
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def respond_to_missing?(method_name, include_private = false)
|
34
|
+
@client.respond_to?(method_name, include_private) || super
|
35
|
+
end
|
36
|
+
|
37
|
+
def version
|
38
|
+
@version
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
module Fog
|
2
|
+
module Kubevirt
|
3
|
+
module Utils
|
4
|
+
#
|
5
|
+
# This class contains functions performing unit calculations.
|
6
|
+
# Originally implemented for manageiq-providers-kubevirt project
|
7
|
+
#
|
8
|
+
class UnitConverter
|
9
|
+
|
10
|
+
#
|
11
|
+
# Converts a value containing an optional unit to another unit. For example, if the value is
|
12
|
+
# `2 MiB` and the unit is `KiB` the result will be 2048.
|
13
|
+
#
|
14
|
+
# @param value [String] The value to convert, with an optional unit suffix.
|
15
|
+
# @param to [Symbol] (:b) The name of the unit to convert to, for example `:gib`.
|
16
|
+
# @return [BigDecimal] The converted value.
|
17
|
+
#
|
18
|
+
def self.convert(value, to)
|
19
|
+
# Return nil if no value is given:
|
20
|
+
return nil unless value
|
21
|
+
|
22
|
+
match = validate(value)
|
23
|
+
value = match[:value]
|
24
|
+
from = match[:suffix]
|
25
|
+
|
26
|
+
# Convert the value from string to big decimal to make sure that we don't loose precission:
|
27
|
+
value = BigDecimal(value)
|
28
|
+
|
29
|
+
# Do the conversion:
|
30
|
+
from_factor = scale_factor(from)
|
31
|
+
to_factor = scale_factor(to)
|
32
|
+
value * from_factor / to_factor
|
33
|
+
end
|
34
|
+
|
35
|
+
#
|
36
|
+
# Validates and extracts the numeric value and the unit
|
37
|
+
#
|
38
|
+
# @param value [String] The value to validate with optional unit suffix.
|
39
|
+
# @return [MatchData] describing the match, or ValidationError is raised if no match.
|
40
|
+
#
|
41
|
+
def self.validate(value)
|
42
|
+
match = VALUE_RE.match(value)
|
43
|
+
raise ::Fog::Kubevirt::Errors::ValidationError, "The value '#{value}' isn't a valid unit" unless match
|
44
|
+
|
45
|
+
match
|
46
|
+
end
|
47
|
+
|
48
|
+
#
|
49
|
+
# Regular expression used to match values and to separate them into the numeric value and the
|
50
|
+
# optional unit suffix.
|
51
|
+
#
|
52
|
+
VALUE_RE = /^\s*(?<value>[[:digit:]]+)\s*(?<suffix>[[:alpha:]]+)?\s*$/i
|
53
|
+
private_constant :VALUE_RE
|
54
|
+
|
55
|
+
#
|
56
|
+
# Scale factors associated to the different unit suffixes.
|
57
|
+
#
|
58
|
+
SCALE_FACTORS = {
|
59
|
+
:b => 1,
|
60
|
+
|
61
|
+
:k => 10**3,
|
62
|
+
:m => 10**6,
|
63
|
+
:g => 10**9,
|
64
|
+
:t => 10**12,
|
65
|
+
:p => 10**15,
|
66
|
+
:e => 10**18,
|
67
|
+
:z => 10**21,
|
68
|
+
:y => 10**24,
|
69
|
+
|
70
|
+
:kb => 10**3,
|
71
|
+
:mb => 10**6,
|
72
|
+
:gb => 10**9,
|
73
|
+
:tb => 10**12,
|
74
|
+
:pb => 10**15,
|
75
|
+
:eb => 10**18,
|
76
|
+
:zb => 10**21,
|
77
|
+
:yb => 10**24,
|
78
|
+
|
79
|
+
:ki => 2**10,
|
80
|
+
:mi => 2**20,
|
81
|
+
:gi => 2**30,
|
82
|
+
:ti => 2**40,
|
83
|
+
:pi => 2**50,
|
84
|
+
:ei => 2**60,
|
85
|
+
:zi => 2**70,
|
86
|
+
:yi => 2**80,
|
87
|
+
|
88
|
+
:kib => 2**10,
|
89
|
+
:mib => 2**20,
|
90
|
+
:gib => 2**30,
|
91
|
+
:tib => 2**40,
|
92
|
+
:pib => 2**50,
|
93
|
+
:eib => 2**60,
|
94
|
+
:zib => 2**70,
|
95
|
+
:yib => 2**80
|
96
|
+
}.freeze
|
97
|
+
private_constant :SCALE_FACTORS
|
98
|
+
|
99
|
+
#
|
100
|
+
# Finds the scale factor that matches the given unit suffix.
|
101
|
+
#
|
102
|
+
# @param sufix [Symbol, String] The unit suffix, as symbol or string. For example `MiB` or `:mib`.
|
103
|
+
# @return [Integer] The scale factor corresponding to that unit.
|
104
|
+
#
|
105
|
+
def self.scale_factor(suffix)
|
106
|
+
suffix = suffix.downcase.to_sym if suffix.kind_of?(String)
|
107
|
+
factor = SCALE_FACTORS[suffix]
|
108
|
+
raise ::Fog::Kubevirt::Errors::ValidationError, "The value '#{suffix}' isn't a valid unit suffix" unless factor
|
109
|
+
factor
|
110
|
+
end
|
111
|
+
private_class_method :scale_factor
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
data/lib/fog/kubevirt/version.rb
CHANGED
@@ -0,0 +1,135 @@
|
|
1
|
+
require_relative './shared_context'
|
2
|
+
|
3
|
+
describe Fog::Kubevirt::Compute do
|
4
|
+
before :all do
|
5
|
+
conn = KubevirtConnection.new()
|
6
|
+
@client = conn.client
|
7
|
+
@watch = nil
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'creates VMI and checks MAC' do
|
11
|
+
vm_name = 'test'
|
12
|
+
cpus = 1
|
13
|
+
memory_size = 64
|
14
|
+
|
15
|
+
volume = Fog::Kubevirt::Compute::Volume.new
|
16
|
+
volume.type = 'containerDisk'
|
17
|
+
volume.name = 'test-disk-01'
|
18
|
+
volume.info = 'registry:5000/kubevirt/cirros-container-disk-demo:devel'
|
19
|
+
|
20
|
+
@client.vms.create(vm_name: vm_name, cpus: cpus, memory_size: memory_size, volumes: [volume])
|
21
|
+
|
22
|
+
vm = @client.vms.get(vm_name)
|
23
|
+
assert_equal(vm.cpu_cores, cpus)
|
24
|
+
assert_equal(vm.memory, "#{memory_size}M")
|
25
|
+
|
26
|
+
vm.start()
|
27
|
+
|
28
|
+
# check whether vmi to be created if not it will raise ClientError
|
29
|
+
@client.vminstances.get(vm_name)
|
30
|
+
|
31
|
+
vmis = @client.vminstances.all()
|
32
|
+
@watch = @client.watch_vminstances(:resource_version => vmis.resource_version)
|
33
|
+
|
34
|
+
thread = Thread.new do
|
35
|
+
@watch.each do |notice|
|
36
|
+
break if notice.type == 'MODIFIED' && notice.status == 'Running'
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
if thread.join(60).nil?
|
41
|
+
fail('VMI did not start')
|
42
|
+
end
|
43
|
+
@watch.finish
|
44
|
+
@watch = nil
|
45
|
+
|
46
|
+
vmi = @client.vminstances.get(vm_name)
|
47
|
+
|
48
|
+
assert_equal(vm.cpu_cores, cpus)
|
49
|
+
assert_equal(vm.memory, "#{memory_size}M")
|
50
|
+
|
51
|
+
vmi.interfaces do |iface|
|
52
|
+
assert !iface.mac_address.nil?
|
53
|
+
end
|
54
|
+
|
55
|
+
vmis = @client.vminstances.all()
|
56
|
+
@watch = @client.watch_vminstances(:resource_version => vmis.resource_version)
|
57
|
+
|
58
|
+
@client.vminstances.destroy(vm_name, @client.namespace)
|
59
|
+
|
60
|
+
thread = Thread.new do
|
61
|
+
@watch.each do |notice|
|
62
|
+
break if notice.type == 'DELETED'
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
if thread.join(60).nil?
|
67
|
+
fail('VMI was not removed')
|
68
|
+
end
|
69
|
+
@watch.finish
|
70
|
+
@watch = nil
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'creates VMI and checks MAC using server' do
|
74
|
+
vm_name = 'test-server'
|
75
|
+
cpus = 1
|
76
|
+
memory_size = 64
|
77
|
+
|
78
|
+
volume = Fog::Kubevirt::Compute::Volume.new
|
79
|
+
volume.type = 'containerDisk'
|
80
|
+
volume.name = 'test.disk.01'
|
81
|
+
volume.info = 'registry:5000/kubevirt/cirros-container-disk-demo:devel'
|
82
|
+
|
83
|
+
@client.vms.create(vm_name: vm_name, cpus: cpus, memory_size: memory_size, volumes: [volume])
|
84
|
+
|
85
|
+
server_vm = @client.servers.get(vm_name)
|
86
|
+
assert_equal(server_vm.cpu_cores, cpus)
|
87
|
+
assert_equal(server_vm.memory, "#{memory_size}M")
|
88
|
+
|
89
|
+
server_vm.start()
|
90
|
+
|
91
|
+
# check whether vmi to be created if not it will raise ClientError
|
92
|
+
@client.servers.get(vm_name)
|
93
|
+
|
94
|
+
vmis = @client.vminstances.all()
|
95
|
+
@watch = @client.watch_vminstances(:resource_version => vmis.resource_version)
|
96
|
+
|
97
|
+
thread = Thread.new do
|
98
|
+
@watch.each do |notice|
|
99
|
+
break if notice.type == 'MODIFIED' && notice.status == 'Running'
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
if thread.join(60).nil?
|
104
|
+
fail('Server did not start')
|
105
|
+
end
|
106
|
+
@watch.finish
|
107
|
+
@watch = nil
|
108
|
+
|
109
|
+
server = @client.servers.get(vm_name)
|
110
|
+
|
111
|
+
assert_equal(server.cpu_cores, cpus)
|
112
|
+
assert_equal(server.memory, "#{memory_size}M")
|
113
|
+
|
114
|
+
server.interfaces do |iface|
|
115
|
+
assert !iface.mac_address.nil?
|
116
|
+
end
|
117
|
+
|
118
|
+
vmis = @client.vminstances.all()
|
119
|
+
@watch = @client.watch_vminstances(:resource_version => vmis.resource_version)
|
120
|
+
|
121
|
+
server.destroy
|
122
|
+
|
123
|
+
thread = Thread.new do
|
124
|
+
@watch.each do |notice|
|
125
|
+
break if notice.type == 'DELETED'
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
if thread.join(60).nil?
|
130
|
+
fail('Server was not removed')
|
131
|
+
end
|
132
|
+
@watch.finish
|
133
|
+
@watch = nil
|
134
|
+
end
|
135
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require_relative './shared_context'
|
2
|
+
|
3
|
+
describe Fog::Kubevirt::Compute do
|
4
|
+
before :all do
|
5
|
+
conn = KubevirtConnection.new()
|
6
|
+
@client = conn.client.networkattachmentdefs
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'CRD network attachements' do
|
10
|
+
name = 'ovs-red'
|
11
|
+
config = '{ cni_version: "0.3.1", type: "ovs", bridge: "red" }'
|
12
|
+
|
13
|
+
@client.create(name: name, config: config)
|
14
|
+
|
15
|
+
net_att_def = @client.get(name)
|
16
|
+
assert_equal(net_att_def.config, config)
|
17
|
+
|
18
|
+
@client.delete(name)
|
19
|
+
|
20
|
+
begin
|
21
|
+
@client.get(name)
|
22
|
+
fail "net_attach_def should not exist"
|
23
|
+
rescue ::Fog::Kubevirt::Errors::ClientError
|
24
|
+
# expected
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'creates empty config' do
|
29
|
+
begin
|
30
|
+
@client.create(name: 'aaa')
|
31
|
+
fail "empty config can not be nil"
|
32
|
+
rescue ::Fog::Kubevirt::Errors::ClientError
|
33
|
+
# expected
|
34
|
+
end
|
35
|
+
|
36
|
+
begin
|
37
|
+
@client.create(name: 'aaa', config: '{}')
|
38
|
+
fail "empty config can not be nil"
|
39
|
+
rescue ::Fog::Kubevirt::Errors::ClientError
|
40
|
+
# expected
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -3,13 +3,14 @@ require_relative './shared_context'
|
|
3
3
|
describe Fog::Kubevirt::Compute do
|
4
4
|
before :all do
|
5
5
|
conn = KubevirtConnection.new()
|
6
|
+
@namespace = conn.client.namespace
|
6
7
|
@client = conn.client.pvcs
|
7
8
|
end
|
8
9
|
|
9
10
|
it 'CRD pvc' do
|
10
11
|
pvc = {
|
11
12
|
:name => 'test-pvc',
|
12
|
-
:namespace =>
|
13
|
+
:namespace => @namespace,
|
13
14
|
:storage_class => '',
|
14
15
|
:access_modes => ['ReadWriteOnce'],
|
15
16
|
:requests => { storage: "1Gi" }
|
@@ -42,7 +43,7 @@ describe Fog::Kubevirt::Compute do
|
|
42
43
|
it 'fails with wrong size format' do
|
43
44
|
pvc = {
|
44
45
|
:name => 'test-pvc',
|
45
|
-
:namespace =>
|
46
|
+
:namespace => @namespace,
|
46
47
|
:storage_class => '',
|
47
48
|
:access_modes => ['ReadWriteOnce'],
|
48
49
|
:requests => { storage: "X" }
|
@@ -8,15 +8,22 @@ class KubevirtConnection
|
|
8
8
|
@host = ENV.key?('KUBE_HOST') ? ENV['KUBE_HOST'] : options[:host]
|
9
9
|
@port = ENV.key?('KUBE_PORT') ? ENV['KUBE_PORT'] : options[:port]
|
10
10
|
@token = ENV.key?('KUBE_TOKEN') ? ENV['KUBE_TOKEN'] : options[:token]
|
11
|
+
@namespace = ENV.key?('KUBE_NAMESPACE') ? ENV['KUBE_NAMESPACE'] : options[:namespace]
|
11
12
|
end
|
12
13
|
|
13
14
|
def client
|
14
15
|
if !ENV.key?('KUBECONFIG')
|
15
|
-
return Fog::Kubevirt::Compute.new(
|
16
|
-
:
|
17
|
-
:
|
16
|
+
return Fog::Kubevirt::Compute.new(
|
17
|
+
:kubevirt_hostname => @host,
|
18
|
+
:kubevirt_port => @port,
|
19
|
+
:kubevirt_token => @token,
|
20
|
+
:kubevirt_namespace => @namespace
|
21
|
+
)
|
18
22
|
else
|
19
|
-
return Fog::Kubevirt::Compute.new(
|
23
|
+
return Fog::Kubevirt::Compute.new(
|
24
|
+
:kubevirt_token => nil,
|
25
|
+
:kubevirt_namespace => @namespace
|
26
|
+
)
|
20
27
|
end
|
21
28
|
end
|
22
29
|
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require_relative './shared_context'
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
describe Fog::Kubevirt::Compute do
|
6
|
+
before :all do
|
7
|
+
conn = KubevirtConnection.new()
|
8
|
+
@client = conn.client
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'creates volumes' do
|
12
|
+
scs = @client.storageclasses.all()
|
13
|
+
default_sc = scs.find { | sc | sc.default }
|
14
|
+
|
15
|
+
dir = Dir.mktmpdir
|
16
|
+
|
17
|
+
name = 'my-local-storage'
|
18
|
+
access_modes = [ 'ReadWriteOnce' ]
|
19
|
+
capacity = '1Gi'
|
20
|
+
type = 'hostPath'
|
21
|
+
config = { path: dir, type: "Directory" }
|
22
|
+
|
23
|
+
@client.persistentvolumes.create(name: name,
|
24
|
+
access_modes: access_modes,
|
25
|
+
capacity: capacity,
|
26
|
+
storage_class: default_sc.name,
|
27
|
+
type: type,
|
28
|
+
config: config)
|
29
|
+
|
30
|
+
pv = @client.persistentvolumes.get(name)
|
31
|
+
assert_equal(pv.storage_class, default_sc.name)
|
32
|
+
assert_equal(pv.capacity, capacity)
|
33
|
+
assert_equal(pv.access_modes, access_modes)
|
34
|
+
|
35
|
+
@client.persistentvolumes.delete(name)
|
36
|
+
FileUtils.remove_entry dir
|
37
|
+
|
38
|
+
begin
|
39
|
+
@client.persistentvolumes.get(name)
|
40
|
+
fail "pv should not exist"
|
41
|
+
rescue ::Fog::Kubevirt::Errors::ClientError
|
42
|
+
# expected
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/spec/unit/create_vm_spec.rb
CHANGED
@@ -18,7 +18,7 @@ describe Fog::Compute do
|
|
18
18
|
begin
|
19
19
|
vm_name = 'test'
|
20
20
|
cpus = 1
|
21
|
-
memory_size = 64
|
21
|
+
memory_size = '64'
|
22
22
|
pvc1 = 'mypvc1'
|
23
23
|
pvc2 = 'mypvc2'
|
24
24
|
|
@@ -104,12 +104,13 @@ describe Fog::Compute do
|
|
104
104
|
begin
|
105
105
|
vm_name = 'test2'
|
106
106
|
cpus = 1
|
107
|
-
memory_size = 64
|
107
|
+
memory_size = '64'
|
108
|
+
memory_unit = 'M'
|
108
109
|
|
109
110
|
volume = Fog::Kubevirt::Compute::Volume.new
|
110
111
|
volume.type = 'persistentVolumeClaim'
|
111
112
|
volume.info = 'mypvc3'
|
112
|
-
@service.vms.create(vm_name: vm_name, cpus: cpus, memory_size: memory_size, volumes: [volume])
|
113
|
+
@service.vms.create(vm_name: vm_name, cpus: cpus, memory_size: memory_size, memory_unit: memory_unit, volumes: [volume])
|
113
114
|
|
114
115
|
vm = @service.vms.get(vm_name)
|
115
116
|
|
@@ -1,8 +1,10 @@
|
|
1
1
|
require_relative './spec_helper'
|
2
2
|
|
3
|
-
|
3
|
+
require 'fog/kubevirt/compute/utils/unit_converter'
|
4
4
|
|
5
|
-
|
5
|
+
describe Fog::Kubevirt::Utils::UnitConverter do
|
6
|
+
|
7
|
+
described_class = Fog::Kubevirt::Utils::UnitConverter
|
6
8
|
|
7
9
|
describe '.convert' do
|
8
10
|
it 'converts correctly units that correspond to powers of 10' do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fog-kubevirt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Piotr Kliczewski
|
@@ -14,7 +14,7 @@ authors:
|
|
14
14
|
autorequire:
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
|
-
date: 2019-
|
17
|
+
date: 2019-05-14 00:00:00.000000000 Z
|
18
18
|
dependencies:
|
19
19
|
- !ruby/object:Gem::Dependency
|
20
20
|
name: minitest
|
@@ -209,6 +209,8 @@ files:
|
|
209
209
|
- lib/fog/kubevirt/compute/requests/list_vms.rb
|
210
210
|
- lib/fog/kubevirt/compute/requests/list_volumes.rb
|
211
211
|
- lib/fog/kubevirt/compute/requests/update_vm.rb
|
212
|
+
- lib/fog/kubevirt/compute/utils/exception_wrapper.rb
|
213
|
+
- lib/fog/kubevirt/compute/utils/unit_converter.rb
|
212
214
|
- lib/fog/kubevirt/version.rb
|
213
215
|
- spec/fixtures/kubevirt/networkattachmentdefinition/networkattachmentdefinitions_crud.yml
|
214
216
|
- spec/fixtures/kubevirt/persistentvolume/persistent_volumes_crud.yml
|
@@ -219,8 +221,11 @@ files:
|
|
219
221
|
- spec/fixtures/kubevirt/storageclass/storageclasses_crud.yml
|
220
222
|
- spec/fixtures/kubevirt/vm/vm_create_multi.yml
|
221
223
|
- spec/fixtures/kubevirt/vm/vm_create_single.yml
|
224
|
+
- spec/integration/mac_vmi_spec.rb
|
225
|
+
- spec/integration/net-attach-def_spec.rb
|
222
226
|
- spec/integration/pvcs_spec.rb
|
223
227
|
- spec/integration/shared_context.rb
|
228
|
+
- spec/integration/volumes_spec.rb
|
224
229
|
- spec/unit/compute_v1alpha2_spec.rb
|
225
230
|
- spec/unit/create_vm_spec.rb
|
226
231
|
- spec/unit/network_attachment_definition_v1alpha2_spec.rb
|
@@ -266,8 +271,11 @@ test_files:
|
|
266
271
|
- spec/fixtures/kubevirt/storageclass/storageclasses_crud.yml
|
267
272
|
- spec/fixtures/kubevirt/vm/vm_create_multi.yml
|
268
273
|
- spec/fixtures/kubevirt/vm/vm_create_single.yml
|
274
|
+
- spec/integration/mac_vmi_spec.rb
|
275
|
+
- spec/integration/net-attach-def_spec.rb
|
269
276
|
- spec/integration/pvcs_spec.rb
|
270
277
|
- spec/integration/shared_context.rb
|
278
|
+
- spec/integration/volumes_spec.rb
|
271
279
|
- spec/unit/compute_v1alpha2_spec.rb
|
272
280
|
- spec/unit/create_vm_spec.rb
|
273
281
|
- spec/unit/network_attachment_definition_v1alpha2_spec.rb
|