diff --git a/docker/internal/tarfile/reader.go b/docker/internal/tarfile/reader.go index 3b986f503..6845893bf 100644 --- a/docker/internal/tarfile/reader.go +++ b/docker/internal/tarfile/reader.go @@ -57,7 +57,7 @@ func NewReaderFromFile(sys *types.SystemContext, path string) (*Reader, error) { // The caller should call .Close() on the returned archive when done. func NewReaderFromStream(sys *types.SystemContext, inputStream io.Reader) (*Reader, error) { // Save inputStream to a temporary file - tarCopyFile, err := os.CreateTemp(tmpdir.TemporaryDirectoryForBigFiles(sys), "docker-tar") + tarCopyFile, err := tmpdir.CreateBigFileTemp(sys, "docker-tar") if err != nil { return nil, fmt.Errorf("creating temporary file: %w", err) } diff --git a/internal/streamdigest/stream_digest.go b/internal/streamdigest/stream_digest.go index 84bb656ac..d5a5436a4 100644 --- a/internal/streamdigest/stream_digest.go +++ b/internal/streamdigest/stream_digest.go @@ -15,7 +15,7 @@ import ( // It is the caller's responsibility to call the cleanup function, which closes and removes the temporary file. // If an error occurs, inputInfo is not modified. func ComputeBlobInfo(sys *types.SystemContext, stream io.Reader, inputInfo *types.BlobInfo) (io.Reader, func(), error) { - diskBlob, err := os.CreateTemp(tmpdir.TemporaryDirectoryForBigFiles(sys), "stream-blob") + diskBlob, err := tmpdir.CreateBigFileTemp(sys, "stream-blob") if err != nil { return nil, nil, fmt.Errorf("creating temporary on-disk layer: %w", err) } diff --git a/internal/tmpdir/tmpdir.go b/internal/tmpdir/tmpdir.go index 809446e18..bab73ee33 100644 --- a/internal/tmpdir/tmpdir.go +++ b/internal/tmpdir/tmpdir.go @@ -17,10 +17,12 @@ var unixTempDirForBigFiles = builtinUnixTempDirForBigFiles // DO NOT change this, instead see unixTempDirForBigFiles above. const builtinUnixTempDirForBigFiles = "/var/tmp" +const prefix = "container_images_" + // TemporaryDirectoryForBigFiles returns a directory for temporary (big) files. // On non Windows systems it avoids the use of os.TempDir(), because the default temporary directory usually falls under /tmp // which on systemd based systems could be the unsuitable tmpfs filesystem. -func TemporaryDirectoryForBigFiles(sys *types.SystemContext) string { +func temporaryDirectoryForBigFiles(sys *types.SystemContext) string { if sys != nil && sys.BigFilesTemporaryDir != "" { return sys.BigFilesTemporaryDir } @@ -32,3 +34,11 @@ func TemporaryDirectoryForBigFiles(sys *types.SystemContext) string { } return temporaryDirectoryForBigFiles } + +func CreateBigFileTemp(sys *types.SystemContext, name string) (*os.File, error) { + return os.CreateTemp(temporaryDirectoryForBigFiles(sys), prefix+name) +} + +func MkDirBigFileTemp(sys *types.SystemContext, name string) (string, error) { + return os.MkdirTemp(temporaryDirectoryForBigFiles(sys), prefix+name) +} diff --git a/internal/tmpdir/tmpdir_test.go b/internal/tmpdir/tmpdir_test.go new file mode 100644 index 000000000..c36caf33e --- /dev/null +++ b/internal/tmpdir/tmpdir_test.go @@ -0,0 +1,54 @@ +package tmpdir + +import ( + "os" + "strings" + "testing" + + "github.com/containers/image/v5/types" + "github.com/stretchr/testify/assert" +) + +func TestCreateBigFileTemp(t *testing.T) { + f, err := CreateBigFileTemp(nil, "") + assert.NoError(t, err) + f.Close() + os.Remove(f.Name()) + + f, err = CreateBigFileTemp(nil, "foobar") + assert.NoError(t, err) + f.Close() + assert.True(t, strings.Contains(f.Name(), prefix+"foobar")) + os.Remove(f.Name()) + + var sys types.SystemContext + sys.BigFilesTemporaryDir = "/tmp" + f, err = CreateBigFileTemp(&sys, "foobar1") + assert.NoError(t, err) + f.Close() + assert.True(t, strings.Contains(f.Name(), "/tmp/"+prefix+"foobar1")) + os.Remove(f.Name()) + + sys.BigFilesTemporaryDir = "/tmp/bogus" + _, err = CreateBigFileTemp(&sys, "foobar1") + assert.Error(t, err) + +} + +func TestMkDirBigFileTemp(t *testing.T) { + d, err := MkDirBigFileTemp(nil, "foobar") + assert.NoError(t, err) + assert.True(t, strings.Contains(d, prefix+"foobar")) + os.RemoveAll(d) + + var sys types.SystemContext + sys.BigFilesTemporaryDir = "/tmp" + d, err = MkDirBigFileTemp(&sys, "foobar1") + assert.NoError(t, err) + assert.True(t, strings.Contains(d, "/tmp/"+prefix+"foobar1")) + os.RemoveAll(d) + + sys.BigFilesTemporaryDir = "/tmp/bogus" + _, err = MkDirBigFileTemp(&sys, "foobar1") + assert.Error(t, err) +} diff --git a/oci/archive/oci_transport.go b/oci/archive/oci_transport.go index 53371796f..2a03feeea 100644 --- a/oci/archive/oci_transport.go +++ b/oci/archive/oci_transport.go @@ -156,7 +156,7 @@ func (t *tempDirOCIRef) deleteTempDir() error { // createOCIRef creates the oci reference of the image // If SystemContext.BigFilesTemporaryDir not "", overrides the temporary directory to use for storing big files func createOCIRef(sys *types.SystemContext, image string) (tempDirOCIRef, error) { - dir, err := os.MkdirTemp(tmpdir.TemporaryDirectoryForBigFiles(sys), "oci") + dir, err := tmpdir.MkDirBigFileTemp(sys, "oci") if err != nil { return tempDirOCIRef{}, fmt.Errorf("creating temp directory: %w", err) } diff --git a/sif/src.go b/sif/src.go index 1f6ab7f3b..261cfbe77 100644 --- a/sif/src.go +++ b/sif/src.go @@ -73,7 +73,7 @@ func newImageSource(ctx context.Context, sys *types.SystemContext, ref sifRefere _ = sifImg.UnloadContainer() }() - workDir, err := os.MkdirTemp(tmpdir.TemporaryDirectoryForBigFiles(sys), "sif") + workDir, err := tmpdir.MkDirBigFileTemp(sys, "sif") if err != nil { return nil, fmt.Errorf("creating temp directory: %w", err) } diff --git a/storage/storage_dest.go b/storage/storage_dest.go index 7bbbf1752..628564559 100644 --- a/storage/storage_dest.go +++ b/storage/storage_dest.go @@ -95,7 +95,7 @@ type addedLayerInfo struct { // newImageDestination sets us up to write a new image, caching blobs in a temporary directory until // it's time to Commit() the image func newImageDestination(sys *types.SystemContext, imageRef storageReference) (*storageImageDestination, error) { - directory, err := os.MkdirTemp(tmpdir.TemporaryDirectoryForBigFiles(sys), "storage") + directory, err := tmpdir.MkDirBigFileTemp(sys, "storage") if err != nil { return nil, fmt.Errorf("creating a temporary directory: %w", err) } diff --git a/storage/storage_src.go b/storage/storage_src.go index 03c2fa28c..66d04da31 100644 --- a/storage/storage_src.go +++ b/storage/storage_src.go @@ -124,7 +124,7 @@ func (s *storageImageSource) GetBlob(ctx context.Context, info types.BlobInfo, c } defer rc.Close() - tmpFile, err := os.CreateTemp(tmpdir.TemporaryDirectoryForBigFiles(s.systemContext), "") + tmpFile, err := tmpdir.CreateBigFileTemp(s.systemContext, "") if err != nil { return nil, 0, err }