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
vdo: module fails when modifying VDO 6.2 volumes without read cache #54556
Comments
Ideally, playbooks without the "readcache" parameter should work normally with VDO 6.2. |
I tried this modification to the original:
It successfully prevents the KeyError listed above, and a "create" playbook with the same options successfully completes with "ok=2 changed=0", as expected. Trying to use a "create" playbook with the missing feature (in this case, "readcache" and "readcachesize")...
...fails with a message: "vdo create: error: unrecognized arguments: --readCache=enabled --readCacheSize=64M". This is good, because it lets the user know that there were unrecognized playbook parameters. However, if trying to "modify" an existing VDO volume with the "added" read cache parameters, this new patch filters out and ignores those options. Ideally, this would be the same "unrecognized arguments" message as seen above, but at least it's more graceful than the original failure case. |
I don't know Here is an example in the |
worst case, search for |
If the vdo command detects that an argument is unrecognized, it will already return an error. However, in this case, the options that are not supported in the current version of VDO (i.e.: do not display in "vdo status", among the strings enumerated in "statusparamkeys") will result in the KeyError. So I added this line, to filter on only the status parameter keys that exist in "vdo status":
I have an idea: would it be possible to generate a list of the status parameter keys that are not in the "vdo status" output, that were specified in the playbook, and then "add" them to the "diffparams" entry, to then send to the "vdo modify" command (i.e.: "vdocmdoptions = add_vdooptions(diffparams)", etc.)? At that point, the "vdo" command would receive the parameters, including the "missing" parameters not supported by that version, and fail. (I guess this is a long-winded way of saying: I was trying to avoid a version check, mostly because there is no "vdo --version" command. One can check the version of VDO installed by "rpm -qa vdo".) |
If you can't do a version check, you can do a feature probe. This essentially means run the command and check the output or error code, as @bcoca suggested. Use this information to add in the extra options, if supported. base_opts = ['--one', '--two'] # always supported options
extra_opts = ['--three', '--four'] # only supported in new version
vdo_bin = self.module.get_bin_path('vdo', True)
supports_extra_opts = False
# Feature probe
cmd = [vdo_bin]
cmd.extend(extra_opts)
rc, out, err = module.run_command(cmd)
if 'unrecognized arguments' not in err:
supports_extra_opts = True
...
cmd = [vdo_bin]
cmd.extend(['--arg', module.params['someparam'])
if supports_extra_opts:
cmd.extend(extra_opts) |
I seem to have found a fix. (Ignore the "result['foo'] = foo" lines; I used those with "ansible-playbook -vvv ..." to check the contents of a few dictionaries during exectuion)
So my original theory when building the module was to filter out any "unsupported" parameters. However, when the "Read cache" and "Read cache size" fields in "vdo status" were no longer present in VDO 6.2, that resulted in the "KeyError". Therefore, use "if statfield in processedvdos[desiredvdo]:" to filter the modifiable parameters with the ones that are supported in this VDO version, then use "if statfield not in processedvdos[desiredvdo]:" to evade the KeyError, and add the "unsupported" parameters. Then, change "for paramkey in currentvdoparams.keys():" to "for paramkey in modtrans.keys():", in order to populate "currentparams" with the parameters that could potentially be modified, to then be processed by this part in vdo.py, where "diffparams" is loaded with "different" parameters; later, "add_vdooptions(diffparams)" is executed.
Test results, using the following test playbooks on VDO 6.2 (using the "Read cache" options, which VDO 6.2 will not have):
Stage 1: execute test_vdocreate.yml with no prior VDO volume: "ok=2 changed=1" (good; VDO volume created.) Stage 2: execute test_vdocreate.yml with prior VDO volume: "ok=2 changed=0" (good; VDO volume remained, with no changes.) Stage 3: execute test_vdoremove.yml with prior VDO volume: "ok=2 changed=1" (good; VDO volume was removed.) Stage 4: execute test_vdoremove.yml with no prior VDO volume: "ok=2 changed=0" (good: no VDO volume existed, and no changes. Stage 5: execute test_vdocreate_withreadcache.yml with no prior VDO volume: "ok=1 changed=0 unreachable=0 failed=1" (failure message: stderr from command: "...vdo create: error: unrecognized arguments: --readCache=enabled --readCacheSize=64M") Stage 6: execute test_vdocreate.yml with no prior VDO volume (to create a VDO volume for the next step) Stage 7: execute test_vdocreate_withreadcache.yml with a prior VDO volume: "ok=1 changed=0 unreachable=0 failed=1" |
Updated patch that fixes the bug (without the extra "result['foo'] = foo" lines):
|
In "status: present" playbook execution for a VDO volume that is absent, all of the parameters that are given in the playbook are issued to the "vdo create" command, therefore any parameters that become "unrecognized" will result in the "vdo" command returning an error with the message "unrecognized arguments", which can then be relayed back to the user. This is a gracefully handled failure case. Examples of "unrecognized" parameters are new features that are not yet in the current version of VDO, or features that were removed since the current version of VDO. In "status: present" playbook execution for a VDO volume that is already present, the same behavior as the "creation" stage of the module should occur, but doesn't occur, since the key strings for the "vdo status" output of the parameter do not exist. This results in a KeyError on the parameter that no longer exists. Therefore, use "if statfield in processedvdos[desiredvdo]:" to filter the modifiable parameters with the ones that are supported in this VDO version, then use "if statfield not in processedvdos[desiredvdo]:" to evade the KeyError, and add the "unsupported" parameters. Also, instead of using the "currentvdoparams" dictionary, which filters only the parameters reported by the "vdo status" output, use the "modtrans" dictionary, which contains all of the possible parameters. Therefore, if the playbook specifies an "unsupported" parameter, let it be passed on to the "vdo" command, to display an actionable error message. This fixes ansible#54556 Signed-off-by: Bryan Gurney <bgurney@redhat.com>
In "status: present" playbook execution for a VDO volume that is absent, all of the parameters that are given in the playbook are issued to the "vdo create" command, therefore any parameters that become "unrecognized" will result in the "vdo" command returning an error with the message "unrecognized arguments", which can then be relayed back to the user. This is a gracefully handled failure case. Examples of "unrecognized" parameters are new features that are not yet in the current version of VDO, or features that were removed since the current version of VDO. In "status: present" playbook execution for a VDO volume that is already present, the same behavior as the "creation" stage of the module should occur, but doesn't occur, since the key strings for the "vdo status" output of the parameter do not exist. This results in a KeyError on the parameter that no longer exists. Therefore, use "if statfield in processedvdos[desiredvdo]:" to filter the modifiable parameters with the ones that are supported in this VDO version, then use "if statfield not in processedvdos[desiredvdo]:" to evade the KeyError, and add the "unsupported" parameters. Also, instead of using the "currentvdoparams" dictionary, which filters only the parameters reported by the "vdo status" output, use the "modtrans" dictionary, which contains all of the possible parameters. Therefore, if the playbook specifies an "unsupported" parameter, let it be passed on to the "vdo" command, to display an actionable error message. This fixes ansible#54556 Signed-off-by: Bryan Gurney <bgurney@redhat.com>
SUMMARY
If a "creation" playbook (i.e.: "state:present" when the VDO volume already exists) is executed with VDO 6.2, the playbook execution fails with an error on vdo.py line 611: "KeyError: 'Read cache'".
ISSUE TYPE
COMPONENT NAME
vdo
ANSIBLE VERSION
CONFIGURATION
OS / ENVIRONMENT
vdo-6.2.0.293 on Red Hat Enterprise Linux 8.0
STEPS TO REPRODUCE
If a "state:present" playbook is executed for a VDO volume that already exists, ideally, it should finish with "ok=2 changed=0". However, for VDO 6.2, where there is no longer a "Read cache" or "Read cache size" parameter, the playbook execution will fail with this error:
(vdo.py) line 611, in run_module: KeyError: 'Read cache'
(However, note that creating or removing a VDO volume works normally.)
EXPECTED RESULTS
For a playbook where no changes are made, the playbook succeeds with "ok=2 changed=0"
For a playbook where changes are made, the playbook succeeds with "ok=2 changed=1"
ACTUAL RESULTS
When running the "Create VDO volume vdo1" playbook after vdo1 has been created (i.e.: in a situation where a parameter is being modified, or where no parameters are being modified), the playbook fails with "(vdo.py) line 611, in run_module: KeyError: 'Read cache'" because VDO 6.2 does not have the read cache feature, therefore the key is not present in the "vdo status" YAML output.
The failing line of code is here:
If I patch the module with this workaround, I get a successful run of "ok=2 chan
ged=0" for a "modify" run (i.e.: "status=present" where the entity already exists):
However, I want the module to be able to work with VDO versions that are both 6.2+, and older than 6.2. Is there a way to remove the "Read cache" and "Read cache size" keys from the "statusparamkeys" dictionary if they're not in the "vdo status" output? (This would be "processedvdos[desiredvdo]".)
The text was updated successfully, but these errors were encountered: