AWS Digest在标记时总是更改

发布于 2025-01-31 17:30:34 字数 601 浏览 4 评论 0原文

我目前正在创建一个Python脚本,以便使用AWS CLI创建一个适合AWS ECR的适配器。 我有一个登台环境,版本1.0.0中具有版本的测试容器。 现在,我尝试使用以下控件流进行重新序列:

  • 保存版本的容器的清单。 - 输出文本(AWS CLI的JSON输出是错误的,无法以可靠的方式解析)
  • 删除旧的“最新”标签:aws aws ecr ecr batch-delete-image-reposority-name登台/测试-Image-IDS Imagetag =最新
  • 使用图像摘要和清单JSON重新标记图像:aws aws ecr put-image -repository-name staging/test/test-image-image-标签最新的-Image-Manifest文件://manifest.json - Image-Digest SHA256:Foobar

问题:ECR引发了一个例外,描述了图像摘要确实有所不同。但是没有“最新”图像 - 它没有标记。因此,我试图将图像标记为不存在的版本“ 2.0.0”,一次没有消化。 ECR标记图像并计算新的图像摘要 - 这似乎是核心问题。有道理 - 它没有任何作用。

I'm currently creating a python script in order to create an adapter to AWS ECR using AWS CLI.
I have a staging environment with a versioned test container in version 1.0.0.
Now I try to retag it using the following control flow:

  • Save the manifest.json of the versioned container: aws ecr batch-get-image --repository-name staging/test --image-ids imageTag=1.0.0 --output text (the json output of the aws cli is buggy and cannot be parsed in a robust way)
  • Delete the old "latest" tag: aws ecr batch-delete-image --repository-name staging/test --image-ids imageTag=latest
  • Use the image digest and the manifest json to re-tag the image: aws ecr put-image --repository-name staging/test --image-tag latest --image-manifest file://manifest.json --image-digest sha256:foobar

The problem: The ECR throws an exception describing that the image digest does differ. But there is no 'latest' image - it was untagged. So I tried to tag the image to a non-existing version '2.0.0' and one time without the digest. The ECR tags the image and calculates a new image digest - which seems to be the core problem. Sense - it does not make any.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

你如我软肋 2025-02-07 17:30:34

因此,事实证明,图像的图像摘要是其清单的SHA256消化。

这就解释了为什么清单JSON文件中的不同空格会导致不同的消化。

一个奇怪的结果是,虽然aws ecr ecr batch-get-get-image返回的清单 - Query'images [0] .ImageManifest'正是您需要的文档,但将其管道输送到文件很容易添加最终的newline字符,以修改清单摘要。

一种解决方案是将最后一个字符与head -c -1进行修剪。

aws ecr batch-get-image --repository-name staging/test --image-ids imageTag=1.0.0 --output=text --query 'images[0].imageManifest' | head -c -1 > manifest.json

aws ecr put-image --repository-name staging/test --image-tag latest --image-manifest file://manifest.json --image-digest sha256:foobar

So, it turns out the image digest of an image is the sha256 digest of its manifest.

This explains why different whitespace in the manifest JSON file leads to different digests.

A strange consequence is that, while the manifest returned by aws ecr batch-get-image --query 'images[0].imageManifest' is exactly the document you need, piping it to a file will easily add a final newline character that modifies the manifest digest.

A solution is to trim that last character with head -c -1

aws ecr batch-get-image --repository-name staging/test --image-ids imageTag=1.0.0 --output=text --query 'images[0].imageManifest' | head -c -1 > manifest.json

aws ecr put-image --repository-name staging/test --image-tag latest --image-manifest file://manifest.json --image-digest sha256:foobar
征﹌骨岁月お 2025-02-07 17:30:34

在联系AWS支持后,一旦您使用CLI的纯文本输出,JSON似乎会发生变化。如果您使用“ JQ”提供了AWS解决方案,则一切正常。其他方法将改变空格,而ECR将计算出不同的消化。

最后,似乎很奇怪,清单的内容与带有空格的苦恼的JSON语法一样重要。

After contacting the AWS support it seems that the json changes once you use plain text output of the cli. If you use the "jq" provided solution of AWS, everything works fine. Other ways will alter the whitespaces and the the ECR will calculate a different digest.

In the end it seems odd, that the content of the manifest is as important as the sorrounding json syntax with whitespaces.

凡间太子 2025-02-07 17:30:34

我修复了此问题(对以下python代码感到非常沮丧之后):

    # read exact "manifest" of src_tag to be duplicated
    _, img_data = run_cmd(
        f"aws ecr batch-get-image --repository-name {repo_name} --image-ids imageTag={src_tag} --output json --region {AWS_CONF['region']} --profile {AWS_CONF['profile']}",
    )
    img_data = json.loads(img_data)
    manifest_str = img_data["images"][0]["imageManifest"]

    # retag image (using boto3 instead of CLI to ensure the exact manifest string is passed in)
    import boto3

    ecr_client = boto3.client("ecr", region_name=AWS_CONF["region"])
    response = ecr_client.put_image(
        registryId=registry_id,
        repositoryName=repo_name,
        imageManifest=manifest_str,
        imageManifestMediaType="string",
        imageTag=dest_tag,
    )
    if response["ResponseMetadata"]["HTTPStatusCode"] != 200:
        print(f"ERROR: failed to retag image! (status code 200)")

请注意,run_cmd()是一个自定义功能,可调用子程序并将输出返回为字符串。请注意,阅读SRC_TAG的清单几乎可以肯定可以使用BOTO3 API来完成,但我选择不进一步重构代码。

对我来说,我无法将其与aws ecr batch-get-get-image一起使用,因为清单字符串总是会稍微更改。该解决方案可确保使用SRC_TAG完全相同的清单字符串(避免通过将其解析为JSON等间接修改它)。

I fixed this (after much frustration with the following python code):

    # read exact "manifest" of src_tag to be duplicated
    _, img_data = run_cmd(
        f"aws ecr batch-get-image --repository-name {repo_name} --image-ids imageTag={src_tag} --output json --region {AWS_CONF['region']} --profile {AWS_CONF['profile']}",
    )
    img_data = json.loads(img_data)
    manifest_str = img_data["images"][0]["imageManifest"]

    # retag image (using boto3 instead of CLI to ensure the exact manifest string is passed in)
    import boto3

    ecr_client = boto3.client("ecr", region_name=AWS_CONF["region"])
    response = ecr_client.put_image(
        registryId=registry_id,
        repositoryName=repo_name,
        imageManifest=manifest_str,
        imageManifestMediaType="string",
        imageTag=dest_tag,
    )
    if response["ResponseMetadata"]["HTTPStatusCode"] != 200:
        print(f"ERROR: failed to retag image! (status code 200)")

Note that run_cmd() is a custom function that calls a subprocess and returns the output as a string. Note that reading the manifest of the src_tag could almost certainly be done with the boto3 API instead but I chose not to refactor my code further.

For me I was unable to get this to work with aws ecr batch-get-image because the manifest string would always slightly change. This solution ensures the exact same manifest string as the src_tag is used (avoiding modifying it indirectly by parsing it as json etc).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文