# ansible-container --debug version
Ansible Container, version 0.9.2
Linux, ubuntu, 4.4.0-112-generic, #135-Ubuntu SMP Fri Jan 19 11:48:36 UTC 2018, x86_64
2.7.12 (default, Nov 20 2017, 18:23:56)
[GCC 5.4.0 20160609] /home/ubuntu/ansible-container/bin/python2
SUMMARY
The intended behavior of jinja2 templating of container.yml is confusing. I'm not sure if it's a documentation or code issue, and is definitely a good feature, hence my indicating all three issue types above.
as a "Note" in a blue box, "Resolving Jinja expressions to render the final container.yml is done inside the conductor container." - implying that the container.yml is read verbatim, and the third and fourth {{os_major_version}} would be properly substituted
later on, "Before the build command can be executed, Jinja is called to perform template rendering." - this certainly makes sense from the position of the "--vars-files" arguments on the command line coming before "build", and implies that all four above {{os_major_version}} would get substituted
further down, "Variable files can also be specified using the vars_files directive under settings in container.yml." - implying the the third and fourth {{os_major_version}} would get substituted, and consistent with indication that substitution happens in conductor container
STEPS TO REPRODUCE
ansible-container --vars-files centos7.yml build
EXPECTED RESULTS
The best outcome is if the container.yml works with all four above variable references, e.g., Jinja is called to perform rendering before the build command is even attempted, which corresponds with the --vars-files arg required before "build".
If substitution happens in the conductor, then the build should work with the last two variable references.
ACTUAL RESULTS
The --vars-files processing does not happen before the build is executed, as evidenced by the below output, where the project_name did not undergo substitution (when used as a name for "-conductor"):
# ansible-container --vars-files centos7.yml build
Building Docker Engine context...
Starting Docker build of Ansible Container Conductor image (please be patient)...
ERROR Unknown exception
Traceback (most recent call last):
<traceback-removed>
APIError: 500 Server Error: Internal Server Error ("Error parsing reference: "centos{{os_major_version}}-test-box-conductor" is not a valid repository/tag: invalid reference format")
The conductor:base is not substituted either; if the (first variable) project_name is changed to "centos7-test-box" the error is now:
BuildError: Error parsing reference: "container-conductor-centos-{{os_major_version}}:0.9.2" is not a valid repository/tag: invalid reference format
The third (services:base:from) variable is the only one that is substituted.
The fourth variable (roles) is not:
# ansible-container --vars-files centos7.yml build
Building Docker Engine context...
Starting Docker build of Ansible Container Conductor image (please be patient)...
Parsing conductor CLI args.
Traceback (most recent call last):
File "/usr/bin/conductor", line 11, in <module>
load_entry_point('ansible-container', 'console_scripts', 'conductor')()
File "/_ansible/container/__init__.py", line 19, in __wrapped__
return fn(*args, **kwargs)
File "/_ansible/container/cli.py", line 389, in conductor_commandline
conductor_config = AnsibleContainerConductorConfig(list_to_ordereddict(containers_config))
File "/_ansible/container/__init__.py", line 19, in __wrapped__
return fn(*args, **kwargs)
File "/_ansible/container/config.py", line 297, in __init__
self._process_services()
File "/_ansible/container/config.py", line 357, in _process_services
role_metadata = get_metadata_from_role(role_name)
File "/_ansible/container/__init__.py", line 19, in __wrapped__
return fn(*args, **kwargs)
File "/_ansible/container/utils/__init__.py", line 275, in get_metadata_from_role
return get_content_from_role(role_name, os.path.join('meta', 'container.yml'))
File "/_ansible/container/__init__.py", line 19, in __wrapped__
return fn(*args, **kwargs)
File "/_ansible/container/utils/__init__.py", line 264, in get_content_from_role
role_path = resolve_role_to_path(role_name)
File "/_ansible/container/__init__.py", line 19, in __wrapped__
return fn(*args, **kwargs)
File "/_ansible/container/utils/__init__.py", line 210, in resolve_role_to_path
loader=loader)
File "/usr/lib/python2.7/site-packages/ansible/playbook/role/include.py", line 59, in load
return ri.load_data(data, variable_manager=variable_manager, loader=loader)
File "/usr/lib/python2.7/site-packages/ansible/playbook/base.py", line 244, in load_data
ds = self.preprocess_data(ds)
File "/usr/lib/python2.7/site-packages/ansible/playbook/role/definition.py", line 94, in preprocess_data
(role_name, role_path) = self._load_role_path(role_name)
File "/usr/lib/python2.7/site-packages/ansible/playbook/role/definition.py", line 172, in _load_role_path
role_name = templar.template(role_name)
File "/usr/lib/python2.7/site-packages/ansible/template/__init__.py", line 453, in template
disable_lookups=disable_lookups,
File "/usr/lib/python2.7/site-packages/ansible/template/__init__.py", line 706, in do_template
raise AnsibleUndefinedVariable(e)
ansible.errors.AnsibleUndefinedVariable: 'os_major_version' is undefined
Conductor terminated. Cleaning up. command_rc=1 conductor_id=5c836d1fba0ffd022f5921214ce8c02ec6b753622b91906375699bb2c8fd4a66 save_container=False
ERROR Conductor exited with status 1
FEATURE REQUEST
As indicated in "expected results", it would be nice if template processing is done before build is attempted. It should be possible given python is available on the ansible-container invoking machine.
Another feature (a new one) is to specify vars on the command line, also before the "build" command, similar to "ansible-playbook --extra-vars"
# ansible-playbook --help
Usage: ansible-playbook [options] playbook.yml [playbook2 ...]
Runs Ansible playbooks, executing the defined tasks on the targeted hosts.
Options:
<snip>
-e EXTRA_VARS, --extra-vars=EXTRA_VARS
set additional variables as key=value or YAML/JSON, if
filename prepend with @
<snip>
ISSUE TYPE
(it may be all three!)
container.yml
centos7.yml
OS / ENVIRONMENT
SUMMARY
The intended behavior of jinja2 templating of container.yml is confusing. I'm not sure if it's a documentation or code issue, and is definitely a good feature, hence my indicating all three issue types above.
At time of writing, the docs at https://docs.ansible.com/ansible-container/container_yml/template.html say
STEPS TO REPRODUCE
EXPECTED RESULTS
The best outcome is if the container.yml works with all four above variable references, e.g., Jinja is called to perform rendering before the build command is even attempted, which corresponds with the --vars-files arg required before "build".
If substitution happens in the conductor, then the build should work with the last two variable references.
ACTUAL RESULTS
The --vars-files processing does not happen before the build is executed, as evidenced by the below output, where the project_name did not undergo substitution (when used as a name for "-conductor"):
The conductor:base is not substituted either; if the (first variable) project_name is changed to "centos7-test-box" the error is now:
The third (services:base:from) variable is the only one that is substituted.
The fourth variable (roles) is not:
FEATURE REQUEST
As indicated in "expected results", it would be nice if template processing is done before build is attempted. It should be possible given python is available on the ansible-container invoking machine.
Another feature (a new one) is to specify vars on the command line, also before the "build" command, similar to "ansible-playbook --extra-vars"
which supports direct or file-referenced vars.