Skip to content

Commit

Permalink
Add support for NVME Controllers
Browse files Browse the repository at this point in the history
  • Loading branch information
girijaasoni committed May 16, 2024
1 parent 4a7f4e7 commit e425c52
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 11 deletions.
2 changes: 2 additions & 0 deletions lib/fog/vsphere/compute.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class Compute < Fog::Service
model :customfield
collection :customfields
model :scsicontroller
model :nvmecontroller
model :process
model :cdrom
collection :cdroms
Expand Down Expand Up @@ -111,6 +112,7 @@ class Compute < Fog::Service
request :list_customfields
request :get_vm_first_scsi_controller
request :list_vm_scsi_controllers
request :list_vm_nvme_controllers
request :set_vm_customvalue
request :vm_take_snapshot
request :list_vm_snapshots
Expand Down
22 changes: 22 additions & 0 deletions lib/fog/vsphere/models/compute/nvmecontroller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module Fog
module Vsphere
class Compute
class NVMEController < Fog::Model
attribute :type
attribute :unit_number
attribute :key, type: :integer
attribute :server_id

def initialize(attributes = {})
super
self.key ||= 2000
self.type ||= "VirtualNVMEController"
end

def to_s
"#{type} ##{key}:, unit_number: #{unit_number}"
end
end
end
end
end
1 change: 1 addition & 0 deletions lib/fog/vsphere/models/compute/scsicontroller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class SCSIController < Fog::Model
def initialize(attributes = {})
super
self.key ||= 1000
self.type ||= "VirtualLsiLogicController"
end

def to_s
Expand Down
53 changes: 45 additions & 8 deletions lib/fog/vsphere/models/compute/server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class Server < Fog::Compute::Server
extend Fog::Deprecation
deprecate(:ipaddress, :public_ip_address)
deprecate(:scsi_controller, :scsi_controllers)
deprecate(:nvme_controller, :nvme_controllers)

# This will be the instance uuid which is globally unique across
# a vSphere deployment.
Expand Down Expand Up @@ -49,6 +50,7 @@ class Server < Fog::Compute::Server
attribute :guest_id
attribute :hardware_version
attribute :scsi_controllers, type: :array
attribute :nvme_controllers, type: :array
attribute :cpuHotAddEnabled
attribute :memoryHotAddEnabled
attribute :firmware
Expand All @@ -60,9 +62,10 @@ def initialize(attributes = {})
super defaults.merge(attributes)
self.instance_uuid ||= id # TODO: remvoe instance_uuid as it can be replaced with simple id
initialize_interfaces
initialize_volumes
initialize_customvalues
initialize_scsi_controllers
initialize_nvme_controllers
initialize_volumes
end

# Lazy Loaded Attributes
Expand Down Expand Up @@ -289,10 +292,18 @@ def scsi_controllers
attributes[:scsi_controllers] ||= service.list_vm_scsi_controllers(id)
end

def nvme_controllers
attributes[:nvme_controllers] ||= service.list_vm_nvme_controllers(id)
end

def scsi_controller
scsi_controllers.first
end

def nvme_controller
nvme_controllers.first
end

def folder
return nil unless datacenter && path
attributes[:folder] ||= service.folders(datacenter: datacenter, type: :vm).get(path)
Expand Down Expand Up @@ -348,9 +359,25 @@ def initialize_interfaces
end
end

def unassigned_volumes?
attributes[:volumes]&.map! do |vol|
return true unless vol.key?(:controller_key)
end
false
end

def update_controller_key(vol)
if !attributes[:scsi_controllers].empty? && !vol[:controller_key]
vol[:controller_key] = attributes[:scsi_controllers].first.key
elsif !vol[:controller_key]
vol[:controller_key] = 1000
end
end

def initialize_volumes
if attributes[:volumes] && attributes[:volumes].is_a?(Array)
if attributes[:volumes] && attributes[:volumes].is_a?(Array) && !attributes[:volumes].empty?
attributes[:volumes].map! do |vol|
update_controller_key(vol)
if vol.is_a?(Hash)
service.volumes.new({ server: self }.merge(vol))
else
Expand All @@ -368,18 +395,28 @@ def initialize_customvalues
end

