-
Notifications
You must be signed in to change notification settings - Fork 3.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(ecr-assets): fix loading image tarballs with existing tags #18823
fix(ecr-assets): fix loading image tarballs with existing tags #18823
Conversation
The current logic for pushing tarball images fails if the tarball being loaded uses a repository and tag that's already loaded into the docker daemon. This is due to the way the ecr-assets module parses the output of the docker load command. If the repository/tag combination already exists in the daemon, it outputs a message about renaming it, which breaks the `sed` command parsing its output. This change updates the `sed` command used for extracting the repository/tag for tarball images to make it more robust and will now successfully parse docker load output in the case where the repository/tag already exist. fixes aws#18822
Title does not follow the guidelines of Conventional Commits. Please adjust title before merge. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for opening this PR, @AndrewGuenther! Do you have any ideas on how to test this a bit more thoroughly?
So the tarball asset code isn't really tested much at all. The test I updated is the only one currently in place. We could add an integration test which specifically tests tarball loading, but the specific case covered here would require an image to already be loaded in the Docker daemon. I'm not sure what the best way to go about that is. Make a subprocess call during test setup? I'd be happy to improve the overall test coverage of tarball functionality in a separate PR. The CDK testing setup is pretty complex and I've had major issues running it locally (sorry for all the failed CI revisions). So it would be a bit before I could really put my head down and improve that. I'd appreciate if we could land this seeing as it updates the existing tests and consider the general coverage improvements separately. |
@madeline-k Can we get this landed? It's a pretty small change and would help remove a lot of workaround cruft for my org. |
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
@@ -78,7 +78,7 @@ export class TarballImageAsset extends CoreConstruct implements IAsset { | |||
executable: [ | |||
'sh', | |||
'-c', | |||
`docker load -i ${relativePathInOutDir} | sed "s/Loaded image: //g"`, | |||
`docker load -i ${relativePathInOutDir} | sed -nr 's/^Loaded image: (.*)$/\\1/p'`, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code will not work on MacOS, as -r
is not a valid flag for sed
on that platform.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you also exercise TarballImageAsset
in the integ test integ.assets-docker.ts (and then run it to update the snapshot)?
Thanks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well that's a bit of a piss off...hmmmm. I'll work on figuring our an alternative. Technically what's really needed is to strip out any following lines. It isn't my ideal, but we could pipe this into head
which should work better cross platform...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rix0rrr For a test like that to work, I would need to communicate with the docker daemon directly in order to replicate the issue being fixed here. Is there an existing precedent for running shell commands in integ tests? I had pushed back earlier when @madeline-k suggested this as I don't think that this PR is the right place to backfill testing for a completely untested class.
This PR has been in the CHANGES REQUESTED state for 3 weeks, and looks abandoned. To keep this PR from being closed, please continue work on it. If not, it will automatically be closed in a week. |
Will leaving a comment keep this open if I'm waiting on follow-up comments from reviewers? A bit frustrating that it takes so long to get a question answered that a bot will close my PR... |
This PR has been deemed to be abandoned, and will be automatically closed. Please create a new PR for these changes if you think this decision has been made in error. |
Are you serious? |
@AndrewGuenther apologies, our bots can be a little ham-fisted sometimes 🙂. @rix0rrr can you reply to Andrew's comment in #18823 (comment)? |
Thanks @skinny85! |
This PR has been deemed to be abandoned, and will be automatically closed. Please create a new PR for these changes if you think this decision has been made in error. |
The current implementation fails because it assumes the output of `docker load` can only be ``` Loaded Image: {image} ``` However, if docker has to take any actions (such as untagging a previous image) the output will look like ``` {error message} {error message} Loaded Image: {image} ``` To fix this, we can simply take the last line of the output via `tail` before we attempt to extract the image. If the last line isn't of the correct form, this will fail in an effectively equivalent way to how it failed previously. A previous attempt at fixing this (aws#18823) used a more complicated `sed` command which used a cli flag that is not consistently available. This approach won't work on all platforms (ex. macos) and is also much less clear that it's correct. This change also adds an integration test. We vendor the tarball of the `hello-world` docker image, which results in ~10kb of additional data in the repo. This about as small as we can get a vendored image with as straightforward a vendoring process. fixes aws#18822
`docker load` can only be ``` Loaded Image: {image} ``` However, if docker has to take any actions (such as untagging a previous image) the output will look like ``` {error message} {error message} Loaded Image: {image} ``` To fix this, we can simply take the last line of the output via `tail` before we attempt to extract the image. If the last line isn't of the correct form, this will fail in an effectively equivalent way to how it failed previously. A previous attempt at fixing this (aws#18823) used a more complicated `sed` command which used a cli flag that is not consistently available. This approach won't work on all platforms (ex. macos) and is also much less clear that it's correct. This change also adds an integration test that tests the tarbell stack, though it doesn't test the repeated deploy automatically. I have tested that by running the integration test multiple times with an image modification in between. We also vendor the tarball of the hello-world docker image, which results in ~10kb of additional data in the repo. This is about as small as we can get a vendored image with as straightforward a vendoring process. fixes aws#18822
The current implementation fails because it assumes the output of `docker load` can only be ``` Loaded Image: {image} ``` However, if docker has to take any actions (such as untagging a previous image) the output will look like ``` {error message} {error message} Loaded Image: {image} ``` To fix this, we can simply take the last line of the output via `tail` before we attempt to extract the image. If the last line isn't of the correct form, this will fail in an effectively equivalent way to how it failed previously. A previous attempt at fixing this (aws#18823) used a more complicated `sed` command which used a cli flag that is not consistently available. This approach won't work on all platforms (ex. macos) and is also much less clear that it's correct. This change also adds an integration test that tests the tarbell stack, though it doesn't test the repeated deploy automatically. I have tested that by running the integration test multiple times with an image modification in between. We also vendor the tarball of the hello-world docker image, which results in ~10kb of additional data in the repo. This is about as small as we can get a vendored image with as straightforward a vendoring process. fixes aws#18822
The current implementation fails because it assumes the output of `docker load` can only be ``` Loaded Image: {image} ``` However, if docker has to take any actions (such as untagging a previous image) the output will look like ``` {error message} {error message} Loaded Image: {image} ``` To fix this, we can simply take the last line of the output via `tail` before we attempt to extract the image. If the last line isn't of the correct form, this will fail in an effectively equivalent way to how it failed previously. A previous attempt at fixing this (aws#18823) used a more complicated `sed` command which used a cli flag that is not consistently available. This approach won't work on all platforms (ex. macos) and is also much less clear that it's correct. This change also adds an integration test that tests the tarbell stack, though it doesn't test the repeated deploy automatically. I have tested that by running the integration test multiple times with an image modification in between. We also vendor the tarball of the hello-world docker image, which results in ~10kb of additional data in the repo. This is about as small as we can get a vendored image with as straightforward a vendoring process. fixes aws#18822
The current implementation fails because it assumes the output of `docker load` can only be ``` Loaded Image: {image} ``` However, if docker has to take any actions (such as untagging a previous image) the output will look like ``` {error message} {error message} Loaded Image: {image} ``` To fix this, we can simply take the last line of the output via `tail` before we attempt to extract the image. If the last line isn't of the correct form, this will fail in an effectively equivalent way to how it failed previously. A previous attempt at fixing this (aws#18823) used a more complicated `sed` command which used a cli flag that is not consistently available. This approach won't work on all platforms (ex. macos) and is also much less clear that it's correct. This change also adds an integration test that tests the tarbell stack, though it doesn't test the repeated deploy automatically. I have tested that by running the integration test multiple times with an image modification in between. We also vendor the tarball of the hello-world docker image, which results in ~10kb of additional data in the repo. This is about as small as we can get a vendored image with as straightforward a vendoring process. fixes aws#18822
The current implementation fails because it assumes the output of `docker load` can only be ``` Loaded Image: {image} ``` However, if docker has to take any actions (such as untagging a previous image) the output will look like ``` {error message} {error message} Loaded Image: {image} ``` To fix this, we can simply take the last line of the output via `tail` before we attempt to extract the image. If the last line isn't of the correct form, this will fail in an effectively equivalent way to how it failed previously. A previous attempt at fixing this (aws#18823) used a more complicated `sed` command which used a cli flag that is not consistently available. This approach won't work on all platforms (ex. macos) and is also much less clear that it's correct. This change also adds an integration test that tests the tarbell stack, though it doesn't test the repeated deploy automatically. I have tested that by running the integration test multiple times with an image modification in between. We also vendor the tarball of the hello-world docker image, which results in ~10kb of additional data in the repo. This is about as small as we can get a vendored image with as straightforward a vendoring process. fixes aws#18822
The current implementation fails because it assumes the output of `docker load` can only be ``` Loaded Image: {image} ``` However, if docker has to take any actions (such as untagging a previous image) the output will look like ``` {error message} {error message} Loaded Image: {image} ``` To fix this, we can simply take the last line of the output via `tail` before we attempt to extract the image. If the last line isn't of the correct form, this will fail in an effectively equivalent way to how it failed previously. A previous attempt at fixing this (#18823) used a more complicated `sed` command which used a cli flag that is not consistently available. This approach won't work on all platforms (ex. macos) and is also much less clear that it's correct. This change also adds an integration test that tests the tarbell stack, though it doesn't test the repeated deploy automatically. I have tested that by running the integration test multiple times with an image modification in between. We also vendor the tarball of the hello-world docker image, which results in ~20kb of additional data in the repo. This is about as small as we can get a vendored image with as straightforward a vendoring process. fixes #18822 ---- ### All Submissions: * [x] Have you followed the guidelines in our [Contributing guide?](https:/aws/aws-cdk/blob/main/CONTRIBUTING.md) ### Adding new Construct Runtime Dependencies: * [ ] This PR adds new construct runtime dependencies following the process described [here](https:/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-construct-runtime-dependencies) ### New Features * [ ] Have you added the new feature to an [integration test](https:/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)? * [ ] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)? *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
…23497) The current implementation fails because it assumes the output of `docker load` can only be ``` Loaded Image: {image} ``` However, if docker has to take any actions (such as untagging a previous image) the output will look like ``` {error message} {error message} Loaded Image: {image} ``` To fix this, we can simply take the last line of the output via `tail` before we attempt to extract the image. If the last line isn't of the correct form, this will fail in an effectively equivalent way to how it failed previously. A previous attempt at fixing this (aws#18823) used a more complicated `sed` command which used a cli flag that is not consistently available. This approach won't work on all platforms (ex. macos) and is also much less clear that it's correct. This change also adds an integration test that tests the tarbell stack, though it doesn't test the repeated deploy automatically. I have tested that by running the integration test multiple times with an image modification in between. We also vendor the tarball of the hello-world docker image, which results in ~20kb of additional data in the repo. This is about as small as we can get a vendored image with as straightforward a vendoring process. fixes aws#18822 ---- ### All Submissions: * [x] Have you followed the guidelines in our [Contributing guide?](https:/aws/aws-cdk/blob/main/CONTRIBUTING.md) ### Adding new Construct Runtime Dependencies: * [ ] This PR adds new construct runtime dependencies following the process described [here](https:/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-construct-runtime-dependencies) ### New Features * [ ] Have you added the new feature to an [integration test](https:/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)? * [ ] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)? *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
The current logic for pushing tarball images fails if the tarball being
loaded uses a repository and tag that's already loaded into the docker
daemon. This is due to the way the ecr-assets module parses the output
of the docker load command. If the repository/tag combination already
exists in the daemon, it outputs a message about renaming it, which
breaks the
sed
command parsing its output.This change updates the
sed
command used for extracting therepository/tag for tarball images to make it more robust and will now
successfully parse docker load output in the case where the
repository/tag already exist.
fixes #18822
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license