Skip to content

Commit 95738b6

Browse files
authored
Merge pull request #1104 from GitGuardian/severine/fix-pull-docker-apple-silicon
fix: docker pull fallback on linux amd64 for apple silicon
2 parents bc4777c + c8835dd commit 95738b6

File tree

4 files changed

+51
-2
lines changed

4 files changed

+51
-2
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,7 @@ Yanked: release process issue.
551551
#### IaC
552552

553553
- `ggshield iac scan` now provides three new commands for use as Git hooks:
554+
554555
- `ggshield iac scan pre-commit`
555556
- `ggshield iac scan pre-push`
556557
- `ggshield iac scan pre-receive`
@@ -635,6 +636,7 @@ Yanked: release process issue.
635636
- New command: `ggshield iac scan all`. This command replaces the now-deprecated `ggshield iac scan`. It scans a directory for IaC vulnerabilities.
636637

637638
- New command: `ggshield iac scan diff`. This command scans a Git repository and inspects changes in IaC vulnerabilities between two points in the history.
639+
638640
- All options from `ggshield iac scan all` are supported: `--ignore-policy`, `--minimum-severity`, `--ignore-path` etc. Execute `ggshield iac scan diff -h` for more details.
639641
- Two new options allow to choose which state to select for the difference: `--ref <GIT-REFERENCE>` and `--staged`.
640642
- The command can be integrated in Git hooks using the `--pre-commit`, `--pre-push`, `--pre-receive` options.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
### Changed
2+
3+
- When scanning a docker image, if no image is found matching the client platform, try to pull the `linux/amd64` image.

ggshield/verticals/secret/docker.py

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -289,15 +289,45 @@ def docker_pull_image(image_name: str, timeout: int) -> None:
289289
290290
Timeout after `timeout` seconds.
291291
"""
292-
command = ["docker", "pull", image_name]
292+
# Base command for docker pull
293+
base_command = ["docker", "pull", image_name]
294+
295+
# Try standard pull first
296+
if _run_docker_command(base_command, timeout):
297+
return
298+
299+
# Fall back to linux/amd64 if no success
300+
amd64_command = base_command + ["--platform=linux/amd64"]
301+
if _run_docker_command(amd64_command, timeout):
302+
return
303+
304+
# Raise error if no success
305+
raise UsageError(f'Image "{image_name}" not found')
306+
307+
308+
def _run_docker_command(command: List[str], timeout: int) -> bool:
309+
"""
310+
Run a docker command with timeout and return success status
311+
312+
Args:
313+
command: Docker command to run as a list of strings
314+
timeout: Timeout in seconds
315+
316+
Returns:
317+
True if command succeeded, False if CalledProcessError
318+
319+
Raises:
320+
UnexpectedError: If command times out
321+
"""
293322
try:
294323
subprocess.run(
295324
command,
296325
check=True,
297326
timeout=timeout,
298327
)
328+
return True
299329
except subprocess.CalledProcessError:
300-
raise UsageError(f'Image "{image_name}" not found')
330+
return False
301331
except subprocess.TimeoutExpired:
302332
raise UnexpectedError('Command "{}" timed out'.format(" ".join(command)))
303333

tests/unit/verticals/secret/test_scan_docker.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,20 @@ def test_docker_pull_image_timeout(self):
148148
):
149149
docker_pull_image("ggshield-non-existant", DOCKER_TIMEOUT)
150150

151+
def test_docker_pull_image_platform_fallback(self):
152+
with patch(
153+
"subprocess.run", side_effect=subprocess.CalledProcessError(1, cmd=[])
154+
) as call, pytest.raises(
155+
click.UsageError,
156+
match='Image "ggshield-non-existant" not found',
157+
):
158+
docker_pull_image("ggshield-non-existant", DOCKER_TIMEOUT)
159+
call.assert_called_once_with(
160+
["docker", "pull", "ggshield-non-existant", "--platform=linux/amd64"],
161+
check=True,
162+
timeout=DOCKER_TIMEOUT,
163+
)
164+
151165

152166
class TestDockerSave:
153167
TMP_ARCHIVE = Path("/tmp/as/archive.tar")

0 commit comments

Comments
 (0)