mirror of
https://github.com/anchore/syft.git
synced 2026-11-02 15:36:41 +01:00
chore: simplify and cleanup
Signed-off-by: Keith Zantow <keith.zantow@anchore.com>
This commit is contained in:
+36
-55
@@ -4,85 +4,66 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
"github.com/anchore/syft/internal/log"
|
||||
"github.com/anchore/syft/internal/tmpdir"
|
||||
)
|
||||
|
||||
// workDirName prefixes the directory holding one archive's content and entries, so a scan's leftovers
|
||||
// are recognizable. Tests that sample what is on disk match on it.
|
||||
// workDirName prefixes the directory holding one archive's overflow files.
|
||||
const workDirName = "syft-archive"
|
||||
|
||||
// WorkDir is the scratch space one archive writes into, created lazily the first time something needs
|
||||
// to write - an archive's own bytes spilling out of memory, or its entries spilling into the overflow
|
||||
// blob.
|
||||
//
|
||||
// Eager creation would put one directory on disk per archive opened, whether or not it ever wrote a
|
||||
// byte; most do not, and a scan walks far more archives than it spills. So the path is asked for at
|
||||
// the point of writing. A nil *WorkDir has no path and fails the write.
|
||||
// WorkDir is the scratch directory one archive writes overflow into. It is created on first use, so
|
||||
// an archive that stays in memory never touches the filesystem.
|
||||
type WorkDir struct {
|
||||
mu sync.Mutex
|
||||
tempDir *tmpdir.TempDir
|
||||
|
||||
// create makes the directory and returns it with the func that removes it. Called at most once.
|
||||
create func() (string, func(), error)
|
||||
|
||||
path string
|
||||
remove func()
|
||||
err error
|
||||
done bool
|
||||
created bool
|
||||
path string
|
||||
remove func()
|
||||
err error
|
||||
}
|
||||
|
||||
// NewWorkDir returns the lazily-created work directory for one archive, rooted under the scan's temp
|
||||
// root (internal/tmpdir) when the context carries one - so files land where the caller configured and
|
||||
// are removed together if an archive's own cleanup is missed - otherwise the system temp dir.
|
||||
// NewWorkDir returns a work directory under the scan's temp root when ctx carries one (see
|
||||
// internal/tmpdir), otherwise under the system temp directory.
|
||||
func NewWorkDir(ctx context.Context) *WorkDir {
|
||||
return &WorkDir{create: func() (string, func(), error) {
|
||||
if td := tmpdir.FromContext(ctx); td != nil {
|
||||
dir, cleanup, err := td.NewChild(workDirName) //nolint:gocritic // cleanup is returned, not deferred here
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("unable to create temp dir for archive extraction: %w", err)
|
||||
}
|
||||
return dir, cleanup, nil
|
||||
}
|
||||
|
||||
dir, err := os.MkdirTemp("", workDirName+"-")
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("unable to create temp dir for archive extraction: %w", err)
|
||||
}
|
||||
return dir, func() {
|
||||
if rmErr := os.RemoveAll(dir); rmErr != nil {
|
||||
log.WithFields("dir", dir, "error", rmErr).Trace("unable to remove archive temp dir")
|
||||
}
|
||||
}, nil
|
||||
}}
|
||||
return &WorkDir{tempDir: tmpdir.FromContext(ctx)}
|
||||
}
|
||||
|
||||
// Path returns the directory, creating it on the first call. Later calls return the same result,
|
||||
// including the same failure.
|
||||
// Path returns the directory, creating it on the first call.
|
||||
func (w *WorkDir) Path() (string, error) {
|
||||
if w == nil {
|
||||
return "", fmt.Errorf("no work directory for archive content")
|
||||
}
|
||||
|
||||
w.mu.Lock()
|
||||
defer w.mu.Unlock()
|
||||
if !w.done {
|
||||
if !w.created {
|
||||
w.created = true
|
||||
w.path, w.remove, w.err = w.create()
|
||||
w.done = true
|
||||
}
|
||||
return w.path, w.err
|
||||
}
|
||||
|
||||
// Remove deletes the directory and its contents, and does nothing if it was never created. Safe to
|
||||
// call more than once.
|
||||
func (w *WorkDir) Remove() {
|
||||
if w == nil {
|
||||
return
|
||||
func (w *WorkDir) create() (string, func(), error) {
|
||||
if w.tempDir != nil {
|
||||
dir, remove, err := w.tempDir.NewChild(workDirName) //nolint:gocritic // the cleanup is returned, not deferred
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("unable to create temp dir for archive extraction: %w", err)
|
||||
}
|
||||
return dir, remove, nil
|
||||
}
|
||||
w.mu.Lock()
|
||||
defer w.mu.Unlock()
|
||||
if w.remove == nil {
|
||||
|
||||
dir, err := os.MkdirTemp("", workDirName+"-")
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("unable to create temp dir for archive extraction: %w", err)
|
||||
}
|
||||
return dir, func() {
|
||||
if err := os.RemoveAll(dir); err != nil {
|
||||
log.WithFields("dir", dir, "error", err).Trace("unable to remove archive temp dir")
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Remove deletes the directory if it was created. Safe to call more than once.
|
||||
func (w *WorkDir) Remove() {
|
||||
if w == nil || w.remove == nil {
|
||||
return
|
||||
}
|
||||
w.remove()
|
||||
|
||||
Reference in New Issue
Block a user