mirror of
https://github.com/anchore/syft.git
synced 2026-10-30 22:12:28 +01:00
72 lines
1.9 KiB
Go
72 lines
1.9 KiB
Go
package archive
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
|
|
"github.com/anchore/syft/internal/log"
|
|
"github.com/anchore/syft/internal/tmpdir"
|
|
)
|
|
|
|
// workDirName prefixes the directory holding one archive's overflow files.
|
|
const workDirName = "syft-archive"
|
|
|
|
// 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 {
|
|
tempDir *tmpdir.TempDir
|
|
|
|
created bool
|
|
path string
|
|
remove func()
|
|
err error
|
|
}
|
|
|
|
// 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{tempDir: tmpdir.FromContext(ctx)}
|
|
}
|
|
|
|
// 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")
|
|
}
|
|
if !w.created {
|
|
w.created = true
|
|
w.path, w.remove, w.err = w.create()
|
|
}
|
|
return w.path, w.err
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
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()
|
|
w.remove = nil
|
|
}
|