docker: avoid unexpected EOF tar errors #4884
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
When performing a live update, we create a tar with a batch of
changed files for efficiency. When adding a file to the tar, if
the source file on disk no longer exists, we can safely skip it:
it has since been deleted, so a delete event should be in the
next batch of file events and will be processed by live update.
However, the header was always being written to the tar file,
which includes the file size, but then we'd simply not write the
file, producing an invalid tar. Specifically, it'd hit EOF too
early since it was expected to read
n
bytes as specified by theheader, but then there was nothing.
This wasn't always caught because often only a single file is in
the live update changeset, so it's the only tar entry. The Go
stdlib catches this on
Flush()
which is called either when thenext entry gets started or when the
TarWriter
is closed, andwe were swallowing errors on close. These are now propagated AND
Flush()
is called explicitly after each entry to ideally surfacemore meaningful errors.
Additionally,
io.Copy
is used instead ofio.CopyN
because thiswill ensure that if the file has been appended to since we started
reading we actually error out instead of silently discarding the
rest of the file. This is an exceedingly unlikely scenario, but it
seems more reasonable to trigger the fallback than potentially
sync only part of a file.