-
Notifications
You must be signed in to change notification settings - Fork 898
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
Add method for restricting to accessible storages #18391
Add method for restricting to accessible storages #18391
Conversation
Use the host_storage.accessible property to filter storages that cannot be accessed by the provider due to be disconnected or otherwise inaccessible. https://bugzilla.redhat.com/show_bug.cgi?id=1668020
cc @tinaafitz |
@@ -47,6 +47,8 @@ class Host < ApplicationRecord | |||
has_many :miq_templates, :inverse_of => :host | |||
has_many :host_storages, :dependent => :destroy | |||
has_many :storages, :through => :host_storages | |||
has_many :writable_accessible_host_storages, -> { writable_accessible }, :class_name => "HostStorage" | |||
has_many :writable_accessible_storages, :through => :writable_accessible_host_storages, :source => :storage |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be good to replace the writable_storages
and read_only_storages
with associations using these scopes, not sure if in this PR or a followup since it isn't really related
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/cc @NickLaMuro since you modified the writable_storages
method for performance, wdyt?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For reference (since I had to go find it), that performance change was done here:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, so I think my to cents with this is that you probably want to leave those methods (writable_storages
and read_only_storages
), and just change them to use the scopes:
def writable_storages
if host_storages.loaded? && host_storages.all? { |hs| hs.association(:storage).loaded? }
host_storages.reject(&:read_only).map(&:storage)
else
- storages.where(:host_storages => {:read_only => [false, nil]})
+ storages.writable # I think my pseudo code here is wrong...
end
end
Or, if we did create a writable_storages
scope, I would suggest possibly doing the following to maintain the performance benefits of #17354 :
has_many :writable_host_storages, -> { writable }, :class_name => "HostStorage"
has_many :writable_storages, :through => :writable_host_storages, :source => :storage
# overwrite default reader method
def writable_storages
if association(:writable_storages).loaded? # use already loaded the relationship (faster)
association(:writable_storages).reader
# can use an existing relationship to avoid another query and instantiation of other records (requires loop)
elsif host_storages.loaded? && host_storages.all? { |hs| hs.association(:storage).loaded? }
host_storages.reject(&:read_only).map(&:storage)
else # call the relationship
association(:writable_storages).reader
end
end
Let me know if any of this needs a further explanation... trying to avoid a 📖
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright I'll leave it as is 😄
b96e95b
to
62f834e
Compare
Checked commits agrare/manageiq@afddd94~...62f834e with ruby 2.3.3, rubocop 0.52.1, haml-lint 0.20.0, and yamllint 1.10.0 app/models/host.rb
app/models/host_storage.rb
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just some thoughts, mainly regarding the original question asked to me by @agrare
https://github.com/ManageIQ/manageiq/pull/18391/files#r250684300
Take it or leave it.
@@ -47,6 +47,8 @@ class Host < ApplicationRecord | |||
has_many :miq_templates, :inverse_of => :host | |||
has_many :host_storages, :dependent => :destroy | |||
has_many :storages, :through => :host_storages | |||
has_many :writable_accessible_host_storages, -> { writable_accessible }, :class_name => "HostStorage" | |||
has_many :writable_accessible_storages, :through => :writable_accessible_host_storages, :source => :storage |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, so I think my to cents with this is that you probably want to leave those methods (writable_storages
and read_only_storages
), and just change them to use the scopes:
def writable_storages
if host_storages.loaded? && host_storages.all? { |hs| hs.association(:storage).loaded? }
host_storages.reject(&:read_only).map(&:storage)
else
- storages.where(:host_storages => {:read_only => [false, nil]})
+ storages.writable # I think my pseudo code here is wrong...
end
end
Or, if we did create a writable_storages
scope, I would suggest possibly doing the following to maintain the performance benefits of #17354 :
has_many :writable_host_storages, -> { writable }, :class_name => "HostStorage"
has_many :writable_storages, :through => :writable_host_storages, :source => :storage
# overwrite default reader method
def writable_storages
if association(:writable_storages).loaded? # use already loaded the relationship (faster)
association(:writable_storages).reader
# can use an existing relationship to avoid another query and instantiation of other records (requires loop)
elsif host_storages.loaded? && host_storages.all? { |hs| hs.association(:storage).loaded? }
host_storages.reject(&:read_only).map(&:storage)
else # call the relationship
association(:writable_storages).reader
end
end
Let me know if any of this needs a further explanation... trying to avoid a 📖
@@ -1069,7 +1069,7 @@ def allowed_storages(_options = {}) | |||
MiqPreloader.preload(hosts, :storages => {}, :host_storages => :storage) | |||
|
|||
storages = hosts.each_with_object({}) do |host, hash| | |||
host.writable_storages.each { |s| hash[s.id] = s } | |||
host.writable_accessible_storages.each { |s| hash[s.id] = s } | |||
end.values |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change will help with the Provisioning UI and Automate callers to eligible_storages
.
Unfortunately the vmware_best_fit_least_utilized
placement method in Automate provisioning uses writable_storages
directly. (See VM/Provisioning/Placement.class/methods/vmware_best_fit_least_utilized.rb)
@tinaafitz As part of fixing this BZ we should look into changing these calls to use allowed_storages
instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall, I'm good with this change. Added a note about changes we will need to address on the Automate side to fully resolve the reported issue.
Now I just need to figure out when @agrare and @NickLaMuro are actually done discussing the changes. 😕
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Marking as approved to avoid any further confusion from @gmcculloug 😉
Use the host_storage.accessible property to filter storages that cannot
be accessed by the provider due to being disconnected or otherwise
inaccessible.
Depends on:
https://bugzilla.redhat.com/show_bug.cgi?id=1668020