NewReaderFromStream returns a Reader for the specified inputStream, which can be either compressed or uncompressed. The caller can close the inputStream immediately after NewReaderFromFile returns. The caller should call .Close() on the returned archive when done.
(sys *types.SystemContext, inputStream io.Reader)
| 56 | // inputStream immediately after NewReaderFromFile returns. |
| 57 | // The caller should call .Close() on the returned archive when done. |
| 58 | func NewReaderFromStream(sys *types.SystemContext, inputStream io.Reader) (*Reader, error) { |
| 59 | // Save inputStream to a temporary file |
| 60 | tarCopyFile, err := tmpdir.CreateBigFileTemp(sys, "docker-tar") |
| 61 | if err != nil { |
| 62 | return nil, fmt.Errorf("creating temporary file: %w", err) |
| 63 | } |
| 64 | defer tarCopyFile.Close() |
| 65 | |
| 66 | succeeded := false |
| 67 | defer func() { |
| 68 | if !succeeded { |
| 69 | os.Remove(tarCopyFile.Name()) |
| 70 | } |
| 71 | }() |
| 72 | |
| 73 | // In order to be compatible with docker-load, we need to support |
| 74 | // auto-decompression (it's also a nice quality-of-life thing to avoid |
| 75 | // giving users really confusing "invalid tar header" errors). |
| 76 | uncompressedStream, _, err := compression.AutoDecompress(inputStream) |
| 77 | if err != nil { |
| 78 | return nil, fmt.Errorf("auto-decompressing input: %w", err) |
| 79 | } |
| 80 | defer uncompressedStream.Close() |
| 81 | |
| 82 | // Copy the plain archive to the temporary file. |
| 83 | // |
| 84 | // TODO: This can take quite some time, and should ideally be cancellable |
| 85 | // using a context.Context. |
| 86 | if _, err := io.Copy(tarCopyFile, uncompressedStream); err != nil { |
| 87 | return nil, fmt.Errorf("copying contents to temporary file %q: %w", tarCopyFile.Name(), err) |
| 88 | } |
| 89 | succeeded = true |
| 90 | |
| 91 | return newReader(tarCopyFile.Name(), true) |
| 92 | } |
| 93 | |
| 94 | // newReader creates a Reader for the specified path and removeOnClose flag. |
| 95 | // The caller should call .Close() on the returned archive when done. |
searching dependent graphs…