Environment variables in the `image` param to a platform are not properly interpolated while creating the instance container when `pre_build_image` is `false`
natefoo opened this issue · 1 comments
Issue Type
- Bug report
Molecule and Ansible details
ansible [core 2.14.0]
config file = None
configured module search path = ['/home/nate/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /home/nate/.virtualenvs/moleculedev/lib/python3.10/site-packages/ansible
ansible collection location = /home/nate/.ansible/collections:/usr/share/ansible/collections
executable location = /home/nate/.virtualenvs/moleculedev/bin/ansible
python version = 3.10.6 (main, Nov 2 2022, 18:53:38) [GCC 11.3.0] (/home/nate/.virtualenvs/moleculedev/bin/python)
jinja version = 3.1.2
libyaml = True
molecule 4.0.4.dev16 using python 3.10
ansible:2.14.0
delegated:4.0.4.dev16 from molecule
docker:2.1.0 from molecule_docker requiring collections: community.docker>=3.0.2 ansible.posix>=1.4.0
Molecule installation method (one of):
- pip (
pip install -e '.[docker]'
)
Ansible installation method (one of):
- pip
Desired Behavior
I'd like to use an environment variable in the image
param to a platform (using the docker driver) for a Github action matrix to test on different images. Jeff Geerling does this in many roles, for example geerlingguy.postgresql workflow and molecule.yml.
I prefer to build the image at runtime (pre_build_image: false
) rather than prebuilding as Jeff does.
Actual Behaviour
Environment variables in the image
param to a platform are not properly interpolated while creating the instance container when pre_build_image
is false
.
molecule.yml
:
dependency:
name: galaxy
driver:
name: docker
platforms:
- name: molecule-test
image: ${FROM_IMAGE:-centos:7}
command: ""
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:rw
privileged: true
dockerfile: Dockerfile.j2
pre_build_image: false
provisioner:
name: ansible
log: true
verifier:
name: ansible
Dockerfile.j2
:
FROM {{ item.image }}
CMD ["/usr/lib/systemd/systemd"]
molecule create
:
$ ANSIBLE_STDOUT_CALLBACK=debug molecule --debug create
ANSIBLE_STDOUT_CALLBACK=debug molecule --debug create
DEBUG Validating schema /home/nate/ansible/molecule-test/molecule/default/molecule.yml.
INFO default scenario test matrix: dependency, create, prepare
INFO Performing prerun with role_name_check=0...
INFO Set ANSIBLE_LIBRARY=/home/nate/.cache/ansible-compat/435e6d/modules:/home/nate/.ansible/plugins/modules:/usr/share/ansible/plugins/modules
INFO Set ANSIBLE_COLLECTIONS_PATH=/home/nate/.cache/ansible-compat/435e6d/collections:/home/nate/.ansible/collections:/usr/share/ansible/collections
INFO Set ANSIBLE_ROLES_PATH=/home/nate/.cache/ansible-compat/435e6d/roles:/home/nate/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles
INFO Running default > dependency
WARNING Skipping, missing the requirements file.
WARNING Skipping, missing the requirements file.
INFO Running default > create
INFO Sanity checks: 'docker'
DEBUG: ANSIBLE ENVIRONMENT:
ANSIBLE_COLLECTIONS_PATH: /home/nate/.cache/ansible-compat/435e6d/collections:/home/nate/.cache/molecule/molecule-test/default/collections:/home/nate/.ansible/collections:/usr/share/ansible/collections:/etc/ansible/collections
ANSIBLE_CONFIG: /home/nate/.cache/molecule/molecule-test/default/ansible.cfg
ANSIBLE_FILTER_PLUGINS: /home/nate/ansible/molecule/src/molecule/provisioner/ansible/plugins/filter:/home/nate/.cache/molecule/molecule-test/default/plugins/filter:/home/nate/ansible/molecule-test/plugins/filter:/home/nate/.ansible/plugins/filter:/usr/share/ansible/plugins/filter
ANSIBLE_FORCE_COLOR: '1'
ANSIBLE_LIBRARY: /home/nate/ansible/molecule/src/molecule/provisioner/ansible/plugins/modules:/home/nate/.cache/molecule/molecule-test/default/library:/home/nate/ansible/molecule-test/library:/home/nate/.ansible/plugins/modules:/usr/share/ansible/plugins/modules
ANSIBLE_ROLES_PATH: /home/nate/.cache/ansible-compat/435e6d/roles:/home/nate/.cache/molecule/molecule-test/default/roles:/home/nate/ansible:/home/nate/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles
ANSIBLE_STDOUT_CALLBACK: debug
DEBUG: MOLECULE ENVIRONMENT:
MOLECULE_DEBUG: 'True'
MOLECULE_DEPENDENCY_NAME: galaxy
MOLECULE_DRIVER_NAME: docker
MOLECULE_ENV_FILE: /home/nate/ansible/molecule-test/.env.yml
MOLECULE_EPHEMERAL_DIRECTORY: /home/nate/.cache/molecule/molecule-test/default
MOLECULE_FILE: /home/nate/.cache/molecule/molecule-test/default/molecule.yml
MOLECULE_INSTANCE_CONFIG: /home/nate/.cache/molecule/molecule-test/default/instance_config.yml
MOLECULE_INVENTORY_FILE: /home/nate/.cache/molecule/molecule-test/default/inventory/ansible_inventory.yml
MOLECULE_PROJECT_DIRECTORY: /home/nate/ansible/molecule-test
MOLECULE_PROVISIONER_NAME: ansible
MOLECULE_SCENARIO_DIRECTORY: /home/nate/ansible/molecule-test/molecule/default
MOLECULE_SCENARIO_NAME: default
MOLECULE_STATE_FILE: /home/nate/.cache/molecule/molecule-test/default/state.yml
MOLECULE_VERIFIER_NAME: ansible
MOLECULE_VERIFIER_TEST_DIRECTORY: /home/nate/ansible/molecule-test/molecule/default/tests
DEBUG: SHELL REPLAY:
ANSIBLE_COLLECTIONS_PATH=/home/nate/.cache/ansible-compat/435e6d/collections:/home/nate/.cache/molecule/molecule-test/default/collections:/home/nate/.ansible/collections:/usr/share/ansible/collections:/etc/ansible/collections ANSIBLE_CONFIG=/home/nate/.cache/molecule/molecule-test/default/ansible.cfg ANSIBLE_FILTER_PLUGINS=/home/nate/ansible/molecule/src/molecule/provisioner/ansible/plugins/filter:/home/nate/.cache/molecule/molecule-test/default/plugins/filter:/home/nate/ansible/molecule-test/plugins/filter:/home/nate/.ansible/plugins/filter:/usr/share/ansible/plugins/filter ANSIBLE_FORCE_COLOR=1 ANSIBLE_LIBRARY=/home/nate/ansible/molecule/src/molecule/provisioner/ansible/plugins/modules:/home/nate/.cache/molecule/molecule-test/default/library:/home/nate/ansible/molecule-test/library:/home/nate/.ansible/plugins/modules:/usr/share/ansible/plugins/modules ANSIBLE_ROLES_PATH=/home/nate/.cache/ansible-compat/435e6d/roles:/home/nate/.cache/molecule/molecule-test/default/roles:/home/nate/ansible:/home/nate/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles ANSIBLE_STDOUT_CALLBACK=debug MOLECULE_DEBUG=True MOLECULE_DEPENDENCY_NAME=galaxy MOLECULE_DRIVER_NAME=docker MOLECULE_ENV_FILE=/home/nate/ansible/molecule-test/.env.yml MOLECULE_EPHEMERAL_DIRECTORY=/home/nate/.cache/molecule/molecule-test/default MOLECULE_FILE=/home/nate/.cache/molecule/molecule-test/default/molecule.yml MOLECULE_INSTANCE_CONFIG=/home/nate/.cache/molecule/molecule-test/default/instance_config.yml MOLECULE_INVENTORY_FILE=/home/nate/.cache/molecule/molecule-test/default/inventory/ansible_inventory.yml MOLECULE_PROJECT_DIRECTORY=/home/nate/ansible/molecule-test MOLECULE_PROVISIONER_NAME=ansible MOLECULE_SCENARIO_DIRECTORY=/home/nate/ansible/molecule-test/molecule/default MOLECULE_SCENARIO_NAME=default MOLECULE_STATE_FILE=/home/nate/.cache/molecule/molecule-test/default/state.yml MOLECULE_VERIFIER_NAME=ansible MOLECULE_VERIFIER_TEST_DIRECTORY=/home/nate/ansible/molecule-test/molecule/default/tests
PLAY [Create] ******************************************************************
TASK [Set async_dir for HOME env] **********************************************
ok: [localhost]
TASK [Log into a Docker registry] **********************************************
skipping: [localhost] => (item=None)
skipping: [localhost]
TASK [Check presence of custom Dockerfiles] ************************************
ok: [localhost] => (item={'command': '', 'dockerfile': 'Dockerfile.j2', 'image': 'centos:7', 'name': 'molecule-test', 'pre_build_image': False, 'privileged': True, 'volumes': ['/sys/fs/cgroup:/sys/fs/cgroup:rw']})
TASK [Create Dockerfiles from image names] *************************************
--- before
+++ after: /home/nate/.ansible/tmp/ansible-local-688129puqlvf0v/tmpalentp1a/Dockerfile.j2
@@ -0,0 +1,2 @@
+FROM centos:7
+CMD ["/usr/lib/systemd/systemd"]
changed: [localhost] => (item={'command': '', 'dockerfile': 'Dockerfile.j2', 'image': 'centos:7', 'name': 'molecule-test', 'pre_build_image': False, 'privileged': True, 'volumes': ['/sys/fs/cgroup:/sys/fs/cgroup:rw']})
TASK [Synchronization the context] *********************************************
.d..t...... ./
>f+++++++++ Dockerfile.j2
>f.st...... molecule.yml
changed: [localhost] => (item={'command': '', 'dockerfile': 'Dockerfile.j2', 'image': 'centos:7', 'name': 'molecule-test', 'pre_build_image': False, 'privileged': True, 'volumes': ['/sys/fs/cgroup:/sys/fs/cgroup:rw']})
TASK [Discover local Docker images] ********************************************
ok: [localhost] => (item={'diff': [{'before': '', 'after_header': '/home/nate/.ansible/tmp/ansible-local-688129puqlvf0v/tmpalentp1a/Dockerfile.j2', 'after': 'FROM centos:7\nCMD ["/usr/lib/systemd/systemd"]\n'}], 'dest': '/home/nate/.cache/molecule/molecule-test/default/Dockerfile_centos_7', 'src': '/home/nate/.ansible/tmp/ansible-tmp-1668112848.056438-688180-166340275842266/source', 'md5sum': '742914a9cf3a9bf93f36ce7686525f2d', 'checksum': '024826b29182fd8e68f1577cac33f8c39710295c', 'changed': True, 'uid': 1000, 'gid': 1000, 'owner': 'nate', 'group': 'nate', 'mode': '0600', 'state': 'file', 'size': 47, 'invocation': {'module_args': {'src': '/home/nate/.ansible/tmp/ansible-tmp-1668112848.056438-688180-166340275842266/source', 'dest': '/home/nate/.cache/molecule/molecule-test/default/Dockerfile_centos_7', 'mode': '0600', 'follow': False, '_original_basename': 'Dockerfile.j2', 'checksum': '024826b29182fd8e68f1577cac33f8c39710295c', 'backup': False, 'force': True, 'unsafe_writes': False, 'content': None, 'validate': None, 'directory_mode': None, 'remote_src': None, 'local_follow': None, 'owner': None, 'group': None, 'seuser': None, 'serole': None, 'selevel': None, 'setype': None, 'attributes': None}}, 'failed': False, 'item': {'command': '', 'dockerfile': 'Dockerfile.j2', 'image': 'centos:7', 'name': 'molecule-test', 'pre_build_image': False, 'privileged': True, 'volumes': ['/sys/fs/cgroup:/sys/fs/cgroup:rw']}, 'ansible_loop_var': 'item', 'i': 0, 'ansible_index_var': 'i'})
TASK [Build an Ansible compatible image (new)] *********************************
changed: [localhost] => (item=molecule_local/centos:7)
TASK [Create docker network(s)] ************************************************
skipping: [localhost]
TASK [Determine the CMD directives] ********************************************
ok: [localhost] => (item={'name': 'molecule-test', 'image': '${FROM_IMAGE:-centos:7}', 'command': '', 'volumes': ['/sys/fs/cgroup:/sys/fs/cgroup:rw'], 'privileged': True, 'dockerfile': 'Dockerfile.j2', 'pre_build_image': False})
TASK [Create molecule instance(s)] *********************************************
changed: [localhost] => (item=molecule-test)
TASK [Wait for instance(s) creation to complete] *******************************
failed: [localhost] (item={'failed': 0, 'started': 1, 'finished': 0, 'ansible_job_id': '805836826211.688378', 'results_file': '/home/nate/.ansible_async/805836826211.688378', 'changed': True, 'item': {'name': 'molecule-test', 'image': '${FROM_IMAGE:-centos:7}', 'command': '', 'volumes': ['/sys/fs/cgroup:/sys/fs/cgroup:rw'], 'privileged': True, 'dockerfile': 'Dockerfile.j2', 'pre_build_image': False}, 'ansible_loop_var': 'item'}) => {
"ansible_job_id": "805836826211.688378",
"ansible_loop_var": "item",
"attempts": 2,
"changed": false,
"finished": 1,
"item": {
"ansible_job_id": "805836826211.688378",
"ansible_loop_var": "item",
"changed": true,
"failed": 0,
"finished": 0,
"item": {
"command": "",
"dockerfile": "Dockerfile.j2",
"image": "${FROM_IMAGE:-centos:7}",
"name": "molecule-test",
"pre_build_image": false,
"privileged": true,
"volumes": [
"/sys/fs/cgroup:/sys/fs/cgroup:rw"
]
},
"results_file": "/home/nate/.ansible_async/805836826211.688378",
"started": 1
},
"results_file": "/home/nate/.ansible_async/805836826211.688378",
"started": 1
}
MSG:
Error pulling image molecule_local/${FROM_IMAGE:-centos:7} - 400 Client Error for http+docker://localhost/v1.41/images/create?tag=7%7D&fromImage=molecule_local%2F%24%7BFROM_IMAGE: Bad Request ("invalid reference format: repository name must be lowercase")
FAILED - RETRYING: [localhost]: Wait for instance(s) creation to complete (300 retries left).
PLAY RECAP *********************************************************************
localhost : ok=8 changed=4 unreachable=0 failed=1 skipped=2 rescued=0 ignored=0
WARNING Retrying execution failure 2 of: ansible-playbook --diff --inventory /home/nate/.cache/molecule/molecule-test/default/inventory --skip-tags molecule-notest,notest /home/nate/.virtualenvs/moleculedev/lib/python3.10/site-packages/molecule_docker/playbooks/create.yml
CRITICAL Ansible return code was 2, command was: ['ansible-playbook', '--diff', '--inventory', '/home/nate/.cache/molecule/molecule-test/default/inventory', '--skip-tags', 'molecule-notest,notest', '/home/nate/.virtualenvs/moleculedev/lib/python3.10/site-packages/molecule_docker/playbooks/create.yml']
Molecule successfully created the image:
$ docker images molecule_local/centos:7
REPOSITORY TAG IMAGE ID CREATED SIZE
molecule_local/centos 7 7863c9c5566b About a minute ago 204MB
And if I update my platform to reference the local image and set pre_built_image
to true
:
platforms:
- name: molecule-test
image: molecule_local/${FROM_IMAGE:-centos:7}
command: ""
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:rw
privileged: true
dockerfile: Dockerfile.j2
pre_build_image: true
It properly interpolates the variable and creates the instance container:
$ molecule create
WARNING The scenario config file ('/home/nate/ansible/molecule-test/molecule/default/molecule.yml') has been modified since the scenario was created. If recent changes are important, reset the scenario with 'molecule destroy' to clean up created items or 'molecule reset' to clear current configuration.
INFO default scenario test matrix: dependency, create, prepare
INFO Performing prerun with role_name_check=0...
INFO Set ANSIBLE_LIBRARY=/home/nate/.cache/ansible-compat/435e6d/modules:/home/nate/.ansible/plugins/modules:/usr/share/ansible/plugins/modules
INFO Set ANSIBLE_COLLECTIONS_PATH=/home/nate/.cache/ansible-compat/435e6d/collections:/home/nate/.ansible/collections:/usr/share/ansible/collections
INFO Set ANSIBLE_ROLES_PATH=/home/nate/.cache/ansible-compat/435e6d/roles:/home/nate/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles
INFO Running default > dependency
WARNING Skipping, missing the requirements file.
WARNING Skipping, missing the requirements file.
INFO Running default > create
INFO Sanity checks: 'docker'
PLAY [Create] ******************************************************************
TASK [Set async_dir for HOME env] **********************************************
ok: [localhost]
TASK [Log into a Docker registry] **********************************************
skipping: [localhost] => (item=None)
skipping: [localhost]
TASK [Check presence of custom Dockerfiles] ************************************
ok: [localhost] => (item={'command': '', 'dockerfile': 'Dockerfile.j2', 'image': 'molecule_local/centos:7', 'name': 'molecule-test', 'pre_build_image': True, 'privileged': True, 'volumes': ['/sys/fs/cgroup:/sys/fs/cgroup:rw']})
TASK [Create Dockerfiles from image names] *************************************
skipping: [localhost] => (item={'command': '', 'dockerfile': 'Dockerfile.j2', 'image': 'molecule_local/centos:7', 'name': 'molecule-test', 'pre_build_image': True, 'privileged': True, 'volumes': ['/sys/fs/cgroup:/sys/fs/cgroup:rw']})
skipping: [localhost]
TASK [Synchronization the context] *********************************************
skipping: [localhost] => (item={'command': '', 'dockerfile': 'Dockerfile.j2', 'image': 'molecule_local/centos:7', 'name': 'molecule-test', 'pre_build_image': True, 'privileged': True, 'volumes': ['/sys/fs/cgroup:/sys/fs/cgroup:rw']})
skipping: [localhost]
TASK [Discover local Docker images] ********************************************
ok: [localhost] => (item={'changed': False, 'skipped': True, 'skip_reason': 'Conditional result was False', 'item': {'command': '', 'dockerfile': 'Dockerfile.j2', 'image': 'molecule_local/centos:7', 'name': 'molecule-test', 'pre_build_image': True, 'privileged': True, 'volumes': ['/sys/fs/cgroup:/sys/fs/cgroup:rw']}, 'ansible_loop_var': 'item', 'i': 0, 'ansible_index_var': 'i'})
TASK [Build an Ansible compatible image (new)] *********************************
skipping: [localhost] => (item=molecule_local/molecule_local/centos:7)
skipping: [localhost]
TASK [Create docker network(s)] ************************************************
skipping: [localhost]
TASK [Determine the CMD directives] ********************************************
ok: [localhost] => (item={'command': '', 'dockerfile': 'Dockerfile.j2', 'image': 'molecule_local/centos:7', 'name': 'molecule-test', 'pre_build_image': True, 'privileged': True, 'volumes': ['/sys/fs/cgroup:/sys/fs/cgroup:rw']})
TASK [Create molecule instance(s)] *********************************************
changed: [localhost] => (item=molecule-test)
TASK [Wait for instance(s) creation to complete] *******************************
FAILED - RETRYING: [localhost]: Wait for instance(s) creation to complete (300 retries left).
changed: [localhost] => (item={'failed': 0, 'started': 1, 'finished': 0, 'ansible_job_id': '523555483669.688684', 'results_file': '/home/nate/.ansible_async/523555483669.688684', 'changed': True, 'item': {'command': '', 'dockerfile': 'Dockerfile.j2', 'image': 'molecule_local/centos:7', 'name': 'molecule-test', 'pre_build_image': True, 'privileged': True, 'volumes': ['/sys/fs/cgroup:/sys/fs/cgroup:rw']}, 'ansible_loop_var': 'item'})
PLAY RECAP *********************************************************************
localhost : ok=6 changed=2 unreachable=0 failed=0 skipped=5 rescued=0 ignored=0
INFO Running default > prepare
WARNING Skipping, prepare playbook not configured.
Nevermind, I see as per ansible-community/molecule-plugins#22 that this bug is in molecule-docker and is already fixed (although as of now, not yet released).