From db42a6b2653705b46bd37117f3e8ede36d5a0e08 Mon Sep 17 00:00:00 2001 From: Chris Pressland Date: Tue, 15 Jul 2025 17:00:16 +0100 Subject: [PATCH 1/7] feat(acr): Use `podman` as `docker_command` if installed --- src/azure-cli/azure/cli/command_modules/acr/custom.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/azure-cli/azure/cli/command_modules/acr/custom.py b/src/azure-cli/azure/cli/command_modules/acr/custom.py index a04ca43b904..5372ffe6c5f 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/custom.py +++ b/src/azure-cli/azure/cli/command_modules/acr/custom.py @@ -7,6 +7,7 @@ import os import re +import shutil from knack.util import CLIError from knack.log import get_logger from azure.cli.core.azclierror import InvalidArgumentValueError, RequiredArgumentMissingError @@ -396,6 +397,8 @@ def get_docker_command(is_diagnostics_context=False): docker_command = os.getenv('DOCKER_COMMAND') else: docker_command = 'docker' + if shutil.which('podman'): + docker_command = 'podman' from subprocess import PIPE, Popen, CalledProcessError try: @@ -405,7 +408,7 @@ def get_docker_command(is_diagnostics_context=False): logger.debug("Could not run '%s' command. Exception: %s", docker_command, str(e)) # The executable may not be discoverable in WSL so retry *.exe once try: - docker_command = 'docker.exe' + docker_command = docker_command + '.exe' p = Popen([docker_command, "ps"], stdout=PIPE, stderr=PIPE) _, stderr = p.communicate() except OSError as inner: From 75bece2bc6f656eddd2a9dcd9826868ca1fc839f Mon Sep 17 00:00:00 2001 From: Chris Pressland Date: Mon, 21 Jul 2025 10:30:14 +0100 Subject: [PATCH 2/7] Update src/azure-cli/azure/cli/command_modules/acr/custom.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/azure-cli/azure/cli/command_modules/acr/custom.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/azure-cli/azure/cli/command_modules/acr/custom.py b/src/azure-cli/azure/cli/command_modules/acr/custom.py index 5372ffe6c5f..2b63f701154 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/custom.py +++ b/src/azure-cli/azure/cli/command_modules/acr/custom.py @@ -397,7 +397,7 @@ def get_docker_command(is_diagnostics_context=False): docker_command = os.getenv('DOCKER_COMMAND') else: docker_command = 'docker' - if shutil.which('podman'): + if not shutil.which('docker') and shutil.which('podman'): docker_command = 'podman' from subprocess import PIPE, Popen, CalledProcessError From d3dc4286bcaaaa5298109f2944f65a4c413b9ac6 Mon Sep 17 00:00:00 2001 From: Chris Pressland Date: Mon, 21 Jul 2025 10:30:36 +0100 Subject: [PATCH 3/7] Update src/azure-cli/azure/cli/command_modules/acr/custom.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/azure-cli/azure/cli/command_modules/acr/custom.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/azure-cli/azure/cli/command_modules/acr/custom.py b/src/azure-cli/azure/cli/command_modules/acr/custom.py index 2b63f701154..84152828a8c 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/custom.py +++ b/src/azure-cli/azure/cli/command_modules/acr/custom.py @@ -408,7 +408,7 @@ def get_docker_command(is_diagnostics_context=False): logger.debug("Could not run '%s' command. Exception: %s", docker_command, str(e)) # The executable may not be discoverable in WSL so retry *.exe once try: - docker_command = docker_command + '.exe' + docker_command = f'{docker_command}.exe' p = Popen([docker_command, "ps"], stdout=PIPE, stderr=PIPE) _, stderr = p.communicate() except OSError as inner: From 8f7e84b999e11c791f495c523c23bfb788b33601 Mon Sep 17 00:00:00 2001 From: Chris Pressland Date: Thu, 11 Dec 2025 12:38:39 +0000 Subject: [PATCH 4/7] support podman in `_get_docker_status_and_version` --- .../cli/command_modules/acr/check_health.py | 26 ++++++++++++++----- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/acr/check_health.py b/src/azure-cli/azure/cli/command_modules/acr/check_health.py index bc997dacfa1..9f8da49c35c 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/check_health.py +++ b/src/azure-cli/azure/cli/command_modules/acr/check_health.py @@ -4,6 +4,7 @@ # -------------------------------------------------------------------------------------------- import re +import json from knack.util import CLIError from knack.log import get_logger from .custom import get_docker_command @@ -88,18 +89,29 @@ def _get_docker_status_and_version(ignore_errors, yes): docker_daemon_available = False if docker_daemon_available: - logger.warning("Docker daemon status: available") + logger.warning(f"{docker_command.title()} daemon status: available") # Docker version check - output, warning, stderr, succeeded = _subprocess_communicate( - [docker_command, "version", "--format", "'Docker version {{.Server.Version}}, " - "build {{.Server.GitCommit}}, platform {{.Server.Os}}/{{.Server.Arch}}'"]) + output, warning, stderr, succeeded = _subprocess_communicate([docker_command, "version", "--format", "json"]) if not succeeded: _handle_error(DOCKER_VERSION_ERROR.append_error_message(stderr), ignore_errors) else: if warning: logger.warning(warning) - logger.warning("Docker version: %s", output) + json_output = json.loads(output).get("Client") + logger.warning( + "".join([ + docker_command.title(), + " version: ", + json_output.get("Version"), + ", build ", + json_output.get("GitCommit")[:7], + ", platform ", + json_output.get("Os"), + "/", + json_output.get("Arch") if docker_command == "docker" else json_output.get("OsArch").split("/")[1] + ]) + ) # Docker pull check - only if docker daemon is available if docker_daemon_available: @@ -114,14 +126,14 @@ def _get_docker_status_and_version(ignore_errors, yes): if not succeeded: if stderr and DOCKER_PULL_WRONG_PLATFORM in stderr: - print_pass("Docker pull of '{}'".format(IMAGE)) + print_pass(f"{docker_command.title()} pull of '{IMAGE}'") logger.warning("Image '%s' can be pulled but cannot be used on this platform", IMAGE) return _handle_error(DOCKER_PULL_ERROR.append_error_message(stderr), ignore_errors) else: if warning: logger.warning(warning) - print_pass("Docker pull of '{}'".format(IMAGE)) + print_pass(f"{docker_command.title()} pull of '{IMAGE}'") # Get current CLI version From 6dd4a4f492572c9c75fb9c434b0ad48cf406d90e Mon Sep 17 00:00:00 2001 From: Chris Pressland Date: Thu, 11 Dec 2025 13:27:26 +0000 Subject: [PATCH 5/7] fix pylint complaint --- src/azure-cli/azure/cli/command_modules/acr/check_health.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/azure-cli/azure/cli/command_modules/acr/check_health.py b/src/azure-cli/azure/cli/command_modules/acr/check_health.py index 9f8da49c35c..0773f9a7263 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/check_health.py +++ b/src/azure-cli/azure/cli/command_modules/acr/check_health.py @@ -89,7 +89,7 @@ def _get_docker_status_and_version(ignore_errors, yes): docker_daemon_available = False if docker_daemon_available: - logger.warning(f"{docker_command.title()} daemon status: available") + logger.warning("%s daemon status: available", docker_command.title()) # Docker version check output, warning, stderr, succeeded = _subprocess_communicate([docker_command, "version", "--format", "json"]) From a165dde96450219824b9576b3b5f769334e48a43 Mon Sep 17 00:00:00 2001 From: Chris Pressland Date: Thu, 11 Dec 2025 14:04:23 +0000 Subject: [PATCH 6/7] improve error handling --- .../cli/command_modules/acr/check_health.py | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/acr/check_health.py b/src/azure-cli/azure/cli/command_modules/acr/check_health.py index 0773f9a7263..8d824f38899 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/check_health.py +++ b/src/azure-cli/azure/cli/command_modules/acr/check_health.py @@ -72,7 +72,6 @@ def _subprocess_communicate(command_parts, shell=False): ) return output, warning, stderr, succeeded - # Checks for the environment # Checks docker command, docker daemon, docker version and docker pull def _get_docker_status_and_version(ignore_errors, yes): @@ -98,20 +97,22 @@ def _get_docker_status_and_version(ignore_errors, yes): else: if warning: logger.warning(warning) - json_output = json.loads(output).get("Client") - logger.warning( - "".join([ - docker_command.title(), - " version: ", - json_output.get("Version"), - ", build ", - json_output.get("GitCommit")[:7], - ", platform ", - json_output.get("Os"), - "/", - json_output.get("Arch") if docker_command == "docker" else json_output.get("OsArch").split("/")[1] - ]) - ) + try: + json_output = json.loads(output).get("Client") + except json.decoder.JSONDecodeError: + json_output = {} + version = json_output.get("Version", "unknown") + commit = json_output.get("GitCommit", "unknown")[:7] + if docker_command == "docker": + os = json_output.get("Os", "unknown") + arch = json_output.get("Arch", "unknown") + else: + try: + os, arch = json_output.get("OsArch", "unknown").split("/") + except ValueError: + os = "unknown" + arch = "unknown" + logger.warning(f"{docker_command.title()} version: {version}, build {commit}, platform {os}/{arch}") # Docker pull check - only if docker daemon is available if docker_daemon_available: From 1efc1ab4de100f112eda762c0a74dfc708d94c05 Mon Sep 17 00:00:00 2001 From: Chris Pressland Date: Thu, 11 Dec 2025 14:47:30 +0000 Subject: [PATCH 7/7] fix style issues --- src/azure-cli/azure/cli/command_modules/acr/check_health.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/azure-cli/azure/cli/command_modules/acr/check_health.py b/src/azure-cli/azure/cli/command_modules/acr/check_health.py index 8d824f38899..be15a7db581 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/check_health.py +++ b/src/azure-cli/azure/cli/command_modules/acr/check_health.py @@ -72,6 +72,7 @@ def _subprocess_communicate(command_parts, shell=False): ) return output, warning, stderr, succeeded + # Checks for the environment # Checks docker command, docker daemon, docker version and docker pull def _get_docker_status_and_version(ignore_errors, yes): @@ -112,7 +113,7 @@ def _get_docker_status_and_version(ignore_errors, yes): except ValueError: os = "unknown" arch = "unknown" - logger.warning(f"{docker_command.title()} version: {version}, build {commit}, platform {os}/{arch}") + logger.warning("%s version: %s, build %s, platform %s/%s", docker_command.title(), version, commit, os, arch) # Docker pull check - only if docker daemon is available if docker_daemon_available: