Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #34839 - Add support for VMware NVME Controllers #10168

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from

Conversation

girijaasoni
Copy link
Contributor

@girijaasoni girijaasoni commented May 15, 2024

blocked by PR
hammer doc PR

I put together a document for better understanding. Please feel free to go through it and provide suggestions/improvisations.

Ready for testing :D

Test cases need the fog-vsphere PR merge. They pass on my local and we can trigger them again after the merge of fog-vpshere PR!

@girijaasoni girijaasoni requested a review from a team as a code owner May 15, 2024 00:51
@github-actions github-actions bot added the UI label May 15, 2024
@girijaasoni girijaasoni marked this pull request as draft May 15, 2024 01:53
@girijaasoni girijaasoni marked this pull request as ready for review May 16, 2024 10:14
@ekohl ekohl changed the title Fixes #34839 - Add support for NVME Controllers Fixes #34839 - Add support for VMware NVME Controllers May 17, 2024
Comment on lines 14 to 15
attrs["nvme_controllers"] = ctrls_and_vol[:controllers]&.select { |controller| controller[:type].include?("VirtualNVMEController") }
attrs["scsi_controllers"] = ctrls_and_vol[:controllers]&.select { |controller| !controller[:type].include?("VirtualNVMEController") }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use #split method to divide the controllers part

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have used #partition instead, wasn't able to understand the use case #split

@@ -484,7 +485,7 @@ def parse_args(args)

# see #26402 - consume scsi_controller_type from hammer as a default scsi type
scsi_type = args.delete(:scsi_controller_type)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will need to create a generic option for Hammer too here: instead of scsi_controller_type it would become controller_type. Plus we will need to deprecate the older scsi_controller_type

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

scsi_controller_type has been removed from compute attributes in this commit Its best we remove this part all together as we use scsi_controller attribute to pass the type and the key

Screenshot from 2024-05-30 15-46-54

def new_vm(args = {})
args = parse_args args
args = args.deep_symbolize_keys
args[:scsi_controllers] = [] if !args.key?(:scsi_controllers) && !args[:volumes].empty? && !unassigned_volumes?(args[:volumes])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A comment explaining why do you need to set scsi_controllers to an empty array would be nice here.

@@ -26,7 +26,18 @@ const initialState = Immutable({
volumes: [],
});

const availableControllerKeys = [1000, 1001, 1002, 1003, 1004];
const availableControllerKeys = [
1000,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please give me a bit more details about this array and the meaning of the items in it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is to assign the keys to scsi or nvme controllers. We can have max of 4 controllers each so the total number of available keys are 8.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I was in university my professor would reduce your grade if you used magic values. Anything other than 0, 1 or 2 needed to be a constant that described what the magic value actually was.

In Foreman that rule isn't strictly applied, but another way to write this would be:

Array.from({length: 8}, (value, index) => 1000 + index);

I'm not sure if it's that much clearer, but as I read the code it's a list of 8 numbers where the base number is 1000.

Having said that, how do you prevent a user from assigning 8 nvme controllers or 8 scsi controllers?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is handled by Rbvmomi. We dont place any restrictions from the UI or the api or hammer

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since controller is ambiguos, I'd suggest to be a bit more explicit and name it something like normalize_vmware_storage_controller_attributes.rb

@@ -192,12 +192,13 @@ def nictypes
}
end

def scsi_controller_types
def controller_types
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

storage_controller_types?

Copy link
Member

@ekohl ekohl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test failures look related.

Comment on lines 10 to 13
volumes = {}
ctrls_and_vol[:volumes].each_with_index do |vol, index|
volumes[index.to_s] = vol
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
volumes = {}
ctrls_and_vol[:volumes].each_with_index do |vol, index|
volumes[index.to_s] = vol
end
volumes = ctrls_and_vol[:volumes].each_with_index.to_h { |vol, index| [index.to_s, vol] }

