3

I have a requirements.yml file that lists dependencies for an Ansible Role:

---

- src: git@gitrepo:group/dependency1.git
  scm: git
  name: name1

- src: git@gitrepo:group/dependency1.git
  scm: git
  name: name2

These roles do not have any dependencies themselves, and as they are on a private SCM system (among other reasons), they do not need any metadata. However, loading in Ansible dependencies requires that this file exists. Therefore, the dependencies have a blank meta/main.yml to enable using ansible-galaxy.

When installing dependencies using:

ansible-galaxy install --role-file requirements.yml --roles-path foo

after the first dependency was installed, it would error out with:

ERROR! Unexpected Exception: 'NoneType' object has no attribute 'get'

Using the very very verbose output, the error gets located:

galaxy.py", line 394

After experimentation, running the command several more times would progress through the dependencies, one at a time. Nested dependencies would, therefore, fail; as either the parent would install then error out, or ansible-galaxy would think the parent is already installed and skip dependencies.

The question is: how do I stop this error from occurring and get ansible-galaxy to correctly process my dependencies?

Jamie Kelly
  • 309
  • 3
  • 15

2 Answers2

5

I just fixed this in devel. Should make the 2.4 release of Ansible.

Sam Doran
  • 51
  • 2
0

As it turns out, a blank meta/main.yml is not sufficient to process a role as a dependency. My hypothesis is that the role object is initialised with no metadata field if the file is blank, as the line mentioned in the verbose output is:

role_dependencies = role.metadata.get('dependencies') or []

"role" is used prior to this line, so will be an instance, whereas this is the first mention of "metadata".

This section of code is dealing with installing nested dependencies, as the line above is making checks to determine if it should process nested dependencies.

if not no_deps and installed:
  role_dependencies = role.metadata.get('dependencies') or []
  ...

If this line also checked for the existence of metadata, for example:

if not no_deps and installed and metadata:

Then this section would be (rightfully) skipped. However, as Ansible does not make this check, metadata is the 'NoneType' object, which indeed has no attribute 'get'.

What this means is that the meta/main.yml file needs at least one key in it in order to be processed as a dependency. Having a meta/main.yml file of:

---

galaxy_info:

is sufficient for this purpose.

Jamie Kelly
  • 309
  • 3
  • 15