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

images: Fix read past end of file for pull --cache #152

Merged
merged 1 commit into from
Jan 26, 2024

Conversation

joestringer
Copy link
Member

@joestringer joestringer commented Jan 25, 2024

Pull has two modes:

  • No cache: Extract and decompress the target VM image from the docker
    filesystem to the host filesystem. Result: One file, image.qcow.
  • Cache: Same as no cache, but also copy the compressed image to the
    host filesystem. Result: two files, image.qcow{,.zst}

Previously, the logic for extracting the target VM image from the docker
image with --cache enabled was to:

  • Extract and decompress the target file directly from inside the docker
    image filesystem to the host filesystem
  • Do not seek the source Reader back to the start of the file
  • Attempt (and fail) to copy the entire compressed image also to the
    host filesystem, but starting from the end of the source file.
  • This resulted in an EOF error because the reader wasn't reset to start
    from the beginning.

Unfortunately, tar.Reader doesn't expose a way to seek back to the start
of the source file. We could perhaps get an additional reference to a
reader starting from the beginning of the current tar header in order to
reset back to the beginning of the target file in cache mode, but this
was getting a bit complicated.

The solution in this patch is to:

  • Copy the compressed file to a temporary path on the host filesystem
  • Extract the compressed file from this temporary host-side cache to the
    intended destination directory.
  • If in cache mode, move the temporary file also to the output
    directory. Otherwise, delete the temporary file.

There's one minor extra case, if the qcow inside the docker image is not
compressed at all then we skip decompression, and in that case we also
need to move the temporary path to the destination directory regardless
of the cache flag setting.

Fixes: #133
Fixes: ea09cb7 ("images: Add docker pull support")
Reported-by: Lorenz Bauer [email protected]
Signed-off-by: Joe Stringer [email protected]

@joestringer
Copy link
Member Author

joestringer commented Jan 25, 2024

Testing here:

cilium/cilium#30447
https://github.com/cilium/cilium/actions/runs/7659070993

EDIT: The PR / workflow above is invoking the action.yaml from this PR as-is, which currently instructs the workflow to install LVH v0.0.13 from quay.io, not the code being proposed here. Looks like I need to get an image pushed and update the action.yaml just to test this PR.

@joestringer
Copy link
Member Author

joestringer commented Jan 25, 2024

OK, looks like the latest version here was now successful, by manually overriding the LVH binary in the workflow:

https://github.com/cilium/cilium/pull/30447/files
https://github.com/cilium/cilium/actions/runs/7659759619/job/20875597120

Copy link
Contributor

@michi-covalent michi-covalent left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems reasonable

Pull has two modes:
- No cache: Extract and decompress the target VM image from the docker
  filesystem to the host filesystem. Result: One file, image.qcow.
- Cache: Same as no cache, but also copy the compressed image to the
  host filesystem. Result: two files, image.qcow{,.zst}

Previously, the logic for extracting the target VM image from the docker
image with --cache enabled was to:
- Extract and decompress the target file directly from inside the docker
  image filesystem to the host filesystem
- Do not seek the source Reader back to the start of the file
- Attempt (and fail) to copy the entire compressed image also to the
  host filesystem, but starting from the end of the source file.
- This resulted in an EOF error because the reader wasn't reset to start
  from the beginning.

Unfortunately, tar.Reader doesn't expose a way to seek back to the start
of the source file. We could perhaps get an additional reference to a
reader starting from the beginning of the current tar header in order to
reset back to the beginning of the target file in cache mode, but this
was getting a bit complicated.

The solution in this patch is to:
- Copy the compressed file to a temporary path on the host filesystem
- Extract the compressed file from this temporary host-side cache to the
  intended destination directory.
- If in cache mode, move the temporary file also to the output
  directory. Otherwise, delete the temporary file.

There's one minor extra case, if the qcow inside the docker image is not
compressed at all then we skip decompression, and in that case we also
need to move the temporary path to the destination directory.

Fixes: ea09cb7 ("images: Add docker pull support")
Reported-by: Lorenz Bauer <[email protected]>
Signed-off-by: Joe Stringer <[email protected]>
@lmb lmb force-pushed the pr/joe/fix-pull-cache-eof branch from e3a5248 to 1dfca60 Compare January 26, 2024 12:21
@lmb lmb merged commit e1c8135 into main Jan 26, 2024
1 check passed
@lmb lmb deleted the pr/joe/fix-pull-cache-eof branch January 26, 2024 13:06
@julianwiedmann
Copy link
Member

👋 I'm here as cilium/cilium#30478 is updating the lvh action to v0.0.15, and the relevant tests fail with

Status: Downloaded newer image for quay.io/lvh-images/complexity-test:5.15-20240110.080621
Error: failed to copy /images/complexity-test_5.15.qcow2.zst from container 9f773a34baa770883bac93b58ca1cdc3706991a1421f6b74ae0b08750cdd8f8c: EOF
Error: Process completed with exit code 1.

@michi-covalent
Copy link
Contributor

i think the issue is that the action is still using v0.0.14: https://github.com/cilium/cilium/actions/runs/7708590978/job/21008029780#step:8:77. i opened #157 to update the release process so that the docker image tag matches the action version.

would be interesting to see if cilium/cilium#30478 works if it uses quay.io/lvh-images/lvh:v0.0.15. i might try it out today 🧑‍🔬

@joestringer
Copy link
Member Author

Yeah it looks like the action has a variable input for version that you could override.

@michi-covalent
Copy link
Contributor

still failing with v0.0.15. struggle: https://github.com/cilium/cilium/actions/runs/7714824322/job/21028190169

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants