From 47d7c9e31dcb5e83e763536afa55937cdf0f2a74 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Sat, 8 Jun 2024 20:23:28 +0200 Subject: [PATCH] api/types: move ContainerPathStat to api/types/container Signed-off-by: Sebastiaan van Stijn --- api/server/router/container/backend.go | 4 ++-- api/server/router/container/copy.go | 4 ++-- api/types/container/container.go | 16 ++++++++++++++++ api/types/types.go | 12 ------------ api/types/types_deprecated.go | 7 +++++++ client/container_copy.go | 13 +++++++------ client/container_copy_test.go | 7 ++++--- client/interface.go | 4 ++-- container/archive_windows.go | 6 +++--- daemon/archive.go | 6 +++--- daemon/archive_unix.go | 6 +++--- daemon/archive_windows.go | 5 ++--- daemon/containerfs_linux.go | 24 ++++++++++++------------ 13 files changed, 63 insertions(+), 51 deletions(-) diff --git a/api/server/router/container/backend.go b/api/server/router/container/backend.go index edb2c73f41..07f2fedd7e 100644 --- a/api/server/router/container/backend.go +++ b/api/server/router/container/backend.go @@ -23,10 +23,10 @@ type execBackend interface { // copyBackend includes functions to implement to provide container copy functionality. type copyBackend interface { - ContainerArchivePath(name string, path string) (content io.ReadCloser, stat *types.ContainerPathStat, err error) + ContainerArchivePath(name string, path string) (content io.ReadCloser, stat *container.PathStat, err error) ContainerExport(ctx context.Context, name string, out io.Writer) error ContainerExtractToDir(name, path string, copyUIDGID, noOverwriteDirNonDir bool, content io.Reader) error - ContainerStatPath(name string, path string) (stat *types.ContainerPathStat, err error) + ContainerStatPath(name string, path string) (stat *container.PathStat, err error) } // stateBackend includes functions to implement to provide container state lifecycle functionality. diff --git a/api/server/router/container/copy.go b/api/server/router/container/copy.go index 7596818e56..0f84c9900c 100644 --- a/api/server/router/container/copy.go +++ b/api/server/router/container/copy.go @@ -10,12 +10,12 @@ import ( "net/http" "github.com/docker/docker/api/server/httputils" - "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" gddohttputil "github.com/golang/gddo/httputil" ) // setContainerPathStatHeader encodes the stat to JSON, base64 encode, and place in a header. -func setContainerPathStatHeader(stat *types.ContainerPathStat, header http.Header) error { +func setContainerPathStatHeader(stat *container.PathStat, header http.Header) error { statJSON, err := json.Marshal(stat) if err != nil { return err diff --git a/api/types/container/container.go b/api/types/container/container.go index 51cd739147..369ca83e02 100644 --- a/api/types/container/container.go +++ b/api/types/container/container.go @@ -1,8 +1,24 @@ package container +import ( + "os" + "time" +) + // PruneReport contains the response for Engine API: // POST "/containers/prune" type PruneReport struct { ContainersDeleted []string SpaceReclaimed uint64 } + +// PathStat is used to encode the header from +// GET "/containers/{name:.*}/archive" +// "Name" is the file or directory name. +type PathStat struct { + Name string `json:"name"` + Size int64 `json:"size"` + Mode os.FileMode `json:"mode"` + Mtime time.Time `json:"mtime"` + LinkTarget string `json:"linkTarget"` +} diff --git a/api/types/types.go b/api/types/types.go index 009eab53c1..d48ed9934f 100644 --- a/api/types/types.go +++ b/api/types/types.go @@ -2,7 +2,6 @@ package types // import "github.com/docker/docker/api/types" import ( "io" - "os" "time" "github.com/docker/docker/api/types/container" @@ -162,17 +161,6 @@ type Container struct { Mounts []MountPoint } -// ContainerPathStat is used to encode the header from -// GET "/containers/{name:.*}/archive" -// "Name" is the file or directory name. -type ContainerPathStat struct { - Name string `json:"name"` - Size int64 `json:"size"` - Mode os.FileMode `json:"mode"` - Mtime time.Time `json:"mtime"` - LinkTarget string `json:"linkTarget"` -} - // ContainerStats contains response of Engine API: // GET "/stats" type ContainerStats struct { diff --git a/api/types/types_deprecated.go b/api/types/types_deprecated.go index 3d555a03b8..9cc4589189 100644 --- a/api/types/types_deprecated.go +++ b/api/types/types_deprecated.go @@ -78,3 +78,10 @@ type ContainerExecInspect = container.ExecInspect // // Deprecated: use [container.PruneReport]. type ContainersPruneReport = container.PruneReport + +// ContainerPathStat is used to encode the header from +// GET "/containers/{name:.*}/archive" +// "Name" is the file or directory name. +// +// Deprecated: use [container.PathStat]. +type ContainerPathStat = container.PathStat diff --git a/client/container_copy.go b/client/container_copy.go index 883be7fa34..034e06a786 100644 --- a/client/container_copy.go +++ b/client/container_copy.go @@ -12,10 +12,11 @@ import ( "strings" "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" ) // ContainerStatPath returns stat information about a path inside the container filesystem. -func (cli *Client) ContainerStatPath(ctx context.Context, containerID, path string) (types.ContainerPathStat, error) { +func (cli *Client) ContainerStatPath(ctx context.Context, containerID, path string) (container.PathStat, error) { query := url.Values{} query.Set("path", filepath.ToSlash(path)) // Normalize the paths used in the API. @@ -23,7 +24,7 @@ func (cli *Client) ContainerStatPath(ctx context.Context, containerID, path stri response, err := cli.head(ctx, urlStr, query, nil) defer ensureReaderClosed(response) if err != nil { - return types.ContainerPathStat{}, err + return container.PathStat{}, err } return getContainerPathStatFromHeader(response.header) } @@ -55,14 +56,14 @@ func (cli *Client) CopyToContainer(ctx context.Context, containerID, dstPath str // CopyFromContainer gets the content from the container and returns it as a Reader // for a TAR archive to manipulate it in the host. It's up to the caller to close the reader. -func (cli *Client) CopyFromContainer(ctx context.Context, containerID, srcPath string) (io.ReadCloser, types.ContainerPathStat, error) { +func (cli *Client) CopyFromContainer(ctx context.Context, containerID, srcPath string) (io.ReadCloser, container.PathStat, error) { query := make(url.Values, 1) query.Set("path", filepath.ToSlash(srcPath)) // Normalize the paths used in the API. apiPath := "/containers/" + containerID + "/archive" response, err := cli.get(ctx, apiPath, query, nil) if err != nil { - return nil, types.ContainerPathStat{}, err + return nil, container.PathStat{}, err } // In order to get the copy behavior right, we need to know information @@ -78,8 +79,8 @@ func (cli *Client) CopyFromContainer(ctx context.Context, containerID, srcPath s return response.body, stat, err } -func getContainerPathStatFromHeader(header http.Header) (types.ContainerPathStat, error) { - var stat types.ContainerPathStat +func getContainerPathStatFromHeader(header http.Header) (container.PathStat, error) { + var stat container.PathStat encodedStat := header.Get("X-Docker-Container-Path-Stat") statDecoder := base64.NewDecoder(base64.StdEncoding, strings.NewReader(encodedStat)) diff --git a/client/container_copy_test.go b/client/container_copy_test.go index 8328a9d00f..ccb9bf9e1c 100644 --- a/client/container_copy_test.go +++ b/client/container_copy_test.go @@ -12,6 +12,7 @@ import ( "testing" "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" "github.com/docker/docker/errdefs" "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" @@ -64,7 +65,7 @@ func TestContainerStatPath(t *testing.T) { if path != expectedPath { return nil, fmt.Errorf("path not set in URL query properly") } - content, err := json.Marshal(types.ContainerPathStat{ + content, err := json.Marshal(container.PathStat{ Name: "name", Mode: 0o700, }) @@ -188,7 +189,7 @@ func TestCopyFromContainerNotFoundError(t *testing.T) { func TestCopyFromContainerEmptyResponse(t *testing.T) { client := &Client{ client: newMockClient(func(req *http.Request) (*http.Response, error) { - content, err := json.Marshal(types.ContainerPathStat{ + content, err := json.Marshal(container.PathStat{ Name: "path/to/file", Mode: 0o700, }) @@ -242,7 +243,7 @@ func TestCopyFromContainer(t *testing.T) { return nil, fmt.Errorf("path not set in URL query properly, expected '%s', got %s", expectedPath, path) } - headercontent, err := json.Marshal(types.ContainerPathStat{ + headercontent, err := json.Marshal(container.PathStat{ Name: "name", Mode: 0o700, }) diff --git a/client/interface.go b/client/interface.go index 6b37449bc7..986800ba8e 100644 --- a/client/interface.go +++ b/client/interface.go @@ -66,7 +66,7 @@ type ContainerAPIClient interface { ContainerRename(ctx context.Context, container, newContainerName string) error ContainerResize(ctx context.Context, container string, options container.ResizeOptions) error ContainerRestart(ctx context.Context, container string, options container.StopOptions) error - ContainerStatPath(ctx context.Context, container, path string) (types.ContainerPathStat, error) + ContainerStatPath(ctx context.Context, container, path string) (container.PathStat, error) ContainerStats(ctx context.Context, container string, stream bool) (types.ContainerStats, error) ContainerStatsOneShot(ctx context.Context, container string) (types.ContainerStats, error) ContainerStart(ctx context.Context, container string, options container.StartOptions) error @@ -75,7 +75,7 @@ type ContainerAPIClient interface { ContainerUnpause(ctx context.Context, container string) error ContainerUpdate(ctx context.Context, container string, updateConfig container.UpdateConfig) (container.ContainerUpdateOKBody, error) ContainerWait(ctx context.Context, container string, condition container.WaitCondition) (<-chan container.WaitResponse, <-chan error) - CopyFromContainer(ctx context.Context, container, srcPath string) (io.ReadCloser, types.ContainerPathStat, error) + CopyFromContainer(ctx context.Context, container, srcPath string) (io.ReadCloser, container.PathStat, error) CopyToContainer(ctx context.Context, container, path string, content io.Reader, options types.CopyToContainerOptions) error ContainersPrune(ctx context.Context, pruneFilters filters.Args) (container.PruneReport, error) } diff --git a/container/archive_windows.go b/container/archive_windows.go index b859493da0..77552d21fb 100644 --- a/container/archive_windows.go +++ b/container/archive_windows.go @@ -4,7 +4,7 @@ import ( "os" "path/filepath" - "github.com/docker/docker/api/types" + containertypes "github.com/docker/docker/api/types/container" "github.com/docker/docker/pkg/archive" "github.com/pkg/errors" ) @@ -45,7 +45,7 @@ func (container *Container) ResolvePath(path string) (resolvedPath, absPath stri // be acquired before calling this method and the given path should be fully // resolved to a path on the host corresponding to the given absolute path // inside the container. -func (container *Container) StatPath(resolvedPath, absPath string) (stat *types.ContainerPathStat, err error) { +func (container *Container) StatPath(resolvedPath, absPath string) (stat *containertypes.PathStat, err error) { if container.BaseFS == "" { return nil, errors.New("StatPath: BaseFS of container " + container.ID + " is unexpectedly empty") } @@ -72,7 +72,7 @@ func (container *Container) StatPath(resolvedPath, absPath string) (stat *types. linkTarget = filepath.Join(string(filepath.Separator), linkTarget) } - return &types.ContainerPathStat{ + return &containertypes.PathStat{ Name: filepath.Base(absPath), Size: lstat.Size(), Mode: lstat.Mode(), diff --git a/daemon/archive.go b/daemon/archive.go index 65a67ffcc2..b18e74649f 100644 --- a/daemon/archive.go +++ b/daemon/archive.go @@ -4,13 +4,13 @@ import ( "io" "os" - "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" "github.com/docker/docker/errdefs" ) // ContainerStatPath stats the filesystem resource at the specified path in the // container identified by the given name. -func (daemon *Daemon) ContainerStatPath(name string, path string) (stat *types.ContainerPathStat, err error) { +func (daemon *Daemon) ContainerStatPath(name string, path string) (stat *container.PathStat, err error) { ctr, err := daemon.GetContainer(name) if err != nil { return nil, err @@ -30,7 +30,7 @@ func (daemon *Daemon) ContainerStatPath(name string, path string) (stat *types.C // ContainerArchivePath creates an archive of the filesystem resource at the // specified path in the container identified by the given name. Returns a // tar archive of the resource and whether it was a directory or a single file. -func (daemon *Daemon) ContainerArchivePath(name string, path string) (content io.ReadCloser, stat *types.ContainerPathStat, err error) { +func (daemon *Daemon) ContainerArchivePath(name string, path string) (content io.ReadCloser, stat *container.PathStat, err error) { ctr, err := daemon.GetContainer(name) if err != nil { return nil, nil, err diff --git a/daemon/archive_unix.go b/daemon/archive_unix.go index cbbf9c5f8a..9c0f3d85ab 100644 --- a/daemon/archive_unix.go +++ b/daemon/archive_unix.go @@ -8,7 +8,7 @@ import ( "os" "path/filepath" - "github.com/docker/docker/api/types" + containertypes "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/events" "github.com/docker/docker/container" "github.com/docker/docker/errdefs" @@ -20,7 +20,7 @@ import ( // containerStatPath stats the filesystem resource at the specified path in this // container. Returns stat info about the resource. -func (daemon *Daemon) containerStatPath(container *container.Container, path string) (stat *types.ContainerPathStat, err error) { +func (daemon *Daemon) containerStatPath(container *container.Container, path string) (stat *containertypes.PathStat, err error) { container.Lock() defer container.Unlock() @@ -36,7 +36,7 @@ func (daemon *Daemon) containerStatPath(container *container.Container, path str // containerArchivePath creates an archive of the filesystem resource at the specified // path in this container. Returns a tar archive of the resource and stat info // about the resource. -func (daemon *Daemon) containerArchivePath(container *container.Container, path string) (content io.ReadCloser, stat *types.ContainerPathStat, err error) { +func (daemon *Daemon) containerArchivePath(container *container.Container, path string) (content io.ReadCloser, stat *containertypes.PathStat, err error) { container.Lock() defer func() { diff --git a/daemon/archive_windows.go b/daemon/archive_windows.go index 32a76f8202..ea100fce60 100644 --- a/daemon/archive_windows.go +++ b/daemon/archive_windows.go @@ -7,7 +7,6 @@ import ( "path/filepath" "strings" - "github.com/docker/docker/api/types" containertypes "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/events" "github.com/docker/docker/container" @@ -19,7 +18,7 @@ import ( // containerStatPath stats the filesystem resource at the specified path in this // container. Returns stat info about the resource. -func (daemon *Daemon) containerStatPath(container *container.Container, path string) (stat *types.ContainerPathStat, err error) { +func (daemon *Daemon) containerStatPath(container *container.Container, path string) (stat *containertypes.PathStat, err error) { container.Lock() defer container.Unlock() @@ -53,7 +52,7 @@ func (daemon *Daemon) containerStatPath(container *container.Container, path str // containerArchivePath creates an archive of the filesystem resource at the specified // path in this container. Returns a tar archive of the resource and stat info // about the resource. -func (daemon *Daemon) containerArchivePath(container *container.Container, path string) (content io.ReadCloser, stat *types.ContainerPathStat, err error) { +func (daemon *Daemon) containerArchivePath(container *container.Container, path string) (content io.ReadCloser, stat *containertypes.PathStat, err error) { container.Lock() defer func() { diff --git a/daemon/containerfs_linux.go b/daemon/containerfs_linux.go index 12b1cb6828..a922a669c4 100644 --- a/daemon/containerfs_linux.go +++ b/daemon/containerfs_linux.go @@ -15,7 +15,7 @@ import ( "github.com/moby/sys/symlink" "golang.org/x/sys/unix" - "github.com/docker/docker/api/types" + containertypes "github.com/docker/docker/api/types/container" "github.com/docker/docker/container" "github.com/docker/docker/internal/compatcontext" "github.com/docker/docker/internal/mounttree" @@ -54,19 +54,19 @@ type containerFSView struct { } // openContainerFS opens a new view of the container's filesystem. -func (daemon *Daemon) openContainerFS(container *container.Container) (_ *containerFSView, err error) { +func (daemon *Daemon) openContainerFS(ctr *container.Container) (_ *containerFSView, err error) { ctx := context.TODO() - if err := daemon.Mount(container); err != nil { + if err := daemon.Mount(ctr); err != nil { return nil, err } defer func() { if err != nil { - _ = daemon.Unmount(container) + _ = daemon.Unmount(ctr) } }() - mounts, cleanup, err := daemon.setupMounts(ctx, container) + mounts, cleanup, err := daemon.setupMounts(ctx, ctr) if err != nil { return nil, err } @@ -74,7 +74,7 @@ func (daemon *Daemon) openContainerFS(container *container.Container) (_ *contai ctx := compatcontext.WithoutCancel(ctx) cleanup(ctx) if err != nil { - _ = container.UnmountVolumes(ctx, daemon.LogVolumeEvent) + _ = ctr.UnmountVolumes(ctx, daemon.LogVolumeEvent) } }() @@ -89,7 +89,7 @@ func (daemon *Daemon) openContainerFS(container *container.Container) (_ *contai return err } for _, m := range mounts { - dest, err := container.GetResourcePath(m.Destination) + dest, err := ctr.GetResourcePath(m.Destination) if err != nil { return err } @@ -147,7 +147,7 @@ func (daemon *Daemon) openContainerFS(container *container.Container) (_ *contai } } - return mounttree.SwitchRoot(container.BaseFS) + return mounttree.SwitchRoot(ctr.BaseFS) }, func() { defer close(done) @@ -168,7 +168,7 @@ func (daemon *Daemon) openContainerFS(container *container.Container) (_ *contai } vw := &containerFSView{ d: daemon, - ctr: container, + ctr: ctr, todo: todo, done: done, } @@ -219,8 +219,8 @@ func (vw *containerFSView) Close() error { // Stat returns the metadata for path, relative to the current working directory // of vw inside the container filesystem view. -func (vw *containerFSView) Stat(ctx context.Context, path string) (*types.ContainerPathStat, error) { - var stat *types.ContainerPathStat +func (vw *containerFSView) Stat(ctx context.Context, path string) (*containertypes.PathStat, error) { + var stat *containertypes.PathStat err := vw.RunInFS(ctx, func() error { lstat, err := os.Lstat(path) if err != nil { @@ -235,7 +235,7 @@ func (vw *containerFSView) Stat(ctx context.Context, path string) (*types.Contai return err } } - stat = &types.ContainerPathStat{ + stat = &containertypes.PathStat{ Name: filepath.Base(path), Size: lstat.Size(), Mode: lstat.Mode(),