-
Notifications
You must be signed in to change notification settings - Fork 24k
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
Slight refactor on vmware_guest to fix path searching #26511
Conversation
The test
|
The test
|
@nerzhul @dav1x @dericcrago @Akasurde @dagwieers Can you guys test this please? |
lib/ansible/module_utils/vmware.py
Outdated
result = eval(expression) | ||
except: | ||
pass | ||
return result |
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.
Something like this instead:
def _get_vm_prop(vm, attributes):
result = vm
for attribute in attributes:
try:
result = getattr(result, attribute)
except AttributeError:
return None
return result
_get_vm_props(vm, ('guest', 'toolsRunningStatus'))
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, using pass
instead of returning None
in AttributeError as return None
fails to retrieve snapshots. Snapshot data works perfect with pass
.
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.
pass doesn't advance result to the next layer of the object, though. Imagine a data structure like this:
class Alice:
foo = 1
class Bob:
bar = Alice()
foo = 2
obj = Bob()
del obj.bar
result = _get_vm_props(obj, ('bar', 'foo')
# with return None:
result == None
# with pass
result == 2
For snapshot, what are you calling? This seems right and it seems like it would do the right thing:
snapshot = _get_vm_prop(vm, ['snapshot'])
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.
@Akasurde I've tested this patch on cloning from snapshots, so I think it does work to some degree. Can you extrapolate on which situations you don't think it will work?
@cigamit are you able to test this? |
self.module.fail_json(msg="Folder %(folder)s needs to be an absolute path, starting with '/'." % self.params) | ||
searchpath = '%(datacenter)s%(folder)s' % self.params | ||
# searchpaths do not need to be absolute | ||
searchpath = self.params['folder'] |
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.
Datacenter is required for FindByInventoryPath
. Without datacenter API, fails to find the 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.
Can we move getvm
method to vmware.py
so that vmware_guest_facts
or other modules could use 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.
I have tested, and found that FindByInventoryPath does need the full path to find a folder in both my scenarios where VMs are nested like so.
/TestDCFolder/TestDC/TestCluster/TestFolder/
and
/TestDC/TestCluster/TestFolder/
In both cases, I needed to change searchpath to match the full path to the DC, then /vm/ and the actual folder. So in the above instances it was.
/TestDCFolder/TestDC/vm/TestFolder/
and
/TestDC/vm/TestFolder/
module.params['folder'] = module.params['folder'].rstrip('/') | ||
|
||
pyv = PyVmomiHelper(module) | ||
|
||
# Check if the VM exists before continuing | ||
vm = pyv.getvm(name=module.params['name'], folder=module.params['folder'], uuid=module.params['uuid']) | ||
if not vm: | ||
module.fail_json(msg="nope") |
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.
Could you please change this message to something descriptive about the error?
I have made changes and tested with
Without datacenter value in searchpath it fails to find VM. |
self.module.fail_json(msg="Folder %(folder)s needs to be an absolute path, starting with '/'." % self.params) | ||
searchpath = '%(datacenter)s%(folder)s' % self.params | ||
# searchpaths do not need to be absolute | ||
searchpath = self.params['folder'] |
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.
Can we move getvm
method to vmware.py
so that vmware_guest_facts
or other modules could use 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.
This leads me to believe that I should set my folder like so
folder: /Test/TestDC/vm/TestF
but doing that causes the clone task (vm_obj.Clone) to fail with
"A specified parameter was not correct: spec.location.folder"
It works in the scenario that the Datacenter is not nested under a folder, but Nesting it under a folder causes the error above.
@cigamit thanks for testing. I'll try to get a a real vcenter setup with this configuration and revise the patch accordingly. |
|
||
# split the searchpath so we can iterate through it | ||
paths = [x.replace('/', '') for x in searchpath.split('/')] | ||
paths = [x.strip() for x in paths if x.strip()] |
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.
x.replace('/', '')
shouldn't be necessary. searchpath.split('/') should have removed all instances of "/" from the output.- Is it valid to strip the path elements? Could you have a valid path like this:
/folder1/ datacenter1 /vm
?
The test
The test
|
The test
|
There still seems to be some regression involving Resource Pools, I'm attempting to debug the code currently. I can clone into my DC that is nested, but not my normal DC. I keep getting the error
All these pass when cloning into my Nested DC though. Cross DC clones from Unnested to Nested DC passes also. Its almost like it is still pulling something from the wrong DC. Also, when debugging the above, I found that if I don't specify a cluster, and instead use esxi_hostname but don't specify a Resource Pool, I get |
If I don't specify a location for the Disk (since I'm not making changes to it) it seems to "Auto-Select" instead of placing it in the same location as the VM I am cloning. I think this is one of the changes that was fixed where it was just inheriting the wrong properties from the template. While this could be acceptable, I can not specify a specific Datastore via disk without also specifying a size (the size seems to want to be required). |
This fix now works for me in all scenarios I have tested (Nested DCs, Unnested DCs, Cross DC Cloning, With/Without Resource Pools, Cloning from Snapshot, and Linked Clones) |
SUMMARY
Fixes #25011
ISSUE TYPE
COMPONENT NAME
vmware_guest
ANSIBLE VERSION