Skip to content
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

Conversation

AndrewGuenther
Copy link

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 #18822


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 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
@gitpod-io
Copy link

gitpod-io bot commented Feb 4, 2022

@github-actions github-actions bot added the @aws-cdk/aws-ecr-assets Related to AWS CDK Docker Image Assets label Feb 4, 2022
@mergify
Copy link
Contributor

mergify bot commented Feb 4, 2022

Title does not follow the guidelines of Conventional Commits. Please adjust title before merge.

@AndrewGuenther AndrewGuenther changed the title fix(ecr-assets) fix loading image tarballs with existing tags fix(ecr-assets): fix loading image tarballs with existing tags Feb 4, 2022
Copy link
Contributor

@madeline-k madeline-k left a 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?

@AndrewGuenther
Copy link
Author

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.

@rix0rrr rix0rrr added bug This issue is a bug. p2 and removed bug This issue is a bug. p2 @aws-cdk/aws-ecr-assets Related to AWS CDK Docker Image Assets labels Mar 4, 2022
@AndrewGuenther
Copy link
Author

@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-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • CodeBuild project: AutoBuildProject89A8053A-LhjRyN9kxr8o
  • Commit ID: ba70f39
  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@madeline-k madeline-k removed their assignment Mar 23, 2022
@@ -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'`,
Copy link
Contributor

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.

Copy link
Contributor

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.

Copy link
Author

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...

Copy link
Author

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.

@github-actions
Copy link

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.

@AndrewGuenther
Copy link
Author

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...

@github-actions
Copy link

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.

@github-actions github-actions bot added the closed-for-staleness This issue was automatically closed because it hadn't received any attention in a while. label Apr 28, 2022
@github-actions github-actions bot closed this Apr 28, 2022
@AndrewGuenther
Copy link
Author

Are you serious?

@skinny85
Copy link
Contributor

@AndrewGuenther apologies, our bots can be a little ham-fisted sometimes 🙂.

@rix0rrr can you reply to Andrew's comment in #18823 (comment)?

@skinny85 skinny85 reopened this Apr 28, 2022
@github-actions github-actions bot added the effort/small Small work item – less than a day of effort label Apr 28, 2022
@AndrewGuenther
Copy link
Author

Thanks @skinny85!

@github-actions
Copy link

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.

@github-actions github-actions bot closed this Apr 29, 2022
dastbe added a commit to dastbe/aws-cdk that referenced this pull request Dec 29, 2022
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
dastbe added a commit to dastbe/aws-cdk that referenced this pull request Dec 29, 2022
`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
dastbe added a commit to dastbe/aws-cdk that referenced this pull request Dec 29, 2022
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
dastbe added a commit to dastbe/aws-cdk that referenced this pull request Dec 31, 2022
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
dastbe added a commit to dastbe/aws-cdk that referenced this pull request Feb 27, 2023
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
dastbe added a commit to dastbe/aws-cdk that referenced this pull request Feb 28, 2023
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
mergify bot pushed a commit that referenced this pull request Feb 28, 2023
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*
homakk pushed a commit to homakk/aws-cdk that referenced this pull request Mar 28, 2023
…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*
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug This issue is a bug. closed-for-staleness This issue was automatically closed because it hadn't received any attention in a while. effort/small Small work item – less than a day of effort p2
Projects
None yet
Development

Successfully merging this pull request may close these issues.

(cdk-assets): TarballImageAsset fails build if trying to load tarball with existing tag
5 participants