-
Notifications
You must be signed in to change notification settings - Fork 62
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
Use OvirtSDK for the provisioning flow #2
Use OvirtSDK for the provisioning flow #2
Conversation
@durandom Moved the PR here. |
add manageiq-providers-openstack.rb
This is a port of ManageIQ/manageiq#14402 |
@gmcculloug @bdunne @syncrou could you review please? This is to enable usage of v4 of the ovirt api. Part of this was already done in We should get this into fine to enable customers to opt into v4 and let it be used in general. |
@durandom Hi! was wondering if there are any news regarding this PR? |
phase_context[:clone_task_ref] = vm.creation_status_link | ||
end | ||
|
||
def nics_for_(vm) |
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.
@borod108
is the trailing underscore in the method name intentional?
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.
yes, i just like this style but I can remove it and write nics_for_vm(vm) instead, but the double "vm" thing...
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.
Yes, I never saw a trailing underscore style in our code base (actually not even in ruby projects...)
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.
well rubocop did not complain!
so should I change it?
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.
well rubocop did not complain!
probably no one ever had the idea 😄 - I'd change it
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.
ok.
@@ -17,7 +17,7 @@ def host_targeted_refresh(target) | |||
end | |||
|
|||
def vm_targeted_refresh(target) | |||
ems.with_provider_connection(:version => 4) do |connection| | |||
@ems.with_provider_connection(:version => 4) do |connection| |
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.
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.
yes definitely, by bad.
@@ -87,6 +87,8 @@ def collect_vms | |||
def collect_vm_by_uuid(uuid) | |||
vm = connection.system_service.vms_service.vm_service(uuid).get | |||
[VmPreloadedAttributesDecorator.new(vm, connection)] | |||
rescue OvirtSDK4::Error | |||
[] |
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.
Seems odd to ignore this error and return an empty array. Can you explain the reasoning 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.
Actually this is currently the right way to check if a VM exists using the oVirt Ruby SDK. The vm_service(uuid)
method will always succeed, even if the VM doesn't exist. Calling the get
method will then raise an exception, corresponding to the Not found
HTTP code. The details of the error are in the exception message which isn't easy to parse.
I'd suggest to keep this code as it is. We will improve the SDK to provide a mechanism to check the kind of error, then this can be improved. For example:
begin
...
rescue OvirtSDK4::Error => e
if e.code == 404
[]
else
raise
end
end
I have opened the following oVirt SDK bug to track it:
[RFE] Add a mechanism to check the HTTP result code of errors
https://bugzilla.redhat.com/1443420
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.
It would be great to rescue a more specific error like OvirtSDK4::ResourceNotFound
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.
Unfortunately, currently this not possible, please refer to Juans answer above, we will do it in future PRs
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.
Please open an issue so that it isn't forgotten @borod108
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.
Done: #17
@@ -8,7 +8,7 @@ def initialize(args) | |||
end | |||
|
|||
def host_targeted_refresh(target) | |||
ems.with_provider_connection(:version => 4) do |connection| | |||
@ems.with_provider_connection(:version => 4) do |connection| |
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.
Since this is in the v4.rb
file would it make sense to make either the 4
or the whole hash a constant.
VERSION = 4
VERSION_HASH = {:version => VERSION}.freeze
...
@ems.with_provider_connection(VERSION_HASH) do |connection|
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.
Oh, good idea!
nic_name = args[:nic_name] | ||
interface = args[:interface] | ||
vnic = args[:vnic] | ||
logger = args[:logger] |
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 do not see any benefit to mapping most of these single-use variables. Just reference them directory from args
in the method. The key names are clear.
Anything being referenced more then once it would make more sense to make a variable.
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.
The benefit of writing like this is that one can easily see args this method can receive.
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.
@borod108 If that's what you're trying to accomplish, you may want to use keyword args
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.
done.
_log.info("#{log_header} Completed.") | ||
end | ||
|
||
class NicsDecorator < SimpleDelegator |
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.
Suggest moving classes into their own files.
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 would like to do this in future refactoring.
There are several more refactoring steps on this code and this will be one of them, but currently will be just a bit easier to do while the classes are still here.
end | ||
end | ||
|
||
class GeneralUpdateMethodNamesDecorator < SimpleDelegator |
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.
Suggest moving classes into their own files.
d540cf2
to
af4b65c
Compare
|
||
def shutdown_guest(operation) | ||
operation.with_provider_object(&:shutdown) | ||
rescue Ovirt::VmIsNotRunning |
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.
@borod108 - I'm not understanding the value in suppressing exceptions, if there is a case for it - should there be some documentation around that case?
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 logic was not changed from before. I found many things I do not like but kept the same logic because this is out of the scope of this PR.
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.
@syncrou This pattern was initially added because the desired result in this case is for the VM to be off. If we sent shutdown_guest
for a VM that is already off, the API would raise this error. So, it was simplest to just rescue the error and move on.
vm.with_provider_object do |rhevm_vm| | ||
rhevm_vm.start { |action| action.use_cloud_init(true) if cloud_init } | ||
end | ||
rescue Ovirt::VmAlreadyRunning |
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.
Same here in regards to suppressing exceptions
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.
Same.
|
||
def vm_stop(vm) | ||
vm.with_provider_object(&:stop) | ||
rescue Ovirt::VmIsNotRunning |
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.
And 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.
Same.
|
||
def collect_disks_by_hrefs(disks) | ||
vm_disks = [] | ||
ext_management_system.with_provider_connection(:version => 4) do |connection| |
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.
Wondering if we should generate a constant for :version => 4
to keep the process consistent.
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.
You are right. Done.
3d60fb1
to
940fb86
Compare
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.
👍 to get it into fine
the mentioned cleanups will be done in future and smaller PRs
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.
In the future, it is much easier to review smaller PR's. If you feel it is necessary to keep all changes in one PR, multiple commits are helpful. I think the respond_to_missing?
method is important.
nic_name = args[:nic_name] | ||
interface = args[:interface] | ||
vnic = args[:vnic] | ||
logger = args[:logger] |
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.
@borod108 If that's what you're trying to accomplish, you may want to use keyword args
|
||
def shutdown_guest(operation) | ||
operation.with_provider_object(&:shutdown) | ||
rescue Ovirt::VmIsNotRunning |
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.
@syncrou This pattern was initially added because the desired result in this case is for the VM to be off. If we sent shutdown_guest
for a VM that is already off, the API would raise this error. So, it was simplest to just rescue the error and move on.
end | ||
|
||
class GeneralUpdateMethodNamesDecorator < SimpleDelegator | ||
def method_missing(method_name, *args) |
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.
You need to also define respond_to_missing?
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.
Please see the comment in the code, the problem is that the ovirt-gem does not actually define the respond_to_missing? so I can't really know without sending the method if it works or not. I do not see a clean way to do this.
In future PR we need to update the ovirt-gem and change this method_missing which is quite ugly. I will then be able to add the respond_to_missing? as well.
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.
Please open an issue so that it is not forgotten @borod108
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.
Done: #18
{:network => network_name, :mac_address => nil}, | ||
{:network => network_name} | ||
]) | ||
{:network => network_name, :mac_address => nil}, |
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.
Why the whitespace addition?
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 is how rubocop liked it...
@@ -12,6 +12,8 @@ | |||
allow(v).to receive(:with_provider_object).and_yield(rhevm_vm) | |||
allow(ems).to receive(:with_disk_attachments_service).with(v).and_return(disk_attachments_service) | |||
allow(ems).to receive(:with_provider_connection).and_return(false) | |||
# TODO: (inventory) wirte for v4 |
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.
typo: write
vnic.nil? ? get_provider_destination.create_nic(options) : vnic.apply_options!(options) | ||
ems.ovirt_services.configure_vnic( | ||
:vm => destination, | ||
:mac_addr => mac_addr, |
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.
Is mac_address
required now? IIRC, if we passed a nil
, it would try to set it to nil
. That was the reason for the delete_blanks
.
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.
It is required for v4, so the delete blanks moved into the ovirt_services/strategies/v3
@@ -87,6 +87,8 @@ def collect_vms | |||
def collect_vm_by_uuid(uuid) | |||
vm = connection.system_service.vms_service.vm_service(uuid).get | |||
[VmPreloadedAttributesDecorator.new(vm, connection)] | |||
rescue OvirtSDK4::Error | |||
[] |
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.
It would be great to rescue a more specific error like OvirtSDK4::ResourceNotFound
b71245b
to
66cd51e
Compare
Please note the PR is currently back to WIP because we want to test fully after all the changes. |
66cd51e
to
dee68de
Compare
This pull request is not mergeable. Please rebase and repush. |
@bdunne thank you for the review! I tried to address your comments. |
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.
It looks like you merged master into your branch rather than rebasing your branch. This can cause problems when commits on master reference bugzillas since all commits in the PR that have a bugzilla reference will be updated with a link to this PR. In this case I think it's okay ¯\_(ツ)_/¯
since that one commit doesn't have a bugzilla reference, but please be aware of this in the future.
Hi please do not merge for the next few hours, we would like to make a final round of tests and internal review. |
…e_sdk setting and will not use OvirtSDK if it is off. This was a common effort with big contribution from @pkliczewski and help from @jhernand and @masayag
a2776a7
to
83f887a
Compare
@miq-bot remove-label wip |
Some comments on commit borod108@83f887a spec/models/manageiq/providers/redhat/infra_manager/provision/configuration_spec.rb
spec/models/manageiq/providers/redhat/infra_manager/provision_spec.rb
|
1 similar comment
Some comments on commit borod108@83f887a spec/models/manageiq/providers/redhat/infra_manager/provision/configuration_spec.rb
spec/models/manageiq/providers/redhat/infra_manager/provision_spec.rb
|
Checked commit borod108@83f887a with ruby 2.2.6, rubocop 0.47.1, and haml-lint 0.20.0 app/models/manageiq/providers/redhat/infra_manager.rb
app/models/manageiq/providers/redhat/infra_manager/ovirt_services/strategies/v3.rb
app/models/manageiq/providers/redhat/infra_manager/ovirt_services/strategies/v4.rb
|
👏 finally 😅 everybody thanks for your patience and efforts |
Fine backport (to manageiq repo) details:
|
Use OvirtSDK for the provisioning flow, this respects use_ovirt_engine_sdk setting
and will not use OvirtSDK if it is off.
This was a common effort with big contribution from @pkliczewski
and help from @jhernand and @masayag