Comment on lines 748 to 750
normalized['nvme_controllers'] = nvme_controllers.map.with_index do |ctrl, idx|
[idx.to_s, ctrl]
end.to_h
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
normalized['nvme_controllers'] = nvme_controllers.map.with_index do |ctrl, idx|
[idx.to_s, ctrl]
end.to_h
normalized['nvme_controllers'] = nvme_controllers.with_index.to_h do |ctrl, idx|
[idx.to_s, ctrl]
end

@girijaasoni
Copy link
Contributor Author

Test failures look related.

Test cases are related to changes in the fog-vpshere. They all pass on my local and we can re-trigger them once the fog-vsphere changes are in.

@ekohl
Copy link
Member

ekohl commented Jun 3, 2024

Test cases are related to changes in the fog-vpshere. They all pass on my local and we can re-trigger them once the fog-vsphere changes are in.

You can change this line here:

gem 'fog-vsphere', '>= 3.6.4', '< 4.0'

If you point that to your git branch (using https://bundler.io/guides/git.html) then you can run CI here. Once a release of fog-vsphere it out, you can change the line to require that specific release which includes the feature. That way our packaging will either fail or pick it up properly. We have some automation in that area.

@girijaasoni girijaasoni force-pushed the nvme_controllers branch 5 times, most recently from 4baa998 to 2eb9c33 Compare June 3, 2024 13:46
Copy link
Member

@ekohl ekohl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I realize some of the comments would have also applied to the existing code you're moving around, but whenever you add code it's also a good chance to revisit the code around it.

private

def normalize_vmware_storage_controller_attributes(attrs)
ctrls_and_vol = JSON.parse(attrs["controllers"]).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can delete here and drop line 13.

Suggested change
ctrls_and_vol = JSON.parse(attrs["controllers"]).
ctrls_and_vol = JSON.parse(attrs.delete("controllers")).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need to delete attrs[controllers] after we extract nvme and scsi controllers from them, Hence, the deleting part is done on line 13

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see it used. You use ctrls_and_vol[:controllers] later on, but you don't depend on attrs["controllers"].

ctrls_and_vol = JSON.parse(attrs["controllers"]).
deep_transform_keys { |key| key.to_s.underscore }.
deep_symbolize_keys
volumes = ctrls_and_vol[:volumes].each_with_index.to_h { |vol, index| [index.to_s, vol] }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps it makes sense to combine line 13 & this one:

Suggested change
volumes = ctrls_and_vol[:volumes].each_with_index.to_h { |vol, index| [index.to_s, vol] }
attrs["volumes_attributes"] = ctrls_and_vol[:volumes].each_with_index.to_h { |vol, index| [index.to_s, vol] }

@@ -638,7 +642,12 @@ def new_interface(attr = { })
end

def new_volume(attr = { })
client.volumes.new attr.merge(:size_gb => 10)
{
:thin => true,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without looking, don't we have some option to control whether it's thin or thick?

You're also completely ignoring the attr now. Is that intended as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, thin is just the default. We can change it as per convenience.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I didn't notice attr being unused. Thanks!!

@@ -1,3 +1,3 @@
group :vmware do
gem 'fog-vsphere', '>= 3.6.4', '< 4.0'
gem 'fog-vsphere', git: 'https://github.com/girijaasoni/fog-vsphere.git', branch: 'nvme-controllers'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fine and works (so no need to change it), but if you're lazy (like me) you can also use:

Suggested change
gem 'fog-vsphere', git: 'https://github.com/girijaasoni/fog-vsphere.git', branch: 'nvme-controllers'
gem 'fog-vsphere', github: 'girijaasoni/fog-vsphere', branch: 'nvme-controllers'

Having to type less is especially useful if you make quick local modifications.

Comment on lines 214 to 216
scsi_controllers = {}
compute_resource.scsi_controller_types.each { |type| scsi_controllers[type[:key]] = type[:title] }
compute_resource.storage_controller_types.each { |type| scsi_controllers[type[:key]] = type[:title] }
scsi_controllers
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, already a problem before but I think this whole method can be implemented as:

compute_resource.storage_controller_types.to_h { |type| [type[:key], type[:title]] }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants