update ansible collections sops, docker and debops #166

Open
c6ristian wants to merge 1 commit from chris/update-collections into main
910 changed files with 27667 additions and 19786 deletions

View file

@ -2,6 +2,6 @@
inventory = ./inventories/z9/hosts.yaml
pipelining = True
vars_plugins_enabled = host_group_vars,community.sops.sops
collections_path = ./
roles_path = ./galaxy-roles
collections_path = ./ansible_collections
roles_path = ./ansible_collections
interpreter_python = python3

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -37,244 +37,116 @@ variables:
- name: coverageBranches
value: main
- name: entryPoint
value: tests/utils/shippable/shippable.sh
value: tests/utils/shippable/nox.sh
- name: prepareEntryPoint
value: tests/utils/shippable/nox-prepare.sh
- name: fetchDepth
value: 0
resources:
containers:
- container: default
image: quay.io/ansible/azure-pipelines-test-container:7.0.0
image: quay.io/ansible/azure-pipelines-test-container:8.0.0
pool: Standard
stages:
### Sanity & units
- stage: Ansible_devel
displayName: Sanity & Units devel
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
targets:
- name: Sanity
test: 'devel/sanity/1'
- name: Units
test: 'devel/units/1'
- stage: Ansible_2_20
displayName: Sanity & Units 2.20
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
targets:
- name: Sanity
test: '2.20/sanity/1'
- name: Units
test: '2.20/units/1'
- stage: Ansible_2_19
displayName: Sanity & Units 2.19
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
targets:
- name: Sanity
test: '2.19/sanity/1'
- name: Units
test: '2.19/units/1'
- stage: Ansible_2_18
displayName: Sanity & Units 2.18
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
targets:
- name: Sanity
test: '2.18/sanity/1'
- name: Units
test: '2.18/units/1'
### Docker
- stage: Docker_devel
displayName: Docker devel
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: devel/linux/{0}
targets:
- name: Fedora 42
test: fedora42
- name: Ubuntu 22.04
test: ubuntu2204
- name: Ubuntu 24.04
test: ubuntu2404
- name: Alpine 3.22
test: alpine322
groups:
- 4
- 5
- stage: Docker_2_20
displayName: Docker 2.20
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.20/linux/{0}
targets:
- name: Fedora 42
test: fedora42
- name: Alpine 3.22
test: alpine322
groups:
- 4
- 5
- stage: Docker_2_19
displayName: Docker 2.19
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.19/linux/{0}
targets:
- name: Fedora 41
test: fedora41
- name: Alpine 3.21
test: alpine321
groups:
- 4
- 5
- stage: Docker_2_18
displayName: Docker 2.18
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.18/linux/{0}
targets:
- name: Fedora 40
test: fedora40
- name: Ubuntu 22.04
test: ubuntu2204
- name: Alpine 3.20
test: alpine320
groups:
- 4
- 5
### Community Docker
- stage: Docker_community_devel
displayName: Docker (community images) devel
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: devel/linux-community/{0}
targets:
- name: Debian 11 Bullseye
test: debian-bullseye/3.9
- name: Debian 12 Bookworm
test: debian-bookworm/3.11
- name: Debian 13 Trixie
test: debian-13-trixie/3.13
- name: ArchLinux
test: archlinux/3.13
groups:
- 4
- 5
### Remote
- stage: Remote_devel
displayName: Remote devel
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: devel/{0}
targets:
- name: RHEL 10.0
test: rhel/10.0
- name: RHEL 9.6 with Docker SDK, urllib3, requests from sources
test: rhel/9.6-dev-latest
# For some reason, Ubuntu 24.04 is *extremely* slower than RHEL 9.6
# - name: Ubuntu 24.04
# test: ubuntu/24.04
groups:
- 1
- 2
- 3
- 4
- 5
- stage: Remote_2_20
displayName: Remote 2.20
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.20/{0}
targets:
- name: RHEL 9.6
test: rhel/9.6
groups:
- 1
- 2
- 3
- 4
- 5
- stage: Remote_2_19
- stage: remote_2_19
displayName: Remote 2.19
dependsOn: []
variables:
entryPoint: tests/utils/shippable/nox.sh
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.19/{0}
targets:
- name: RHEL 9.5
test: rhel/9.5
- name: Ubuntu 22.04
test: ubuntu/22.04
groups:
- 1
- 2
- 3
- 4
- 5
- stage: Remote_2_18
displayName: Remote 2.18
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.18/{0}
targets:
- name: RHEL 9.4
test: rhel/9.4
groups:
- 1
- 2
- 3
- 4
- 5
- name: Ubuntu 22.04 + group 1
test: ansible-test-integration-2.19-ubuntu-22.04-azp-1
- name: Ubuntu 22.04 + group 2
test: ansible-test-integration-2.19-ubuntu-22.04-azp-2
- name: Ubuntu 22.04 + group 3
test: ansible-test-integration-2.19-ubuntu-22.04-azp-3
- name: Ubuntu 22.04 + group 4
test: ansible-test-integration-2.19-ubuntu-22.04-azp-4
- name: Ubuntu 22.04 + group 5
test: ansible-test-integration-2.19-ubuntu-22.04-azp-5
## Finally
- stage: remote_2_20
displayName: Remote 2.20
dependsOn: []
variables:
entryPoint: tests/utils/shippable/nox.sh
jobs:
- template: templates/matrix.yml
parameters:
targets:
- name: RHEL 9.7 + group 1
test: ansible-test-integration-2.20-rhel-9.7-azp-1
- name: RHEL 9.7 + group 2
test: ansible-test-integration-2.20-rhel-9.7-azp-2
- name: RHEL 9.7 + group 3
test: ansible-test-integration-2.20-rhel-9.7-azp-3
- name: RHEL 9.7 + group 4
test: ansible-test-integration-2.20-rhel-9.7-azp-4
- name: RHEL 9.7 + group 5
test: ansible-test-integration-2.20-rhel-9.7-azp-5
- stage: remote_2_21
displayName: Remote 2.21
dependsOn: []
variables:
entryPoint: tests/utils/shippable/nox.sh
jobs:
- template: templates/matrix.yml
parameters:
targets:
- name: RHEL 10.1 + group 1
test: ansible-test-integration-2.21-rhel-10.1-azp-1
- name: RHEL 10.1 + group 2
test: ansible-test-integration-2.21-rhel-10.1-azp-2
- name: RHEL 10.1 + group 3
test: ansible-test-integration-2.21-rhel-10.1-azp-3
- name: RHEL 10.1 + group 4
test: ansible-test-integration-2.21-rhel-10.1-azp-4
- name: RHEL 10.1 + group 5
test: ansible-test-integration-2.21-rhel-10.1-azp-5
- stage: remote_devel
displayName: Remote devel
dependsOn: []
variables:
entryPoint: tests/utils/shippable/nox.sh
jobs:
- template: templates/matrix.yml
parameters:
targets:
- name: RHEL 10.2 + group 1 + sdk-dev-latest
test: ansible-test-integration-devel-rhel-10.2-azp-1
- name: RHEL 10.2 + group 2 + sdk-dev-latest
test: ansible-test-integration-devel-rhel-10.2-azp-2
- name: RHEL 10.2 + group 3 + sdk-dev-latest
test: ansible-test-integration-devel-rhel-10.2-azp-3
- name: RHEL 10.2 + group 4 + sdk-dev-latest
test: ansible-test-integration-devel-rhel-10.2-azp-4
- name: RHEL 10.2 + group 5 + sdk-dev-latest
test: ansible-test-integration-devel-rhel-10.2-azp-5
- name: RHEL 9.8 + group 1
test: ansible-test-integration-devel-rhel-9.8-azp-1
- name: RHEL 9.8 + group 2
test: ansible-test-integration-devel-rhel-9.8-azp-2
- name: RHEL 9.8 + group 3
test: ansible-test-integration-devel-rhel-9.8-azp-3
- name: RHEL 9.8 + group 4
test: ansible-test-integration-devel-rhel-9.8-azp-4
- name: RHEL 9.8 + group 5
test: ansible-test-integration-devel-rhel-9.8-azp-5
- stage: Summary
condition: succeededOrFailed()
dependsOn:
- Ansible_devel
- Ansible_2_20
- Ansible_2_19
- Ansible_2_18
- Remote_devel
- Remote_2_20
- Remote_2_19
- Remote_2_18
- Docker_devel
- Docker_2_20
- Docker_2_19
- Docker_2_18
- Docker_community_devel
- remote_2_19
- remote_2_20
- remote_2_21
- remote_devel
jobs:
- template: templates/coverage.yml

View file

@ -1,10 +1,10 @@
#!/usr/bin/env bash
# Aggregate code coverage results for later processing.
# 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
# Aggregate code coverage results for later processing.
set -o pipefail -eu
agent_temp_directory="$1"
@ -13,10 +13,6 @@ PATH="${PWD}/bin:${PATH}"
mkdir "${agent_temp_directory}/coverage/"
if [[ "$(ansible --version)" =~ \ 2\.9\. ]]; then
exit
fi
options=(--venv --venv-system-site-packages --color -v)
ansible-test coverage combine --group-by command --export "${agent_temp_directory}/coverage/" "${options[@]}"

View file

