Fix invalid argument error on push
With 32ba6ab from #9261, TempArchive now closes the underlying file and cleans it up as soon as the file's contents have been read. When pushing an image, PushImageLayerRegistry attempts to call Close() on the layer, which is a TempArchive that has already been closed. In this situation, Close() returns an "invalid argument" error. Add a Close method to TempArchive that does a no-op if the underlying file has already been closed. Signed-off-by: Andy Goldstein <agoldste@redhat.com>
This commit is contained in:
parent
2b403ab360
commit
5e3e0f129e
2 changed files with 33 additions and 4 deletions
|
@ -771,20 +771,33 @@ func NewTempArchive(src Archive, dir string) (*TempArchive, error) {
|
|||
return nil, err
|
||||
}
|
||||
size := st.Size()
|
||||
return &TempArchive{f, size, 0}, nil
|
||||
return &TempArchive{File: f, Size: size}, nil
|
||||
}
|
||||
|
||||
type TempArchive struct {
|
||||
*os.File
|
||||
Size int64 // Pre-computed from Stat().Size() as a convenience
|
||||
read int64
|
||||
Size int64 // Pre-computed from Stat().Size() as a convenience
|
||||
read int64
|
||||
closed bool
|
||||
}
|
||||
|
||||
// Close closes the underlying file if it's still open, or does a no-op
|
||||
// to allow callers to try to close the TempArchive multiple times safely.
|
||||
func (archive *TempArchive) Close() error {
|
||||
if archive.closed {
|
||||
return nil
|
||||
}
|
||||
|
||||
archive.closed = true
|
||||
|
||||
return archive.File.Close()
|
||||
}
|
||||
|
||||
func (archive *TempArchive) Read(data []byte) (int, error) {
|
||||
n, err := archive.File.Read(data)
|
||||
archive.read += int64(n)
|
||||
if err != nil || archive.read == archive.Size {
|
||||
archive.File.Close()
|
||||
archive.Close()
|
||||
os.Remove(archive.File.Name())
|
||||
}
|
||||
return n, err
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"syscall"
|
||||
"testing"
|
||||
"time"
|
||||
|
@ -607,3 +608,18 @@ func TestUntarInvalidSymlink(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTempArchiveCloseMultipleTimes(t *testing.T) {
|
||||
reader := ioutil.NopCloser(strings.NewReader("hello"))
|
||||
tempArchive, err := NewTempArchive(reader, "")
|
||||
buf := make([]byte, 10)
|
||||
n, err := tempArchive.Read(buf)
|
||||
if n != 5 {
|
||||
t.Fatalf("Expected to read 5 bytes. Read %d instead", n)
|
||||
}
|
||||
for i := 0; i < 3; i++ {
|
||||
if err = tempArchive.Close(); err != nil {
|
||||
t.Fatalf("i=%d. Unexpected error closing temp archive: %v", i, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue