newReader creates a Reader for the specified path and removeOnClose flag. The caller should call .Close() on the returned archive when done.
(path string, removeOnClose bool)
| 94 | // newReader creates a Reader for the specified path and removeOnClose flag. |
| 95 | // The caller should call .Close() on the returned archive when done. |
| 96 | func newReader(path string, removeOnClose bool) (*Reader, error) { |
| 97 | // This is a valid enough archive, except Manifest is not yet filled. |
| 98 | r := Reader{ |
| 99 | path: path, |
| 100 | removeOnClose: removeOnClose, |
| 101 | } |
| 102 | succeeded := false |
| 103 | defer func() { |
| 104 | if !succeeded { |
| 105 | r.Close() |
| 106 | } |
| 107 | }() |
| 108 | |
| 109 | // We initialize Manifest immediately when constructing the Reader instead |
| 110 | // of later on-demand because every caller will need the data, and because doing it now |
| 111 | // removes the need to synchronize the access/creation of the data if the archive is later |
| 112 | // used from multiple goroutines to access different images. |
| 113 | |
| 114 | // FIXME? Do we need to deal with the legacy format? |
| 115 | bytes, err := r.readTarComponent(manifestFileName, iolimits.MaxTarFileManifestSize) |
| 116 | if err != nil { |
| 117 | return nil, err |
| 118 | } |
| 119 | if err := json.Unmarshal(bytes, &r.Manifest); err != nil { |
| 120 | return nil, fmt.Errorf("decoding tar manifest.json: %w", err) |
| 121 | } |
| 122 | |
| 123 | succeeded = true |
| 124 | return &r, nil |
| 125 | } |
| 126 | |
| 127 | // Close removes resources associated with an initialized Reader, if any. |
| 128 | func (r *Reader) Close() error { |
no test coverage detected
searching dependent graphs…