diff --git a/api/swagger.yaml b/api/swagger.yaml index 8122b0f41d..084830599f 100644 --- a/api/swagger.yaml +++ b/api/swagger.yaml @@ -1610,6 +1610,34 @@ definitions: "WorkDir": "/var/lib/docker/overlay2/ef749362d13333e65fc95c572eb525abbe0052e16e086cb64bc3b98ae9aa6d74/work" } + FilesystemChange: + description: | + Change in the container's filesystem. + type: "object" + required: [Path, Kind] + properties: + Path: + description: | + Path to file or directory that has changed. + type: "string" + x-nullable: false + Kind: + $ref: "#/definitions/ChangeType" + + ChangeType: + description: | + Kind of change + + Can be one of: + + - `0`: Modified ("C") + - `1`: Added ("A") + - `2`: Deleted ("D") + type: "integer" + format: "uint8" + enum: [0, 1, 2] + x-nullable: false + ImageInspect: description: | Information about an image in the local image cache. @@ -6873,9 +6901,9 @@ paths: Returns which files in a container's filesystem have been added, deleted, or modified. The `Kind` of modification can be one of: - - `0`: Modified - - `1`: Added - - `2`: Deleted + - `0`: Modified ("C") + - `1`: Added ("A") + - `2`: Deleted ("D") operationId: "ContainerChanges" produces: ["application/json"] responses: @@ -6884,22 +6912,7 @@ paths: schema: type: "array" items: - type: "object" - x-go-name: "ContainerChangeResponseItem" - title: "ContainerChangeResponseItem" - description: "change item in response to ContainerChanges operation" - required: [Path, Kind] - properties: - Path: - description: "Path to file that has changed" - type: "string" - x-nullable: false - Kind: - description: "Kind of change" - type: "integer" - format: "uint8" - enum: [0, 1, 2] - x-nullable: false + $ref: "#/definitions/FilesystemChange" examples: application/json: - Path: "/dev" diff --git a/api/types/container/change_response_deprecated.go b/api/types/container/change_response_deprecated.go new file mode 100644 index 0000000000..6b4b47390d --- /dev/null +++ b/api/types/container/change_response_deprecated.go @@ -0,0 +1,6 @@ +package container + +// ContainerChangeResponseItem change item in response to ContainerChanges operation +// +// Deprecated: use [FilesystemChange]. +type ContainerChangeResponseItem = FilesystemChange diff --git a/api/types/container/change_type.go b/api/types/container/change_type.go new file mode 100644 index 0000000000..fe8d6d3696 --- /dev/null +++ b/api/types/container/change_type.go @@ -0,0 +1,15 @@ +package container + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +// ChangeType Kind of change +// +// Can be one of: +// +// - `0`: Modified ("C") +// - `1`: Added ("A") +// - `2`: Deleted ("D") +// +// swagger:model ChangeType +type ChangeType uint8 diff --git a/api/types/container/change_types.go b/api/types/container/change_types.go new file mode 100644 index 0000000000..3a3a83866e --- /dev/null +++ b/api/types/container/change_types.go @@ -0,0 +1,23 @@ +package container + +const ( + // ChangeModify represents the modify operation. + ChangeModify ChangeType = 0 + // ChangeAdd represents the add operation. + ChangeAdd ChangeType = 1 + // ChangeDelete represents the delete operation. + ChangeDelete ChangeType = 2 +) + +func (ct ChangeType) String() string { + switch ct { + case ChangeModify: + return "C" + case ChangeAdd: + return "A" + case ChangeDelete: + return "D" + default: + return "" + } +} diff --git a/api/types/container/container_changes.go b/api/types/container/container_changes.go deleted file mode 100644 index 16dd5019ee..0000000000 --- a/api/types/container/container_changes.go +++ /dev/null @@ -1,20 +0,0 @@ -package container // import "github.com/docker/docker/api/types/container" - -// ---------------------------------------------------------------------------- -// Code generated by `swagger generate operation`. DO NOT EDIT. -// -// See hack/generate-swagger-api.sh -// ---------------------------------------------------------------------------- - -// ContainerChangeResponseItem change item in response to ContainerChanges operation -// swagger:model ContainerChangeResponseItem -type ContainerChangeResponseItem struct { - - // Kind of change - // Required: true - Kind uint8 `json:"Kind"` - - // Path to file that has changed - // Required: true - Path string `json:"Path"` -} diff --git a/api/types/container/filesystem_change.go b/api/types/container/filesystem_change.go new file mode 100644 index 0000000000..9e9c2ad1d5 --- /dev/null +++ b/api/types/container/filesystem_change.go @@ -0,0 +1,19 @@ +package container + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +// FilesystemChange Change in the container's filesystem. +// +// swagger:model FilesystemChange +type FilesystemChange struct { + + // kind + // Required: true + Kind ChangeType `json:"Kind"` + + // Path to file or directory that has changed. + // + // Required: true + Path string `json:"Path"` +} diff --git a/client/container_diff.go b/client/container_diff.go index 29dac8491d..c22c819a79 100644 --- a/client/container_diff.go +++ b/client/container_diff.go @@ -9,8 +9,8 @@ import ( ) // ContainerDiff shows differences in a container filesystem since it was started. -func (cli *Client) ContainerDiff(ctx context.Context, containerID string) ([]container.ContainerChangeResponseItem, error) { - var changes []container.ContainerChangeResponseItem +func (cli *Client) ContainerDiff(ctx context.Context, containerID string) ([]container.FilesystemChange, error) { + var changes []container.FilesystemChange serverResp, err := cli.get(ctx, "/containers/"+containerID+"/changes", url.Values{}, nil) defer ensureReaderClosed(serverResp) diff --git a/client/container_diff_test.go b/client/container_diff_test.go index 14e243343e..6fad8767b2 100644 --- a/client/container_diff_test.go +++ b/client/container_diff_test.go @@ -12,6 +12,8 @@ import ( "github.com/docker/docker/api/types/container" "github.com/docker/docker/errdefs" + "gotest.tools/v3/assert" + is "gotest.tools/v3/assert/cmp" ) func TestContainerDiffError(t *testing.T) { @@ -19,28 +21,33 @@ func TestContainerDiffError(t *testing.T) { client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, err := client.ContainerDiff(context.Background(), "nothing") - if !errdefs.IsSystem(err) { - t.Fatalf("expected a Server Error, got %[1]T: %[1]v", err) - } + assert.Check(t, is.ErrorType(err, errdefs.IsSystem)) } func TestContainerDiff(t *testing.T) { - expectedURL := "/containers/container_id/changes" + const expectedURL = "/containers/container_id/changes" + + expected := []container.FilesystemChange{ + { + Kind: container.ChangeModify, + Path: "/path/1", + }, + { + Kind: container.ChangeAdd, + Path: "/path/2", + }, + { + Kind: container.ChangeDelete, + Path: "/path/3", + }, + } + client := &Client{ client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { - return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) + return nil, fmt.Errorf("expected URL '%s', got '%s'", expectedURL, req.URL) } - b, err := json.Marshal([]container.ContainerChangeResponseItem{ - { - Kind: 0, - Path: "/path/1", - }, - { - Kind: 1, - Path: "/path/2", - }, - }) + b, err := json.Marshal(expected) if err != nil { return nil, err } @@ -52,10 +59,6 @@ func TestContainerDiff(t *testing.T) { } changes, err := client.ContainerDiff(context.Background(), "container_id") - if err != nil { - t.Fatal(err) - } - if len(changes) != 2 { - t.Fatalf("expected an array of 2 changes, got %v", changes) - } + assert.Check(t, err) + assert.Check(t, is.DeepEqual(changes, expected)) } diff --git a/client/interface.go b/client/interface.go index 692dcfbece..64877d1641 100644 --- a/client/interface.go +++ b/client/interface.go @@ -48,7 +48,7 @@ type ContainerAPIClient interface { ContainerAttach(ctx context.Context, container string, options types.ContainerAttachOptions) (types.HijackedResponse, error) ContainerCommit(ctx context.Context, container string, options types.ContainerCommitOptions) (types.IDResponse, error) ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, platform *specs.Platform, containerName string) (container.CreateResponse, error) - ContainerDiff(ctx context.Context, container string) ([]container.ContainerChangeResponseItem, error) + ContainerDiff(ctx context.Context, container string) ([]container.FilesystemChange, error) ContainerExecAttach(ctx context.Context, execID string, config types.ExecStartCheck) (types.HijackedResponse, error) ContainerExecCreate(ctx context.Context, container string, config types.ExecConfig) (types.IDResponse, error) ContainerExecInspect(ctx context.Context, execID string) (types.ContainerExecInspect, error) diff --git a/hack/generate-swagger-api.sh b/hack/generate-swagger-api.sh index 8a4832cbde..d5032178e5 100755 --- a/hack/generate-swagger-api.sh +++ b/hack/generate-swagger-api.sh @@ -20,7 +20,9 @@ swagger generate model -f api/swagger.yaml \ -t api -m types/container --skip-validator -C api/swagger-gen.yaml \ -n ContainerCreateResponse \ -n ContainerWaitResponse \ - -n ContainerWaitExitError + -n ContainerWaitExitError \ + -n ChangeType \ + -n FilesystemChange swagger generate model -f api/swagger.yaml \ -t api -m types/volume --skip-validator -C api/swagger-gen.yaml \ @@ -32,7 +34,6 @@ swagger generate operation -f api/swagger.yaml \ -t api -a types -m types -C api/swagger-gen.yaml \ -T api/templates --skip-responses --skip-parameters --skip-validator \ -n Authenticate \ - -n ContainerChanges \ -n ContainerTop \ -n ContainerUpdate \ -n ImageHistory diff --git a/integration/container/diff_test.go b/integration/container/diff_test.go index 7df11ce605..c1e7ea6974 100644 --- a/integration/container/diff_test.go +++ b/integration/container/diff_test.go @@ -7,7 +7,6 @@ import ( containertypes "github.com/docker/docker/api/types/container" "github.com/docker/docker/integration/internal/container" - "github.com/docker/docker/pkg/archive" "gotest.tools/v3/assert" "gotest.tools/v3/poll" "gotest.tools/v3/skip" @@ -25,15 +24,15 @@ func TestDiff(t *testing.T) { // it will take a few seconds to exit. Also there's no way in Windows to // differentiate between an Add or a Modify, and all files are under // a "Files/" prefix. - expected := []containertypes.ContainerChangeResponseItem{ - {Kind: archive.ChangeAdd, Path: "/foo"}, - {Kind: archive.ChangeAdd, Path: "/foo/bar"}, + expected := []containertypes.FilesystemChange{ + {Kind: containertypes.ChangeAdd, Path: "/foo"}, + {Kind: containertypes.ChangeAdd, Path: "/foo/bar"}, } if testEnv.OSType == "windows" { poll.WaitOn(t, container.IsInState(ctx, client, cID, "exited"), poll.WithDelay(100*time.Millisecond), poll.WithTimeout(60*time.Second)) - expected = []containertypes.ContainerChangeResponseItem{ - {Kind: archive.ChangeModify, Path: "Files/foo"}, - {Kind: archive.ChangeModify, Path: "Files/foo/bar"}, + expected = []containertypes.FilesystemChange{ + {Kind: containertypes.ChangeModify, Path: "Files/foo"}, + {Kind: containertypes.ChangeModify, Path: "Files/foo/bar"}, } } diff --git a/integration/plugin/graphdriver/external_test.go b/integration/plugin/graphdriver/external_test.go index 8b14754467..5e9d9b851e 100644 --- a/integration/plugin/graphdriver/external_test.go +++ b/integration/plugin/graphdriver/external_test.go @@ -450,8 +450,8 @@ func testGraphDriver(ctx context.Context, t *testing.T, c client.APIClient, driv diffs, err := c.ContainerDiff(ctx, id) assert.NilError(t, err) - assert.Check(t, is.Contains(diffs, containertypes.ContainerChangeResponseItem{ - Kind: archive.ChangeAdd, + assert.Check(t, is.Contains(diffs, containertypes.FilesystemChange{ + Kind: containertypes.ChangeAdd, Path: "/hello", }), "diffs: %v", diffs)