localstack-core 4.7.1.dev49__py3-none-any.whl → 4.10.1.dev12__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- localstack/aws/api/cloudformation/__init__.py +18 -4
- localstack/aws/api/cloudwatch/__init__.py +41 -1
- localstack/aws/api/config/__init__.py +4 -0
- localstack/aws/api/core.py +6 -2
- localstack/aws/api/dynamodb/__init__.py +30 -0
- localstack/aws/api/ec2/__init__.py +1522 -65
- localstack/aws/api/iam/__init__.py +7 -0
- localstack/aws/api/kinesis/__init__.py +19 -0
- localstack/aws/api/kms/__init__.py +6 -0
- localstack/aws/api/lambda_/__init__.py +13 -0
- localstack/aws/api/logs/__init__.py +15 -0
- localstack/aws/api/redshift/__init__.py +9 -3
- localstack/aws/api/route53/__init__.py +5 -0
- localstack/aws/api/s3/__init__.py +12 -0
- localstack/aws/api/s3control/__init__.py +54 -0
- localstack/aws/api/ssm/__init__.py +2 -0
- localstack/aws/api/transcribe/__init__.py +17 -0
- localstack/aws/client.py +7 -2
- localstack/aws/forwarder.py +52 -5
- localstack/aws/handlers/analytics.py +1 -1
- localstack/aws/handlers/internal_requests.py +6 -1
- localstack/aws/handlers/logging.py +12 -2
- localstack/aws/handlers/metric_handler.py +41 -1
- localstack/aws/handlers/service.py +40 -20
- localstack/aws/mocking.py +2 -2
- localstack/aws/patches.py +2 -2
- localstack/aws/protocol/parser.py +459 -32
- localstack/aws/protocol/serializer.py +689 -69
- localstack/aws/protocol/service_router.py +120 -20
- localstack/aws/protocol/validate.py +1 -1
- localstack/aws/scaffold.py +1 -1
- localstack/aws/skeleton.py +4 -2
- localstack/aws/spec-patches.json +58 -0
- localstack/aws/spec.py +37 -16
- localstack/cli/exceptions.py +1 -1
- localstack/cli/localstack.py +6 -6
- localstack/cli/lpm.py +3 -4
- localstack/cli/plugins.py +1 -1
- localstack/cli/profiles.py +1 -2
- localstack/config.py +25 -18
- localstack/constants.py +4 -29
- localstack/dev/kubernetes/__main__.py +130 -7
- localstack/dev/run/configurators.py +1 -4
- localstack/dev/run/paths.py +1 -1
- localstack/dns/plugins.py +5 -1
- localstack/dns/server.py +13 -4
- localstack/logging/format.py +3 -3
- localstack/packages/api.py +9 -8
- localstack/packages/core.py +2 -2
- localstack/packages/plugins.py +0 -8
- localstack/runtime/analytics.py +3 -0
- localstack/runtime/hooks.py +1 -1
- localstack/runtime/init.py +2 -2
- localstack/runtime/main.py +5 -5
- localstack/runtime/patches.py +2 -2
- localstack/services/apigateway/helpers.py +1 -4
- localstack/services/apigateway/legacy/helpers.py +7 -8
- localstack/services/apigateway/legacy/integration.py +4 -3
- localstack/services/apigateway/legacy/invocations.py +6 -5
- localstack/services/apigateway/legacy/provider.py +148 -68
- localstack/services/apigateway/legacy/templates.py +1 -1
- localstack/services/apigateway/next_gen/execute_api/handlers/method_request.py +7 -2
- localstack/services/apigateway/next_gen/execute_api/handlers/resource_router.py +1 -2
- localstack/services/apigateway/next_gen/execute_api/integrations/aws.py +3 -0
- localstack/services/apigateway/next_gen/execute_api/integrations/http.py +3 -3
- localstack/services/apigateway/next_gen/execute_api/template_mapping.py +2 -2
- localstack/services/apigateway/next_gen/execute_api/test_invoke.py +114 -9
- localstack/services/apigateway/next_gen/provider.py +5 -0
- localstack/services/apigateway/resource_providers/aws_apigateway_resource.py +1 -1
- localstack/services/cloudformation/api_utils.py +4 -8
- localstack/services/cloudformation/cfn_utils.py +1 -1
- localstack/services/cloudformation/engine/entities.py +14 -4
- localstack/services/cloudformation/engine/template_deployer.py +6 -4
- localstack/services/cloudformation/engine/transformers.py +6 -4
- localstack/services/cloudformation/engine/v2/change_set_model.py +201 -13
- localstack/services/cloudformation/engine/v2/change_set_model_describer.py +52 -3
- localstack/services/cloudformation/engine/v2/change_set_model_executor.py +117 -76
- localstack/services/cloudformation/engine/v2/change_set_model_preproc.py +205 -52
- localstack/services/cloudformation/engine/v2/change_set_model_transform.py +350 -116
- localstack/services/cloudformation/engine/v2/change_set_model_validator.py +56 -14
- localstack/services/cloudformation/engine/v2/change_set_model_visitor.py +1 -0
- localstack/services/cloudformation/engine/v2/resolving.py +7 -5
- localstack/services/cloudformation/engine/yaml_parser.py +9 -2
- localstack/services/cloudformation/provider.py +7 -5
- localstack/services/cloudformation/resource_provider.py +7 -1
- localstack/services/cloudformation/resources.py +24149 -0
- localstack/services/cloudformation/service_models.py +2 -2
- localstack/services/cloudformation/v2/entities.py +19 -9
- localstack/services/cloudformation/v2/provider.py +336 -106
- localstack/services/cloudformation/v2/types.py +13 -7
- localstack/services/cloudformation/v2/utils.py +4 -1
- localstack/services/cloudwatch/alarm_scheduler.py +4 -1
- localstack/services/cloudwatch/provider.py +18 -13
- localstack/services/cloudwatch/provider_v2.py +25 -28
- localstack/services/dynamodb/packages.py +2 -1
- localstack/services/dynamodb/provider.py +42 -0
- localstack/services/dynamodb/server.py +2 -2
- localstack/services/dynamodb/v2/provider.py +42 -0
- localstack/services/ecr/resource_providers/aws_ecr_repository.py +5 -2
- localstack/services/edge.py +1 -1
- localstack/services/es/provider.py +2 -2
- localstack/services/events/event_rule_engine.py +31 -13
- localstack/services/events/models.py +4 -5
- localstack/services/events/provider.py +17 -14
- localstack/services/events/target.py +17 -9
- localstack/services/events/v1/provider.py +5 -5
- localstack/services/firehose/provider.py +14 -4
- localstack/services/iam/provider.py +11 -116
- localstack/services/iam/resources/policy_simulator.py +133 -0
- localstack/services/kinesis/models.py +15 -2
- localstack/services/kinesis/provider.py +86 -3
- localstack/services/kms/provider.py +14 -5
- localstack/services/lambda_/api_utils.py +6 -3
- localstack/services/lambda_/invocation/docker_runtime_executor.py +1 -1
- localstack/services/lambda_/invocation/event_manager.py +1 -1
- localstack/services/lambda_/invocation/internal_sqs_queue.py +5 -9
- localstack/services/lambda_/invocation/lambda_models.py +10 -7
- localstack/services/lambda_/invocation/lambda_service.py +5 -1
- localstack/services/lambda_/packages.py +1 -1
- localstack/services/lambda_/provider.py +4 -3
- localstack/services/lambda_/provider_utils.py +1 -1
- localstack/services/logs/provider.py +36 -19
- localstack/services/moto.py +2 -1
- localstack/services/opensearch/cluster.py +15 -7
- localstack/services/opensearch/packages.py +26 -7
- localstack/services/opensearch/provider.py +8 -2
- localstack/services/opensearch/versions.py +56 -7
- localstack/services/plugins.py +11 -7
- localstack/services/providers.py +10 -2
- localstack/services/redshift/provider.py +0 -21
- localstack/services/s3/constants.py +5 -2
- localstack/services/s3/cors.py +4 -4
- localstack/services/s3/models.py +1 -1
- localstack/services/s3/notifications.py +55 -39
- localstack/services/s3/presigned_url.py +35 -54
- localstack/services/s3/provider.py +73 -15
- localstack/services/s3/utils.py +42 -22
- localstack/services/s3/validation.py +46 -32
- localstack/services/s3/website_hosting.py +4 -2
- localstack/services/ses/provider.py +18 -8
- localstack/services/sns/constants.py +7 -1
- localstack/services/sns/executor.py +9 -2
- localstack/services/sns/provider.py +8 -5
- localstack/services/sns/publisher.py +31 -16
- localstack/services/sns/v2/models.py +167 -0
- localstack/services/sns/v2/provider.py +867 -0
- localstack/services/sns/v2/utils.py +130 -0
- localstack/services/sqs/constants.py +1 -1
- localstack/services/sqs/developer_api.py +205 -0
- localstack/services/sqs/models.py +48 -5
- localstack/services/sqs/provider.py +38 -311
- localstack/services/sqs/query_api.py +6 -2
- localstack/services/sqs/utils.py +121 -2
- localstack/services/ssm/provider.py +1 -1
- localstack/services/stepfunctions/asl/component/intrinsic/member.py +1 -1
- localstack/services/stepfunctions/asl/component/state/state_choice/comparison/comparison.py +5 -11
- localstack/services/stepfunctions/asl/component/state/state_choice/state_choice.py +2 -2
- localstack/services/stepfunctions/asl/component/state/state_execution/state_map/state_map.py +2 -2
- localstack/services/stepfunctions/asl/component/state/state_execution/state_parallel/state_parallel.py +1 -1
- localstack/services/stepfunctions/asl/component/state/state_execution/state_task/state_task.py +2 -2
- localstack/services/stepfunctions/asl/component/state/state_fail/state_fail.py +1 -1
- localstack/services/stepfunctions/asl/component/state/state_pass/state_pass.py +2 -2
- localstack/services/stepfunctions/asl/component/state/state_succeed/state_succeed.py +1 -1
- localstack/services/stepfunctions/asl/component/state/state_wait/state_wait.py +1 -1
- localstack/services/stepfunctions/asl/eval/environment.py +1 -1
- localstack/services/stepfunctions/asl/jsonata/jsonata.py +1 -1
- localstack/services/stepfunctions/backend/execution.py +2 -1
- localstack/services/stores.py +1 -1
- localstack/services/transcribe/provider.py +6 -1
- localstack/state/codecs.py +61 -0
- localstack/state/core.py +11 -5
- localstack/state/pickle.py +10 -49
- localstack/testing/aws/cloudformation_utils.py +1 -1
- localstack/testing/pytest/cloudformation/fixtures.py +3 -3
- localstack/testing/pytest/cloudformation/transformers.py +0 -0
- localstack/testing/pytest/container.py +4 -5
- localstack/testing/pytest/fixtures.py +33 -31
- localstack/testing/pytest/in_memory_localstack.py +0 -4
- localstack/testing/pytest/marking.py +38 -11
- localstack/testing/pytest/stepfunctions/utils.py +4 -3
- localstack/testing/pytest/util.py +1 -1
- localstack/testing/pytest/validation_tracking.py +1 -2
- localstack/testing/snapshots/transformer_utility.py +6 -1
- localstack/utils/analytics/events.py +2 -2
- localstack/utils/analytics/metadata.py +6 -4
- localstack/utils/analytics/metrics/counter.py +8 -15
- localstack/utils/analytics/publisher.py +1 -2
- localstack/utils/analytics/service_providers.py +19 -0
- localstack/utils/analytics/service_request_aggregator.py +2 -2
- localstack/utils/archives.py +11 -11
- localstack/utils/asyncio.py +2 -2
- localstack/utils/aws/arns.py +24 -29
- localstack/utils/aws/aws_responses.py +8 -8
- localstack/utils/aws/aws_stack.py +2 -3
- localstack/utils/aws/dead_letter_queue.py +1 -5
- localstack/utils/aws/message_forwarding.py +1 -2
- localstack/utils/aws/request_context.py +4 -5
- localstack/utils/aws/resources.py +1 -1
- localstack/utils/aws/templating.py +1 -1
- localstack/utils/batch_policy.py +3 -3
- localstack/utils/bootstrap.py +21 -13
- localstack/utils/catalog/catalog.py +139 -0
- localstack/utils/catalog/catalog_loader.py +119 -0
- localstack/utils/catalog/common.py +58 -0
- localstack/utils/catalog/plugins.py +28 -0
- localstack/utils/cloudwatch/cloudwatch_util.py +5 -5
- localstack/utils/collections.py +7 -8
- localstack/utils/config_listener.py +1 -1
- localstack/utils/container_networking.py +2 -3
- localstack/utils/container_utils/container_client.py +135 -136
- localstack/utils/container_utils/docker_cmd_client.py +85 -69
- localstack/utils/container_utils/docker_sdk_client.py +69 -66
- localstack/utils/crypto.py +10 -10
- localstack/utils/diagnose.py +3 -4
- localstack/utils/docker_utils.py +9 -5
- localstack/utils/files.py +33 -13
- localstack/utils/functions.py +4 -3
- localstack/utils/http.py +11 -11
- localstack/utils/json.py +20 -6
- localstack/utils/kinesis/kinesis_connector.py +2 -1
- localstack/utils/net.py +15 -9
- localstack/utils/no_exit_argument_parser.py +2 -2
- localstack/utils/numbers.py +9 -2
- localstack/utils/objects.py +7 -6
- localstack/utils/patch.py +10 -3
- localstack/utils/run.py +12 -11
- localstack/utils/scheduler.py +11 -11
- localstack/utils/server/tcp_proxy.py +2 -2
- localstack/utils/serving.py +3 -4
- localstack/utils/strings.py +15 -16
- localstack/utils/sync.py +126 -1
- localstack/utils/tagging.py +8 -6
- localstack/utils/testutil.py +8 -8
- localstack/utils/threads.py +2 -2
- localstack/utils/time.py +12 -4
- localstack/utils/urls.py +1 -3
- localstack/utils/xray/traceid.py +1 -1
- localstack/version.py +16 -3
- {localstack_core-4.7.1.dev49.dist-info → localstack_core-4.10.1.dev12.dist-info}/METADATA +18 -14
- {localstack_core-4.7.1.dev49.dist-info → localstack_core-4.10.1.dev12.dist-info}/RECORD +248 -239
- {localstack_core-4.7.1.dev49.dist-info → localstack_core-4.10.1.dev12.dist-info}/entry_points.txt +8 -4
- localstack_core-4.10.1.dev12.dist-info/plux.json +1 -0
- localstack/packages/terraform.py +0 -46
- localstack/services/cloudformation/deploy.html +0 -144
- localstack/services/cloudformation/deploy_ui.py +0 -47
- localstack/services/cloudformation/plugins.py +0 -12
- localstack_core-4.7.1.dev49.dist-info/plux.json +0 -1
- {localstack_core-4.7.1.dev49.data → localstack_core-4.10.1.dev12.data}/scripts/localstack +0 -0
- {localstack_core-4.7.1.dev49.data → localstack_core-4.10.1.dev12.data}/scripts/localstack-supervisor +0 -0
- {localstack_core-4.7.1.dev49.data → localstack_core-4.10.1.dev12.data}/scripts/localstack.bat +0 -0
- {localstack_core-4.7.1.dev49.dist-info → localstack_core-4.10.1.dev12.dist-info}/WHEEL +0 -0
- {localstack_core-4.7.1.dev49.dist-info → localstack_core-4.10.1.dev12.dist-info}/licenses/LICENSE.txt +0 -0
- {localstack_core-4.7.1.dev49.dist-info → localstack_core-4.10.1.dev12.dist-info}/top_level.txt +0 -0
|
@@ -6,7 +6,7 @@ import os
|
|
|
6
6
|
import re
|
|
7
7
|
import shlex
|
|
8
8
|
import subprocess
|
|
9
|
-
from
|
|
9
|
+
from collections.abc import Callable
|
|
10
10
|
|
|
11
11
|
from localstack import config
|
|
12
12
|
from localstack.utils.collections import ensure_list
|
|
@@ -96,7 +96,7 @@ class CmdDockerClient(ContainerClient):
|
|
|
96
96
|
different response payloads or error messages returned by the `docker` vs `podman` commands.
|
|
97
97
|
"""
|
|
98
98
|
|
|
99
|
-
default_run_outfile:
|
|
99
|
+
default_run_outfile: str | None = None
|
|
100
100
|
|
|
101
101
|
def _docker_cmd(self) -> list[str]:
|
|
102
102
|
"""
|
|
@@ -202,7 +202,7 @@ class CmdDockerClient(ContainerClient):
|
|
|
202
202
|
except subprocess.CalledProcessError as e:
|
|
203
203
|
self._check_and_raise_no_such_container_error(container_name, error=e)
|
|
204
204
|
raise ContainerException(
|
|
205
|
-
"Docker process returned with errorcode
|
|
205
|
+
f"Docker process returned with errorcode {e.returncode}", e.stdout, e.stderr
|
|
206
206
|
) from e
|
|
207
207
|
|
|
208
208
|
def pause_container(self, container_name: str) -> None:
|
|
@@ -214,7 +214,7 @@ class CmdDockerClient(ContainerClient):
|
|
|
214
214
|
except subprocess.CalledProcessError as e:
|
|
215
215
|
self._check_and_raise_no_such_container_error(container_name, error=e)
|
|
216
216
|
raise ContainerException(
|
|
217
|
-
"Docker process returned with errorcode
|
|
217
|
+
f"Docker process returned with errorcode {e.returncode}", e.stdout, e.stderr
|
|
218
218
|
) from e
|
|
219
219
|
|
|
220
220
|
def unpause_container(self, container_name: str) -> None:
|
|
@@ -226,7 +226,7 @@ class CmdDockerClient(ContainerClient):
|
|
|
226
226
|
except subprocess.CalledProcessError as e:
|
|
227
227
|
self._check_and_raise_no_such_container_error(container_name, error=e)
|
|
228
228
|
raise ContainerException(
|
|
229
|
-
"Docker process returned with errorcode
|
|
229
|
+
f"Docker process returned with errorcode {e.returncode}", e.stdout, e.stderr
|
|
230
230
|
) from e
|
|
231
231
|
|
|
232
232
|
def remove_image(self, image: str, force: bool = True) -> None:
|
|
@@ -243,7 +243,7 @@ class CmdDockerClient(ContainerClient):
|
|
|
243
243
|
if any(msg in to_str(e.stdout) for msg in error_messages):
|
|
244
244
|
raise NoSuchImage(image, stdout=e.stdout, stderr=e.stderr)
|
|
245
245
|
raise ContainerException(
|
|
246
|
-
"Docker process returned with errorcode
|
|
246
|
+
f"Docker process returned with errorcode {e.returncode}", e.stdout, e.stderr
|
|
247
247
|
) from e
|
|
248
248
|
|
|
249
249
|
def commit(
|
|
@@ -262,26 +262,34 @@ class CmdDockerClient(ContainerClient):
|
|
|
262
262
|
except subprocess.CalledProcessError as e:
|
|
263
263
|
self._check_and_raise_no_such_container_error(container_name_or_id, error=e)
|
|
264
264
|
raise ContainerException(
|
|
265
|
-
"Docker process returned with errorcode
|
|
265
|
+
f"Docker process returned with errorcode {e.returncode}", e.stdout, e.stderr
|
|
266
266
|
) from e
|
|
267
267
|
|
|
268
|
-
def remove_container(
|
|
269
|
-
|
|
268
|
+
def remove_container(
|
|
269
|
+
self, container_name: str, force=True, check_existence=False, volumes=False
|
|
270
|
+
) -> None:
|
|
271
|
+
if check_existence and container_name not in self.get_all_container_names():
|
|
270
272
|
return
|
|
271
273
|
cmd = self._docker_cmd() + ["rm"]
|
|
272
274
|
if force:
|
|
273
275
|
cmd.append("-f")
|
|
276
|
+
if volumes:
|
|
277
|
+
cmd.append("--volumes")
|
|
274
278
|
cmd.append(container_name)
|
|
275
279
|
LOG.debug("Removing container with cmd %s", cmd)
|
|
276
280
|
try:
|
|
277
|
-
run(cmd)
|
|
281
|
+
output = run(cmd)
|
|
282
|
+
# When the container does not exist, the output could have the error message without any exception
|
|
283
|
+
if isinstance(output, str) and not force:
|
|
284
|
+
self._check_output_and_raise_no_such_container_error(container_name, output=output)
|
|
278
285
|
except subprocess.CalledProcessError as e:
|
|
279
|
-
|
|
286
|
+
if not force:
|
|
287
|
+
self._check_and_raise_no_such_container_error(container_name, error=e)
|
|
280
288
|
raise ContainerException(
|
|
281
|
-
"Docker process returned with errorcode
|
|
289
|
+
f"Docker process returned with errorcode {e.returncode}", e.stdout, e.stderr
|
|
282
290
|
) from e
|
|
283
291
|
|
|
284
|
-
def list_containers(self, filter:
|
|
292
|
+
def list_containers(self, filter: list[str] | str | None = None, all=True) -> list[dict]:
|
|
285
293
|
filter = [filter] if isinstance(filter, str) else filter
|
|
286
294
|
cmd = self._docker_cmd()
|
|
287
295
|
cmd.append("ps")
|
|
@@ -297,7 +305,7 @@ class CmdDockerClient(ContainerClient):
|
|
|
297
305
|
cmd_result = run(cmd).strip()
|
|
298
306
|
except subprocess.CalledProcessError as e:
|
|
299
307
|
raise ContainerException(
|
|
300
|
-
"Docker process returned with errorcode
|
|
308
|
+
f"Docker process returned with errorcode {e.returncode}", e.stdout, e.stderr
|
|
301
309
|
) from e
|
|
302
310
|
container_list = []
|
|
303
311
|
if cmd_result:
|
|
@@ -351,14 +359,14 @@ class CmdDockerClient(ContainerClient):
|
|
|
351
359
|
if re.match(".*container .+ does not exist", to_str(e.stdout)):
|
|
352
360
|
raise NoSuchContainer(container_name, stdout=e.stdout, stderr=e.stderr)
|
|
353
361
|
raise ContainerException(
|
|
354
|
-
"Docker process returned with errorcode
|
|
362
|
+
f"Docker process returned with errorcode {e.returncode}", e.stdout, e.stderr
|
|
355
363
|
) from e
|
|
356
364
|
|
|
357
365
|
def pull_image(
|
|
358
366
|
self,
|
|
359
367
|
docker_image: str,
|
|
360
|
-
platform:
|
|
361
|
-
log_handler:
|
|
368
|
+
platform: DockerPlatform | None = None,
|
|
369
|
+
log_handler: Callable[[str], None] | None = None,
|
|
362
370
|
) -> None:
|
|
363
371
|
cmd = self._docker_cmd()
|
|
364
372
|
docker_image = self.registry_resolver_strategy.resolve(docker_image)
|
|
@@ -380,7 +388,7 @@ class CmdDockerClient(ContainerClient):
|
|
|
380
388
|
if "Trying to pull" in stdout_str and "access to the resource is denied" in stdout_str:
|
|
381
389
|
raise NoSuchImage(docker_image, stdout=e.stdout, stderr=e.stderr)
|
|
382
390
|
raise ContainerException(
|
|
383
|
-
"Docker process returned with errorcode
|
|
391
|
+
f"Docker process returned with errorcode {e.returncode}", e.stdout, e.stderr
|
|
384
392
|
) from e
|
|
385
393
|
|
|
386
394
|
def push_image(self, docker_image: str) -> None:
|
|
@@ -412,7 +420,7 @@ class CmdDockerClient(ContainerClient):
|
|
|
412
420
|
dockerfile_path: str,
|
|
413
421
|
image_name: str,
|
|
414
422
|
context_path: str = None,
|
|
415
|
-
platform:
|
|
423
|
+
platform: DockerPlatform | None = None,
|
|
416
424
|
):
|
|
417
425
|
cmd = self._docker_cmd()
|
|
418
426
|
dockerfile_path = Util.resolve_dockerfile_path(dockerfile_path)
|
|
@@ -474,7 +482,7 @@ class CmdDockerClient(ContainerClient):
|
|
|
474
482
|
return ""
|
|
475
483
|
self._check_and_raise_no_such_container_error(container_name_or_id, error=e)
|
|
476
484
|
raise ContainerException(
|
|
477
|
-
"Docker process returned with errorcode
|
|
485
|
+
f"Docker process returned with errorcode {e.returncode}", e.stdout, e.stderr
|
|
478
486
|
) from e
|
|
479
487
|
|
|
480
488
|
def stream_container_logs(self, container_name_or_id: str) -> CancellableStream:
|
|
@@ -489,7 +497,7 @@ class CmdDockerClient(ContainerClient):
|
|
|
489
497
|
|
|
490
498
|
return CancellableProcessStream(process)
|
|
491
499
|
|
|
492
|
-
def _inspect_object(self, object_name_or_id: str) -> dict[str,
|
|
500
|
+
def _inspect_object(self, object_name_or_id: str) -> dict[str, dict | list | str]:
|
|
493
501
|
cmd = self._docker_cmd()
|
|
494
502
|
cmd += ["inspect", "--format", "{{json .}}", object_name_or_id]
|
|
495
503
|
try:
|
|
@@ -499,7 +507,7 @@ class CmdDockerClient(ContainerClient):
|
|
|
499
507
|
if "no such object" in to_str(e.stdout).lower():
|
|
500
508
|
raise NoSuchObject(object_name_or_id, stdout=e.stdout, stderr=e.stderr)
|
|
501
509
|
raise ContainerException(
|
|
502
|
-
"Docker process returned with errorcode
|
|
510
|
+
f"Docker process returned with errorcode {e.returncode}", e.stdout, e.stderr
|
|
503
511
|
) from e
|
|
504
512
|
object_data = json.loads(cmd_result.strip())
|
|
505
513
|
if isinstance(object_data, list):
|
|
@@ -516,7 +524,7 @@ class CmdDockerClient(ContainerClient):
|
|
|
516
524
|
)
|
|
517
525
|
return object_data
|
|
518
526
|
|
|
519
|
-
def inspect_container(self, container_name_or_id: str) -> dict[str,
|
|
527
|
+
def inspect_container(self, container_name_or_id: str) -> dict[str, dict | str]:
|
|
520
528
|
try:
|
|
521
529
|
return self._inspect_object(container_name_or_id)
|
|
522
530
|
except NoSuchObject as e:
|
|
@@ -527,7 +535,7 @@ class CmdDockerClient(ContainerClient):
|
|
|
527
535
|
image_name: str,
|
|
528
536
|
pull: bool = True,
|
|
529
537
|
strip_wellknown_repo_prefixes: bool = True,
|
|
530
|
-
) -> dict[str,
|
|
538
|
+
) -> dict[str, dict | list | str]:
|
|
531
539
|
image_name = self.registry_resolver_strategy.resolve(image_name)
|
|
532
540
|
try:
|
|
533
541
|
result = self._inspect_object(image_name)
|
|
@@ -552,7 +560,7 @@ class CmdDockerClient(ContainerClient):
|
|
|
552
560
|
return run(cmd).strip()
|
|
553
561
|
except subprocess.CalledProcessError as e:
|
|
554
562
|
raise ContainerException(
|
|
555
|
-
"Docker process returned with errorcode
|
|
563
|
+
f"Docker process returned with errorcode {e.returncode}", e.stdout, e.stderr
|
|
556
564
|
) from e
|
|
557
565
|
|
|
558
566
|
def delete_network(self, network_name: str) -> None:
|
|
@@ -566,10 +574,10 @@ class CmdDockerClient(ContainerClient):
|
|
|
566
574
|
raise NoSuchNetwork(network_name=network_name)
|
|
567
575
|
else:
|
|
568
576
|
raise ContainerException(
|
|
569
|
-
"Docker process returned with errorcode
|
|
577
|
+
f"Docker process returned with errorcode {e.returncode}", e.stdout, e.stderr
|
|
570
578
|
) from e
|
|
571
579
|
|
|
572
|
-
def inspect_network(self, network_name: str) -> dict[str,
|
|
580
|
+
def inspect_network(self, network_name: str) -> dict[str, dict | str]:
|
|
573
581
|
try:
|
|
574
582
|
return self._inspect_object(network_name)
|
|
575
583
|
except NoSuchObject as e:
|
|
@@ -579,7 +587,7 @@ class CmdDockerClient(ContainerClient):
|
|
|
579
587
|
self,
|
|
580
588
|
network_name: str,
|
|
581
589
|
container_name_or_id: str,
|
|
582
|
-
aliases:
|
|
590
|
+
aliases: list | None = None,
|
|
583
591
|
link_local_ips: list[str] = None,
|
|
584
592
|
) -> None:
|
|
585
593
|
LOG.debug(
|
|
@@ -603,7 +611,7 @@ class CmdDockerClient(ContainerClient):
|
|
|
603
611
|
raise NoSuchNetwork(network_name=network_name)
|
|
604
612
|
self._check_and_raise_no_such_container_error(container_name_or_id, error=e)
|
|
605
613
|
raise ContainerException(
|
|
606
|
-
"Docker process returned with errorcode
|
|
614
|
+
f"Docker process returned with errorcode {e.returncode}", e.stdout, e.stderr
|
|
607
615
|
) from e
|
|
608
616
|
|
|
609
617
|
def disconnect_container_from_network(
|
|
@@ -621,7 +629,7 @@ class CmdDockerClient(ContainerClient):
|
|
|
621
629
|
raise NoSuchNetwork(network_name=network_name)
|
|
622
630
|
self._check_and_raise_no_such_container_error(container_name_or_id, error=e)
|
|
623
631
|
raise ContainerException(
|
|
624
|
-
"Docker process returned with errorcode
|
|
632
|
+
f"Docker process returned with errorcode {e.returncode}", e.stdout, e.stderr
|
|
625
633
|
) from e
|
|
626
634
|
|
|
627
635
|
def get_container_ip(self, container_name_or_id: str) -> str:
|
|
@@ -641,10 +649,10 @@ class CmdDockerClient(ContainerClient):
|
|
|
641
649
|
if "no such object" in to_str(e.stdout).lower():
|
|
642
650
|
raise NoSuchContainer(container_name_or_id, stdout=e.stdout, stderr=e.stderr)
|
|
643
651
|
raise ContainerException(
|
|
644
|
-
"Docker process returned with errorcode
|
|
652
|
+
f"Docker process returned with errorcode {e.returncode}", e.stdout, e.stderr
|
|
645
653
|
) from e
|
|
646
654
|
|
|
647
|
-
def login(self, username: str, password: str, registry:
|
|
655
|
+
def login(self, username: str, password: str, registry: str | None = None) -> None:
|
|
648
656
|
cmd = self._docker_cmd()
|
|
649
657
|
# TODO specify password via stdin
|
|
650
658
|
cmd += ["login", "-u", username, "-p", password]
|
|
@@ -654,7 +662,7 @@ class CmdDockerClient(ContainerClient):
|
|
|
654
662
|
run(cmd)
|
|
655
663
|
except subprocess.CalledProcessError as e:
|
|
656
664
|
raise ContainerException(
|
|
657
|
-
"Docker process returned with errorcode
|
|
665
|
+
f"Docker process returned with errorcode {e.returncode}", e.stdout, e.stderr
|
|
658
666
|
) from e
|
|
659
667
|
|
|
660
668
|
@functools.cache
|
|
@@ -680,7 +688,7 @@ class CmdDockerClient(ContainerClient):
|
|
|
680
688
|
if any(msg in to_str(e.stdout) for msg in error_messages):
|
|
681
689
|
raise NoSuchImage(image_name, stdout=e.stdout, stderr=e.stderr)
|
|
682
690
|
raise ContainerException(
|
|
683
|
-
"Docker process returned with errorcode
|
|
691
|
+
f"Docker process returned with errorcode {e.returncode}", e.stdout, e.stderr
|
|
684
692
|
) from e
|
|
685
693
|
finally:
|
|
686
694
|
Util.rm_env_vars_file(env_file)
|
|
@@ -701,13 +709,13 @@ class CmdDockerClient(ContainerClient):
|
|
|
701
709
|
def exec_in_container(
|
|
702
710
|
self,
|
|
703
711
|
container_name_or_id: str,
|
|
704
|
-
command:
|
|
712
|
+
command: list[str] | str,
|
|
705
713
|
interactive=False,
|
|
706
714
|
detach=False,
|
|
707
|
-
env_vars:
|
|
708
|
-
stdin:
|
|
709
|
-
user:
|
|
710
|
-
workdir:
|
|
715
|
+
env_vars: dict[str, str | None] | None = None,
|
|
716
|
+
stdin: bytes | None = None,
|
|
717
|
+
user: str | None = None,
|
|
718
|
+
workdir: str | None = None,
|
|
711
719
|
) -> tuple[bytes, bytes]:
|
|
712
720
|
env_file = None
|
|
713
721
|
cmd = self._docker_cmd()
|
|
@@ -737,7 +745,7 @@ class CmdDockerClient(ContainerClient):
|
|
|
737
745
|
stdin=None,
|
|
738
746
|
interactive: bool = False,
|
|
739
747
|
attach: bool = False,
|
|
740
|
-
flags:
|
|
748
|
+
flags: str | None = None,
|
|
741
749
|
) -> tuple[bytes, bytes]:
|
|
742
750
|
cmd = self._docker_cmd() + ["start"]
|
|
743
751
|
if flags:
|
|
@@ -787,7 +795,7 @@ class CmdDockerClient(ContainerClient):
|
|
|
787
795
|
if any(msg.lower() in to_str(e.stderr).lower() for msg in error_messages):
|
|
788
796
|
raise NoSuchContainer(container_name, stdout=e.stdout, stderr=e.stderr)
|
|
789
797
|
raise ContainerException(
|
|
790
|
-
"Docker process returned with errorcode
|
|
798
|
+
f"Docker process returned with errorcode {e.returncode}", e.stdout, e.stderr
|
|
791
799
|
) from e
|
|
792
800
|
|
|
793
801
|
def _build_run_create_cmd(
|
|
@@ -795,31 +803,31 @@ class CmdDockerClient(ContainerClient):
|
|
|
795
803
|
action: str,
|
|
796
804
|
image_name: str,
|
|
797
805
|
*,
|
|
798
|
-
name:
|
|
799
|
-
entrypoint:
|
|
806
|
+
name: str | None = None,
|
|
807
|
+
entrypoint: list[str] | str | None = None,
|
|
800
808
|
remove: bool = False,
|
|
801
809
|
interactive: bool = False,
|
|
802
810
|
tty: bool = False,
|
|
803
811
|
detach: bool = False,
|
|
804
|
-
command:
|
|
805
|
-
volumes:
|
|
806
|
-
ports:
|
|
807
|
-
exposed_ports:
|
|
808
|
-
env_vars:
|
|
809
|
-
user:
|
|
810
|
-
cap_add:
|
|
811
|
-
cap_drop:
|
|
812
|
-
security_opt:
|
|
813
|
-
network:
|
|
814
|
-
dns:
|
|
815
|
-
additional_flags:
|
|
816
|
-
workdir:
|
|
817
|
-
privileged:
|
|
818
|
-
labels:
|
|
819
|
-
platform:
|
|
820
|
-
ulimits:
|
|
821
|
-
init:
|
|
822
|
-
log_config:
|
|
812
|
+
command: list[str] | str | None = None,
|
|
813
|
+
volumes: list[SimpleVolumeBind] | None = None,
|
|
814
|
+
ports: PortMappings | None = None,
|
|
815
|
+
exposed_ports: list[str] | None = None,
|
|
816
|
+
env_vars: dict[str, str] | None = None,
|
|
817
|
+
user: str | None = None,
|
|
818
|
+
cap_add: list[str] | None = None,
|
|
819
|
+
cap_drop: list[str] | None = None,
|
|
820
|
+
security_opt: list[str] | None = None,
|
|
821
|
+
network: str | None = None,
|
|
822
|
+
dns: str | list[str] | None = None,
|
|
823
|
+
additional_flags: str | None = None,
|
|
824
|
+
workdir: str | None = None,
|
|
825
|
+
privileged: bool | None = None,
|
|
826
|
+
labels: dict[str, str] | None = None,
|
|
827
|
+
platform: DockerPlatform | None = None,
|
|
828
|
+
ulimits: list[Ulimit] | None = None,
|
|
829
|
+
init: bool | None = None,
|
|
830
|
+
log_config: LogConfig | None = None,
|
|
823
831
|
) -> tuple[list[str], str]:
|
|
824
832
|
env_file = None
|
|
825
833
|
cmd = self._docker_cmd() + [action]
|
|
@@ -892,7 +900,7 @@ class CmdDockerClient(ContainerClient):
|
|
|
892
900
|
return cmd, env_file
|
|
893
901
|
|
|
894
902
|
@staticmethod
|
|
895
|
-
def _map_to_volume_param(volume:
|
|
903
|
+
def _map_to_volume_param(volume: SimpleVolumeBind | BindMount | VolumeDirMount) -> str:
|
|
896
904
|
"""
|
|
897
905
|
Maps the mount volume, to a parameter for the -v docker cli argument.
|
|
898
906
|
|
|
@@ -915,14 +923,22 @@ class CmdDockerClient(ContainerClient):
|
|
|
915
923
|
Check the given client invocation error and raise a `NoSuchContainer` exception if it
|
|
916
924
|
represents a `no such container` exception from Docker or Podman.
|
|
917
925
|
"""
|
|
926
|
+
self._check_output_and_raise_no_such_container_error(
|
|
927
|
+
container_name_or_id, str(error.stdout), error=str(error.stderr)
|
|
928
|
+
)
|
|
918
929
|
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
930
|
+
def _check_output_and_raise_no_such_container_error(
|
|
931
|
+
self, container_name_or_id: str, output: str, error: str | None = None
|
|
932
|
+
):
|
|
933
|
+
"""
|
|
934
|
+
Check the given client invocation output and raise a `NoSuchContainer` exception if it
|
|
935
|
+
represents a `no such container` exception from Docker or Podman.
|
|
936
|
+
"""
|
|
937
|
+
possible_not_found_messages = ("No such container", "no container with name or ID")
|
|
938
|
+
if any(msg.lower() in output.lower() for msg in possible_not_found_messages):
|
|
939
|
+
raise NoSuchContainer(container_name_or_id, stdout=output, stderr=error)
|
|
924
940
|
|
|
925
|
-
def _transform_container_labels(self, labels:
|
|
941
|
+
def _transform_container_labels(self, labels: str | dict[str, str]) -> dict[str, str]:
|
|
926
942
|
"""
|
|
927
943
|
Transforms the container labels returned by the docker command from the key-value pair format to a dict
|
|
928
944
|
:param labels: Input string, comma separated key value pairs. Example: key1=value1,key2=value2
|
|
@@ -6,9 +6,10 @@ import queue
|
|
|
6
6
|
import re
|
|
7
7
|
import socket
|
|
8
8
|
import threading
|
|
9
|
+
from collections.abc import Callable
|
|
9
10
|
from functools import cache
|
|
10
11
|
from time import sleep
|
|
11
|
-
from typing import
|
|
12
|
+
from typing import cast
|
|
12
13
|
from urllib.parse import quote
|
|
13
14
|
|
|
14
15
|
import docker
|
|
@@ -56,7 +57,7 @@ class SdkDockerClient(ContainerClient):
|
|
|
56
57
|
is doing some of the heavy lifting for us to support both target platforms.
|
|
57
58
|
"""
|
|
58
59
|
|
|
59
|
-
docker_client:
|
|
60
|
+
docker_client: DockerClient | None
|
|
60
61
|
|
|
61
62
|
def __init__(self):
|
|
62
63
|
try:
|
|
@@ -264,21 +265,23 @@ class SdkDockerClient(ContainerClient):
|
|
|
264
265
|
except APIError as e:
|
|
265
266
|
raise ContainerException() from e
|
|
266
267
|
|
|
267
|
-
def remove_container(
|
|
268
|
-
|
|
269
|
-
|
|
268
|
+
def remove_container(
|
|
269
|
+
self, container_name: str, force=True, check_existence=False, volumes=False
|
|
270
|
+
) -> None:
|
|
271
|
+
LOG.debug("Removing container: %s, with volumes: %s", container_name, volumes)
|
|
272
|
+
if check_existence and container_name not in self.get_all_container_names():
|
|
270
273
|
LOG.debug("Aborting removing due to check_existence check")
|
|
271
274
|
return
|
|
272
275
|
try:
|
|
273
276
|
container = self.client().containers.get(container_name)
|
|
274
|
-
container.remove(force=force)
|
|
277
|
+
container.remove(force=force, v=volumes)
|
|
275
278
|
except NotFound:
|
|
276
279
|
if not force:
|
|
277
280
|
raise NoSuchContainer(container_name)
|
|
278
281
|
except APIError as e:
|
|
279
282
|
raise ContainerException() from e
|
|
280
283
|
|
|
281
|
-
def list_containers(self, filter:
|
|
284
|
+
def list_containers(self, filter: list[str] | str | None = None, all=True) -> list[dict]:
|
|
282
285
|
if filter:
|
|
283
286
|
filter = [filter] if isinstance(filter, str) else filter
|
|
284
287
|
filter = dict([f.split("=", 1) for f in filter])
|
|
@@ -337,14 +340,14 @@ class SdkDockerClient(ContainerClient):
|
|
|
337
340
|
def pull_image(
|
|
338
341
|
self,
|
|
339
342
|
docker_image: str,
|
|
340
|
-
platform:
|
|
341
|
-
log_handler:
|
|
343
|
+
platform: DockerPlatform | None = None,
|
|
344
|
+
log_handler: Callable[[str], None] | None = None,
|
|
342
345
|
) -> None:
|
|
343
346
|
LOG.debug("Pulling Docker image: %s", docker_image)
|
|
344
347
|
# some path in the docker image string indicates a custom repository
|
|
345
348
|
|
|
346
349
|
docker_image = self.registry_resolver_strategy.resolve(docker_image)
|
|
347
|
-
kwargs: dict[str,
|
|
350
|
+
kwargs: dict[str, str | bool] = {"platform": platform}
|
|
348
351
|
try:
|
|
349
352
|
if log_handler:
|
|
350
353
|
# Use a lower-level API, as the 'stream' argument is not available in the higher-level `pull`-API
|
|
@@ -389,7 +392,7 @@ class SdkDockerClient(ContainerClient):
|
|
|
389
392
|
dockerfile_path: str,
|
|
390
393
|
image_name: str,
|
|
391
394
|
context_path: str = None,
|
|
392
|
-
platform:
|
|
395
|
+
platform: DockerPlatform | None = None,
|
|
393
396
|
):
|
|
394
397
|
try:
|
|
395
398
|
dockerfile_path = Util.resolve_dockerfile_path(dockerfile_path)
|
|
@@ -466,7 +469,7 @@ class SdkDockerClient(ContainerClient):
|
|
|
466
469
|
except APIError as e:
|
|
467
470
|
raise ContainerException() from e
|
|
468
471
|
|
|
469
|
-
def inspect_container(self, container_name_or_id: str) -> dict[str,
|
|
472
|
+
def inspect_container(self, container_name_or_id: str) -> dict[str, dict | str]:
|
|
470
473
|
try:
|
|
471
474
|
return self.client().containers.get(container_name_or_id).attrs
|
|
472
475
|
except NotFound:
|
|
@@ -479,7 +482,7 @@ class SdkDockerClient(ContainerClient):
|
|
|
479
482
|
image_name: str,
|
|
480
483
|
pull: bool = True,
|
|
481
484
|
strip_wellknown_repo_prefixes: bool = True,
|
|
482
|
-
) -> dict[str,
|
|
485
|
+
) -> dict[str, dict | list | str]:
|
|
483
486
|
image_name = self.registry_resolver_strategy.resolve(image_name)
|
|
484
487
|
try:
|
|
485
488
|
result = self.client().images.get(image_name).attrs
|
|
@@ -513,7 +516,7 @@ class SdkDockerClient(ContainerClient):
|
|
|
513
516
|
except APIError as e:
|
|
514
517
|
raise ContainerException() from e
|
|
515
518
|
|
|
516
|
-
def inspect_network(self, network_name: str) -> dict[str,
|
|
519
|
+
def inspect_network(self, network_name: str) -> dict[str, dict | str]:
|
|
517
520
|
try:
|
|
518
521
|
return self.client().networks.get(network_name).attrs
|
|
519
522
|
except NotFound:
|
|
@@ -525,7 +528,7 @@ class SdkDockerClient(ContainerClient):
|
|
|
525
528
|
self,
|
|
526
529
|
network_name: str,
|
|
527
530
|
container_name_or_id: str,
|
|
528
|
-
aliases:
|
|
531
|
+
aliases: list | None = None,
|
|
529
532
|
link_local_ips: list[str] = None,
|
|
530
533
|
) -> None:
|
|
531
534
|
LOG.debug(
|
|
@@ -619,7 +622,7 @@ class SdkDockerClient(ContainerClient):
|
|
|
619
622
|
stdin=None,
|
|
620
623
|
interactive: bool = False,
|
|
621
624
|
attach: bool = False,
|
|
622
|
-
flags:
|
|
625
|
+
flags: str | None = None,
|
|
623
626
|
) -> tuple[bytes, bytes]:
|
|
624
627
|
LOG.debug("Starting container %s", container_name_or_id)
|
|
625
628
|
try:
|
|
@@ -668,7 +671,7 @@ class SdkDockerClient(ContainerClient):
|
|
|
668
671
|
sock.sendall(to_bytes(stdin))
|
|
669
672
|
sock.shutdown(socket.SHUT_WR)
|
|
670
673
|
stdout, stderr = self._read_from_sock(sock, False)
|
|
671
|
-
except
|
|
674
|
+
except TimeoutError:
|
|
672
675
|
LOG.debug(
|
|
673
676
|
"Socket timeout when talking to the I/O streams of Docker container '%s'",
|
|
674
677
|
container_name_or_id,
|
|
@@ -701,31 +704,31 @@ class SdkDockerClient(ContainerClient):
|
|
|
701
704
|
self,
|
|
702
705
|
image_name: str,
|
|
703
706
|
*,
|
|
704
|
-
name:
|
|
705
|
-
entrypoint:
|
|
707
|
+
name: str | None = None,
|
|
708
|
+
entrypoint: list[str] | str | None = None,
|
|
706
709
|
remove: bool = False,
|
|
707
710
|
interactive: bool = False,
|
|
708
711
|
tty: bool = False,
|
|
709
712
|
detach: bool = False,
|
|
710
|
-
command:
|
|
711
|
-
volumes:
|
|
712
|
-
ports:
|
|
713
|
-
exposed_ports:
|
|
714
|
-
env_vars:
|
|
715
|
-
user:
|
|
716
|
-
cap_add:
|
|
717
|
-
cap_drop:
|
|
718
|
-
security_opt:
|
|
719
|
-
network:
|
|
720
|
-
dns:
|
|
721
|
-
additional_flags:
|
|
722
|
-
workdir:
|
|
723
|
-
privileged:
|
|
724
|
-
labels:
|
|
725
|
-
platform:
|
|
726
|
-
ulimits:
|
|
727
|
-
init:
|
|
728
|
-
log_config:
|
|
713
|
+
command: list[str] | str | None = None,
|
|
714
|
+
volumes: list[SimpleVolumeBind] | None = None,
|
|
715
|
+
ports: PortMappings | None = None,
|
|
716
|
+
exposed_ports: list[str] | None = None,
|
|
717
|
+
env_vars: dict[str, str] | None = None,
|
|
718
|
+
user: str | None = None,
|
|
719
|
+
cap_add: list[str] | None = None,
|
|
720
|
+
cap_drop: list[str] | None = None,
|
|
721
|
+
security_opt: list[str] | None = None,
|
|
722
|
+
network: str | None = None,
|
|
723
|
+
dns: str | list[str] | None = None,
|
|
724
|
+
additional_flags: str | None = None,
|
|
725
|
+
workdir: str | None = None,
|
|
726
|
+
privileged: bool | None = None,
|
|
727
|
+
labels: dict[str, str] | None = None,
|
|
728
|
+
platform: DockerPlatform | None = None,
|
|
729
|
+
ulimits: list[Ulimit] | None = None,
|
|
730
|
+
init: bool | None = None,
|
|
731
|
+
log_config: LogConfig | None = None,
|
|
729
732
|
) -> str:
|
|
730
733
|
LOG.debug("Creating container with attributes: %s", locals())
|
|
731
734
|
extra_hosts = None
|
|
@@ -832,31 +835,31 @@ class SdkDockerClient(ContainerClient):
|
|
|
832
835
|
image_name: str,
|
|
833
836
|
stdin=None,
|
|
834
837
|
*,
|
|
835
|
-
name:
|
|
836
|
-
entrypoint:
|
|
838
|
+
name: str | None = None,
|
|
839
|
+
entrypoint: str | None = None,
|
|
837
840
|
remove: bool = False,
|
|
838
841
|
interactive: bool = False,
|
|
839
842
|
tty: bool = False,
|
|
840
843
|
detach: bool = False,
|
|
841
|
-
command:
|
|
842
|
-
volumes:
|
|
843
|
-
ports:
|
|
844
|
-
exposed_ports:
|
|
845
|
-
env_vars:
|
|
846
|
-
user:
|
|
847
|
-
cap_add:
|
|
848
|
-
cap_drop:
|
|
849
|
-
security_opt:
|
|
850
|
-
network:
|
|
851
|
-
dns:
|
|
852
|
-
additional_flags:
|
|
853
|
-
workdir:
|
|
854
|
-
labels:
|
|
855
|
-
platform:
|
|
856
|
-
privileged:
|
|
857
|
-
ulimits:
|
|
858
|
-
init:
|
|
859
|
-
log_config:
|
|
844
|
+
command: list[str] | str | None = None,
|
|
845
|
+
volumes: list[SimpleVolumeBind] | None = None,
|
|
846
|
+
ports: PortMappings | None = None,
|
|
847
|
+
exposed_ports: list[str] | None = None,
|
|
848
|
+
env_vars: dict[str, str] | None = None,
|
|
849
|
+
user: str | None = None,
|
|
850
|
+
cap_add: list[str] | None = None,
|
|
851
|
+
cap_drop: list[str] | None = None,
|
|
852
|
+
security_opt: list[str] | None = None,
|
|
853
|
+
network: str | None = None,
|
|
854
|
+
dns: str | None = None,
|
|
855
|
+
additional_flags: str | None = None,
|
|
856
|
+
workdir: str | None = None,
|
|
857
|
+
labels: dict[str, str] | None = None,
|
|
858
|
+
platform: DockerPlatform | None = None,
|
|
859
|
+
privileged: bool | None = None,
|
|
860
|
+
ulimits: list[Ulimit] | None = None,
|
|
861
|
+
init: bool | None = None,
|
|
862
|
+
log_config: LogConfig | None = None,
|
|
860
863
|
) -> tuple[bytes, bytes]:
|
|
861
864
|
LOG.debug("Running container with image: %s", image_name)
|
|
862
865
|
container = None
|
|
@@ -903,13 +906,13 @@ class SdkDockerClient(ContainerClient):
|
|
|
903
906
|
def exec_in_container(
|
|
904
907
|
self,
|
|
905
908
|
container_name_or_id: str,
|
|
906
|
-
command:
|
|
909
|
+
command: list[str] | str,
|
|
907
910
|
interactive=False,
|
|
908
911
|
detach=False,
|
|
909
|
-
env_vars:
|
|
910
|
-
stdin:
|
|
911
|
-
user:
|
|
912
|
-
workdir:
|
|
912
|
+
env_vars: dict[str, str | None] | None = None,
|
|
913
|
+
stdin: bytes | None = None,
|
|
914
|
+
user: str | None = None,
|
|
915
|
+
workdir: str | None = None,
|
|
913
916
|
) -> tuple[bytes, bytes]:
|
|
914
917
|
LOG.debug("Executing command in container %s: %s", container_name_or_id, command)
|
|
915
918
|
try:
|
|
@@ -936,7 +939,7 @@ class SdkDockerClient(ContainerClient):
|
|
|
936
939
|
sock.shutdown(socket.SHUT_WR)
|
|
937
940
|
stdout, stderr = self._read_from_sock(sock, tty)
|
|
938
941
|
return stdout, stderr
|
|
939
|
-
except
|
|
942
|
+
except TimeoutError:
|
|
940
943
|
pass
|
|
941
944
|
else:
|
|
942
945
|
if detach:
|
|
@@ -957,7 +960,7 @@ class SdkDockerClient(ContainerClient):
|
|
|
957
960
|
except APIError as e:
|
|
958
961
|
raise ContainerException() from e
|
|
959
962
|
|
|
960
|
-
def login(self, username: str, password: str, registry:
|
|
963
|
+
def login(self, username: str, password: str, registry: str | None = None) -> None:
|
|
961
964
|
LOG.debug("Docker login for %s", username)
|
|
962
965
|
try:
|
|
963
966
|
self.client().login(username, password=password, registry=registry, reauth=True)
|