Compare commits

...

12 Commits
5.0.6 ... main

Author SHA1 Message Date
Felix Fontein
b00fc741e1
Make tests more lenient. (#1252) 2026-03-27 14:29:49 +01:00
spatterlight
9c313bb9d0
Docker image export platform (#1251)
* docker_image_export: Add 'platform' option

docker_image_export: Add 'platform' option

* docker_image_export: Add 'platform' option

* Update changelogs/fragments/1064-docker-image-export-platform.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/modules/docker_image_export.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* docker_image_export: Add 'platform' option

* docker_image_export: Add 'platform' option

* docker_image_export: Add 'platform' option

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
2026-03-27 13:16:04 +01:00
Felix Fontein
91b350019a The next expected release will be 5.2.0. 2026-03-23 20:40:52 +01:00
Felix Fontein
7a9c846fbf Release 5.1.0. 2026-03-23 20:26:28 +01:00
Felix Fontein
e81d5883ef Prepare 5.1.0 release. 2026-03-21 23:10:50 +01:00
Felix Fontein
639c2391e8 Use podman manifest push instead of podman push. 2026-03-21 17:44:46 +01:00
Felix Fontein
a54353e2d6 Push all images. 2026-03-21 17:41:39 +01:00
Felix Fontein
05c4b48b2b
Replace apt_repository with deb822_repository. (#1250) 2026-03-20 08:07:26 +01:00
Felix Fontein
e02d4d06af
Get rid of unmaintained redhat-actions/push-to-registry action. (#1249) 2026-03-14 23:10:51 +01:00
Matthieu Berthomé
15690313f3
docker_compose_v2_pull: Add ignore_pull_failures option (#1248)
* feat(docker_compose_v2_pull): Add `ignore_pull_failures` option


Co-authored-by: Felix Fontein <felix@fontein.de>

* changelog fragment

* Update changelogs/fragments/1248-ignore-pull-failures.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
2026-03-06 18:51:36 +01:00
Felix Fontein
241ba443ac
CI: fix GHA by downgrading Docker (#1244)
* Show more information on Docker.

* Downgrade Docker on GHA.
2026-02-14 21:29:04 +01:00
Felix Fontein
67448fd5bb The next expected release will be 5.1.0. 2026-02-12 07:58:44 +01:00
16 changed files with 489 additions and 324 deletions

View File

@ -28,7 +28,7 @@ env:
jobs:
build:
name: Build image ${{ matrix.name }}:${{ matrix.tag }}
runs-on: ubuntu-24.04
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
@ -53,10 +53,10 @@ jobs:
run: |
sudo apt-get install podman buildah
- name: Set up Go 1.22
- name: Set up Go 1.26
uses: actions/setup-go@v6
with:
go-version: '1.22'
go-version: '1.26'
cache: false # true (default) results in warnings since we don't use Go modules
- name: Build ${{ matrix.name }} image
@ -66,25 +66,22 @@ jobs:
- name: Tag image as latest
if: matrix.tag-as-latest && matrix.tag != 'latest'
run: |
podman tag "${CONTAINER_REGISTRY}/${{ matrix.name }}:${{ matrix.tag }}" "${CONTAINER_REGISTRY}/${{ matrix.name }}:latest"
env:
SOURCE_IMAGE: ${{ matrix.name }}:${{ matrix.tag }}
DEST_IMAGE: ${{ matrix.name }}:latest
run: >-
podman tag "${CONTAINER_REGISTRY}/${SOURCE_IMAGE}" "${CONTAINER_REGISTRY}/${DEST_IMAGE}"
- name: Publish container image ${{ env.CONTAINER_REGISTRY }}/${{ matrix.name }}:${{ matrix.tag }}
if: github.event_name != 'pull_request'
uses: redhat-actions/push-to-registry@v2
with:
registry: ${{ env.CONTAINER_REGISTRY }}
image: ${{ matrix.name }}
tags: ${{ matrix.tag }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
env:
IMAGE: ${{ matrix.name }}:${{ matrix.tag }}
run: >-
podman manifest push --all "${IMAGE}" "${CONTAINER_REGISTRY}/${IMAGE}" --tls-verify=true --creds=${{ github.actor }}:${{ secrets.GITHUB_TOKEN }}
- name: Publish container image ${{ env.CONTAINER_REGISTRY }}/${{ matrix.name }}:latest
if: github.event_name != 'pull_request' && matrix.tag-as-latest && matrix.tag != 'latest'
uses: redhat-actions/push-to-registry@v2
with:
registry: ${{ env.CONTAINER_REGISTRY }}
image: ${{ matrix.name }}
tags: latest
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
env:
IMAGE: ${{ matrix.name }}:latest
run: >-
podman manifest push --all "${IMAGE}" "${CONTAINER_REGISTRY}/${IMAGE}" --tls-verify=true --creds=${{ github.actor }}:${{ secrets.GITHUB_TOKEN }}

View File

@ -31,5 +31,28 @@ jobs:
upload-codecov-push: false
upload-codecov-schedule: true
max-ansible-core: "2.17"
# For some reason GitHub decided to bump Docker on the ubuntu-24.04 image,
# which is not compatible with podman and various other things.
pre-test-cmd-integration: |-
# See https://docs.docker.com/engine/install/ubuntu/.
# Add Docker's official GPG key:
sudo apt update
sudo apt install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
# Add the repository to Apt sources:
sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Signed-By: /etc/apt/keyrings/docker.asc
EOF
sudo apt update
sudo apt-get install -y --allow-downgrades docker-ce-cli=5:28.0.4-1~ubuntu.24.04~noble docker-ce=5:28.0.4-1~ubuntu.24.04~noble
secrets:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

File diff suppressed because it is too large Load Diff

View File

@ -4,6 +4,19 @@ Docker Community Collection Release Notes
.. contents:: Topics
v5.1.0
======
Release Summary
---------------
Feature release.
Minor Changes
-------------
- docker_compose_v2_pull - adds ``ignore_pull_failures`` parameter that passes ``--ignore-pull-failures`` to the ``docker compose pull`` call when set to ``true`` (https://github.com/ansible-collections/community.docker/pull/1248).
v5.0.6
======

View File

@ -2367,3 +2367,14 @@ releases:
- 1242-pull.yml
- 5.0.6.yml
release_date: '2026-02-12'
5.1.0:
changes:
minor_changes:
- docker_compose_v2_pull - adds ``ignore_pull_failures`` parameter that passes
``--ignore-pull-failures`` to the ``docker compose pull`` call when set
to ``true`` (https://github.com/ansible-collections/community.docker/pull/1248).
release_summary: Feature release.
fragments:
- 1248-ignore-pull-failures.yml
- 5.1.0.yml
release_date: '2026-03-23'

View File

@ -0,0 +1,2 @@
minor_changes:
- docker_image_export - adds ``platform`` parameter to allow exporting a specific platform variant from a multi-arch image (https://github.com/ansible-collections/community.docker/issues/1064, https://github.com/ansible-collections/community.docker/pull/1251).

View File

@ -7,7 +7,7 @@
namespace: community
name: docker
version: 5.0.6
version: 5.2.0
readme: README.md
authors:
- Ansible Docker Working Group

View File

@ -51,6 +51,12 @@ options:
type: bool
default: false
version_added: 3.12.0
ignore_pull_failures:
description:
- If set to V(true), will pull what it can and ignores images with pull failures.
type: bool
default: false
version_added: 5.1.0
include_deps:
description:
- If set to V(true), also pull services that are declared as dependencies.
@ -132,6 +138,7 @@ class PullManager(BaseComposeManager):
self.policy: t.Literal["always", "missing"] = parameters["policy"]
self.ignore_buildable: bool = parameters["ignore_buildable"]
self.ignore_pull_failures: bool = parameters["ignore_pull_failures"]
self.include_deps: bool = parameters["include_deps"]
self.services: list[str] = parameters["services"] or []
@ -152,6 +159,8 @@ class PullManager(BaseComposeManager):
args.extend(["--policy", self.policy])
if self.ignore_buildable:
args.append("--ignore-buildable")
if self.ignore_pull_failures:
args.append("--ignore-pull-failures")
if self.include_deps:
args.append("--include-deps")
if dry_run:
@ -187,6 +196,7 @@ def main() -> None:
"default": "always",
},
"ignore_buildable": {"type": "bool", "default": False},
"ignore_pull_failures": {"type": "bool", "default": False},
"include_deps": {"type": "bool", "default": False},
"services": {"type": "list", "elements": "str"},
}

View File

@ -31,9 +31,12 @@ attributes:
details:
- Whether the module is idempotent depends on the storage API used for images,
which determines how the image ID is computed. The idempotency check needs
that the image ID equals the ID stored in archive's C(manifest.json).
the image ID to equal the ID stored in archive's C(manifest.json).
This seemed to have worked fine with the default storage backend up to Docker 28,
but seems to have changed in Docker 29.
- This module is B(not idempotent) when used with multi-architecture images,
regardless of Docker version.
- Full idempotency requires Docker 28 or earlier B(and) a single-architecture image.
options:
names:
@ -61,6 +64,13 @@ options:
- Export the image even if the C(.tar) file already exists and seems to contain the right image.
type: bool
default: false
platform:
description:
- Ask for this specific platform when exporting.
- For example, C(linux/amd64), C(linux/arm64).
- Requires Docker API 1.48 or newer.
type: str
version_added: 5.2.0
requirements:
- "Docker API >= 1.25"
@ -98,6 +108,7 @@ images:
sample: []
"""
import json
import traceback
import typing as t
@ -119,6 +130,9 @@ from ansible_collections.community.docker.plugins.module_utils._image_archive im
api_image_id,
load_archived_image_manifest,
)
from ansible_collections.community.docker.plugins.module_utils._platform import (
_Platform,
)
from ansible_collections.community.docker.plugins.module_utils._util import (
DockerBaseClass,
is_image_name_id,
@ -137,6 +151,7 @@ class ImageExportManager(DockerBaseClass):
self.path = parameters["path"]
self.force = parameters["force"]
self.tag = parameters["tag"]
self.platform = parameters["platform"]
if not is_valid_tag(self.tag, allow_empty=True):
self.fail(f'"{self.tag}" is not a valid docker tag')
@ -198,15 +213,31 @@ class ImageExportManager(DockerBaseClass):
except Exception as exc: # pylint: disable=broad-exception-caught
self.fail(f"Error writing image archive {self.path} - {exc}")
def _platform_param(self) -> str:
platform = _Platform.parse_platform_string(self.platform)
platform_spec: dict[str, str] = {}
if platform.os:
platform_spec["os"] = platform.os
if platform.arch:
platform_spec["architecture"] = platform.arch
if platform.variant:
platform_spec["variant"] = platform.variant
return json.dumps(platform_spec)
def export_images(self) -> None:
image_names = [name["joined"] for name in self.names]
image_names_str = ", ".join(image_names)
if len(image_names) == 1:
self.log(f"Getting archive of image {image_names[0]}")
params: dict[str, t.Any] = {}
if self.platform:
params["platform"] = self._platform_param()
try:
chunks = self.client._stream_raw_result(
self.client._get(
self.client._url("/images/{0}/get", image_names[0]), stream=True
self.client._url("/images/{0}/get", image_names[0]),
stream=True,
params=params,
),
chunk_size=DEFAULT_DATA_CHUNK_SIZE,
decode=False,
@ -215,12 +246,15 @@ class ImageExportManager(DockerBaseClass):
self.fail(f"Error getting image {image_names[0]} - {exc}")
else:
self.log(f"Getting archive of images {image_names_str}")
params = {"names": image_names}
if self.platform:
params["platform"] = self._platform_param()
try:
chunks = self.client._stream_raw_result(
self.client._get(
self.client._url("/images/get"),
stream=True,
params={"names": image_names},
params=params,
),
chunk_size=DEFAULT_DATA_CHUNK_SIZE,
decode=False,
@ -277,11 +311,17 @@ def main() -> None:
"aliases": ["name"],
},
"tag": {"type": "str", "default": "latest"},
"platform": {"type": "str"},
}
option_minimal_versions = {
"platform": {"docker_api_version": "1.48"},
}
client = AnsibleDockerClient(
argument_spec=argument_spec,
supports_check_mode=True,
option_minimal_versions=option_minimal_versions,
)
try:

View File

@ -7,6 +7,10 @@
community.docker.current_container_facts:
register: result
- name: Print facts returned by module
ansible.builtin.debug:
var: result.ansible_facts
# The following two tasks are useful if we ever have to debug why this fails.
- name: Print all Ansible facts
@ -20,13 +24,10 @@
- /proc/self/cpuset
- /proc/1/cgroup
- /proc/1/environ
ignore_errors: true # not all of these files always exist
loop_control:
loop_var: path
- name: Print facts returned by module
ansible.builtin.debug:
var: result.ansible_facts
- name: Validate results
ansible.builtin.assert:
that:

View File

@ -27,8 +27,8 @@
- /proc/self/cgroup
- /proc/self/cpuset
- /proc/self/mountinfo
ignore_errors: true # not all of these files always exist
register: slurp
ignore_errors: true
- name: Print files
ansible.builtin.debug:

View File

@ -957,7 +957,7 @@
- when: device_read_bps_1 is failed
ansible.builtin.assert:
that:
- "'error setting cgroup config for procHooks process' in device_read_bps_1.msg and 'blkio.throttle.read_bps_device: no such device' in device_read_bps_1.msg"
- "'error setting cgroup config for procHooks process' in device_read_bps_1.msg and ': no such device' in device_read_bps_1.msg"
####################################################################
## device_read_iops ################################################
@ -1040,7 +1040,7 @@
- when: device_read_iops_1 is failed
ansible.builtin.assert:
that:
- "'error setting cgroup config for procHooks process' in device_read_iops_1.msg and 'blkio.throttle.read_iops_device: no such device' in device_read_iops_1.msg"
- "'error setting cgroup config for procHooks process' in device_read_iops_1.msg and ': no such device' in device_read_iops_1.msg"
####################################################################
## device_write_bps and device_write_iops ##########################
@ -1110,7 +1110,7 @@
- when: device_write_limit_1 is failed
ansible.builtin.assert:
that:
- "'error setting cgroup config for procHooks process' in device_write_limit_1.msg and 'blkio.throttle.write_bps_device: no such device' in device_write_limit_1.msg"
- "'error setting cgroup config for procHooks process' in device_write_limit_1.msg and ': no such device' in device_write_limit_1.msg"
####################################################################
## device_requests #################################################

View File

@ -0,0 +1,34 @@
---
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
- when: docker_api_version is version('1.48', '>=')
block:
- name: Pull image for platform test
community.docker.docker_image_pull:
name: "{{ docker_test_image_hello_world }}"
platform: linux/amd64
- name: Export image with platform (check mode)
community.docker.docker_image_export:
name: "{{ docker_test_image_hello_world }}"
path: "{{ remote_tmp_dir }}/platform-test.tar"
platform: linux/amd64
register: result_check
check_mode: true
- ansible.builtin.assert:
that:
- result_check is changed
- name: Export image with platform
community.docker.docker_image_export:
name: "{{ docker_test_image_hello_world }}"
path: "{{ remote_tmp_dir }}/platform-test.tar"
platform: linux/amd64
register: result
- ansible.builtin.assert:
that:
- result is changed

View File

@ -9,38 +9,32 @@
- name: Install pre-reqs
ansible.builtin.apt:
name: '{{ docker_prereq_packages }}'
name: '{{ docker_prereq_packages + ["python3-debian"] }}'
state: present
update_cache: true
notify: cleanup docker
- when:
- (ansible_facts.distribution == "Ubuntu" and (ansible_facts.distribution_major_version | int) >= 22) or
(ansible_facts.distribution == "Debian" and (ansible_facts.distribution_major_version | int) >= 12)
name: Add Docker repo on Ubuntu 22+ or Debian 12+
block:
- name: Add gpg key
ansible.builtin.get_url:
url: "https://download.docker.com/linux/{{ ansible_facts.distribution | lower }}/gpg"
dest: /etc/apt/keyrings/docker.asc
- name: Add Docker repo on Ubuntu or Debian
ansible.builtin.deb822_repository:
name: docker
types: deb
architectures:
- >-
{{ 'arm64' if ansible_facts.architecture == 'aarch64' else 'amd64' }}
signed_by: "https://download.docker.com/linux/{{ ansible_facts.distribution | lower }}/gpg"
uris:
- https://download.docker.com/linux/{{ ansible_facts.distribution | lower }}
suites:
- "{{ ansible_facts.distribution_release }}"
components:
- stable
state: present
register: apt_repo
- name: Add Docker repo
ansible.builtin.apt_repository:
repo: deb [arch={{ 'arm64' if ansible_facts.architecture == 'aarch64' else 'amd64' }} signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/{{ ansible_facts.distribution | lower }} {{ ansible_facts.distribution_release }} stable
state: present
- when:
- (ansible_facts.distribution == "Ubuntu" and (ansible_facts.distribution_major_version | int) < 22) or
(ansible_facts.distribution == "Debian" and (ansible_facts.distribution_major_version | int) < 12)
name: Add Docker repo on Ubuntu 20 or before, or Debian 11 or before
block:
- name: Add gpg key
ansible.builtin.shell: curl -fsSL https://download.docker.com/linux/{{ ansible_facts.distribution | lower }}/gpg >key && apt-key add key # noqa: command-instead-of-module
- name: Add Docker repo
ansible.builtin.apt_repository:
repo: deb [arch={{ 'arm64' if ansible_facts.architecture == 'aarch64' else 'amd64' }}] https://download.docker.com/linux/{{ ansible_facts.distribution | lower }} {{ ansible_facts.distribution_release }} stable
state: present
- name: Update apt cache
ansible.builtin.apt:
update_cache: true
when: apt_repo is changed
- block:
- name: Prevent service restart

View File

@ -70,6 +70,26 @@
state: touch
when: docker_skip_cleanup
- name: Retrieve more information (0/4)
ansible.builtin.command:
cmd: sh -c export
- name: Retrieve more information (1/4)
ansible.builtin.command:
cmd: docker version
- name: Retrieve more information (2/4)
ansible.builtin.command:
cmd: docker info
- name: Retrieve more information (3/4)
ansible.builtin.command:
cmd: docker context ls
- name: Retrieve more information (4/4)
ansible.builtin.command:
cmd: which docker
# Detect docker API version
- name: Check Docker API version
ansible.builtin.command: "docker version -f {% raw %}'{{(index .Server.Components 0).Details.ApiVersion}}'{% endraw %}"

View File

@ -63,4 +63,8 @@
{{ docker_cli_plugins_stdout.stdout | from_json | selectattr('Name', 'eq', 'compose') | map(attribute='Version') | first | default('0.0') | regex_replace('^v', '') }}
- ansible.builtin.debug:
msg: "Has Docker compoes plugin: {{ docker_has_compose }}; Docker compose plugin version: {{ docker_compose_version }}"
msg: "Has Docker compose plugin: {{ docker_has_compose }}; Docker compose plugin version: {{ docker_compose_version }}"
- name: Retrieve more information
ansible.builtin.command:
cmd: docker version