ansible-collections / community.docker

Community Docker Collection for Ansible: modules and plugins for working with Docker
https://galaxy.ansible.com/ui/repo/published/community/docker/
GNU General Public License v3.0
203 stars 121 forks source link

docker_image requesting wrong image architecture on build #984

Open Maddog2050 opened 3 weeks ago

Maddog2050 commented 3 weeks ago
SUMMARY

I'm having a problem building an image using docker_image for amd64 on my M1 Mac when using Ansible Molecule. I have replicated what the Docker Molecule plugin does into a simplified playbook and still get the same error.

ISSUE TYPE
COMPONENT NAME

docker_image

ANSIBLE VERSION
ansible [core 2.17.5]
  config file = None
  configured module search path = ['/Users/username/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /Users/username/.pyenv/versions/3.11.10/lib/python3.11/site-packages/ansible
  ansible collection location = /Users/username/.ansible/collections:/usr/share/ansible/collections
  executable location = /Users/username/.pyenv/versions/3.11.10/bin/ansible
  python version = 3.11.10 (main, Oct 11 2024, 08:59:11) [Clang 16.0.0 (clang-1600.0.26.3)] (/Users/username/.pyenv/versions/3.11.10/bin/python3.11)
  jinja version = 3.1.2
  libyaml = True
COLLECTION VERSION
# /Users/username/.pyenv/versions/3.11.10/lib/python3.11/site-packages/ansible_collections
Collection       Version
---------------- -------
community.docker 3.13.0 
CONFIGURATION
CONFIG_FILE() = None
PAGER(env: PAGER) = less
OS / ENVIRONMENT

Apple M1 Max, Sequoia 15.1, Python 3.11.10

STEPS TO REPRODUCE

Run the following commands after creating the playbook.yml and Dockerfile below.

export DOCKER_DEFAULT_PLATFORM=linux/amd64
docker pull --platform linux/amd64 geerlingguy/docker-rockylinux8-ansible:latest
ansible-playbook playbook.yml

Playbook

---
- name: Test
  hosts: localhost
  become: true
  gather_facts: true

  tasks:
    - name: Build a Docker image from Dockerfile
      community.general.docker_image:
        build:
          path: "{{ playbook_dir }}"
          pull: true
          dockerfile: Dockerfile
          platform: linux/amd64
        name: test-amd64
        source: build

Dockerfile

FROM geerlingguy/docker-rockylinux8-ansible:latest

RUN echo test
EXPECTED RESULTS

I expect that it successfully builds an amd64 image using the Dockerfile.

ACTUAL RESULTS

The playbook fails to build the Docker image and errors out reporting that it can't find the arm64 version of the Docker image.

The digests for the images from Docker hub are as follows:

Digest OS/Arch
83b1a3934737 linux/amd64
5f90e771ee26 linux/arm64

As you can see at the bottom of the output it's failing to get the arm64 version of the image and failing when this should be the amd64 version of the image as the platform is defined as linux/amd64.

ansible-playbook [core 2.17.5]
  config file = None
  configured module search path = ['/Users/username/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /Users/username/.pyenv/versions/3.11.10/lib/python3.11/site-packages/ansible
  ansible collection location = /Users/username/.ansible/collections:/usr/share/ansible/collections
  executable location = /Users/username/.pyenv/versions/3.11.10/bin/ansible-playbook
  python version = 3.11.10 (main, Oct 11 2024, 08:59:11) [Clang 16.0.0 (clang-1600.0.26.3)] (/Users/username/.pyenv/versions/3.11.10/bin/python3.11)
  jinja version = 3.1.2
  libyaml = True
No config file found; using defaults
setting up inventory plugins
Loading collection ansible.builtin from 
host_list declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
script declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
auto declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
yaml declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
ini declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
toml declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
[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'
Loading collection community.general from /Users/username/.pyenv/versions/3.11.10/lib/python3.11/site-packages/ansible_collections/community/general
redirecting (type: modules) community.general.docker_image to community.docker.docker_image
Loading collection community.docker from /Users/username/.pyenv/versions/3.11.10/lib/python3.11/site-packages/ansible_collections/community/docker
Loading callback plugin default of type stdout, v2.0 from /Users/username/.pyenv/versions/3.11.10/lib/python3.11/site-packages/ansible/plugins/callback/default.py
Skipping callback 'default', as we already have a stdout callback.
Skipping callback 'minimal', as we already have a stdout callback.
Skipping callback 'oneline', as we already have a stdout callback.

PLAYBOOK: playbook.yml ************************************************************************************************************************************************************************
Positional arguments: playbook.yml
verbosity: 4
connection: ssh
become_method: sudo
tags: ('all',)
inventory: ('/etc/ansible/hosts',)
forks: 5
1 plays in playbook.yml

PLAY [Test] ***********************************************************************************************************************************************************************************

TASK [Gathering Facts] ************************************************************************************************************************************************************************
task path: /Users/username/my_ansible_role/molecule/default/playbook.yml:2
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: username
<127.0.0.1> EXEC /bin/sh -c 'echo ~username && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /Users/username/.ansible/tmp `"&& mkdir "` echo /Users/username/.ansible/tmp/ansible-tmp-1730469256.572114-35671-140297956884658 `" && echo ansible-tmp-1730469256.572114-35671-140297956884658="` echo /Users/username/.ansible/tmp/ansible-tmp-1730469256.572114-35671-140297956884658 `" ) && sleep 0'
Using module file /Users/username/.pyenv/versions/3.11.10/lib/python3.11/site-packages/ansible/modules/setup.py
<127.0.0.1> PUT /Users/username/.ansible/tmp/ansible-local-35391tsvs7gej/tmp55q7u7es TO /Users/username/.ansible/tmp/ansible-tmp-1730469256.572114-35671-140297956884658/AnsiballZ_setup.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+x /Users/username/.ansible/tmp/ansible-tmp-1730469256.572114-35671-140297956884658/ /Users/username/.ansible/tmp/ansible-tmp-1730469256.572114-35671-140297956884658/AnsiballZ_setup.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c 'sudo -H -S -n  -u root /bin/sh -c '"'"'echo BECOME-SUCCESS-lqgpggbeenwtjjhhlduidmjskprmmrrj ; /Users/username/.pyenv/versions/3.11.10/bin/python3.11 /Users/username/.ansible/tmp/ansible-tmp-1730469256.572114-35671-140297956884658/AnsiballZ_setup.py'"'"' && sleep 0'
<127.0.0.1> EXEC /bin/sh -c 'rm -f -r /Users/username/.ansible/tmp/ansible-tmp-1730469256.572114-35671-140297956884658/ > /dev/null 2>&1 && sleep 0'
ok: [localhost]

TASK [Build a Docker image from Dockerfile] ***************************************************************************************************************************************************
task path: /Users/username/my_ansible_role/molecule/default/playbook.yml:8
redirecting (type: modules) community.general.docker_image to community.docker.docker_image
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: username
<127.0.0.1> EXEC /bin/sh -c 'echo ~username && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /Users/username/.ansible/tmp `"&& mkdir "` echo /Users/username/.ansible/tmp/ansible-tmp-1730469257.196337-35709-100632183245912 `" && echo ansible-tmp-1730469257.196337-35709-100632183245912="` echo /Users/username/.ansible/tmp/ansible-tmp-1730469257.196337-35709-100632183245912 `" ) && sleep 0'
redirecting (type: modules) community.general.docker_image to community.docker.docker_image
Using module file /Users/username/.pyenv/versions/3.11.10/lib/python3.11/site-packages/ansible_collections/community/docker/plugins/modules/docker_image.py
<127.0.0.1> PUT /Users/username/.ansible/tmp/ansible-local-35391tsvs7gej/tmpfo_7n1vn TO /Users/username/.ansible/tmp/ansible-tmp-1730469257.196337-35709-100632183245912/AnsiballZ_docker_image.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+x /Users/username/.ansible/tmp/ansible-tmp-1730469257.196337-35709-100632183245912/ /Users/username/.ansible/tmp/ansible-tmp-1730469257.196337-35709-100632183245912/AnsiballZ_docker_image.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c 'sudo -H -S -n  -u root /bin/sh -c '"'"'echo BECOME-SUCCESS-yorkadkrcbcbemdpnkdrtdatlffcwfpj ; /Users/username/.pyenv/versions/3.11.10/bin/python3.11 /Users/username/.ansible/tmp/ansible-tmp-1730469257.196337-35709-100632183245912/AnsiballZ_docker_image.py'"'"' && sleep 0'
<127.0.0.1> EXEC /bin/sh -c 'rm -f -r /Users/username/.ansible/tmp/ansible-tmp-1730469257.196337-35709-100632183245912/ > /dev/null 2>&1 && sleep 0'
fatal: [localhost]: FAILED! => {
    "changed": false,
    "invocation": {
        "module_args": {
            "api_version": "auto",
            "archive_path": null,
            "build": {
                "args": null,
                "cache_from": null,
                "container_limits": null,
                "dockerfile": "Dockerfile",
                "etc_hosts": null,
                "http_timeout": null,
                "labels": null,
                "network": null,
                "nocache": false,
                "path": "/Users/username/my_ansible_role/molecule/default",
                "platform": "linux/amd64",
                "pull": true,
                "rm": true,
                "shm_size": null,
                "target": null,
                "use_config_proxy": null
            },
            "ca_path": null,
            "client_cert": null,
            "client_key": null,
            "debug": false,
            "docker_host": "unix:///var/run/docker.sock",
            "force_absent": false,
            "force_source": false,
            "force_tag": false,
            "load_path": null,
            "name": "test-amd64",
            "pull": null,
            "push": false,
            "repository": null,
            "source": "build",
            "ssl_version": null,
            "state": "present",
            "tag": "latest",
            "timeout": 60,
            "tls": false,
            "tls_hostname": null,
            "use_ssh_client": false,
            "validate_certs": false
        }
    },
    "msg": "Error building test-amd64 - code: None, message: NotFound: content digest sha256:5f90e771ee26830cbeb33cdc971e5397364073a24c1cc38e4114baba46b5b3e4: not found, logs: ['Step 1/2 : FROM geerlingguy/docker-rockylinux8-ansible:latest', '', 'Pulling from geerlingguy/docker-rockylinux8-ansible', 'Digest: sha256:32f3e65d5ba4de028ef3c7453d5d90a1ad5a7f2e57fbdd5a9eff418ed37bef8a', 'Status: Image is up to date for geerlingguy/docker-rockylinux8-ansible:latest', ' ---> 32f3e65d5ba4', 'Step 2/2 : RUN echo test', '']"
}

PLAY RECAP ************************************************************************************************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   
felixfontein commented 3 weeks ago

The module passes that information on to the Docker daemon. If you get an error, then that's because the Docker daemon doesn't handle it as you expect.

Also you might want to use the community.docker.docker_image_build module, which uses the docker buildx CLI tool. I think it has better support for other platforms.