Skip to content

Commit 6921a56

Browse files
JP-EllisFizzadar
andauthored
connectors/docker: add platform and architecture option via connector data
Signed-off-by: JP-Ellis <[email protected]> Co-authored-by: Nick Mills-Barrett <[email protected]>
1 parent 8d7b710 commit 6921a56

File tree

2 files changed

+75
-1
lines changed

2 files changed

+75
-1
lines changed

src/pyinfra/connectors/docker.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,14 @@
2626

2727
class ConnectorData(TypedDict):
2828
docker_identifier: str
29+
docker_platform: str
30+
docker_architecture: str
2931

3032

3133
connector_data_meta: dict[str, DataMeta] = {
3234
"docker_identifier": DataMeta("ID of container or image to start from"),
35+
"docker_platform": DataMeta("Platform to use for Docker image (e.g., linux/amd64)"),
36+
"docker_architecture": DataMeta("Architecture to use for Docker image (e.g., amd64, arm64)"),
3337
}
3438

3539

@@ -108,9 +112,29 @@ def _find_start_docker_container(self, container_id) -> tuple[str, bool]:
108112
return container_id, True
109113

110114
def _start_docker_image(self, image_name):
115+
docker_cmd_parts = [
116+
self.docker_cmd,
117+
"run",
118+
"-d",
119+
]
120+
121+
if self.data.get("docker_platform"):
122+
docker_cmd_parts.extend(["--platform", self.data["docker_platform"]])
123+
if self.data.get("docker_architecture"):
124+
docker_cmd_parts.extend(["--arch", self.data["docker_architecture"]])
125+
126+
docker_cmd_parts.extend(
127+
[
128+
image_name,
129+
"tail",
130+
"-f",
131+
"/dev/null",
132+
]
133+
)
134+
111135
try:
112136
return local.shell(
113-
f"{self.docker_cmd} run -d {image_name} tail -f /dev/null",
137+
" ".join(docker_cmd_parts),
114138
splitlines=True,
115139
)[-1] # last line is the container ID
116140
except PyinfraError as e:

tests/test_connectors/test_docker.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,44 @@ def test_get_file_error(self):
180180
with self.assertRaises(IOError):
181181
host.get_file("not-a-file", "not-another-file", print_output=True)
182182

183+
def test_docker_platform(self):
184+
inventory = make_inventory(
185+
hosts=((f"@{self.connector_name}/not-an-image", {"docker_platform": "linux/amd64"}),),
186+
)
187+
State(inventory, Config())
188+
189+
host = inventory.get_host(f"@{self.connector_name}/not-an-image")
190+
assert host.data.docker_platform == "linux/amd64"
191+
192+
def test_docker_architecture(self):
193+
inventory = make_inventory(
194+
hosts=((f"@{self.connector_name}/not-an-image", {"docker_architecture": "arm64"}),),
195+
)
196+
State(inventory, Config())
197+
198+
host = inventory.get_host(f"@{self.connector_name}/not-an-image")
199+
assert host.data.docker_architecture == "arm64"
200+
201+
def test_connect_with_docker_platform(self):
202+
inventory = make_inventory(
203+
hosts=((f"@{self.connector_name}/not-an-image", {"docker_platform": "linux/amd64"}),),
204+
)
205+
state = State(inventory, Config())
206+
host = inventory.get_host(f"@{self.connector_name}/not-an-image")
207+
host.connect(reason=True)
208+
assert len(state.active_hosts) == 0
209+
host.disconnect()
210+
211+
def test_connect_with_docker_architecture(self):
212+
inventory = make_inventory(
213+
hosts=((f"@{self.connector_name}/not-an-image", {"docker_architecture": "arm64"}),),
214+
)
215+
state = State(inventory, Config())
216+
host = inventory.get_host(f"@{self.connector_name}/not-an-image")
217+
host.connect(reason=True)
218+
assert len(state.active_hosts) == 0
219+
host.disconnect()
220+
183221

184222
# Reuse the container testing code for docker and podman
185223

@@ -188,6 +226,12 @@ def fake_docker_shell(command, splitlines=None):
188226
if command == "docker run -d not-an-image tail -f /dev/null":
189227
return ["containerid"]
190228

229+
if command == "docker run -d --platform linux/amd64 not-an-image tail -f /dev/null":
230+
return ["containerid"]
231+
232+
if command == "docker run -d --arch arm64 not-an-image tail -f /dev/null":
233+
return ["containerid"]
234+
191235
if command == "docker commit containerid":
192236
return ["sha256:blahsomerandomstringdata"]
193237

@@ -213,6 +257,12 @@ def fake_podman_shell(command, splitlines=None):
213257
if command == "podman run -d not-an-image tail -f /dev/null":
214258
return ["containerid"]
215259

260+
if command == "podman run -d --platform linux/amd64 not-an-image tail -f /dev/null":
261+
return ["containerid"]
262+
263+
if command == "podman run -d --arch arm64 not-an-image tail -f /dev/null":
264+
return ["containerid"]
265+
216266
if command == "podman commit containerid":
217267
return ["sha256:blahsomerandomstringdata"]
218268

0 commit comments

Comments
 (0)