def initialize_scsi_controllers
if attributes[:scsi_controllers] && attributes[:scsi_controllers].is_a?(Array)
if attributes[:scsi_controllers] && attributes[:scsi_controllers].is_a?(Array) && !attributes[:scsi_controllers].empty?
attributes[:scsi_controllers].map! do |controller|
controller.is_a?(Hash) ? Fog::Vsphere::Compute::SCSIController.new(controller) : controller
end
elsif attributes[:scsi_controller] && attributes[:scsi_controller].is_a?(Hash)
elsif attributes[:scsi_controller] && attributes[:scsi_controller].is_a?(Hash) && !attributes[:scsi_controller].empty?

attributes[:scsi_controllers] = [
Fog::Vsphere::Compute::SCSIController.new(attributes[:scsi_controller])
]
elsif attributes[:volumes] && attributes[:volumes].is_a?(Array) && !attributes[:volumes].empty?
# Create a default scsi controller if there are any disks but no controller defined
attributes[:scsi_controllers] = [
Fog::Vsphere::Compute::SCSIController.new
elsif unassigned_volumes? && !attributes[:volume].empty?
attributes[:scsi_controllers] = [Fog::Vsphere::Compute::SCSIController.new]
end
end

def initialize_nvme_controllers
if attributes[:nvme_controllers] && attributes[:nvme_controllers].is_a?(Array) && !attributes[:nvme_controllers].empty?
attributes[:nvme_controllers].map! do |controller|
controller.is_a?(Hash) ? Fog::Vsphere::Compute::NVMEController.new(controller) : controller
end
elsif attributes[:nvme_controller] && attributes[:nvme_controller].is_a?(Hash)
attributes[:nvme_controllers] = [
Fog::Vsphere::Compute::NVMEController.new(attributes[:nvme_controllers]) && !attributes[:nvme_controller].empty?
]
end
end
Expand Down
3 changes: 1 addition & 2 deletions lib/fog/vsphere/models/compute/volume.rb
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,7 @@ def defaults
{
thin: true,
name: 'Hard disk',
mode: 'persistent',
controller_key: 1000
mode: 'persistent'
}
end

Expand Down
10 changes: 9 additions & 1 deletion lib/fog/vsphere/requests/compute/create_vm.rb
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,10 @@ def device_change(attributes)
devices << scsi_controllers.each_with_index.map { |controller, index| create_controller(controller, index) }
end

if (nvme_controllers = (attributes[:nvme_controllers] || attributes['nvme_controller']))
devices << nvme_controllers.each_with_index.map { |controller, index| create_controller(controller, index) }
end

if (disks = attributes[:volumes])
devices << disks.map { |disk| create_disk(disk, :add, storage_pod: get_storage_pod_from_volumes(attributes)) }
end
Expand Down Expand Up @@ -255,14 +259,18 @@ def create_controller(controller = nil, index = 0)
operation: options[:operation],
device: controller_class.new(key: options[:key] || (1000 + index),
busNumber: options[:bus_id] || index,
**(options[:type] == RbVmomi::VIM::VirtualAHCIController ? {} : {sharedBus: controller_get_shared_from_options(options)}))
**(check_type(options[:type]) ? {} : {sharedBus: controller_get_shared_from_options(options)}))
}
end

def controller_default_options
{ operation: :add, type: RbVmomi::VIM.VirtualLsiLogicController.class, shared: false }
end

def check_type(type)
[RbVmomi::VIM::VirtualAHCIController, RbVmomi::VIM::VirtualNVMEController, "VirtualNVMEController"].include?(type)
end

def controller_get_shared_from_options(options)
if (options.key?(:shared) && (options[:shared] == false)) || (!options.key? :shared)
:noSharing
Expand Down
29 changes: 29 additions & 0 deletions lib/fog/vsphere/requests/compute/list_vm_nvme_controllers.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
module Fog
module Vsphere
class Compute
class Real
def list_vm_nvme_controllers(vm_id)
list_vm_nvme_controllers_raw(vm_id).map do |raw_controller|
Fog::Vsphere::Compute::NVMEController.new(raw_controller)
end
end

def list_vm_nvme_controllers_raw(vm_id)
get_vm_ref(vm_id).config.hardware.device.grep(RbVmomi::VIM::VirtualNVMEController).map do |ctrl|
{
type: ctrl.class.to_s,
key: ctrl.key
}
end
end
end
class Mock
def list_vm_nvme_controllers(vm_id)
raise Fog::Vsphere::Compute::NotFound, 'VM not Found' unless data[:servers].key?(vm_id)
return [] unless data[:servers][vm_id].key?('nvme_controllers')
data[:servers][vm_id]['nvme_controllers'].map { |h| h.merge(server_id: vm_id) }
end
end
end
end
end

0 comments on commit e425c52

Please sign in to comment.