mirror of
https://github.com/moby/moby.git
synced 2026-01-11 18:51:37 +00:00
pkg/ioutils: move atomic file-writers to a separate (pkg/atomicwriter) package
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
@@ -31,8 +31,8 @@ import (
|
||||
"github.com/docker/docker/layer"
|
||||
libcontainerdtypes "github.com/docker/docker/libcontainerd/types"
|
||||
"github.com/docker/docker/oci"
|
||||
"github.com/docker/docker/pkg/atomicwriter"
|
||||
"github.com/docker/docker/pkg/idtools"
|
||||
"github.com/docker/docker/pkg/ioutils"
|
||||
"github.com/docker/docker/restartmanager"
|
||||
"github.com/docker/docker/volume"
|
||||
volumemounts "github.com/docker/docker/volume/mounts"
|
||||
@@ -193,7 +193,7 @@ func (container *Container) toDisk() (*Container, error) {
|
||||
}
|
||||
|
||||
// Save container settings
|
||||
f, err := ioutils.NewAtomicFileWriter(pth, 0o600)
|
||||
f, err := atomicwriter.New(pth, 0o600)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -273,7 +273,7 @@ func (container *Container) WriteHostConfig() (*containertypes.HostConfig, error
|
||||
return nil, err
|
||||
}
|
||||
|
||||
f, err := ioutils.NewAtomicFileWriter(pth, 0o600)
|
||||
f, err := atomicwriter.New(pth, 0o600)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/pkg/ioutils"
|
||||
"github.com/docker/docker/pkg/atomicwriter"
|
||||
)
|
||||
|
||||
// convertKVStringsToMap converts ["key=value"] to {"key":"value"}
|
||||
@@ -44,7 +44,7 @@ func savePersistentState(root string, config nodeStartConfig) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return ioutils.AtomicWriteFile(filepath.Join(root, stateFile), dt, 0o600)
|
||||
return atomicwriter.WriteFile(filepath.Join(root, stateFile), dt, 0o600)
|
||||
}
|
||||
|
||||
func clearPersistentState(root string) error {
|
||||
|
||||
@@ -23,9 +23,9 @@ import (
|
||||
"github.com/docker/docker/internal/containerfs"
|
||||
"github.com/docker/docker/internal/directory"
|
||||
"github.com/docker/docker/pkg/archive"
|
||||
"github.com/docker/docker/pkg/atomicwriter"
|
||||
"github.com/docker/docker/pkg/chrootarchive"
|
||||
"github.com/docker/docker/pkg/idtools"
|
||||
"github.com/docker/docker/pkg/ioutils"
|
||||
"github.com/docker/docker/pkg/parsers"
|
||||
"github.com/docker/docker/quota"
|
||||
"github.com/docker/go-units"
|
||||
@@ -393,7 +393,7 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts) (retErr
|
||||
}
|
||||
|
||||
// Write link id to link file
|
||||
if err := ioutils.AtomicWriteFile(path.Join(dir, "link"), []byte(lid), 0o644); err != nil {
|
||||
if err := atomicwriter.WriteFile(path.Join(dir, "link"), []byte(lid), 0o644); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -406,7 +406,7 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts) (retErr
|
||||
return err
|
||||
}
|
||||
|
||||
if err := ioutils.AtomicWriteFile(path.Join(d.dir(parent), "committed"), []byte{}, 0o600); err != nil {
|
||||
if err := atomicwriter.WriteFile(path.Join(d.dir(parent), "committed"), []byte{}, 0o600); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -415,7 +415,7 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts) (retErr
|
||||
return err
|
||||
}
|
||||
if lower != "" {
|
||||
if err := ioutils.AtomicWriteFile(path.Join(dir, lowerFile), []byte(lower), 0o644); err != nil {
|
||||
if err := atomicwriter.WriteFile(path.Join(dir, lowerFile), []byte(lower), 0o644); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/docker/docker/pkg/ioutils"
|
||||
"github.com/docker/docker/pkg/atomicwriter"
|
||||
"github.com/google/uuid"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
@@ -24,7 +24,7 @@ func LoadOrCreateID(root string) (string, error) {
|
||||
idb, err := os.ReadFile(idPath)
|
||||
if os.IsNotExist(err) {
|
||||
id = uuid.New().String()
|
||||
if err := ioutils.AtomicWriteFile(idPath, []byte(id), os.FileMode(0o600)); err != nil {
|
||||
if err := atomicwriter.WriteFile(idPath, []byte(id), os.FileMode(0o600)); err != nil {
|
||||
return "", errors.Wrap(err, "error saving ID file")
|
||||
}
|
||||
} else if err != nil {
|
||||
|
||||
@@ -21,7 +21,7 @@ import (
|
||||
"github.com/docker/docker/daemon/config"
|
||||
"github.com/docker/docker/errdefs"
|
||||
"github.com/docker/docker/libcontainerd/shimopts"
|
||||
"github.com/docker/docker/pkg/ioutils"
|
||||
"github.com/docker/docker/pkg/atomicwriter"
|
||||
"github.com/opencontainers/runtime-spec/specs-go/features"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
@@ -191,7 +191,7 @@ func wrapRuntime(dir, name, binary string, args []string) (string, error) {
|
||||
// containers.
|
||||
suffix := base32Disemvoweled.EncodeToString(sum.Sum(nil))
|
||||
scriptPath := filepath.Join(dir, name+"."+suffix)
|
||||
if err := ioutils.AtomicWriteFile(scriptPath, wrapper.Bytes(), 0o700); err != nil {
|
||||
if err := atomicwriter.WriteFile(scriptPath, wrapper.Bytes(), 0o700); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return scriptPath, nil
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"path/filepath"
|
||||
"sync"
|
||||
|
||||
"github.com/docker/docker/pkg/ioutils"
|
||||
"github.com/docker/docker/pkg/atomicwriter"
|
||||
)
|
||||
|
||||
// Store implements a K/V store for mapping distribution-related IDs
|
||||
@@ -60,7 +60,7 @@ func (store *FSMetadataStore) Set(namespace, key string, value []byte) error {
|
||||
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
|
||||
return err
|
||||
}
|
||||
return ioutils.AtomicWriteFile(path, value, 0o644)
|
||||
return atomicwriter.WriteFile(path, value, 0o644)
|
||||
}
|
||||
|
||||
// Delete removes data indexed by namespace and key. The data file named after
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"sync"
|
||||
|
||||
"github.com/containerd/log"
|
||||
"github.com/docker/docker/pkg/ioutils"
|
||||
"github.com/docker/docker/pkg/atomicwriter"
|
||||
"github.com/opencontainers/go-digest"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
@@ -118,7 +118,7 @@ func (s *fs) Set(data []byte) (digest.Digest, error) {
|
||||
}
|
||||
|
||||
dgst := digest.FromBytes(data)
|
||||
if err := ioutils.AtomicWriteFile(s.contentFile(dgst), data, 0o600); err != nil {
|
||||
if err := atomicwriter.WriteFile(s.contentFile(dgst), data, 0o600); err != nil {
|
||||
return "", errors.Wrap(err, "failed to write digest data")
|
||||
}
|
||||
|
||||
@@ -148,7 +148,7 @@ func (s *fs) SetMetadata(dgst digest.Digest, key string, data []byte) error {
|
||||
if err := os.MkdirAll(baseDir, 0o700); err != nil {
|
||||
return err
|
||||
}
|
||||
return ioutils.AtomicWriteFile(filepath.Join(s.metadataDir(dgst), key), data, 0o600)
|
||||
return atomicwriter.WriteFile(filepath.Join(s.metadataDir(dgst), key), data, 0o600)
|
||||
}
|
||||
|
||||
// GetMetadata returns metadata for a given digest.
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
|
||||
"github.com/containerd/log"
|
||||
"github.com/docker/distribution"
|
||||
"github.com/docker/docker/pkg/atomicwriter"
|
||||
"github.com/docker/docker/pkg/ioutils"
|
||||
"github.com/opencontainers/go-digest"
|
||||
"github.com/pkg/errors"
|
||||
@@ -29,7 +30,7 @@ type fileMetadataStore struct {
|
||||
|
||||
type fileMetadataTransaction struct {
|
||||
store *fileMetadataStore
|
||||
ws *ioutils.AtomicWriteSet
|
||||
ws *atomicwriter.WriteSet
|
||||
}
|
||||
|
||||
// newFSMetadataStore returns an instance of a metadata store
|
||||
@@ -66,7 +67,7 @@ func (fms *fileMetadataStore) StartTransaction() (*fileMetadataTransaction, erro
|
||||
if err := os.MkdirAll(tmpDir, 0o755); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ws, err := ioutils.NewAtomicWriteSet(tmpDir)
|
||||
ws, err := atomicwriter.NewWriteSet(tmpDir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ import (
|
||||
"text/template"
|
||||
|
||||
"github.com/containerd/log"
|
||||
"github.com/docker/docker/pkg/ioutils"
|
||||
"github.com/docker/docker/pkg/atomicwriter"
|
||||
"github.com/opencontainers/go-digest"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
@@ -370,7 +370,7 @@ func (rc *ResolvConf) WriteFile(path, hashPath string, perm os.FileMode) error {
|
||||
|
||||
// Write the hash file.
|
||||
if hashPath != "" {
|
||||
hashFile, err := ioutils.NewAtomicFileWriter(hashPath, perm)
|
||||
hashFile, err := atomicwriter.New(hashPath, perm)
|
||||
if err != nil {
|
||||
return errSystem{err}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package ioutils // import "github.com/docker/docker/pkg/ioutils"
|
||||
package atomicwriter
|
||||
|
||||
import (
|
||||
"io"
|
||||
@@ -6,11 +6,11 @@ import (
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
// NewAtomicFileWriter returns WriteCloser so that writing to it writes to a
|
||||
// New returns a WriteCloser so that writing to it writes to a
|
||||
// temporary file and closing it atomically changes the temporary file to
|
||||
// destination path. Writing and closing concurrently is not allowed.
|
||||
// NOTE: umask is not considered for the file's permissions.
|
||||
func NewAtomicFileWriter(filename string, perm os.FileMode) (io.WriteCloser, error) {
|
||||
func New(filename string, perm os.FileMode) (io.WriteCloser, error) {
|
||||
f, err := os.CreateTemp(filepath.Dir(filename), ".tmp-"+filepath.Base(filename))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -27,10 +27,10 @@ func NewAtomicFileWriter(filename string, perm os.FileMode) (io.WriteCloser, err
|
||||
}, nil
|
||||
}
|
||||
|
||||
// AtomicWriteFile atomically writes data to a file named by filename and with the specified permission bits.
|
||||
// WriteFile atomically writes data to a file named by filename and with the specified permission bits.
|
||||
// NOTE: umask is not considered for the file's permissions.
|
||||
func AtomicWriteFile(filename string, data []byte, perm os.FileMode) error {
|
||||
f, err := NewAtomicFileWriter(filename, perm)
|
||||
func WriteFile(filename string, data []byte, perm os.FileMode) error {
|
||||
f, err := New(filename, perm)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -82,32 +82,32 @@ func (w *atomicFileWriter) Close() (retErr error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// AtomicWriteSet is used to atomically write a set
|
||||
// WriteSet is used to atomically write a set
|
||||
// of files and ensure they are visible at the same time.
|
||||
// Must be committed to a new directory.
|
||||
type AtomicWriteSet struct {
|
||||
type WriteSet struct {
|
||||
root string
|
||||
}
|
||||
|
||||
// NewAtomicWriteSet creates a new atomic write set to
|
||||
// NewWriteSet creates a new atomic write set to
|
||||
// atomically create a set of files. The given directory
|
||||
// is used as the base directory for storing files before
|
||||
// commit. If no temporary directory is given the system
|
||||
// default is used.
|
||||
func NewAtomicWriteSet(tmpDir string) (*AtomicWriteSet, error) {
|
||||
func NewWriteSet(tmpDir string) (*WriteSet, error) {
|
||||
td, err := os.MkdirTemp(tmpDir, "write-set-")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &AtomicWriteSet{
|
||||
return &WriteSet{
|
||||
root: td,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// WriteFile writes a file to the set, guaranteeing the file
|
||||
// has been synced.
|
||||
func (ws *AtomicWriteSet) WriteFile(filename string, data []byte, perm os.FileMode) error {
|
||||
func (ws *WriteSet) WriteFile(filename string, data []byte, perm os.FileMode) error {
|
||||
f, err := ws.FileWriter(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -136,7 +136,7 @@ func (w syncFileCloser) Close() error {
|
||||
|
||||
// FileWriter opens a file writer inside the set. The file
|
||||
// should be synced and closed before calling commit.
|
||||
func (ws *AtomicWriteSet) FileWriter(name string, flag int, perm os.FileMode) (io.WriteCloser, error) {
|
||||
func (ws *WriteSet) FileWriter(name string, flag int, perm os.FileMode) (io.WriteCloser, error) {
|
||||
f, err := os.OpenFile(filepath.Join(ws.root, name), flag, perm)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -146,18 +146,18 @@ func (ws *AtomicWriteSet) FileWriter(name string, flag int, perm os.FileMode) (i
|
||||
|
||||
// Cancel cancels the set and removes all temporary data
|
||||
// created in the set.
|
||||
func (ws *AtomicWriteSet) Cancel() error {
|
||||
func (ws *WriteSet) Cancel() error {
|
||||
return os.RemoveAll(ws.root)
|
||||
}
|
||||
|
||||
// Commit moves all created files to the target directory. The
|
||||
// target directory must not exist and the parent of the target
|
||||
// directory must exist.
|
||||
func (ws *AtomicWriteSet) Commit(target string) error {
|
||||
func (ws *WriteSet) Commit(target string) error {
|
||||
return os.Rename(ws.root, target)
|
||||
}
|
||||
|
||||
// String returns the location the set is writing to.
|
||||
func (ws *AtomicWriteSet) String() string {
|
||||
func (ws *WriteSet) String() string {
|
||||
return ws.root
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package ioutils // import "github.com/docker/docker/pkg/ioutils"
|
||||
package atomicwriter
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@@ -21,7 +21,7 @@ func TestAtomicWriteToFile(t *testing.T) {
|
||||
tmpDir := t.TempDir()
|
||||
|
||||
expected := []byte("barbaz")
|
||||
if err := AtomicWriteFile(filepath.Join(tmpDir, "foo"), expected, testMode); err != nil {
|
||||
if err := WriteFile(filepath.Join(tmpDir, "foo"), expected, testMode); err != nil {
|
||||
t.Fatalf("Error writing to file: %v", err)
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ func TestAtomicWriteSetCommit(t *testing.T) {
|
||||
}
|
||||
|
||||
targetDir := filepath.Join(tmpDir, "target")
|
||||
ws, err := NewAtomicWriteSet(filepath.Join(tmpDir, "tmp"))
|
||||
ws, err := NewWriteSet(filepath.Join(tmpDir, "tmp"))
|
||||
if err != nil {
|
||||
t.Fatalf("Error creating atomic write set: %s", err)
|
||||
}
|
||||
@@ -94,7 +94,7 @@ func TestAtomicWriteSetCancel(t *testing.T) {
|
||||
t.Fatalf("Error creating tmp directory: %s", err)
|
||||
}
|
||||
|
||||
ws, err := NewAtomicWriteSet(filepath.Join(tmpDir, "tmp"))
|
||||
ws, err := NewWriteSet(filepath.Join(tmpDir, "tmp"))
|
||||
if err != nil {
|
||||
t.Fatalf("Error creating atomic write set: %s", err)
|
||||
}
|
||||
44
pkg/ioutils/fswriters_deprecated.go
Normal file
44
pkg/ioutils/fswriters_deprecated.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package ioutils
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/docker/docker/pkg/atomicwriter"
|
||||
)
|
||||
|
||||
// NewAtomicFileWriter returns WriteCloser so that writing to it writes to a
|
||||
// temporary file and closing it atomically changes the temporary file to
|
||||
// destination path. Writing and closing concurrently is not allowed.
|
||||
// NOTE: umask is not considered for the file's permissions.
|
||||
//
|
||||
// Deprecated: use [atomicwriter.New] instead.
|
||||
func NewAtomicFileWriter(filename string, perm os.FileMode) (io.WriteCloser, error) {
|
||||
return atomicwriter.New(filename, perm)
|
||||
}
|
||||
|
||||
// AtomicWriteFile atomically writes data to a file named by filename and with the specified permission bits.
|
||||
// NOTE: umask is not considered for the file's permissions.
|
||||
//
|
||||
// Deprecated: use [atomicwriter.WriteFile] instead.
|
||||
func AtomicWriteFile(filename string, data []byte, perm os.FileMode) error {
|
||||
return atomicwriter.WriteFile(filename, data, perm)
|
||||
}
|
||||
|
||||
// AtomicWriteSet is used to atomically write a set
|
||||
// of files and ensure they are visible at the same time.
|
||||
// Must be committed to a new directory.
|
||||
//
|
||||
// Deprecated: use [atomicwriter.WriteSet] instead.
|
||||
type AtomicWriteSet = atomicwriter.WriteSet
|
||||
|
||||
// NewAtomicWriteSet creates a new atomic write set to
|
||||
// atomically create a set of files. The given directory
|
||||
// is used as the base directory for storing files before
|
||||
// commit. If no temporary directory is given the system
|
||||
// default is used.
|
||||
//
|
||||
// Deprecated: use [atomicwriter.NewWriteSet] instead.
|
||||
func NewAtomicWriteSet(tmpDir string) (*atomicwriter.WriteSet, error) {
|
||||
return atomicwriter.NewWriteSet(tmpDir)
|
||||
}
|
||||
@@ -19,8 +19,8 @@ import (
|
||||
"github.com/docker/docker/api/types/events"
|
||||
"github.com/docker/docker/internal/containerfs"
|
||||
"github.com/docker/docker/internal/lazyregexp"
|
||||
"github.com/docker/docker/pkg/atomicwriter"
|
||||
"github.com/docker/docker/pkg/authorization"
|
||||
"github.com/docker/docker/pkg/ioutils"
|
||||
v2 "github.com/docker/docker/plugin/v2"
|
||||
"github.com/docker/docker/registry"
|
||||
"github.com/moby/pubsub"
|
||||
@@ -281,7 +281,7 @@ func (pm *Manager) save(p *v2.Plugin) error {
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to marshal plugin json")
|
||||
}
|
||||
if err := ioutils.AtomicWriteFile(filepath.Join(pm.config.Root, p.GetID(), configFileName), pluginJSON, 0o600); err != nil {
|
||||
if err := atomicwriter.WriteFile(filepath.Join(pm.config.Root, p.GetID(), configFileName), pluginJSON, 0o600); err != nil {
|
||||
return errors.Wrap(err, "failed to write atomically plugin json")
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"sync"
|
||||
|
||||
"github.com/distribution/reference"
|
||||
"github.com/docker/docker/pkg/ioutils"
|
||||
"github.com/docker/docker/pkg/atomicwriter"
|
||||
"github.com/opencontainers/go-digest"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
@@ -315,7 +315,7 @@ func (store *refStore) save() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return ioutils.AtomicWriteFile(store.jsonPath, jsonData, 0o600)
|
||||
return atomicwriter.WriteFile(store.jsonPath, jsonData, 0o600)
|
||||
}
|
||||
|
||||
func (store *refStore) reload() error {
|
||||
|
||||
@@ -16,8 +16,8 @@ import (
|
||||
"github.com/containerd/log"
|
||||
"github.com/docker/docker/daemon/names"
|
||||
"github.com/docker/docker/errdefs"
|
||||
"github.com/docker/docker/pkg/atomicwriter"
|
||||
"github.com/docker/docker/pkg/idtools"
|
||||
"github.com/docker/docker/pkg/ioutils"
|
||||
"github.com/docker/docker/quota"
|
||||
"github.com/docker/docker/volume"
|
||||
"github.com/pkg/errors"
|
||||
@@ -389,7 +389,7 @@ func (v *localVolume) saveOpts() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = ioutils.AtomicWriteFile(filepath.Join(v.rootPath, "opts.json"), b, 0o600)
|
||||
err = atomicwriter.WriteFile(filepath.Join(v.rootPath, "opts.json"), b, 0o600)
|
||||
if err != nil {
|
||||
return errdefs.System(errors.Wrap(err, "error while persisting volume options"))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user