diff --git a/pkg/mountutil/volumestore/volumestore.go b/pkg/mountutil/volumestore/volumestore.go index 48fbbfa539..281f304d1f 100644 --- a/pkg/mountutil/volumestore/volumestore.go +++ b/pkg/mountutil/volumestore/volumestore.go @@ -24,6 +24,7 @@ import ( "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/identifiers" + "github.com/containerd/log" "github.com/containerd/nerdctl/v2/pkg/inspecttypes/native" "github.com/containerd/nerdctl/v2/pkg/lockutil" "github.com/containerd/nerdctl/v2/pkg/strutil" @@ -83,13 +84,30 @@ func (vs *volumeStore) Create(name string, labels []string) (*native.Volume, err } volPath := filepath.Join(vs.dir, name) volDataPath := filepath.Join(volPath, DataDirName) - fn := func() error { + volFilePath := filepath.Join(volPath, volumeJSONFileName) + fn := func() (err error) { if err := os.Mkdir(volPath, 0700); err != nil { return err } + defer func() { + if err != nil { + os.Remove(volPath) + } + }() if err := os.Mkdir(volDataPath, 0755); err != nil { return err } + defer func() { + if err != nil { + if _, statErr := os.Stat(volFilePath); statErr != nil && !os.IsNotExist(statErr) { + log.L.Warnf("failed to stat volume file: %v", statErr) + return + } else if statErr == nil { + os.Remove(volFilePath) + } + os.Remove(volDataPath) + } + }() type volumeOpts struct { Labels map[string]string `json:"labels"` @@ -106,7 +124,6 @@ func (vs *volumeStore) Create(name string, labels []string) (*native.Volume, err return err } - volFilePath := filepath.Join(volPath, volumeJSONFileName) return os.WriteFile(volFilePath, labelsJSON, 0644) } @@ -114,6 +131,8 @@ func (vs *volumeStore) Create(name string, labels []string) (*native.Volume, err return nil, err } + // If other new actions that might fail are added below, we should move the cleanup function out of fn. + vol := &native.Volume{ Name: name, Mountpoint: volDataPath,