@ -11,8 +11,7 @@ Keep in mind that Azure Pipelines does not enforce unique job display names (onl
It is up to pipeline authors to avoid name collisions when deviating from the recommended format.
"""
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
import os
import re
@ -24,12 +23,12 @@ def main():
"""Main program entry point."""
source_directory = sys.argv[1]
if '/ansible_collections/' in os.getcwd():
if "/ansible_collections/" in os.getcwd():
output_path = "tests/output"
else:
output_path = "test/results"
destination_directory = os.path.join(output_path, 'coverage')
destination_directory = os.path.join(output_path, "coverage")
if not os.path.exists(destination_directory):
os.makedirs(destination_directory)
@ -38,27 +37,27 @@ def main():
count = 0
for name in os.listdir(source_directory):
match = re.search('^Coverage (?P<attempt>[0-9]+) (?P<label>.+)$', name)
label = match.group('label')
attempt = int(match.group('attempt'))
match = re.search("^Coverage (?P<attempt>[0-9]+) (?P<label>.+)$", name)
label = match.group("label")
attempt = int(match.group("attempt"))
jobs[label] = max(attempt, jobs.get(label, 0))
for label, attempt in jobs.items():
name = 'Coverage {attempt} {label}'.format(label=label, attempt=attempt)
name = f"Coverage {attempt} {label}"
source = os.path.join(source_directory, name)
source_files = os.listdir(source)
for source_file in source_files:
source_path = os.path.join(source, source_file)
destination_path = os.path.join(destination_directory, source_file + '.' + label)
print('"%s" -> "%s"' % (source_path, destination_path))
destination_path = os.path.join(destination_directory, source_file + "." + label)
print(f'"{source_path}" -> "{destination_path}"')
shutil.copyfile(source_path, destination_path)
count += 1
print('Coverage file count: %d' % count)
print('##vso[task.setVariable variable=coverageFileCount]%d' % count)
print('##vso[task.setVariable variable=outputPath]%s' % output_path)
print(f"Coverage file count: {count}")
print(f"##vso[task.setVariable variable=coverageFileCount]{count}")
print(f"##vso[task.setVariable variable=outputPath]{output_path}")
if __name__ == '__main__':
if __name__ == "__main__":
main()

View file

@ -1,10 +1,10 @@
#!/usr/bin/env bash
# Check the test results and set variables for use in later steps.
# 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
# Check the test results and set variables for use in later steps.
set -o pipefail -eu
if [[ "$PWD" =~ /ansible_collections/ ]]; then

View file

@ -15,7 +15,6 @@ import pathlib
import shutil
import subprocess
import tempfile
import typing as t
import urllib.request
@ -23,7 +22,7 @@ import urllib.request
class CoverageFile:
name: str
path: pathlib.Path
flags: t.List[str]
flags: list[str]
@dataclasses.dataclass(frozen=True)
@ -34,8 +33,8 @@ class Args:
def parse_args() -> Args:
parser = argparse.ArgumentParser()
parser.add_argument('-n', '--dry-run', action='store_true')
parser.add_argument('path', type=pathlib.Path)
parser.add_argument("-n", "--dry-run", action="store_true")
parser.add_argument("path", type=pathlib.Path)
args = parser.parse_args()
@ -46,32 +45,36 @@ def parse_args() -> Args:
return Args(**kwargs)
def process_files(directory: pathlib.Path) -> t.Tuple[CoverageFile, ...]:
def process_files(directory: pathlib.Path) -> tuple[CoverageFile, ...]:
processed = []
for file in directory.joinpath('reports').glob('coverage*.xml'):
name = file.stem.replace('coverage=', '')
for file in directory.joinpath("reports").glob("coverage*.xml"):
name = file.stem.replace("coverage=", "")
# Get flags from name
flags = name.replace('-powershell', '').split('=') # Drop '-powershell' suffix
flags = [flag if not flag.startswith('stub') else flag.split('-')[0] for flag in flags] # Remove "-01" from stub files
flags = name.replace("-powershell", "").split("=") # Drop '-powershell' suffix
flags = [
flag if not flag.startswith("stub") else flag.split("-")[0] for flag in flags
] # Remove "-01" from stub files
processed.append(CoverageFile(name, file, flags))
return tuple(processed)
def upload_files(codecov_bin: pathlib.Path, files: t.Tuple[CoverageFile, ...], dry_run: bool = False) -> None:
def upload_files(codecov_bin: pathlib.Path, files: tuple[CoverageFile, ...], dry_run: bool = False) -> None:
for file in files:
cmd = [
str(codecov_bin),
'--name', file.name,
'--file', str(file.path),
"--name",
file.name,
"--file",
str(file.path),
]
for flag in file.flags:
cmd.extend(['--flags', flag])
cmd.extend(["--flags", flag])
if dry_run:
print(f'DRY-RUN: Would run command: {cmd}')
print(f"DRY-RUN: Would run command: {cmd}")
continue
subprocess.run(cmd, check=True)
@ -79,11 +82,11 @@ def upload_files(codecov_bin: pathlib.Path, files: t.Tuple[CoverageFile, ...], d
def download_file(url: str, dest: pathlib.Path, flags: int, dry_run: bool = False) -> None:
if dry_run:
print(f'DRY-RUN: Would download {url} to {dest} and set mode to {flags:o}')
print(f"DRY-RUN: Would download {url} to {dest} and set mode to {flags:o}")
return
with urllib.request.urlopen(url) as resp:
with dest.open('w+b') as f:
with dest.open("w+b") as f:
# Read data in chunks rather than all at once
shutil.copyfileobj(resp, f, 64 * 1024)
@ -92,14 +95,14 @@ def download_file(url: str, dest: pathlib.Path, flags: int, dry_run: bool = Fals
def main():
args = parse_args()
url = 'https://ansible-ci-files.s3.amazonaws.com/codecov/linux/codecov'
with tempfile.TemporaryDirectory(prefix='codecov-') as tmpdir:
codecov_bin = pathlib.Path(tmpdir) / 'codecov'
url = "https://ansible-ci-files.s3.amazonaws.com/codecov/linux/codecov"
with tempfile.TemporaryDirectory(prefix="codecov-") as tmpdir:
codecov_bin = pathlib.Path(tmpdir) / "codecov"
download_file(url, codecov_bin, 0o755, args.dry_run)
files = process_files(args.path)
upload_files(codecov_bin, files, args.dry_run)
if __name__ == '__main__':
if __name__ == "__main__":
main()

View file

@ -1,18 +1,14 @@
#!/usr/bin/env bash
# Generate code coverage reports for uploading to Azure Pipelines and codecov.io.
# 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
# Generate code coverage reports for uploading to Azure Pipelines and codecov.io.
set -o pipefail -eu
PATH="${PWD}/bin:${PATH}"
if [[ "$(ansible --version)" =~ \ 2\.9\. ]]; then
exit
fi
if ! ansible-test --help >/dev/null 2>&1; then
# Install the devel version of ansible-test for generating code coverage reports.
# This is only used by Ansible Collections, which are typically tested against multiple Ansible versions (in separate jobs).

View file

@ -1,20 +1,22 @@
#!/usr/bin/env bash
# Configure the test environment and run the tests.
# 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
# Configure the test environment and run the tests.
set -o pipefail -eu
entry_point="$1"
test="$2"
read -r -a coverage_branches <<< "$3" # space separated list of branches to run code coverage on for scheduled builds
agent_temp_directory="$4"
export COMMIT_MESSAGE
export COMPLETE
export COVERAGE
export IS_PULL_REQUEST
export COVERAGE_DESTINATION_DIRECTORY="${agent_temp_directory}/coverage"
if [ "${SYSTEM_PULLREQUEST_TARGETBRANCH:-}" ]; then
IS_PULL_REQUEST=true

View file

@ -5,8 +5,7 @@
"""Prepends a relative timestamp to each input line from stdin and writes it to stdout."""
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from __future__ import annotations
import sys
import time
@ -16,14 +15,14 @@ def main():
"""Main program entry point."""
start = time.time()
sys.stdin.reconfigure(errors='surrogateescape')
sys.stdout.reconfigure(errors='surrogateescape')
sys.stdin.reconfigure(errors="surrogateescape")
sys.stdout.reconfigure(errors="surrogateescape")
for line in sys.stdin:
seconds = time.time() - start
sys.stdout.write('%02d:%02d %s' % (seconds // 60, seconds % 60, line))
seconds = int(time.time() - start)
sys.stdout.write(f"{seconds // 60:02}:{seconds % 60:02} {line}")
sys.stdout.flush()
if __name__ == '__main__':
if __name__ == "__main__":
main()

View file

@ -23,14 +23,16 @@ jobs:
- checkout: self
fetchDepth: $(fetchDepth)
path: $(checkoutPath)
- bash: .azure-pipelines/scripts/run-tests.sh "$(entryPoint)" "${{ job.test }}" "$(coverageBranches)"
- bash: .azure-pipelines/scripts/run-tests.sh "$(prepareEntryPoint)" "${{ job.test }}" "$(coverageBranches)" "$(Agent.TempDirectory)"
displayName: Prepare Tests
- bash: .azure-pipelines/scripts/run-tests.sh "$(entryPoint)" "${{ job.test }}" "$(coverageBranches)" "$(Agent.TempDirectory)"
displayName: Run Tests
- bash: .azure-pipelines/scripts/process-results.sh
condition: succeededOrFailed()
displayName: Process Results
- bash: .azure-pipelines/scripts/aggregate-coverage.sh "$(Agent.TempDirectory)"
condition: eq(variables.haveCoverageData, 'true')
displayName: Aggregate Coverage Data
# - bash: .azure-pipelines/scripts/aggregate-coverage.sh "$(Agent.TempDirectory)"
# condition: eq(variables.haveCoverageData, 'true')
# displayName: Aggregate Coverage Data
- task: PublishTestResults@2
condition: eq(variables.haveTestResults, 'true')
inputs:

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:
@ -43,9 +43,13 @@ jobs:
tag: check
tag-as-latest: true
permissions:
contents: read
packages: write
steps:
- name: Check out repository
uses: actions/checkout@v6
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
@ -53,10 +57,10 @@ jobs:
run: |
sudo apt-get install podman buildah
- name: Set up Go 1.22
uses: actions/setup-go@v6
- name: Set up Go 1.26
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
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 +70,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

@ -15,6 +15,14 @@ name: nox
- cron: '0 9 * * *'
workflow_dispatch:
permissions:
contents: read
concurrency:
# Make sure there is at most one active run per PR, but do not cancel any non-PR runs
group: ${{ github.workflow }}-${{ (github.head_ref && github.event.number) || github.run_id }}
cancel-in-progress: true
jobs:
nox:
uses: ansible-community/antsibull-nox/.github/workflows/reusable-nox-run.yml@main
@ -30,6 +38,6 @@ jobs:
upload-codecov-pr: false
upload-codecov-push: false
upload-codecov-schedule: true
max-ansible-core: "2.17"
allow-coverage-cd-override: true
secrets:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

File diff suppressed because it is too large Load diff

View file

@ -4,6 +4,87 @@ Docker Community Collection Release Notes
.. contents:: Topics
v5.3.0
======
Release Summary
---------------
Feature release.
Minor Changes
-------------
- docker_swarm_service - add ``command_as_args`` option. When set to ``true``, ``command`` and ``args`` are concatenated and mapped to ``ContainerSpec.Args`` (matching ``docker service create IMAGE [COMMAND] [ARG...]``), preserving the image ``ENTRYPOINT``. The default remains ``false`` (historical mapping of ``command`` to ``ContainerSpec.Command`` and ``args`` to ``ContainerSpec.Args``) for backward compatibility (https://github.com/ansible-collections/community.docker/issues/1044, https://github.com/ansible-collections/community.docker/issues/212, https://github.com/ansible-collections/community.docker/pull/1307).
v5.2.2
======
Release Summary
---------------
Bugfix release.
Bugfixes
--------
- Handle empty 'docker compose images' stdout in case of errors (https://github.com/ansible-collections/community.docker/pull/1305).
- docker_api connection plugin - the environment fallbacks for ``docker_host``, ``tls_hostname``, ``api_version``, ``timeout``, ``tls``, and ``validate_certs`` now finally work (https://github.com/ansible-collections/community.docker/issues/1298, https://github.com/ansible-collections/community.docker/pull/1299).
- docker_containers inventory plugin - the environment fallbacks for ``docker_host``, ``tls_hostname``, ``api_version``, ``timeout``, ``tls``, and ``validate_certs`` now finally work (https://github.com/ansible-collections/community.docker/issues/1298, https://github.com/ansible-collections/community.docker/pull/1299).
- docker_image, docker_image_pull, docker_container - also handle errors if only ``errorDetail`` is set, but not ``error``. The ``error`` field has been `deprecated in Moby apparently a very long time ago <https://github.com/moby/moby/commit/3043c2641990d94298c6377b7ef14709263a4709>`__ (https://github.com/ansible-collections/community.docker/pull/1302).
v5.2.1
======
Release Summary
---------------
Bugfix release.
Bugfixes
--------
- docker_container_exec module, docker_api connection plugin - ensure that when a command is run in a container with stdin provided, that the actual response is closed and not a socket derived from it. The old behavior causes warnings to be shown on Python 3.13+ under certain conditions (https://github.com/ansible-collections/community.docker/issues/1247, https://github.com/ansible-collections/community.docker/pull/1260).
v5.2.0
======
Release Summary
---------------
Feature release.
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).
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
======
Release Summary
---------------
Bugfix release.
Bugfixes
--------
- docker_image_pull, docker_container - fix pulled image change detection for Docker 29.2+ (https://github.com/ansible-collections/community.docker/pull/1242).
v5.0.5
======

File diff suppressed because it is too large Load diff

View file

@ -2,7 +2,7 @@
"collection_info": {
"namespace": "community",
"name": "docker",
"version": "5.0.5",
"version": "5.3.0",
"authors": [
"Ansible Docker Working Group"
],
@ -28,7 +28,7 @@
"name": "FILES.json",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "1aa5979880106388e42eb161e2d88931ab8a128b982afd506536bed31a71c176",
"chksum_sha256": "eb242635f86c2b8822011d87dd69bd17ff371f5ddeb89f9961001fa28c705e85",
"format": 1
},
"format": 1

View file

@ -38,7 +38,7 @@ For more information about communication, see the [Ansible communication guide](
## Tested with Ansible
Tested with the current ansible-core 2.17, ansible-core 2.18, and ansible-core 2.19 releases, and the current development version of ansible-core. Ansible/ansible-base versions before 2.17.0 are not supported.
Tested with the current ansible-core 2.17, ansible-core 2.18, ansible-core 2.19, ansible-core 2.20, ansible-core 2.21 releases, and the current development version of ansible-core. Ansible/ansible-base versions before 2.17.0 are not supported.
## External requirements

View file

@ -4,10 +4,15 @@
[collection_sources]
"ansible.posix" = "git+https://github.com/ansible-collections/ansible.posix.git,main"
"community.crypto" = "git+https://github.com/ansible-collections/community.crypto.git,main"
"community.general" = "git+https://github.com/ansible-collections/community.general.git,main"
"community.internal_test_tools" = "git+https://github.com/ansible-collections/community.internal_test_tools.git,main"
"community.library_inventory_filtering_v1" = "git+https://github.com/ansible-collections/community.library_inventory_filtering.git,stable-1"
[collection_sources_per_ansible.'2.17']
# community.general's main branch needs ansible-core >= 2.18
"community.general" = "git+https://github.com/ansible-collections/community.general.git,stable-12"
[vcs]
vcs = "git"
development_branch = "main"
@ -98,13 +103,28 @@ include_devel = true
[sessions.ansible_test_integration]
session_name_template = "ansible-test-integration-{ansible_core}{dash_docker_short}{dash_remote}{dash_python_version}{dash_target_dashized}"
display_name_template = "main+Ⓐ{ansible_core}{plus_docker_short}{plus_remote}{plus_py_python_version}{plus_target}{plus_force_docker_sdk_for_python_dev}{plus_force_docker_sdk_for_python_pypi}"
description_template = "Run main integration tests with ansible-core {ansible_core}{comma_docker_short}{comma_remote}{comma_py_python_version}{comma_target}{comma_force_docker_sdk_for_python_dev}{comma_force_docker_sdk_for_python_pypi}"
display_name_template = "Ⓐ{ansible_core}{plus_docker_nice}{plus_remote_nice}{plus_py_python_version}{plus_target_nice}{plus_force_docker_sdk_for_python_dev}{plus_force_docker_sdk_for_python_pypi}"
description_template = "Run integration tests with ansible-core {ansible_core}{comma_docker_nice}{comma_remote_nice}{comma_py_python_version}{comma_target_nice}{comma_force_docker_sdk_for_python_dev}{comma_force_docker_sdk_for_python_pypi}"
retry_on_error = "in-ci"
[sessions.ansible_test_integration.ansible_vars]
force_docker_sdk_for_python_dev = { type = "value", value = false, template_value = "" }
force_docker_sdk_for_python_pypi = { type = "value", value = false, template_value = "" }
[sessions.ansible_test_integration.nice_target_names]
"azp/1/" = "group 1"
"azp/2/" = "group 2"
"azp/3/" = "group 3"
"azp/4/" = "group 4"
"azp/5/" = "group 5"
[sessions.ansible_test_integration.nice_docker_names]
"quay.io/ansible-community/test-image:debian-bullseye" = "Debian 11"
"quay.io/ansible-community/test-image:debian-bookworm" = "Debian 12"
"quay.io/ansible-community/test-image:debian-13-trixie" = "Debian 13"
"quay.io/ansible-community/test-image:archlinux" = "Arch Linux"
"quay.io/ansible-community/test-image:opensuse-tumbleweed" = "OpenSuSE Tumbleweed"
##################################################################################################
# Ansible-core 2.17:
@ -137,7 +157,7 @@ docker = [ "fedora40", "ubuntu2204", "alpine320" ]
[[sessions.ansible_test_integration.groups.sessions]]
ansible_core = "2.18"
target = [ "azp/1/", "azp/2/", "azp/3/", "azp/4/", "azp/5/" ]
remote = [ "rhel/9.4" ]
remote = [ "rhel/9.7" ]
# Ansible-core 2.19:
@ -153,7 +173,7 @@ docker = [ "fedora41", "alpine321" ]
[[sessions.ansible_test_integration.groups.sessions]]
ansible_core = "2.19"
target = [ "azp/1/", "azp/2/", "azp/3/", "azp/4/", "azp/5/" ]
remote = [ "rhel/9.5", "ubuntu/22.04" ]
remote = [ "ubuntu/22.04" ]
# Ansible-core 2.20:
@ -169,7 +189,23 @@ docker = [ "fedora42", "alpine322" ]
[[sessions.ansible_test_integration.groups.sessions]]
ansible_core = "2.20"
target = [ "azp/1/", "azp/2/", "azp/3/", "azp/4/", "azp/5/" ]
remote = [ "rhel/9.6" ]
remote = [ "rhel/9.7" ]
# Ansible-core 2.21:
[[sessions.ansible_test_integration.groups]]
session_name = "ansible-test-integration-2.21"
description = "Meta session for running all ansible-test-integration-2.21-* sessions."
[[sessions.ansible_test_integration.groups.sessions]]
ansible_core = "2.21"
target = [ "azp/4/", "azp/5/" ]
docker = [ "fedora43", "ubuntu2204", "ubuntu2404", "alpine323" ]
[[sessions.ansible_test_integration.groups.sessions]]
ansible_core = "2.21"
target = [ "azp/1/", "azp/2/", "azp/3/", "azp/4/", "azp/5/" ]
remote = [ "rhel/10.1" ]
# Ansible-core devel:
@ -180,7 +216,7 @@ description = "Meta session for running all ansible-test-integration-devel-* ses
[[sessions.ansible_test_integration.groups.sessions]]
ansible_core = "devel"
target = [ "azp/4/", "azp/5/" ]
docker = [ "fedora42", "ubuntu2204", "ubuntu2404", "alpine322" ]
docker = [ "fedora44", "ubuntu2404", "ubuntu2604", "alpine324" ]
[[sessions.ansible_test_integration.groups.sessions]]
ansible_core = "devel"
@ -204,19 +240,25 @@ docker = "quay.io/ansible-community/test-image:debian-13-trixie"
ansible_core = "devel"
target = [ "azp/4/", "azp/5/" ]
python_version = "3.13"
docker = "quay.io/ansible-community/test-image:opensuse-tumbleweed"
[[sessions.ansible_test_integration.groups.sessions]]
ansible_core = "devel"
target = [ "azp/4/", "azp/5/" ]
python_version = "3.14"
docker = "quay.io/ansible-community/test-image:archlinux"
[[sessions.ansible_test_integration.groups.sessions]]
ansible_core = "devel"
target = [ "azp/1/", "azp/2/", "azp/3/", "azp/4/", "azp/5/" ]
remote = [ "rhel/9.6" ]
remote = [ "rhel/10.2" ]
ansible_vars = { force_docker_sdk_for_python_dev = { type = "value", value = true, template_value = "sdk-dev-latest" } }
[[sessions.ansible_test_integration.groups.sessions]]
ansible_core = "devel"
target = [ "azp/1/", "azp/2/", "azp/3/", "azp/4/", "azp/5/" ]
remote = [
"rhel/10.0",
"rhel/9.8",
# For some reason, Ubuntu 24.04 is *extremely* slower than RHEL 9.6
# "ubuntu/24.04",
]
@ -226,14 +268,14 @@ remote = [
[sessions.ansible_lint]
[[sessions.ee_check.execution_environments]]
name = "devel-ubi-9"
description = "ansible-core devel @ RHEL UBI 9"
name = "devel-ubi-10"
description = "ansible-core devel @ RHEL UBI 10"
test_playbooks = ["tests/ee/all.yml"]
config.images.base_image.name = "docker.io/redhat/ubi9:latest"
config.images.base_image.name = "docker.io/redhat/ubi10:latest"
config.dependencies.ansible_core.package_pip = "https://github.com/ansible/ansible/archive/devel.tar.gz"
config.dependencies.ansible_runner.package_pip = "ansible-runner"
config.dependencies.python_interpreter.package_system = "python3.12 python3.12-pip python3.12-wheel python3.12-cryptography"
config.dependencies.python_interpreter.python_path = "/usr/bin/python3.12"
config.dependencies.python_interpreter.package_system = "python3.14 python3.14-pip python3.14-cryptography"
config.dependencies.python_interpreter.python_path = "/usr/bin/python3.14"
runtime_environment = {"ANSIBLE_PRIVATE_ROLE_VARS" = "true"}
runtime_container_options = [
# Mount Docker socket into the container so we can talk to Docker outside the container

View file

@ -2357,3 +2357,86 @@ releases:
- 1226-docker-sdk-tls.yml
- 5.0.5.yml
release_date: '2025-12-31'
5.0.6:
changes:
bugfixes:
- docker_image_pull, docker_container - fix pulled image change detection
for Docker 29.2+ (https://github.com/ansible-collections/community.docker/pull/1242).
release_summary: Bugfix release.
fragments:
- 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'
5.2.0:
changes:
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).
release_summary: Feature release.
fragments:
- 1064-docker-image-export-platform.yml
- 5.2.0.yml
release_date: '2026-04-08'
5.2.1:
changes:
bugfixes:
- docker_container_exec module, docker_api connection plugin - ensure that
when a command is run in a container with stdin provided, that the actual
response is closed and not a socket derived from it. The old behavior causes
warnings to be shown on Python 3.13+ under certain conditions (https://github.com/ansible-collections/community.docker/issues/1247,
https://github.com/ansible-collections/community.docker/pull/1260).
release_summary: Bugfix release.
fragments:
- 1260-close.yml
- 5.2.1.yml
release_date: '2026-05-26'
5.2.2:
changes:
bugfixes:
- Handle empty 'docker compose images' stdout in case of errors (https://github.com/ansible-collections/community.docker/pull/1305).
- docker_api connection plugin - the environment fallbacks for ``docker_host``,
``tls_hostname``, ``api_version``, ``timeout``, ``tls``, and ``validate_certs``
now finally work (https://github.com/ansible-collections/community.docker/issues/1298,
https://github.com/ansible-collections/community.docker/pull/1299).
- docker_containers inventory plugin - the environment fallbacks for ``docker_host``,
``tls_hostname``, ``api_version``, ``timeout``, ``tls``, and ``validate_certs``
now finally work (https://github.com/ansible-collections/community.docker/issues/1298,
https://github.com/ansible-collections/community.docker/pull/1299).
- docker_image, docker_image_pull, docker_container - also handle errors if
only ``errorDetail`` is set, but not ``error``. The ``error`` field has
been `deprecated in Moby apparently a very long time ago <https://github.com/moby/moby/commit/3043c2641990d94298c6377b7ef14709263a4709>`__
(https://github.com/ansible-collections/community.docker/pull/1302).
release_summary: Bugfix release.
fragments:
- 1299-env.yml
- 1302-docker-image.yml
- 1305-docker-compose.yml
- 5.2.2.yml
release_date: '2026-08-08'
5.3.0:
changes:
minor_changes:
- docker_swarm_service - add ``command_as_args`` option. When set to ``true``,
``command`` and ``args`` are concatenated and mapped to ``ContainerSpec.Args``
(matching ``docker service create IMAGE [COMMAND] [ARG...]``), preserving
the image ``ENTRYPOINT``. The default remains ``false`` (historical mapping
of ``command`` to ``ContainerSpec.Command`` and ``args`` to ``ContainerSpec.Args``)
for backward compatibility (https://github.com/ansible-collections/community.docker/issues/1044,
https://github.com/ansible-collections/community.docker/issues/212, https://github.com/ansible-collections/community.docker/pull/1307).
release_summary: Feature release.
fragments:
- 1044-swarm-service-command-args.yml
- 5.3.0.yml
release_date: '2026-09-06'

View file

@ -12,6 +12,7 @@ import nox
try:
import antsibull_nox
from antsibull_nox.cli import run as run_antsibull_nox
except ImportError:
print("You need to install antsibull-nox in the same Python environment as nox.")
sys.exit(1)
@ -20,6 +21,24 @@ except ImportError:
antsibull_nox.load_antsibull_nox_toml()
@nox.session(name="update-azp-config", python=False)
def update_azp_config(session: nox.Session) -> None:
command = [
"antsibull-nox",
"update-azp-config",
"--exclude-tags",
"docker",
"--min-ansible-core",
"2.19",
]
if antsibull_nox.IN_CI:
command.append("--fail-on-change")
session.debug(" ".join(command))
result = run_antsibull_nox(command)
if result != 0:
session.error(f"Execution failed with status code {result}")
# Allow to run the noxfile with `python noxfile.py`, `pipx run noxfile.py`, or similar.
# Requires nox >= 2025.02.09
if __name__ == "__main__":

View file

@ -19,6 +19,7 @@ notes:
with Python's C(SSLSocket)s. See U(https://github.com/ansible-collections/community.docker/issues/605) for more information.
extends_documentation_fragment:
- community.docker._docker.api_documentation
- community.docker._docker.api_environment_documentation
- community.docker._docker.var_names
options:
remote_user:
@ -303,7 +304,7 @@ class Connection(ConnectionBase):
data = {"Tty": False, "Detach": False}
if need_stdin:
exec_socket = self._call_client(
exec_socket, response = self._call_client(
lambda client: client.post_json_to_stream_socket(
"/exec/{0}/start", exec_id, data=data
)
@ -356,7 +357,7 @@ class Connection(ConnectionBase):
stdout, stderr = exec_socket_handler.consume()
finally:
exec_socket.close()
response.close()
else:
stdout, stderr = self._call_client(
lambda client: client.post_json_to_stream(

View file

@ -387,3 +387,25 @@ notes:
- This module does B(not) use the L(Docker SDK for Python,https://docker-py.readthedocs.io/en/stable/) to
communicate with the Docker daemon. It directly calls the Docker CLI program.
"""
API_ENVIRONMENT_DOCUMENTATION = r"""
options:
docker_host:
env:
- name: DOCKER_HOST
tls_hostname:
env:
- name: DOCKER_TLS_HOSTNAME
api_version:
env:
- name: DOCKER_API_VERSION
timeout:
env:
- name: DOCKER_TIMEOUT
tls:
env:
- name: DOCKER_TLS
validate_certs:
env:
- name: DOCKER_TLS_VERIFY
"""

View file

@ -17,6 +17,7 @@ author:
extends_documentation_fragment:
- ansible.builtin.constructed
- community.docker._docker.api_documentation
- community.docker._docker.api_environment_documentation
- community.library_inventory_filtering_v1.inventory_filter
description:
- Reads inventories from the Docker API.

View file

@ -388,7 +388,7 @@ class APIClient(_Session):
@t.overload
def _stream_helper(
self, response: Response, *, decode: t.Literal[False] = False
) -> t.Generator[bytes]: ...
) -> t.Generator[bytes | str]: ...
@t.overload
def _stream_helper(
@ -795,7 +795,7 @@ class APIClient(_Session):
data: t.Any = None,
headers: dict[str, str] | None = None,
**kwargs: t.Any,
) -> SocketLike:
) -> tuple[SocketLike, Response]:
headers = headers.copy() if headers else {}
headers.update(
{
@ -803,15 +803,14 @@ class APIClient(_Session):
"Upgrade": "tcp",
}
)
return self._get_raw_response_socket(
self._post_json(
self._url(pathfmt, *args, versioned_api=True),
data,
headers=headers,
stream=True,
**kwargs,
)
response = self._post_json(
self._url(pathfmt, *args, versioned_api=True),
data,
headers=headers,
stream=True,
**kwargs,
)
return self._get_raw_response_socket(response), response
@t.overload
def post_json_to_stream(

View file

@ -117,7 +117,9 @@ class UnixHTTPAdapter(BaseHTTPAdapter):
return pool
def request_url(self, request: PreparedRequest, proxies: Mapping[str, str]) -> str:
def request_url(
self, request: PreparedRequest, proxies: Mapping[str, str] | None
) -> str:
# The select_proxy utility in requests errors out when the provided URL
# does not have a hostname, like is the case when using a UNIX socket.
# Since proxies are an irrelevant notion in the case of UNIX sockets

View file

@ -127,7 +127,7 @@ def frames_iter_no_tty(socket: SocketLike) -> t.Generator[tuple[int, bytes]]:
not enabled.
"""
while True:
(stream, n) = next_frame_header(socket)
stream, n = next_frame_header(socket)
if n < 0:
break
while n > 0:

View file

@ -523,7 +523,10 @@ class AnsibleDockerClientBase(Client):
) -> bool:
if img1 is None or img2 is None:
return img1 == img2
filter_keys = {"Metadata"}
filter_keys = {"Metadata", "Identity"}
# Since Docker 29.2 (?) the order of entries in Identity.Pull can change
# even though the image is the same. Since we're only really interested
# in the image's Id field, we simply skip all of Identity.
img1_filtered = {k: v for k, v in img1.items() if k not in filter_keys}
img2_filtered = {k: v for k, v in img2.items() if k not in filter_keys}
return img1_filtered == img2_filtered
@ -561,7 +564,7 @@ class AnsibleDockerClientBase(Client):
self._raise_for_status(response)
for line in self._stream_helper(response, decode=True):
self.log(line, pretty_print=True)
if line.get("error"):
if line.get("error") or line.get("errorDetail"):
if line.get("errorDetail"):
error_detail = line.get("errorDetail")
self.fail(

View file

@ -186,12 +186,15 @@ class AnsibleDockerClientBase:
cwd: str | None = None,
environ_update: dict[str, str] | None = None,
warn_on_stderr: bool = False,
parse_empty_as_none: bool = False,
) -> tuple[int, t.Any, bytes]:
rc, stdout, stderr = self.call_cli(
*args, check_rc=check_rc, data=data, cwd=cwd, environ_update=environ_update
)
if warn_on_stderr and stderr:
self.warn(to_text(stderr))
if parse_empty_as_none and not stdout.strip():
return rc, None, stderr
try:
data = json.loads(stdout)
except Exception as exc: # pylint: disable=broad-exception-caught

View file

@ -707,7 +707,7 @@ def update_failed(
result: dict[str, t.Any],
events: Sequence[Event],
args: list[str],
stdout: str | bytes,
stdout: str | bytes | None,
stderr: str | bytes,
rc: int,
cli: str,
@ -739,7 +739,7 @@ def update_failed(
result["failed"] = True
result["msg"] = "\n".join(errors)
result["cmd"] = " ".join(quote(arg) for arg in [cli] + args)
result["stdout"] = to_text(stdout)
result["stdout"] = to_text(stdout) if stdout is not None else ""
result["stderr"] = to_text(stderr)
result["rc"] = rc
return True
@ -900,7 +900,7 @@ class BaseComposeManager(DockerBaseClass):
return args
def _handle_failed_cli_call(
self, args: list[str], rc: int, stdout: str | bytes, stderr: bytes
self, args: list[str], rc: int, stdout: str | bytes | None, stderr: bytes
) -> t.NoReturn:
events = parse_json_events(stderr, warn_function=self.client.warn)
result: dict[str, t.Any] = {}
@ -945,15 +945,20 @@ class BaseComposeManager(DockerBaseClass):
def list_images(self) -> list[str]:
args = self.get_base_args() + ["images", "--format", "json"]
rc, images, stderr = self.client.call_cli_json(
*args, cwd=self.project_src, check_rc=not self.use_json_events
*args,
cwd=self.project_src,
check_rc=not self.use_json_events,
parse_empty_as_none=True,
)
if self.use_json_events and rc != 0:
self._handle_failed_cli_call(args, rc, images, stderr)
if images is None:
return []
if isinstance(images, dict):
# Handle breaking change in Docker Compose 2.37.0; see
# https://github.com/ansible-collections/community.docker/issues/1082
# and https://github.com/docker/compose/issues/12916 for details
images = list(images.values())
return list(images.values())
return images
def parse_events(
@ -994,7 +999,7 @@ class BaseComposeManager(DockerBaseClass):
result: dict[str, t.Any],
events: Sequence[Event],
args: list[str],
stdout: str | bytes,
stdout: str | bytes | None,
stderr: bytes,
rc: int,
) -> bool:

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

@ -274,7 +274,7 @@ def main() -> None:
stdout: bytes | None
stderr: bytes | None
if stdin and not detach:
exec_socket = client.post_json_to_stream_socket(
exec_socket, response = client.post_json_to_stream_socket(
"/exec/{0}/start", exec_id, data=data
)
try:
@ -286,7 +286,7 @@ def main() -> None:
stdout, stderr = exec_socket_handler.consume()
finally:
exec_socket.close()
response.close()
elif tty:
stdout, stderr = client.post_json_to_stream(
"/exec/{0}/start",

View file

@ -995,7 +995,7 @@ class ImageManager(DockerBaseClass):
self.log(line, pretty_print=True)
self._extract_output_line(line, build_output)
if line.get("error"):
if line.get("error") or line.get("errorDetail"):
if line.get("errorDetail"):
error_detail = line.get("errorDetail")
self.fail(

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

@ -189,7 +189,7 @@ class DockerFileStore:
if not server_creds:
raise CredentialsNotFound("No matching credentials")
(username, password) = decode_auth(server_creds["auth"])
username, password = decode_auth(server_creds["auth"])
return {"Username": username, "Secret": password}

View file

@ -36,6 +36,10 @@ options:
description:
- List arguments to be passed to the container.
- Corresponds to the C(ARG) parameter of C(docker service create).
- When O(command_as_args=true), these values are appended after O(command)
and both are sent as ContainerSpec.Args (matching the Docker CLI).
- When O(command_as_args=false), O(args) is sent as C(ContainerSpec.Args)
while O(command) is sent as ContainerSpec.Command.
type: list
elements: str
command:
@ -43,7 +47,28 @@ options:
- Command to execute when the container starts.
- A command may be either a string or a list or a list of strings.
- Corresponds to the C(COMMAND) parameter of C(docker service create).
- When O(command_as_args=false), this is sent as C(ContainerSpec.Command),
which replaces the image C(ENTRYPOINT). This is the historical module behavior.
- When O(command_as_args=true), this is combined with O(args) and sent as
C(ContainerSpec.Args) (same as the Docker CLI
C(docker service create IMAGE [COMMAND] [ARG...])), so the image C(ENTRYPOINT)
is preserved. Use this for flag-style commands (for example V(--config.file=...))
that must be passed as arguments to the image entrypoint
(see U(https://github.com/ansible-collections/community.docker/issues/1044)).
type: raw
command_as_args:
description:
- Controls how O(command) and O(args) are mapped to the service C(ContainerSpec).
- If V(false) (default), O(command) is written to C(ContainerSpec.Command) and
O(args) to C(ContainerSpec.Args). This matches the historical module behavior
(ContainerSpec.Command replaces the image C(ENTRYPOINT)).
- If V(true), O(command) and O(args) are concatenated and written only to
C(ContainerSpec.Args), matching C(docker service create IMAGE [COMMAND] [ARG...])
so the image C(ENTRYPOINT) is preserved.
- The current default will eventually be depreacted and change to V(true).
type: bool
default: false
version_added: 5.3.0
configs:
description:
- List of dictionaries describing the service configs.
@ -696,7 +721,7 @@ rebuilt:
EXAMPLES = r"""
---
- name: Set command and arguments
- name: Set command and arguments (historical mapping)
community.docker.docker_swarm_service:
name: myservice
image: alpine
@ -704,6 +729,14 @@ EXAMPLES = r"""
args:
- "3600"
- name: Pass flags to the image ENTRYPOINT (CLI-compatible mapping)
community.docker.docker_swarm_service:
name: loki
image: grafana/loki:main
command_as_args: true
command:
- '-config.file=/etc/loki/loki-config.yaml'
- name: Set a bind mount
community.docker.docker_swarm_service:
name: myservice
@ -1054,6 +1087,22 @@ def has_dict_changed(
return False
def _combine_command_args(
command: list[str] | None, args: list[str] | None
) -> list[str] | None:
"""
Combine ansible command + args into a single argv list.
Matches docker CLI ``service create IMAGE [COMMAND] [ARG...]``, which places
all post-image tokens into ContainerSpec.Args (preserving ENTRYPOINT).
"""
if command is None:
return args
if args is None:
return command
return command + args
def has_list_changed(
new_list: list[t.Any] | None,
old_list: list[t.Any] | None,
@ -1161,6 +1210,7 @@ class DockerService(DockerBaseClass):
self.image: str | None = ""
self.command: t.Any = None
self.args: list[str] | None = None
self.command_as_args: bool = False
self.endpoint_mode: t.Literal["vip", "dnsrr"] | None = None
self.dns: list[str] | None = None
self.healthcheck: dict[str, t.Any] | None = None
@ -1473,6 +1523,7 @@ class DockerService(DockerBaseClass):
s = DockerService(client.docker_api_version, client.docker_py_version)
s.image = image_digest
s.args = ap["args"]
s.command_as_args = ap["command_as_args"]
s.endpoint_mode = ap["endpoint_mode"]
s.dns = ap["dns"]
s.dns_search = ap["dns_search"]
@ -1675,10 +1726,21 @@ class DockerService(DockerBaseClass):
needs_rebuild = not self.can_update_networks
if self.replicas != os.replicas:
differences.add("replicas", parameter=self.replicas, active=os.replicas)
if has_list_changed(self.command, os.command, sort_lists=False):
differences.add("command", parameter=self.command, active=os.command)
if has_list_changed(self.args, os.args, sort_lists=False):
differences.add("args", parameter=self.args, active=os.args)
if self.command_as_args:
# command + args are stored as ContainerSpec.Args (CLI-compatible).
# Older module versions wrote command to ContainerSpec.Command,
# so compare the combined command line from either field.
desired_cmdline = _combine_command_args(self.command, self.args)
active_cmdline = _combine_command_args(os.command, os.args)
if has_list_changed(desired_cmdline, active_cmdline, sort_lists=False):
differences.add(
"command", parameter=desired_cmdline, active=active_cmdline
)
else:
if has_list_changed(self.command, os.command, sort_lists=False):
differences.add("command", parameter=self.command, active=os.command)
if has_list_changed(self.args, os.args, sort_lists=False):
differences.add("args", parameter=self.args, active=os.args)
if has_list_changed(self.constraints, os.constraints):
differences.add(
"constraints", parameter=self.constraints, active=os.constraints
@ -1999,10 +2061,20 @@ class DockerService(DockerBaseClass):
dns_config = types.DNSConfig(**dns_config_args) if dns_config_args else None
container_spec_args: dict[str, t.Any] = {}
if self.command is not None:
container_spec_args["command"] = self.command
if self.args is not None:
container_spec_args["args"] = self.args
if self.command_as_args:
# Match `docker service create IMAGE [COMMAND] [ARG...]`: the CLI places
# all post-image tokens into ContainerSpec.Args so ENTRYPOINT is kept.
# Writing Command instead replaces ENTRYPOINT and breaks flag-style
# commands such as `-config.file=...` (see #1044, #212).
combined_args = _combine_command_args(self.command, self.args)
if combined_args is not None:
container_spec_args["args"] = combined_args
else:
# Historical mapping: command -> ContainerSpec.Command, args -> Args.
if self.command is not None:
container_spec_args["command"] = self.command
if self.args is not None:
container_spec_args["args"] = self.args
if self.env is not None:
container_spec_args["env"] = self.env
if self.user is not None:
@ -2748,6 +2820,7 @@ def main() -> None:
"networks": {"type": "list", "elements": "raw"},
"command": {"type": "raw"},
"args": {"type": "list", "elements": "str"},
"command_as_args": {"type": "bool", "default": False},
"env": {"type": "raw"},
"env_files": {"type": "list", "elements": "path"},
"force_update": {"type": "bool", "default": False},

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

@ -12,4 +12,4 @@
when: docker_py_version is version('2.6.0', '>=') and docker_api_version is version('1.30', '>=')
- ansible.builtin.fail: msg="Too old docker / docker-py version to run docker_config tests!"
when: not(docker_py_version is version('2.6.0', '>=') and docker_api_version is version('1.30', '>=')) and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)
when: not(docker_py_version is version('2.6.0', '>=') and docker_api_version is version('1.30', '>=')) and (ansible_facts.distribution != 'CentOS' or ansible_facts.distribution_major_version|int > 6)

View file

@ -17,7 +17,7 @@
community.docker.docker_swarm:
name: default
state: present
advertise_addr: "{{ ansible_default_ipv4.address | default('127.0.0.1') }}"
advertise_addr: "{{ ansible_facts.default_ipv4.address | default('127.0.0.1') }}"
- name: Parameter name should be required
community.docker.docker_config: # noqa: args[module]

View file

@ -70,4 +70,4 @@
when: docker_api_version is version('1.25', '>=')
- ansible.builtin.fail: msg="Too old docker / docker-py version to run all docker_container tests!"
when: not(docker_api_version is version('1.25', '>=')) and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)
when: not(docker_api_version is version('1.25', '>=')) and (ansible_facts.distribution != 'CentOS' or ansible_facts.distribution_major_version|int > 6)

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

@ -44,4 +44,4 @@
when: docker_api_version is version('1.25', '>=')
- ansible.builtin.fail: msg="Too old Docker API version to run all docker_container_copy_into tests!"
when: not(docker_api_version is version('1.25', '>=')) and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)
when: not(docker_api_version is version('1.25', '>=')) and (ansible_facts.distribution != 'CentOS' or ansible_facts.distribution_major_version|int > 6)

View file

@ -243,4 +243,4 @@
when: docker_api_version is version('1.25', '>=')
- ansible.builtin.fail: msg="Too old docker / docker-py version to run docker_container_exec tests!"
when: not(docker_api_version is version('1.25', '>=')) and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)
when: not(docker_api_version is version('1.25', '>=')) and (ansible_facts.distribution != 'CentOS' or ansible_facts.distribution_major_version|int > 6)

View file

@ -81,4 +81,4 @@
when: docker_api_version is version('1.25', '>=')
- ansible.builtin.fail: msg="Too old docker / docker-py version to run docker_container_info tests!"
when: not(docker_api_version is version('1.25', '>=')) and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)
when: not(docker_api_version is version('1.25', '>=')) and (ansible_facts.distribution != 'CentOS' or ansible_facts.distribution_major_version|int > 6)

View file

@ -37,4 +37,4 @@
when: docker_api_version is version('1.25', '>=')
- ansible.builtin.fail: msg="Too old docker / docker-py version to run all docker_container tests!"
when: not(docker_api_version is version('1.25', '>=')) and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)
when: not(docker_api_version is version('1.25', '>=')) and (ansible_facts.distribution != 'CentOS' or ansible_facts.distribution_major_version|int > 6)

View file

@ -12,7 +12,7 @@
when: docker_api_version is version('1.25', '>=')
- ansible.builtin.fail: msg="Too old docker / docker-py version to run docker_host_info tests!"
when: not(docker_api_version is version('1.25', '>=')) and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)
when: not(docker_api_version is version('1.25', '>=')) and (ansible_facts.distribution != 'CentOS' or ansible_facts.distribution_major_version|int > 6)
- when: podman_cli_version is version('1.0.0', '>=')
block:

View file

@ -53,4 +53,4 @@
when: docker_api_version is version('1.25', '>=')
- ansible.builtin.fail: msg="Too old docker / docker-py version to run docker_image tests!"
when: not(docker_api_version is version('1.25', '>=')) and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)
when: not(docker_api_version is version('1.25', '>=')) and (ansible_facts.distribution != 'CentOS' or ansible_facts.distribution_major_version|int > 6)

View file

@ -68,4 +68,4 @@
when: docker_api_version is version('1.25', '>=') and docker_cli_version is version('19.03', '>=') and docker_has_buildx
- ansible.builtin.fail: msg="Too old docker / docker-py version to run docker_image tests!"
when: not(docker_api_version is version('1.25', '>=') and docker_cli_version is version('19.03', '>=')) and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6) and docker_has_buildx
when: not(docker_api_version is version('1.25', '>=') and docker_cli_version is version('19.03', '>=')) and (ansible_facts.distribution != 'CentOS' or ansible_facts.distribution_major_version|int > 6) and docker_has_buildx

View file

@ -36,4 +36,4 @@
when: docker_api_version is version('1.25', '>=')
- ansible.builtin.fail: msg="Too old docker / docker-py version to run docker_image tests!"
when: not(docker_api_version is version('1.25', '>=')) and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)
when: not(docker_api_version is version('1.25', '>=')) and (ansible_facts.distribution != 'CentOS' or ansible_facts.distribution_major_version|int > 6)

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

@ -57,4 +57,4 @@
when: docker_api_version is version('1.25', '>=')
- ansible.builtin.fail: msg="Too old docker / docker-py version to run docker_image_info tests!"
when: not(docker_api_version is version('1.25', '>=')) and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)
when: not(docker_api_version is version('1.25', '>=')) and (ansible_facts.distribution != 'CentOS' or ansible_facts.distribution_major_version|int > 6)

View file

@ -36,4 +36,4 @@
when: docker_api_version is version('1.25', '>=')
- ansible.builtin.fail: msg="Too old docker / docker-py version to run docker_image tests!"
when: not(docker_api_version is version('1.25', '>=')) and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)
when: not(docker_api_version is version('1.25', '>=')) and (ansible_facts.distribution != 'CentOS' or ansible_facts.distribution_major_version|int > 6)

View file

@ -36,4 +36,4 @@
when: docker_api_version is version('1.25', '>=')
- ansible.builtin.fail: msg="Too old docker / docker-py version to run docker_image tests!"
when: not(docker_api_version is version('1.25', '>=')) and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)
when: not(docker_api_version is version('1.25', '>=')) and (ansible_facts.distribution != 'CentOS' or ansible_facts.distribution_major_version|int > 6)

View file

@ -36,4 +36,4 @@
when: docker_api_version is version('1.25', '>=')
- ansible.builtin.fail: msg="Too old docker / docker-py version to run docker_image tests!"
when: not(docker_api_version is version('1.25', '>=')) and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)
when: not(docker_api_version is version('1.25', '>=')) and (ansible_facts.distribution != 'CentOS' or ansible_facts.distribution_major_version|int > 6)

View file

@ -303,4 +303,4 @@
when: docker_api_version is version('1.25', '>=')
- ansible.builtin.fail: msg="Too old docker / docker-py version to run docker_image_info tests!"
when: not(docker_api_version is version('1.25', '>=')) and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)
when: not(docker_api_version is version('1.25', '>=')) and (ansible_facts.distribution != 'CentOS' or ansible_facts.distribution_major_version|int > 6)

View file

@ -6,3 +6,4 @@
dependencies:
- setup_docker
- setup_docker_python_deps
- setup_utils

View file

@ -76,7 +76,7 @@
- info_1.images | length == 2
- info_1.images[0].Id == pulled_images.results[0].image.Id
- info_1.images[1].Id == pulled_images.results[0].image.Id
- tag_1_check == tag_1
- tag_1_check | internal__normalize_image("image") == tag_1 | internal__normalize_image("image")
- name: Tag image 1 (idempotent, check mode)
community.docker.docker_image_tag:
@ -102,7 +102,7 @@
- tag_2 is not changed
- tag_2.diff.before == tag_2.diff.after
- tag_2.diff.before.images | length == 2
- tag_2_check == tag_2
- tag_2_check | internal__normalize_image("image") == tag_2 | internal__normalize_image("image")
- name: Tag image 1 (idempotent, different input format, check mode)
community.docker.docker_image_tag:
@ -130,7 +130,7 @@
- tag_3 is not changed
- tag_3.diff.before == tag_3.diff.after
- tag_3.diff.before.images | length == 2
- tag_3_check == tag_3
- tag_3_check | internal__normalize_image("image") == tag_3 | internal__normalize_image("image")
- name: Tag image 1 (one more, check mode)
community.docker.docker_image_tag:
@ -173,7 +173,7 @@
- info_4.images[0].Id == pulled_images.results[0].image.Id
- info_4.images[1].Id == pulled_images.results[0].image.Id
- info_4.images[2].Id == pulled_images.results[0].image.Id
- tag_4_check == tag_4
- tag_4_check | internal__normalize_image("image") == tag_4 | internal__normalize_image("image")
- name: Tag image 2 (only change missing one, check mode)
community.docker.docker_image_tag:
@ -219,7 +219,7 @@
- info_5.images[1].Id == pulled_images.results[0].image.Id
- info_5.images[2].Id == pulled_images.results[1].image.Id
- info_5.images[3].Id == pulled_images.results[0].image.Id
- tag_5_check == tag_5
- tag_5_check | internal__normalize_image("image") == tag_5 | internal__normalize_image("image")
- name: Tag image 2 (idempotent, check mode)
community.docker.docker_image_tag:
@ -249,7 +249,7 @@
- tag_6 is not changed
- tag_6.diff.before == tag_6.diff.after
- tag_6.diff.before.images | length == 3
- tag_6_check == tag_6
- tag_6_check | internal__normalize_image("image") == tag_6 | internal__normalize_image("image")
- name: Tag image 2 (only change wrong ones, check mode)
community.docker.docker_image_tag:
@ -296,7 +296,7 @@
- info_7.images[1].Id == pulled_images.results[1].image.Id
- info_7.images[2].Id == pulled_images.results[1].image.Id
- info_7.images[3].Id == pulled_images.results[0].image.Id
- tag_7_check == tag_7
- tag_7_check | internal__normalize_image("image") == tag_7 | internal__normalize_image("image")
- name: Tag image 2 (idempotent, check mode)
community.docker.docker_image_tag:
@ -326,7 +326,7 @@
- tag_8 is not changed
- tag_8.diff.before == tag_8.diff.after
- tag_8.diff.before.images | length == 3
- tag_8_check == tag_8
- tag_8_check | internal__normalize_image("image") == tag_8 | internal__normalize_image("image")
- name: Tag image 3 (source image has digest)
community.docker.docker_image_tag:
@ -399,4 +399,4 @@
when: docker_api_version is version('1.25', '>=')
- ansible.builtin.fail: msg="Too old docker / docker-py version to run docker_image_info tests!"
when: not(docker_api_version is version('1.25', '>=')) and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)
when: not(docker_api_version is version('1.25', '>=')) and (ansible_facts.distribution != 'CentOS' or ansible_facts.distribution_major_version|int > 6)

View file

@ -12,4 +12,4 @@
when: docker_api_version is version('1.25', '>=')
- ansible.builtin.fail: msg="Too old docker / docker-py version to run docker_image tests!"
when: not(docker_api_version is version('1.25', '>=')) and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)
when: not(docker_api_version is version('1.25', '>=')) and (ansible_facts.distribution != 'CentOS' or ansible_facts.distribution_major_version|int > 6)

View file

@ -51,4 +51,4 @@
when: docker_api_version is version('1.25', '>=') # FIXME: find out API version!
- ansible.builtin.fail: msg="Too old docker / docker-py version to run docker_network tests!"
when: not(docker_api_version is version('1.25', '>=')) and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)
when: not(docker_api_version is version('1.25', '>=')) and (ansible_facts.distribution != 'CentOS' or ansible_facts.distribution_major_version|int > 6)

View file

@ -205,7 +205,7 @@
name: "{{ nname_ipam_3 }}"
driver: "macvlan"
driver_options:
parent: "{{ ansible_default_ipv4.alias }}"
parent: "{{ ansible_facts.default_ipv4.alias }}"
ipam_config:
- subnet: 10.26.120.0/24
- subnet: 10.26.121.0/24
@ -220,7 +220,7 @@
name: "{{ nname_ipam_3 }}"
driver: "macvlan"
driver_options:
parent: "{{ ansible_default_ipv4.alias }}"
parent: "{{ ansible_facts.default_ipv4.alias }}"
ipam_config:
- subnet: 10.26.121.0/24
- subnet: 10.26.120.0/24
@ -235,7 +235,7 @@
name: "{{ nname_ipam_3 }}"
driver: "macvlan"
driver_options:
parent: "{{ ansible_default_ipv4.alias }}"
parent: "{{ ansible_facts.default_ipv4.alias }}"
ipam_config:
- subnet: 10.26.120.0/24
- subnet: 10.26.122.0/24
@ -252,7 +252,7 @@
name: "{{ nname_ipam_3 }}"
driver: "macvlan"
driver_options:
parent: "{{ ansible_default_ipv4.alias }}"
parent: "{{ ansible_facts.default_ipv4.alias }}"
ipam_config:
- subnet: 10.26.122.0/24
register: network
@ -266,7 +266,7 @@
name: "{{ nname_ipam_3 }}"
state: absent
when: ansible_facts.virtualization_type != 'docker' and ansible_default_ipv4.alias is defined
when: ansible_facts.virtualization_type != 'docker' and ansible_facts.default_ipv4.alias is defined
#################### IPAM driver options ####################

View file

@ -119,7 +119,7 @@
- name: swarm
community.docker.docker_swarm:
state: present
advertise_addr: "{{ ansible_default_ipv4.address | default('127.0.0.1') }}"
advertise_addr: "{{ ansible_facts.default_ipv4.address | default('127.0.0.1') }}"
# Driver change alongside scope is intentional - bridge doesn't appear to support anything but local, and overlay can't downgrade to local. Additionally, overlay reports as swarm for swarm OR global, so no change is reported in that case.
# Test output indicates that the scope is altered, at least, so manual inspection will be required to verify this going forward, unless we come up with a test driver that supports multiple scopes.

View file

@ -15,7 +15,7 @@
- name: swarm
community.docker.docker_swarm:
state: present
advertise_addr: "{{ ansible_default_ipv4.address | default('127.0.0.1') }}"
advertise_addr: "{{ ansible_facts.default_ipv4.address | default('127.0.0.1') }}"
####################################################################
## overlay #########################################################

View file

@ -77,4 +77,4 @@
when: docker_api_version is version('1.25', '>=')
- ansible.builtin.fail: msg="Too old docker / docker-py version to run docker_network_info tests!"
when: not(docker_api_version is version('1.25', '>=')) and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)
when: not(docker_api_version is version('1.25', '>=')) and (ansible_facts.distribution != 'CentOS' or ansible_facts.distribution_major_version|int > 6)

View file

@ -38,4 +38,4 @@
when: docker_py_version is version('2.4.0', '>=') and docker_api_version is version('1.25', '>=')
- ansible.builtin.fail: msg="Too old docker / docker-py version to run docker_node tests!"
when: not(docker_py_version is version('2.4.0', '>=') and docker_api_version is version('1.25', '>=')) and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)
when: not(docker_py_version is version('2.4.0', '>=') and docker_api_version is version('1.25', '>=')) and (ansible_facts.distribution != 'CentOS' or ansible_facts.distribution_major_version|int > 6)

View file

@ -23,7 +23,7 @@
- name: Create a Swarm cluster
community.docker.docker_swarm:
state: present
advertise_addr: "{{ ansible_default_ipv4.address | default('127.0.0.1') }}"
advertise_addr: "{{ ansible_facts.default_ipv4.address | default('127.0.0.1') }}"
register: output
- name: assert changed when create a new swarm cluster

View file

@ -12,4 +12,4 @@
when: docker_py_version is version('2.4.0', '>=') and docker_api_version is version('1.25', '>=')
- ansible.builtin.fail: msg="Too old docker / docker-py version to run docker_node_info tests!"
when: not(docker_py_version is version('2.4.0', '>=') and docker_api_version is version('1.25', '>=')) and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)
when: not(docker_py_version is version('2.4.0', '>=') and docker_api_version is version('1.25', '>=')) and (ansible_facts.distribution != 'CentOS' or ansible_facts.distribution_major_version|int > 6)

View file

@ -23,7 +23,7 @@
- name: Create a Swarm cluster
community.docker.docker_swarm:
state: present
advertise_addr: "{{ ansible_default_ipv4.address | default('127.0.0.1') }}"
advertise_addr: "{{ ansible_facts.default_ipv4.address | default('127.0.0.1') }}"
register: output
- name: assert changed when create a new swarm cluster

View file

@ -33,4 +33,4 @@
when: docker_api_version is version('1.25', '>=') and dev_fuse_stat.stat.exists
- ansible.builtin.fail: msg="Too old docker / docker-py version to run docker_plugin tests!"
when: not(docker_api_version is version('1.25', '>=')) and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)
when: not(docker_api_version is version('1.25', '>=')) and (ansible_facts.distribution != 'CentOS' or ansible_facts.distribution_major_version|int > 6)

View file

@ -172,4 +172,4 @@
when: docker_api_version is version('1.25', '>=')
- ansible.builtin.fail: msg="Too old docker / docker-py version to run docker_prune tests!"
when: not(docker_api_version is version('1.25', '>=')) and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)
when: not(docker_api_version is version('1.25', '>=')) and (ansible_facts.distribution != 'CentOS' or ansible_facts.distribution_major_version|int > 6)

View file

@ -12,4 +12,4 @@
when: docker_py_version is version('2.1.0', '>=') and docker_api_version is version('1.25', '>=')
- ansible.builtin.fail: msg="Too old docker / docker-py version to run docker_secrets tests!"
when: not(docker_py_version is version('2.1.0', '>=') and docker_api_version is version('1.25', '>=')) and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)
when: not(docker_py_version is version('2.1.0', '>=') and docker_api_version is version('1.25', '>=')) and (ansible_facts.distribution != 'CentOS' or ansible_facts.distribution_major_version|int > 6)

View file

@ -12,7 +12,7 @@
- name: Create a Swarm cluster
community.docker.docker_swarm:
state: present
advertise_addr: "{{ ansible_default_ipv4.address | default('127.0.0.1') }}"
advertise_addr: "{{ ansible_facts.default_ipv4.address | default('127.0.0.1') }}"
- name: Parameter name should be required
community.docker.docker_secret: # noqa: args[module]

View file

@ -12,4 +12,4 @@
when: docker_api_version is version('1.25', '>=')
- ansible.builtin.fail: msg="Too old docker / docker-py version to run docker_stack tests!"
when: not(docker_api_version is version('1.25', '>=')) and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)
when: not(docker_api_version is version('1.25', '>=')) and (ansible_facts.distribution != 'CentOS' or ansible_facts.distribution_major_version|int > 6)

View file

@ -12,7 +12,7 @@
- name: Create a Swarm cluster
community.docker.docker_swarm:
state: present
advertise_addr: "{{ ansible_default_ipv4.address | default('127.0.0.1') }}"
advertise_addr: "{{ ansible_facts.default_ipv4.address | default('127.0.0.1') }}"
- name: install docker_stack python requirements
ansible.builtin.pip:

View file

@ -12,4 +12,4 @@
when: docker_api_version is version('1.25', '>=')
- ansible.builtin.fail: msg="Too old docker / docker-py version to run docker_stack tests!"
when: not(docker_api_version is version('1.25', '>=')) and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)
when: not(docker_api_version is version('1.25', '>=')) and (ansible_facts.distribution != 'CentOS' or ansible_facts.distribution_major_version|int > 6)

View file

@ -23,7 +23,7 @@
- name: Create a swarm cluster
community.docker.docker_swarm:
state: present
advertise_addr: "{{ ansible_default_ipv4.address | default('127.0.0.1') }}"
advertise_addr: "{{ ansible_facts.default_ipv4.address | default('127.0.0.1') }}"
- name: Get docker_stack_info when docker is running and not stack available
community.docker.docker_stack_info:

View file

@ -12,4 +12,4 @@
when: docker_api_version is version('1.25', '>=')
- ansible.builtin.fail: msg="Too old docker / docker-py version to run docker_stack tests!"
when: not(docker_api_version is version('1.25', '>=')) and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)
when: not(docker_api_version is version('1.25', '>=')) and (ansible_facts.distribution != 'CentOS' or ansible_facts.distribution_major_version|int > 6)

View file

@ -23,7 +23,7 @@
- name: Create a swarm cluster
community.docker.docker_swarm:
state: present
advertise_addr: "{{ ansible_default_ipv4.address | default('127.0.0.1') }}"
advertise_addr: "{{ ansible_facts.default_ipv4.address | default('127.0.0.1') }}"
- name: Get docker_stack_info when docker is running and not stack available
community.docker.docker_stack_info:

View file

@ -27,4 +27,4 @@
msg: "Too old docker / docker-py version to run docker_swarm tests!"
when:
- not(docker_py_version is version('1.10.0', '>=') and docker_api_version is version('1.25', '>='))
- (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)
- (ansible_facts.distribution != 'CentOS' or ansible_facts.distribution_major_version|int > 6)

View file

@ -40,7 +40,7 @@
- name: Create a Swarm cluster (check mode)
community.docker.docker_swarm:
state: present
advertise_addr: "{{ ansible_default_ipv4.address | default('127.0.0.1') }}"
advertise_addr: "{{ ansible_facts.default_ipv4.address | default('127.0.0.1') }}"
check_mode: true
diff: true
register: output_1
@ -48,21 +48,21 @@
- name: Create a Swarm cluster
community.docker.docker_swarm:
state: present
advertise_addr: "{{ ansible_default_ipv4.address | default('127.0.0.1') }}"
advertise_addr: "{{ ansible_facts.default_ipv4.address | default('127.0.0.1') }}"
diff: true
register: output_2
- name: Create a Swarm cluster (idempotent)
community.docker.docker_swarm:
state: present
advertise_addr: "{{ ansible_default_ipv4.address | default('127.0.0.1') }}"
advertise_addr: "{{ ansible_facts.default_ipv4.address | default('127.0.0.1') }}"
diff: true
register: output_3
- name: Create a Swarm cluster (idempotent, check mode)
community.docker.docker_swarm:
state: present
advertise_addr: "{{ ansible_default_ipv4.address | default('127.0.0.1') }}"
advertise_addr: "{{ ansible_facts.default_ipv4.address | default('127.0.0.1') }}"
check_mode: true
diff: true
register: output_4
@ -70,7 +70,7 @@
- name: Create a Swarm cluster (force re-create)
community.docker.docker_swarm:
state: present
advertise_addr: "{{ ansible_default_ipv4.address | default('127.0.0.1') }}"
advertise_addr: "{{ ansible_facts.default_ipv4.address | default('127.0.0.1') }}"
force: true
diff: true
register: output_5
@ -78,7 +78,7 @@
- name: Create a Swarm cluster (force re-create, check mode)
community.docker.docker_swarm:
state: present
advertise_addr: "{{ ansible_default_ipv4.address | default('127.0.0.1') }}"
advertise_addr: "{{ ansible_facts.default_ipv4.address | default('127.0.0.1') }}"
force: true
check_mode: true
diff: true

View file

@ -58,7 +58,7 @@
register: ansible_keys
- name: signing_ca_cert and signing_ca_key (check mode)
community.docker.docker_swarm:
advertise_addr: '{{ ansible_default_ipv4.address | default("127.0.0.1") }}'
advertise_addr: '{{ ansible_facts.default_ipv4.address | default("127.0.0.1") }}'
state: present
signing_ca_cert: '{{ ansible_certificates.results[0].content | b64decode }}'
signing_ca_key: '{{ ansible_keys.results[0].content | b64decode }}'
@ -69,7 +69,7 @@
ignore_errors: true
- name: signing_ca_cert and signing_ca_key
community.docker.docker_swarm:
advertise_addr: '{{ ansible_default_ipv4.address | default("127.0.0.1") }}'
advertise_addr: '{{ ansible_facts.default_ipv4.address | default("127.0.0.1") }}'
state: present
signing_ca_cert: '{{ ansible_certificates.results[0].content | b64decode }}'
signing_ca_key: '{{ ansible_keys.results[0].content | b64decode }}'

View file

@ -9,7 +9,7 @@
- name: Create a Swarm cluster
community.docker.docker_swarm:
state: present
advertise_addr: "{{ ansible_default_ipv4.address | default('127.0.0.1') }}"
advertise_addr: "{{ ansible_facts.default_ipv4.address | default('127.0.0.1') }}"
name: default
diff: true
@ -72,7 +72,7 @@
community.docker.docker_swarm:
state: present
force: true
advertise_addr: "{{ ansible_default_ipv4.address | default('127.0.0.1') }}"
advertise_addr: "{{ ansible_facts.default_ipv4.address | default('127.0.0.1') }}"
autolock_managers: true
diff: true
register: output_7

View file

@ -12,4 +12,4 @@
when: docker_py_version is version('1.10.0', '>=') and docker_api_version is version('1.25', '>=')
- ansible.builtin.fail: msg="Too old docker / docker-py version to run docker_swarm_info tests!"
when: not(docker_py_version is version('1.10.0', '>=') and docker_api_version is version('1.25', '>=')) and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)
when: not(docker_py_version is version('1.10.0', '>=') and docker_api_version is version('1.25', '>=')) and (ansible_facts.distribution != 'CentOS' or ansible_facts.distribution_major_version|int > 6)

View file

@ -27,7 +27,7 @@
- name: Create a Swarm cluster
community.docker.docker_swarm:
state: present
advertise_addr: "{{ ansible_default_ipv4.address | default('127.0.0.1') }}"
advertise_addr: "{{ ansible_facts.default_ipv4.address | default('127.0.0.1') }}"
register: output
- name: assert changed when create a new swarm cluster
@ -160,7 +160,7 @@
- name: Update swarm cluster to be locked
community.docker.docker_swarm:
state: present
advertise_addr: "{{ ansible_default_ipv4.address | default('127.0.0.1') }}"
advertise_addr: "{{ ansible_facts.default_ipv4.address | default('127.0.0.1') }}"
autolock_managers: true
register: autolock_managers_update_output
ignore_errors: true

View file

@ -27,7 +27,7 @@
- name: Create a Swarm cluster
community.docker.docker_swarm:
state: present
advertise_addr: "{{ ansible_default_ipv4.address | default('127.0.0.1') }}"
advertise_addr: "{{ ansible_facts.default_ipv4.address | default('127.0.0.1') }}"
- ansible.builtin.include_tasks: run-test.yml
with_fileglob:
@ -82,4 +82,4 @@
when: docker_py_version is version('2.0.2', '>=') and docker_api_version is version('1.25', '>=')
- ansible.builtin.fail: msg="Too old docker / docker-py version to run docker_swarm_service tests!"
when: not(docker_py_version is version('2.0.2', '>=') and docker_api_version is version('1.25', '>=')) and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)
when: not(docker_py_version is version('2.0.2', '>=') and docker_api_version is version('1.25', '>=')) and (ansible_facts.distribution != 'CentOS' or ansible_facts.distribution_major_version|int > 6)

View file

@ -12,4 +12,4 @@
when: docker_py_version is version('2.0.0', '>=') and docker_api_version is version('1.25', '>=')
- ansible.builtin.fail: msg="Too old docker / docker-py version to run docker_swarm_service_info tests!"
when: not(docker_py_version is version('2.0.0', '>=') and docker_api_version is version('1.25', '>=')) and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)
when: not(docker_py_version is version('2.0.0', '>=') and docker_api_version is version('1.25', '>=')) and (ansible_facts.distribution != 'CentOS' or ansible_facts.distribution_major_version|int > 6)

View file

@ -32,7 +32,7 @@
- name: Create a Swarm cluster
community.docker.docker_swarm:
state: present
advertise_addr: "{{ ansible_default_ipv4.address | default('127.0.0.1') }}"
advertise_addr: "{{ ansible_facts.default_ipv4.address | default('127.0.0.1') }}"
register: output
- name: Create services
@ -82,4 +82,4 @@
when: docker_py_version is version('2.0.2', '>=') and docker_api_version is version('1.25', '>=')
- ansible.builtin.fail: msg="Too old docker / docker-py version to run docker_swarm_service_info tests!"
when: not(docker_py_version is version('2.0.2', '>=') and docker_api_version is version('1.25', '>=')) and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)
when: not(docker_py_version is version('2.0.2', '>=') and docker_api_version is version('1.25', '>=')) and (ansible_facts.distribution != 'CentOS' or ansible_facts.distribution_major_version|int > 6)

View file

@ -33,4 +33,4 @@
when: docker_api_version is version('1.25', '>=')
- ansible.builtin.fail: msg="Too old docker / docker-py version to run docker_volume tests!"
when: not(docker_api_version is version('1.25', '>=')) and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)
when: not(docker_api_version is version('1.25', '>=')) and (ansible_facts.distribution != 'CentOS' or ansible_facts.distribution_major_version|int > 6)

View file

@ -74,4 +74,4 @@
when: docker_api_version is version('1.25', '>=')
- ansible.builtin.fail: msg="Too old docker / docker-py version to run docker_volume_info tests!"
when: not(docker_api_version is version('1.25', '>=')) and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)
when: not(docker_api_version is version('1.25', '>=')) and (ansible_facts.distribution != 'CentOS' or ansible_facts.distribution_major_version|int > 6)

View file

@ -20,4 +20,4 @@
- name: Create a Swarm cluster
community.docker.docker_swarm:
state: present
advertise_addr: "{{ ansible_default_ipv4.address | default('127.0.0.1') }}"
advertise_addr: "{{ ansible_facts.default_ipv4.address | default('127.0.0.1') }}"

Some files were not shown because too many files have changed in this diff Show more