community.general
community.general copied to clipboard
Unable to parse virtualbox inventory file "'str' object does not support item assignment"
Summary
I'm unable to get the virtualbox inventory using the community.general.virtualbox module.
Issue Type
Bug Report
Component Name
virtualbox
Ansible Version
$ ansible --version
ansible [core 2.13.4]
config file = /home/etienne/playbook/ansible.cfg
configured module search path = ['/home/etienne/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /home/etienne/.local/lib/python3.8/site-packages/ansible
ansible collection location = /home/etienne/.ansible/collections:/usr/share/ansible/collections
executable location = /usr/bin/ansible
python version = 3.8.10 (default, Jun 22 2022, 20:18:18) [GCC 9.4.0]
jinja version = 3.1.2
libyaml = True
Community.general Version
$ ansible-galaxy collection list community.general
# /usr/lib/python3/dist-packages/ansible_collections
Collection Version
----------------- -------
community.general 4.8.3
# /home/etienne/.ansible/collections/ansible_collections
Collection Version
----------------- -------
community.general 5.6.0
Configuration
$ ansible-config dump --only-changed
ANSIBLE_FORCE_COLOR(/home/etienne/playbook/ansible.cfg) = True
INVENTORY_ENABLED(/home/etienne/playbook/ansible.cfg) = ['host_list', 'script', 'auto', 'yaml', 'ini', 'toml', 'virtualbox']
OS / Environment
Ubuntu 20.04 Linux P50 5.15.0-48-generic #54~20.04.1-Ubuntu SMP Thu Sep 1 16:17:26 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
Steps to Reproduce
When I try to load a VIrtualBox inventory with the following example:
vbox.yml
---
plugin: virtualbox
Doing the following command:
ansible all -i vbox.yml --list -vvv
I get:
ansible [core 2.13.4] config file = /home/etienne/playbook/ansible.cfg configured module search path = ['/home/etienne/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules'] ansible python module location = /home/etienne/.local/lib/python3.8/site-packages/ansible ansible collection location = /home/etienne/.ansible/collections:/usr/share/ansible/collections executable location = /usr/bin/ansible python version = 3.8.10 (default, Jun 22 2022, 20:18:18) [GCC 9.4.0] jinja version = 3.1.2 libyaml = True Using /home/etienne/playbook/ansible.cfg as config file redirecting (type: inventory) ansible.builtin.virtualbox to community.general.virtualbox host_list declined parsing /home/etienne/playbook/vbox.yml as it did not pass its verify_file() method script declined parsing /home/etienne/playbook/vbox.yml as it did not pass its verify_file() method redirecting (type: inventory) ansible.builtin.virtualbox to community.general.virtualbox Using inventory plugin 'ansible_collections.community.general.plugins.inventory.virtualbox' to process inventory source '/home/etienne/playbook/vbox.yml' toml declined parsing /home/etienne/playbook/vbox.yml as it did not pass its verify_file() method [WARNING]: * Failed to parse /home/etienne/playbook/vbox.yml with auto plugin: 'str' object does not support item assignment File "/home/etienne/.local/lib/python3.8/site-packages/ansible/inventory/manager.py", line 290, in parse_source plugin.parse(self._inventory, self._loader, source, cache=cache) File "/home/etienne/.local/lib/python3.8/site-packages/ansible/plugins/inventory/auto.py", line 59, in parse plugin.parse(inventory, loader, path, cache=cache) File "/home/etienne/.ansible/collections/ansible_collections/community/general/plugins/inventory/virtualbox.py", line 281, in parse cacheable_results = self._populate_from_source(source_data, using_current_cache) File "/home/etienne/.ansible/collections/ansible_collections/community/general/plugins/inventory/virtualbox.py", line 192, in _populate_from_source hostvars[current_host][prevkey][pref_k] = v [WARNING]: * Failed to parse /home/etienne/playbook/vbox.yml with yaml plugin: Plugin configuration YAML file, not YAML inventory File "/home/etienne/.local/lib/python3.8/site-packages/ansible/inventory/manager.py", line 290, in parse_source plugin.parse(self._inventory, self._loader, source, cache=cache) File "/home/etienne/.local/lib/python3.8/site-packages/ansible/plugins/inventory/yaml.py", line 114, in parse raise AnsibleParserError('Plugin configuration YAML file, not YAML inventory') [WARNING]: * Failed to parse /home/etienne/playbook/vbox.yml with ini plugin: Invalid host pattern '---' supplied, '---' is normally a sign this is a YAML file. File "/home/etienne/.local/lib/python3.8/site-packages/ansible/inventory/manager.py", line 290, in parse_source plugin.parse(self._inventory, self._loader, source, cache=cache) File "/home/etienne/.local/lib/python3.8/site-packages/ansible/plugins/inventory/ini.py", line 136, in parse raise AnsibleParserError(e) [WARNING]: * Failed to parse /home/etienne/playbook/vbox.yml with ansible_collections.community.general.plugins.inventory.virtualbox plugin: 'str' object does not support item assignment File "/home/etienne/.local/lib/python3.8/site-packages/ansible/inventory/manager.py", line 290, in parse_source plugin.parse(self._inventory, self._loader, source, cache=cache) File "/home/etienne/.ansible/collections/ansible_collections/community/general/plugins/inventory/virtualbox.py", line 281, in parse cacheable_results = self._populate_from_source(source_data, using_current_cache) File "/home/etienne/.ansible/collections/ansible_collections/community/general/plugins/inventory/virtualbox.py", line 192, in _populate_from_source hostvars[current_host][prevkey][pref_k] = v [WARNING]: Unable to parse /home/etienne/playbook/vbox.yml as an inventory source [WARNING]: No inventory was parsed, only implicit localhost is available [WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all' hosts (0):
Where:
[WARNING]: * Failed to parse /home/etienne/playbook/vbox.yml with ansible_collections.community.general.plugins.inventory.virtualbox plugin: 'str' object does not support item assignment File "/home/etienne/.local/lib/python3.8/site-packages/ansible/inventory/manager.py", line 290, in parse_source plugin.parse(self._inventory, self._loader, source, cache=cache) File "/home/etienne/.ansible/collections/ansible_collections/community/general/plugins/inventory/virtualbox.py", line 281, in parse cacheable_results = self._populate_from_source(source_data, using_current_cache) File "/home/etienne/.ansible/collections/ansible_collections/community/general/plugins/inventory/virtualbox.py", line 192, in _populate_from_source hostvars[current_host][prevkey][pref_k] = v
is what we want.
Expected Results
I would expect to get a valid VirtualBox inventory.
Actual Results
$ ansible all -i vbox.yml --list -vvvv
ansible [core 2.13.4]
config file = /home/etienne/playbook/ansible.cfg
configured module search path = ['/home/etienne/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /home/etienne/.local/lib/python3.8/site-packages/ansible
ansible collection location = /home/etienne/.ansible/collections:/usr/share/ansible/collections
executable location = /usr/bin/ansible
python version = 3.8.10 (default, Jun 22 2022, 20:18:18) [GCC 9.4.0]
jinja version = 3.1.2
libyaml = True
Using /home/etienne/playbook/ansible.cfg as config file
setting up inventory plugins
redirecting (type: inventory) ansible.builtin.virtualbox to community.general.virtualbox
Loading collection community.general from /home/etienne/.ansible/collections/ansible_collections/community/general
host_list declined parsing /home/etienne/playbook/vbox.yml as it did not pass its verify_file() method
script declined parsing /home/etienne/playbook/vbox.yml as it did not pass its verify_file() method
redirecting (type: inventory) ansible.builtin.virtualbox to community.general.virtualbox
Using inventory plugin 'ansible_collections.community.general.plugins.inventory.virtualbox' to process inventory source '/home/etienne/playbook/vbox.yml'
toml declined parsing /home/etienne/playbook/vbox.yml as it did not pass its verify_file() method
[WARNING]: * Failed to parse /home/etienne/playbook/vbox.yml with auto plugin: 'str' object does not support item assignment
File "/home/etienne/.local/lib/python3.8/site-packages/ansible/inventory/manager.py", line 290, in parse_source
plugin.parse(self._inventory, self._loader, source, cache=cache)
File "/home/etienne/.local/lib/python3.8/site-packages/ansible/plugins/inventory/auto.py", line 59, in parse
plugin.parse(inventory, loader, path, cache=cache)
File "/home/etienne/.ansible/collections/ansible_collections/community/general/plugins/inventory/virtualbox.py", line 281, in parse
cacheable_results = self._populate_from_source(source_data, using_current_cache)
File "/home/etienne/.ansible/collections/ansible_collections/community/general/plugins/inventory/virtualbox.py", line 192, in _populate_from_source
hostvars[current_host][prevkey][pref_k] = v
[WARNING]: * Failed to parse /home/etienne/playbook/vbox.yml with yaml plugin: Plugin configuration YAML file, not YAML inventory
File "/home/etienne/.local/lib/python3.8/site-packages/ansible/inventory/manager.py", line 290, in parse_source
plugin.parse(self._inventory, self._loader, source, cache=cache)
File "/home/etienne/.local/lib/python3.8/site-packages/ansible/plugins/inventory/yaml.py", line 114, in parse
raise AnsibleParserError('Plugin configuration YAML file, not YAML inventory')
[WARNING]: * Failed to parse /home/etienne/playbook/vbox.yml with ini plugin: Invalid host pattern '---' supplied, '---' is normally a sign this is a YAML file.
File "/home/etienne/.local/lib/python3.8/site-packages/ansible/inventory/manager.py", line 290, in parse_source
plugin.parse(self._inventory, self._loader, source, cache=cache)
File "/home/etienne/.local/lib/python3.8/site-packages/ansible/plugins/inventory/ini.py", line 136, in parse
raise AnsibleParserError(e)
[WARNING]: * Failed to parse /home/etienne/playbook/vbox.yml with ansible_collections.community.general.plugins.inventory.virtualbox plugin: 'str' object does not support item assignment
File "/home/etienne/.local/lib/python3.8/site-packages/ansible/inventory/manager.py", line 290, in parse_source
plugin.parse(self._inventory, self._loader, source, cache=cache)
File "/home/etienne/.ansible/collections/ansible_collections/community/general/plugins/inventory/virtualbox.py", line 281, in parse
cacheable_results = self._populate_from_source(source_data, using_current_cache)
File "/home/etienne/.ansible/collections/ansible_collections/community/general/plugins/inventory/virtualbox.py", line 192, in _populate_from_source
hostvars[current_host][prevkey][pref_k] = v
[WARNING]: Unable to parse /home/etienne/playbook/vbox.yml as an inventory source
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
hosts (0):
Code of Conduct
- [X] I agree to follow the Ansible Code of Conduct
Files identified in the description:
If these files are incorrect, please update the component name section of the description or use the !component bot command.
@ansibullbot !component +plugins/inventory/virtualbox.py
Just ran into this as well. I'm running VirtualBox version 6.1.38 on MacOS 12.6.
I did some sleuthing of the code with a bunch of print statements and found that the logic to parse the VBoxManage showvminfo data isn't handling some of the nested data correctly. Here's the showvminfo that's blowing up for me:
Recording screens: 1
Screen 0:
Enabled: yes
ID: 0
Record video: yes
Record audio: no
Destination: File
File: /Users/<me>/VirtualBox VMs/<vbox instance>/<vbox-instance>-screen0.webm
Options: vc_enabled=true,ac_enabled=false,ac_profile=med
Video dimensions: 1024x768
Video rate: 512kbps
Video FPS: 25fps
It seems since Recording screens has both a value and a nested dictionary, it's blowing up on line 192: https://github.com/ansible-collections/community.general/blob/main/plugins/inventory/virtualbox.py#L192
In addition, it seems it's a double nested dictionary, so not sure if that's being handled correctly either. As a temporary fix, I just edited ~/.ansible/collections/ansible_collections/community/general/plugins/inventory/virtualbox.py file, line 190 to this:
if prevkey not in hostvars[current_host] or not isinstance(hostvars[current_host][prevkey], dict):
It doesn't handle the double nested information correctly, but it at least doesn't cause the whole thing to blow up.
@basicdays want to create a PR for that (with a changelog fragment)? While this isn't a great long-term fix (as you noted), at least it makes it restores basic functionality short-term :)
@basicdays want to create a PR for that (with a changelog fragment)? While this isn't a great long-term fix (as you noted), at least it makes it restores basic functionality short-term :)
@felixfontein Yeah I can do that, I was actually just looking into the process to do a PR for this.
@basicdays thanks for looking into that. I did start debugging, but when I suspected it had to do with parsing, I gave up. Is it specific to a version of VirtualBox?
Edit: I saw you mentioned you didn't know which version is affected in the PR.
@notetiene Yeah not sure which version. My guess is this change in information format might have started with version 6.1 perhaps.