community.general icon indicating copy to clipboard operation
community.general copied to clipboard

Unable to parse virtualbox inventory file "'str' object does not support item assignment"

Open notetiene opened this issue 3 years ago • 7 comments

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

notetiene avatar Oct 03 '22 21:10 notetiene

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.

click here for bot help

ansibullbot avatar Oct 03 '22 21:10 ansibullbot

@ansibullbot !component +plugins/inventory/virtualbox.py

notetiene avatar Oct 06 '22 15:10 notetiene

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 avatar Oct 11 '22 20:10 basicdays

@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 avatar Oct 11 '22 20:10 felixfontein

@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 avatar Oct 11 '22 22:10 basicdays

@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 avatar Oct 13 '22 20:10 notetiene

@notetiene Yeah not sure which version. My guess is this change in information format might have started with version 6.1 perhaps.

basicdays avatar Oct 13 '22 21:10 basicdays