localstack-core 4.7.1.dev96__py3-none-any.whl → 4.7.1.dev98__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.
Potentially problematic release.
This version of localstack-core might be problematic. Click here for more details.
- localstack/aws/mocking.py +2 -2
- localstack/aws/protocol/parser.py +6 -6
- localstack/aws/protocol/serializer.py +5 -5
- localstack/aws/scaffold.py +1 -1
- localstack/cli/localstack.py +1 -1
- localstack/cli/plugins.py +1 -1
- localstack/config.py +5 -5
- localstack/dev/run/configurators.py +1 -4
- localstack/runtime/hooks.py +1 -1
- localstack/runtime/init.py +1 -1
- localstack/runtime/main.py +5 -5
- 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 +2 -2
- localstack/services/apigateway/legacy/provider.py +4 -4
- 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 +1 -2
- localstack/services/cloudformation/engine/template_deployer.py +2 -2
- localstack/services/cloudformation/engine/v2/change_set_model_transform.py +2 -2
- localstack/services/cloudformation/provider.py +2 -2
- localstack/services/cloudformation/service_models.py +1 -1
- localstack/services/dynamodb/server.py +1 -1
- localstack/services/edge.py +1 -1
- localstack/services/events/v1/provider.py +5 -5
- localstack/services/kinesis/provider.py +1 -1
- localstack/services/plugins.py +6 -6
- localstack/services/ssm/provider.py +1 -1
- localstack/state/pickle.py +1 -1
- localstack/testing/pytest/fixtures.py +3 -3
- localstack/utils/analytics/metadata.py +1 -1
- localstack/utils/aws/arns.py +7 -20
- localstack/utils/aws/aws_responses.py +1 -1
- localstack/utils/aws/dead_letter_queue.py +1 -5
- localstack/utils/aws/resources.py +1 -1
- localstack/utils/aws/templating.py +1 -1
- localstack/utils/bootstrap.py +4 -4
- localstack/utils/container_utils/docker_cmd_client.py +19 -19
- localstack/utils/crypto.py +10 -10
- localstack/utils/diagnose.py +1 -1
- localstack/utils/files.py +2 -6
- localstack/utils/functions.py +1 -1
- localstack/utils/http.py +5 -5
- localstack/utils/net.py +3 -2
- localstack/utils/objects.py +1 -1
- localstack/utils/run.py +2 -2
- localstack/utils/serving.py +1 -1
- localstack/utils/strings.py +5 -5
- localstack/utils/testutil.py +3 -4
- localstack/utils/time.py +1 -1
- localstack/utils/xray/traceid.py +1 -1
- localstack/version.py +2 -2
- {localstack_core-4.7.1.dev96.dist-info → localstack_core-4.7.1.dev98.dist-info}/METADATA +1 -1
- {localstack_core-4.7.1.dev96.dist-info → localstack_core-4.7.1.dev98.dist-info}/RECORD +64 -64
- localstack_core-4.7.1.dev98.dist-info/plux.json +1 -0
- localstack_core-4.7.1.dev96.dist-info/plux.json +0 -1
- {localstack_core-4.7.1.dev96.data → localstack_core-4.7.1.dev98.data}/scripts/localstack +0 -0
- {localstack_core-4.7.1.dev96.data → localstack_core-4.7.1.dev98.data}/scripts/localstack-supervisor +0 -0
- {localstack_core-4.7.1.dev96.data → localstack_core-4.7.1.dev98.data}/scripts/localstack.bat +0 -0
- {localstack_core-4.7.1.dev96.dist-info → localstack_core-4.7.1.dev98.dist-info}/WHEEL +0 -0
- {localstack_core-4.7.1.dev96.dist-info → localstack_core-4.7.1.dev98.dist-info}/entry_points.txt +0 -0
- {localstack_core-4.7.1.dev96.dist-info → localstack_core-4.7.1.dev98.dist-info}/licenses/LICENSE.txt +0 -0
- {localstack_core-4.7.1.dev96.dist-info → localstack_core-4.7.1.dev98.dist-info}/top_level.txt +0 -0
localstack/state/pickle.py
CHANGED
|
@@ -232,7 +232,7 @@ def s3_create_bucket(s3_empty_bucket, aws_client):
|
|
|
232
232
|
|
|
233
233
|
def factory(**kwargs) -> str:
|
|
234
234
|
if "Bucket" not in kwargs:
|
|
235
|
-
kwargs["Bucket"] = "test-bucket
|
|
235
|
+
kwargs["Bucket"] = f"test-bucket-{short_uid()}"
|
|
236
236
|
|
|
237
237
|
if (
|
|
238
238
|
"CreateBucketConfiguration" not in kwargs
|
|
@@ -335,7 +335,7 @@ def sqs_create_queue(aws_client):
|
|
|
335
335
|
|
|
336
336
|
def factory(**kwargs):
|
|
337
337
|
if "QueueName" not in kwargs:
|
|
338
|
-
kwargs["QueueName"] = "test-queue
|
|
338
|
+
kwargs["QueueName"] = f"test-queue-{short_uid()}"
|
|
339
339
|
|
|
340
340
|
response = aws_client.sqs.create_queue(**kwargs)
|
|
341
341
|
url = response["QueueUrl"]
|
|
@@ -503,7 +503,7 @@ def sns_create_topic(aws_client):
|
|
|
503
503
|
|
|
504
504
|
def _create_topic(**kwargs):
|
|
505
505
|
if "Name" not in kwargs:
|
|
506
|
-
kwargs["Name"] = "test-topic
|
|
506
|
+
kwargs["Name"] = f"test-topic-{short_uid()}"
|
|
507
507
|
response = aws_client.sns.create_topic(**kwargs)
|
|
508
508
|
topic_arns.append(response["TopicArn"])
|
|
509
509
|
return response
|
localstack/utils/aws/arns.py
CHANGED
|
@@ -120,7 +120,7 @@ def iam_role_arn(role_name: str, account_id: str, region_name: str) -> str:
|
|
|
120
120
|
return role_name
|
|
121
121
|
if re.match(f"{ARN_PARTITION_REGEX}:iam::", role_name):
|
|
122
122
|
return role_name
|
|
123
|
-
return "arn
|
|
123
|
+
return f"arn:{get_partition(region_name)}:iam::{account_id}:role/{role_name}"
|
|
124
124
|
|
|
125
125
|
|
|
126
126
|
def iam_resource_arn(resource: str, account_id: str, role: str = None) -> str:
|
|
@@ -180,13 +180,7 @@ def dynamodb_table_arn(table_name: str, account_id: str, region_name: str) -> st
|
|
|
180
180
|
def dynamodb_stream_arn(
|
|
181
181
|
table_name: str, latest_stream_label: str, account_id: str, region_name: str
|
|
182
182
|
) -> str:
|
|
183
|
-
return "arn
|
|
184
|
-
get_partition(region_name),
|
|
185
|
-
region_name,
|
|
186
|
-
account_id,
|
|
187
|
-
table_name,
|
|
188
|
-
latest_stream_label,
|
|
189
|
-
)
|
|
183
|
+
return f"arn:{get_partition(region_name)}:dynamodb:{region_name}:{account_id}:table/{table_name}/stream/{latest_stream_label}"
|
|
190
184
|
|
|
191
185
|
|
|
192
186
|
#
|
|
@@ -453,7 +447,7 @@ def s3_bucket_arn(bucket_name_or_arn: str, region="us-east-1") -> str:
|
|
|
453
447
|
|
|
454
448
|
def sqs_queue_arn(queue_name: str, account_id: str, region_name: str) -> str:
|
|
455
449
|
queue_name = queue_name.split("/")[-1]
|
|
456
|
-
return "arn
|
|
450
|
+
return f"arn:{get_partition(region_name)}:sqs:{region_name}:{account_id}:{queue_name}"
|
|
457
451
|
|
|
458
452
|
|
|
459
453
|
#
|
|
@@ -462,20 +456,13 @@ def sqs_queue_arn(queue_name: str, account_id: str, region_name: str) -> str:
|
|
|
462
456
|
|
|
463
457
|
|
|
464
458
|
def apigateway_restapi_arn(api_id: str, account_id: str, region_name: str) -> str:
|
|
465
|
-
return
|
|
466
|
-
get_partition(region_name)
|
|
467
|
-
region_name,
|
|
468
|
-
account_id,
|
|
469
|
-
api_id,
|
|
459
|
+
return (
|
|
460
|
+
f"arn:{get_partition(region_name)}:apigateway:{region_name}:{account_id}:/restapis/{api_id}"
|
|
470
461
|
)
|
|
471
462
|
|
|
472
463
|
|
|
473
464
|
def apigateway_invocations_arn(lambda_uri: str, region_name: str) -> str:
|
|
474
|
-
return "arn
|
|
475
|
-
get_partition(region_name),
|
|
476
|
-
region_name,
|
|
477
|
-
lambda_uri,
|
|
478
|
-
)
|
|
465
|
+
return f"arn:{get_partition(region_name)}:apigateway:{region_name}:lambda:path/2015-03-31/functions/{lambda_uri}/invocations"
|
|
479
466
|
|
|
480
467
|
|
|
481
468
|
#
|
|
@@ -555,7 +542,7 @@ def lambda_function_name(name_or_arn: str) -> str:
|
|
|
555
542
|
if ":" in name_or_arn:
|
|
556
543
|
arn = parse_arn(name_or_arn)
|
|
557
544
|
if arn["service"] != "lambda":
|
|
558
|
-
raise ValueError("arn is not a lambda arn
|
|
545
|
+
raise ValueError(f"arn is not a lambda arn {name_or_arn}")
|
|
559
546
|
|
|
560
547
|
return parse_arn(name_or_arn)["resource"].split(":")[1]
|
|
561
548
|
else:
|
|
@@ -42,7 +42,7 @@ def requests_error_response_xml(
|
|
|
42
42
|
xmlns: Optional[str] = None,
|
|
43
43
|
):
|
|
44
44
|
response = RequestsResponse()
|
|
45
|
-
xmlns = xmlns or "http
|
|
45
|
+
xmlns = xmlns or f"http://{service}.amazonaws.com/doc/2010-03-31/"
|
|
46
46
|
response._content = f"""<ErrorResponse xmlns="{xmlns}"><Error>
|
|
47
47
|
<Type>Sender</Type>
|
|
48
48
|
<Code>{code_string}</Code>
|
|
@@ -59,11 +59,7 @@ def _send_to_dead_letter_queue(source_arn: str, dlq_arn: str, event: dict, error
|
|
|
59
59
|
except Exception as e:
|
|
60
60
|
error = e
|
|
61
61
|
if error or not result_code or result_code >= 400:
|
|
62
|
-
msg = "Unable to send message to dead letter queue
|
|
63
|
-
queue_url,
|
|
64
|
-
result_code,
|
|
65
|
-
error,
|
|
66
|
-
)
|
|
62
|
+
msg = f"Unable to send message to dead letter queue {queue_url} (code {result_code}): {error}"
|
|
67
63
|
if "InvalidMessageContents" in str(error):
|
|
68
64
|
msg += f" - messages: {messages}"
|
|
69
65
|
LOG.info(msg)
|
|
@@ -86,7 +86,7 @@ def create_api_gateway(
|
|
|
86
86
|
resources = resources or []
|
|
87
87
|
stage_name = stage_name or "testing"
|
|
88
88
|
usage_plan_name = usage_plan_name or "Basic Usage"
|
|
89
|
-
description = description or 'Test description for API "
|
|
89
|
+
description = description or f'Test description for API "{name}"'
|
|
90
90
|
|
|
91
91
|
LOG.info('Creating API resources under API Gateway "%s".', name)
|
|
92
92
|
api = client.create_rest_api(name=name, description=description)
|
localstack/utils/bootstrap.py
CHANGED
|
@@ -427,7 +427,7 @@ def validate_localstack_config(name: str):
|
|
|
427
427
|
|
|
428
428
|
def port_exposed(port):
|
|
429
429
|
for exposed in docker_ports:
|
|
430
|
-
if re.match(
|
|
430
|
+
if re.match(rf"^([0-9]+-)?{port}(-[0-9]+)?$", exposed):
|
|
431
431
|
return True
|
|
432
432
|
|
|
433
433
|
if not port_exposed(edge_port):
|
|
@@ -455,7 +455,7 @@ def get_docker_image_to_start():
|
|
|
455
455
|
|
|
456
456
|
def extract_port_flags(user_flags, port_mappings: PortMappings):
|
|
457
457
|
regex = r"-p\s+([0-9]+)(\-([0-9]+))?:([0-9]+)(\-([0-9]+))?"
|
|
458
|
-
matches = re.match("
|
|
458
|
+
matches = re.match(f".*{regex}", user_flags)
|
|
459
459
|
if matches:
|
|
460
460
|
for match in re.findall(regex, user_flags):
|
|
461
461
|
start = int(match[0])
|
|
@@ -1115,7 +1115,7 @@ class LocalstackContainerServer(Server):
|
|
|
1115
1115
|
def do_run(self):
|
|
1116
1116
|
if self.is_container_running():
|
|
1117
1117
|
raise ContainerExists(
|
|
1118
|
-
'LocalStack container named "
|
|
1118
|
+
f'LocalStack container named "{self.container.name}" is already running'
|
|
1119
1119
|
)
|
|
1120
1120
|
|
|
1121
1121
|
config.dirs.mkdirs()
|
|
@@ -1156,7 +1156,7 @@ def prepare_docker_start():
|
|
|
1156
1156
|
container_name = config.MAIN_CONTAINER_NAME
|
|
1157
1157
|
|
|
1158
1158
|
if DOCKER_CLIENT.is_container_running(container_name):
|
|
1159
|
-
raise ContainerExists('LocalStack container named "
|
|
1159
|
+
raise ContainerExists(f'LocalStack container named "{container_name}" is already running')
|
|
1160
1160
|
|
|
1161
1161
|
config.dirs.mkdirs()
|
|
1162
1162
|
|
|
@@ -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,7 +262,7 @@ 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
268
|
def remove_container(self, container_name: str, force=True, check_existence=False) -> None:
|
|
@@ -282,7 +282,7 @@ class CmdDockerClient(ContainerClient):
|
|
|
282
282
|
if not force:
|
|
283
283
|
self._check_and_raise_no_such_container_error(container_name, error=e)
|
|
284
284
|
raise ContainerException(
|
|
285
|
-
"Docker process returned with errorcode
|
|
285
|
+
f"Docker process returned with errorcode {e.returncode}", e.stdout, e.stderr
|
|
286
286
|
) from e
|
|
287
287
|
|
|
288
288
|
def list_containers(self, filter: Union[list[str], str, None] = None, all=True) -> list[dict]:
|
|
@@ -301,7 +301,7 @@ class CmdDockerClient(ContainerClient):
|
|
|
301
301
|
cmd_result = run(cmd).strip()
|
|
302
302
|
except subprocess.CalledProcessError as e:
|
|
303
303
|
raise ContainerException(
|
|
304
|
-
"Docker process returned with errorcode
|
|
304
|
+
f"Docker process returned with errorcode {e.returncode}", e.stdout, e.stderr
|
|
305
305
|
) from e
|
|
306
306
|
container_list = []
|
|
307
307
|
if cmd_result:
|
|
@@ -355,7 +355,7 @@ class CmdDockerClient(ContainerClient):
|
|
|
355
355
|
if re.match(".*container .+ does not exist", to_str(e.stdout)):
|
|
356
356
|
raise NoSuchContainer(container_name, stdout=e.stdout, stderr=e.stderr)
|
|
357
357
|
raise ContainerException(
|
|
358
|
-
"Docker process returned with errorcode
|
|
358
|
+
f"Docker process returned with errorcode {e.returncode}", e.stdout, e.stderr
|
|
359
359
|
) from e
|
|
360
360
|
|
|
361
361
|
def pull_image(
|
|
@@ -384,7 +384,7 @@ class CmdDockerClient(ContainerClient):
|
|
|
384
384
|
if "Trying to pull" in stdout_str and "access to the resource is denied" in stdout_str:
|
|
385
385
|
raise NoSuchImage(docker_image, stdout=e.stdout, stderr=e.stderr)
|
|
386
386
|
raise ContainerException(
|
|
387
|
-
"Docker process returned with errorcode
|
|
387
|
+
f"Docker process returned with errorcode {e.returncode}", e.stdout, e.stderr
|
|
388
388
|
) from e
|
|
389
389
|
|
|
390
390
|
def push_image(self, docker_image: str) -> None:
|
|
@@ -478,7 +478,7 @@ class CmdDockerClient(ContainerClient):
|
|
|
478
478
|
return ""
|
|
479
479
|
self._check_and_raise_no_such_container_error(container_name_or_id, error=e)
|
|
480
480
|
raise ContainerException(
|
|
481
|
-
"Docker process returned with errorcode
|
|
481
|
+
f"Docker process returned with errorcode {e.returncode}", e.stdout, e.stderr
|
|
482
482
|
) from e
|
|
483
483
|
|
|
484
484
|
def stream_container_logs(self, container_name_or_id: str) -> CancellableStream:
|
|
@@ -503,7 +503,7 @@ class CmdDockerClient(ContainerClient):
|
|
|
503
503
|
if "no such object" in to_str(e.stdout).lower():
|
|
504
504
|
raise NoSuchObject(object_name_or_id, stdout=e.stdout, stderr=e.stderr)
|
|
505
505
|
raise ContainerException(
|
|
506
|
-
"Docker process returned with errorcode
|
|
506
|
+
f"Docker process returned with errorcode {e.returncode}", e.stdout, e.stderr
|
|
507
507
|
) from e
|
|
508
508
|
object_data = json.loads(cmd_result.strip())
|
|
509
509
|
if isinstance(object_data, list):
|
|
@@ -556,7 +556,7 @@ class CmdDockerClient(ContainerClient):
|
|
|
556
556
|
return run(cmd).strip()
|
|
557
557
|
except subprocess.CalledProcessError as e:
|
|
558
558
|
raise ContainerException(
|
|
559
|
-
"Docker process returned with errorcode
|
|
559
|
+
f"Docker process returned with errorcode {e.returncode}", e.stdout, e.stderr
|
|
560
560
|
) from e
|
|
561
561
|
|
|
562
562
|
def delete_network(self, network_name: str) -> None:
|
|
@@ -570,7 +570,7 @@ class CmdDockerClient(ContainerClient):
|
|
|
570
570
|
raise NoSuchNetwork(network_name=network_name)
|
|
571
571
|
else:
|
|
572
572
|
raise ContainerException(
|
|
573
|
-
"Docker process returned with errorcode
|
|
573
|
+
f"Docker process returned with errorcode {e.returncode}", e.stdout, e.stderr
|
|
574
574
|
) from e
|
|
575
575
|
|
|
576
576
|
def inspect_network(self, network_name: str) -> dict[str, Union[dict, str]]:
|
|
@@ -607,7 +607,7 @@ class CmdDockerClient(ContainerClient):
|
|
|
607
607
|
raise NoSuchNetwork(network_name=network_name)
|
|
608
608
|
self._check_and_raise_no_such_container_error(container_name_or_id, error=e)
|
|
609
609
|
raise ContainerException(
|
|
610
|
-
"Docker process returned with errorcode
|
|
610
|
+
f"Docker process returned with errorcode {e.returncode}", e.stdout, e.stderr
|
|
611
611
|
) from e
|
|
612
612
|
|
|
613
613
|
def disconnect_container_from_network(
|
|
@@ -625,7 +625,7 @@ class CmdDockerClient(ContainerClient):
|
|
|
625
625
|
raise NoSuchNetwork(network_name=network_name)
|
|
626
626
|
self._check_and_raise_no_such_container_error(container_name_or_id, error=e)
|
|
627
627
|
raise ContainerException(
|
|
628
|
-
"Docker process returned with errorcode
|
|
628
|
+
f"Docker process returned with errorcode {e.returncode}", e.stdout, e.stderr
|
|
629
629
|
) from e
|
|
630
630
|
|
|
631
631
|
def get_container_ip(self, container_name_or_id: str) -> str:
|
|
@@ -645,7 +645,7 @@ class CmdDockerClient(ContainerClient):
|
|
|
645
645
|
if "no such object" in to_str(e.stdout).lower():
|
|
646
646
|
raise NoSuchContainer(container_name_or_id, stdout=e.stdout, stderr=e.stderr)
|
|
647
647
|
raise ContainerException(
|
|
648
|
-
"Docker process returned with errorcode
|
|
648
|
+
f"Docker process returned with errorcode {e.returncode}", e.stdout, e.stderr
|
|
649
649
|
) from e
|
|
650
650
|
|
|
651
651
|
def login(self, username: str, password: str, registry: Optional[str] = None) -> None:
|
|
@@ -658,7 +658,7 @@ class CmdDockerClient(ContainerClient):
|
|
|
658
658
|
run(cmd)
|
|
659
659
|
except subprocess.CalledProcessError as e:
|
|
660
660
|
raise ContainerException(
|
|
661
|
-
"Docker process returned with errorcode
|
|
661
|
+
f"Docker process returned with errorcode {e.returncode}", e.stdout, e.stderr
|
|
662
662
|
) from e
|
|
663
663
|
|
|
664
664
|
@functools.cache
|
|
@@ -684,7 +684,7 @@ class CmdDockerClient(ContainerClient):
|
|
|
684
684
|
if any(msg in to_str(e.stdout) for msg in error_messages):
|
|
685
685
|
raise NoSuchImage(image_name, stdout=e.stdout, stderr=e.stderr)
|
|
686
686
|
raise ContainerException(
|
|
687
|
-
"Docker process returned with errorcode
|
|
687
|
+
f"Docker process returned with errorcode {e.returncode}", e.stdout, e.stderr
|
|
688
688
|
) from e
|
|
689
689
|
finally:
|
|
690
690
|
Util.rm_env_vars_file(env_file)
|
|
@@ -791,7 +791,7 @@ class CmdDockerClient(ContainerClient):
|
|
|
791
791
|
if any(msg.lower() in to_str(e.stderr).lower() for msg in error_messages):
|
|
792
792
|
raise NoSuchContainer(container_name, stdout=e.stdout, stderr=e.stderr)
|
|
793
793
|
raise ContainerException(
|
|
794
|
-
"Docker process returned with errorcode
|
|
794
|
+
f"Docker process returned with errorcode {e.returncode}", e.stdout, e.stderr
|
|
795
795
|
) from e
|
|
796
796
|
|
|
797
797
|
def _build_run_create_cmd(
|
localstack/utils/crypto.py
CHANGED
|
@@ -43,8 +43,8 @@ def generate_ssl_cert(
|
|
|
43
43
|
return all(os.path.exists(f) for f in files)
|
|
44
44
|
|
|
45
45
|
def store_cert_key_files(base_filename):
|
|
46
|
-
key_file_name = "
|
|
47
|
-
cert_file_name = "
|
|
46
|
+
key_file_name = f"{base_filename}.key"
|
|
47
|
+
cert_file_name = f"{base_filename}.crt"
|
|
48
48
|
# TODO: Cleaner code to load the cert dynamically
|
|
49
49
|
# extract key and cert from target_file and store into separate files
|
|
50
50
|
content = load_file(target_file)
|
|
@@ -74,9 +74,9 @@ def generate_ssl_cert(
|
|
|
74
74
|
return target_file, cert_file_name, key_file_name
|
|
75
75
|
if random and target_file:
|
|
76
76
|
if "." in target_file:
|
|
77
|
-
target_file = target_file.replace(".", "
|
|
77
|
+
target_file = target_file.replace(".", f".{short_uid()}.", 1)
|
|
78
78
|
else:
|
|
79
|
-
target_file = "
|
|
79
|
+
target_file = f"{target_file}.{short_uid()}"
|
|
80
80
|
|
|
81
81
|
# create a key pair
|
|
82
82
|
k = crypto.PKey()
|
|
@@ -123,10 +123,10 @@ def generate_ssl_cert(
|
|
|
123
123
|
key_file.write(to_str(crypto.dump_privatekey(crypto.FILETYPE_PEM, k)))
|
|
124
124
|
cert_file_content = cert_file.getvalue().strip()
|
|
125
125
|
key_file_content = key_file.getvalue().strip()
|
|
126
|
-
file_content = "
|
|
126
|
+
file_content = f"{key_file_content}\n{cert_file_content}"
|
|
127
127
|
if target_file:
|
|
128
|
-
key_file_name = "
|
|
129
|
-
cert_file_name = "
|
|
128
|
+
key_file_name = f"{target_file}.key"
|
|
129
|
+
cert_file_name = f"{target_file}.crt"
|
|
130
130
|
# check existence to avoid permission denied issues:
|
|
131
131
|
# https://github.com/localstack/localstack/issues/1607
|
|
132
132
|
if not all_exist(target_file, key_file_name, cert_file_name):
|
|
@@ -145,9 +145,9 @@ def generate_ssl_cert(
|
|
|
145
145
|
e,
|
|
146
146
|
)
|
|
147
147
|
# Fix for https://github.com/localstack/localstack/issues/1743
|
|
148
|
-
target_file = "
|
|
149
|
-
key_file_name = "
|
|
150
|
-
cert_file_name = "
|
|
148
|
+
target_file = f"{new_tmp_file()}.pem"
|
|
149
|
+
key_file_name = f"{target_file}.key"
|
|
150
|
+
cert_file_name = f"{target_file}.crt"
|
|
151
151
|
TMP_FILES.append(target_file)
|
|
152
152
|
TMP_FILES.append(key_file_name)
|
|
153
153
|
TMP_FILES.append(cert_file_name)
|
localstack/utils/diagnose.py
CHANGED
|
@@ -134,7 +134,7 @@ def traverse_file_tree(root: str) -> list[str]:
|
|
|
134
134
|
result.append(dirpath)
|
|
135
135
|
return result
|
|
136
136
|
except Exception as e:
|
|
137
|
-
return ["traversing files failed
|
|
137
|
+
return [f"traversing files failed {e}"]
|
|
138
138
|
|
|
139
139
|
|
|
140
140
|
def get_docker_image_details() -> dict[str, str]:
|
localstack/utils/files.py
CHANGED
|
@@ -201,7 +201,7 @@ def rm_rf(path: str):
|
|
|
201
201
|
# Running the native command can be an order of magnitude faster in Alpine on Travis-CI
|
|
202
202
|
if is_debian():
|
|
203
203
|
try:
|
|
204
|
-
return run('rm -rf "
|
|
204
|
+
return run(f'rm -rf "{path}"')
|
|
205
205
|
except Exception:
|
|
206
206
|
pass
|
|
207
207
|
# Make sure all files are writeable and dirs executable to remove
|
|
@@ -247,11 +247,7 @@ def cp_r(src: str, dst: str, rm_dest_on_conflict=False, ignore_copystat_errors=F
|
|
|
247
247
|
except Exception as e:
|
|
248
248
|
|
|
249
249
|
def _info(_path):
|
|
250
|
-
return "
|
|
251
|
-
_path,
|
|
252
|
-
os.path.isfile(_path),
|
|
253
|
-
os.path.islink(_path),
|
|
254
|
-
)
|
|
250
|
+
return f"{_path} (file={os.path.isfile(_path)}, symlink={os.path.islink(_path)})"
|
|
255
251
|
|
|
256
252
|
LOG.debug("Error copying files from %s to %s: %s", _info(src), _info(dst), e)
|
|
257
253
|
raise
|
localstack/utils/functions.py
CHANGED
|
@@ -32,7 +32,7 @@ def call_safe(
|
|
|
32
32
|
:return: whatever the func returns
|
|
33
33
|
"""
|
|
34
34
|
if exception_message is None:
|
|
35
|
-
exception_message = "error calling function
|
|
35
|
+
exception_message = f"error calling function {func.__name__}"
|
|
36
36
|
if args is None:
|
|
37
37
|
args = ()
|
|
38
38
|
if kwargs is None:
|
localstack/utils/http.py
CHANGED
|
@@ -43,12 +43,12 @@ def create_chunked_data(data, chunk_size: int = 80):
|
|
|
43
43
|
dl = len(data)
|
|
44
44
|
ret = ""
|
|
45
45
|
for i in range(dl // chunk_size):
|
|
46
|
-
ret += "
|
|
47
|
-
ret += "
|
|
46
|
+
ret += f"{hex(chunk_size)[2:]}\r\n"
|
|
47
|
+
ret += f"{data[i * chunk_size : (i + 1) * chunk_size]}\r\n\r\n"
|
|
48
48
|
|
|
49
49
|
if len(data) % chunk_size != 0:
|
|
50
|
-
ret += "
|
|
51
|
-
ret += "
|
|
50
|
+
ret += f"{hex(len(data) % chunk_size)[2:]}\r\n"
|
|
51
|
+
ret += f"{data[-(len(data) % chunk_size) :]}\r\n"
|
|
52
52
|
|
|
53
53
|
ret += "0\r\n\r\n"
|
|
54
54
|
return ret
|
|
@@ -202,7 +202,7 @@ def download(
|
|
|
202
202
|
r = s.get(url, stream=True, verify=_verify, timeout=timeout, headers=request_headers)
|
|
203
203
|
# check status code before attempting to read body
|
|
204
204
|
if not r.ok:
|
|
205
|
-
raise Exception("Failed to download
|
|
205
|
+
raise Exception(f"Failed to download {url}, response code {r.status_code}")
|
|
206
206
|
|
|
207
207
|
total_size = 0
|
|
208
208
|
if r.headers.get("Content-Length"):
|
localstack/utils/net.py
CHANGED
|
@@ -164,8 +164,9 @@ def wait_for_port_status(
|
|
|
164
164
|
status = is_port_open(port, http_path=http_path, expect_success=expect_success)
|
|
165
165
|
if bool(status) != (not expect_closed):
|
|
166
166
|
raise Exception(
|
|
167
|
-
"Port
|
|
168
|
-
|
|
167
|
+
"Port {} (path: {}) was not {}".format(
|
|
168
|
+
port, http_path, "closed" if expect_closed else "open"
|
|
169
|
+
)
|
|
169
170
|
)
|
|
170
171
|
|
|
171
172
|
return retry(check, sleep=sleep_time, retries=retries)
|
localstack/utils/objects.py
CHANGED
|
@@ -163,7 +163,7 @@ def keys_to(
|
|
|
163
163
|
skip_children_of = ensure_list(skip_children_of or [])
|
|
164
164
|
|
|
165
165
|
def fix_keys(o, path="", **kwargs):
|
|
166
|
-
if any(re.match(
|
|
166
|
+
if any(re.match(rf"(^|.*\.){k}($|[.\[].*)", path) for k in skip_children_of):
|
|
167
167
|
return o
|
|
168
168
|
if isinstance(o, dict):
|
|
169
169
|
for k, v in dict(o).items():
|
localstack/utils/run.py
CHANGED
|
@@ -114,7 +114,7 @@ def run(
|
|
|
114
114
|
return process
|
|
115
115
|
except subprocess.CalledProcessError as e:
|
|
116
116
|
if print_error:
|
|
117
|
-
print("ERROR: '
|
|
117
|
+
print(f"ERROR: '{cmd}': exit code {e.returncode}; output: {e.output}")
|
|
118
118
|
sys.stdout.flush()
|
|
119
119
|
raise e
|
|
120
120
|
|
|
@@ -268,7 +268,7 @@ class ShellCommandThread(FuncThread):
|
|
|
268
268
|
if self.strip_color:
|
|
269
269
|
# strip color codes
|
|
270
270
|
line = re.sub(r"\x1b(\[.*?[@-~]|\].*?(\x07|\x1b\\))", "", line)
|
|
271
|
-
return "
|
|
271
|
+
return f"{line.strip()}\r\n"
|
|
272
272
|
|
|
273
273
|
def filter_line(line):
|
|
274
274
|
"""Return True if this line should be filtered, i.e., not printed"""
|
localstack/utils/serving.py
CHANGED
localstack/utils/strings.py
CHANGED
|
@@ -42,7 +42,7 @@ def to_bytes(obj: Union[str, bytes], encoding: str = DEFAULT_ENCODING, errors="s
|
|
|
42
42
|
|
|
43
43
|
def truncate(data: str, max_length: int = 100) -> str:
|
|
44
44
|
data = str(data or "")
|
|
45
|
-
return ("
|
|
45
|
+
return (f"{data[:max_length]}...") if len(data) > max_length else data
|
|
46
46
|
|
|
47
47
|
|
|
48
48
|
def is_string(s, include_unicode=True, exclude_binary=False):
|
|
@@ -104,11 +104,11 @@ def convert_to_printable_chars(value: Union[list, dict, str]) -> str:
|
|
|
104
104
|
|
|
105
105
|
|
|
106
106
|
def first_char_to_lower(s: str) -> str:
|
|
107
|
-
return s and "
|
|
107
|
+
return s and f"{s[0].lower()}{s[1:]}"
|
|
108
108
|
|
|
109
109
|
|
|
110
110
|
def first_char_to_upper(s: str) -> str:
|
|
111
|
-
return s and "
|
|
111
|
+
return s and f"{s[0].upper()}{s[1:]}"
|
|
112
112
|
|
|
113
113
|
|
|
114
114
|
def str_to_bool(value):
|
|
@@ -121,13 +121,13 @@ def str_to_bool(value):
|
|
|
121
121
|
|
|
122
122
|
def str_insert(string, index, content):
|
|
123
123
|
"""Insert a substring into an existing string at a certain index."""
|
|
124
|
-
return "
|
|
124
|
+
return f"{string[:index]}{content}{string[index:]}"
|
|
125
125
|
|
|
126
126
|
|
|
127
127
|
def str_remove(string, index, end_index=None):
|
|
128
128
|
"""Remove a substring from an existing string at a certain from-to index range."""
|
|
129
129
|
end_index = end_index or (index + 1)
|
|
130
|
-
return "
|
|
130
|
+
return f"{string[:index]}{string[end_index:]}"
|
|
131
131
|
|
|
132
132
|
|
|
133
133
|
def str_startswith_ignore_case(value: str, prefix: str) -> bool:
|
localstack/utils/testutil.py
CHANGED
|
@@ -94,7 +94,7 @@ def create_lambda_archive(
|
|
|
94
94
|
chmod_r(script_file, 0o777)
|
|
95
95
|
# copy libs
|
|
96
96
|
for lib in libs:
|
|
97
|
-
paths = [lib, "
|
|
97
|
+
paths = [lib, f"{lib}.py"]
|
|
98
98
|
try:
|
|
99
99
|
module = importlib.import_module(lib)
|
|
100
100
|
paths.append(module.__file__)
|
|
@@ -382,7 +382,7 @@ def assert_object(expected_object, all_objects):
|
|
|
382
382
|
all_objects = [all_objects]
|
|
383
383
|
found = find_object(expected_object, all_objects)
|
|
384
384
|
if not found:
|
|
385
|
-
raise Exception("Expected object not found:
|
|
385
|
+
raise Exception(f"Expected object not found: {expected_object} in list {all_objects}")
|
|
386
386
|
|
|
387
387
|
|
|
388
388
|
def find_object(expected_object, object_list):
|
|
@@ -522,8 +522,7 @@ def check_expected_lambda_log_events_length(
|
|
|
522
522
|
events = [line for line in events if line not in ["\x1b[0m", "\\x1b[0m"]]
|
|
523
523
|
if len(events) != expected_length:
|
|
524
524
|
print(
|
|
525
|
-
"Invalid # of Lambda
|
|
526
|
-
% (
|
|
525
|
+
"Invalid # of Lambda {} log events: {} / {}: {}".format(
|
|
527
526
|
function_name,
|
|
528
527
|
len(events),
|
|
529
528
|
expected_length,
|
localstack/utils/time.py
CHANGED
|
@@ -52,7 +52,7 @@ def parse_timestamp(ts_str: str) -> datetime:
|
|
|
52
52
|
return datetime.strptime(ts_str, ts_format)
|
|
53
53
|
except ValueError:
|
|
54
54
|
pass
|
|
55
|
-
raise Exception("Unable to parse timestamp string with any known formats:
|
|
55
|
+
raise Exception(f"Unable to parse timestamp string with any known formats: {ts_str}")
|
|
56
56
|
|
|
57
57
|
|
|
58
58
|
def now(millis: bool = False, tz: Optional[tzinfo] = None) -> int:
|
localstack/utils/xray/traceid.py
CHANGED
localstack/version.py
CHANGED
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '4.7.1.
|
|
32
|
-
__version_tuple__ = version_tuple = (4, 7, 1, '
|
|
31
|
+
__version__ = version = '4.7.1.dev98'
|
|
32
|
+
__version_tuple__ = version_tuple = (4, 7, 1, 'dev98')
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|