From 01c2d1a815610e590ef41715b10bea5383f8cece Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20Burzy=C5=84ski?= Date: Mon, 22 Jan 2024 11:04:08 +0100 Subject: [PATCH] fix: negotiate Docker API version (#932) --- CHANGELOG.md | 6 ++++++ pkg/utils/docker/client.go | 19 +++++++++++++++++++ pkg/utils/docker/command.go | 2 +- pkg/utils/docker/copy.go | 4 ++-- pkg/utils/docker/docker.go | 5 +++-- 5 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 pkg/utils/docker/client.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 14caf06a..c4edab11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## v0.44.0 + +- Added a call to `NegotiateAPIVersion` when creating a Docker client to + ensure that the client is able to communicate with the Docker daemon. + [#932](https://github.com/Kong/kubernetes-testing-framework/pull/932) + ## v0.43.0 - Added `WithReleaseChannel` to the GKE cluster builder to allow specifying diff --git a/pkg/utils/docker/client.go b/pkg/utils/docker/client.go new file mode 100644 index 00000000..6c738af9 --- /dev/null +++ b/pkg/utils/docker/client.go @@ -0,0 +1,19 @@ +package docker + +import ( + "context" + + "github.com/docker/docker/client" +) + +// NewNegotiatedClientWithOpts is a wrapper around docker.NewClientWithOpts that negotiates the API version +// with the server. +func NewNegotiatedClientWithOpts(ctx context.Context, opts ...client.Opt) (*client.Client, error) { + c, err := client.NewClientWithOpts(opts...) + if err != nil { + return nil, err + } + // Make sure the client API version matches server's API version to avoid discrepancy issues. + c.NegotiateAPIVersion(ctx) + return c, nil +} diff --git a/pkg/utils/docker/command.go b/pkg/utils/docker/command.go index 7965685b..225d16a9 100644 --- a/pkg/utils/docker/command.go +++ b/pkg/utils/docker/command.go @@ -11,7 +11,7 @@ import ( // given command and arguments on the given container (by ID) privileged. func RunPrivilegedCommand(ctx context.Context, containerID, command string, args ...string) error { // connect to the local docker env - dockerc, err := client.NewClientWithOpts(client.FromEnv) + dockerc, err := NewNegotiatedClientWithOpts(ctx, client.FromEnv) if err != nil { return err } diff --git a/pkg/utils/docker/copy.go b/pkg/utils/docker/copy.go index b951d39f..9f0c8b32 100644 --- a/pkg/utils/docker/copy.go +++ b/pkg/utils/docker/copy.go @@ -16,7 +16,7 @@ import ( // ReadFileFromContainer reads a specific file from a given container by ID. func ReadFileFromContainer(ctx context.Context, containerID string, path string) (*bytes.Buffer, error) { // connect to the local docker environment - dockerc, err := client.NewClientWithOpts(client.FromEnv) + dockerc, err := NewNegotiatedClientWithOpts(ctx, client.FromEnv) if err != nil { return nil, err } @@ -76,7 +76,7 @@ func WriteFileToContainer(ctx context.Context, containerID string, path string, } // connect to the local docker environment - dockerc, err := client.NewClientWithOpts(client.FromEnv) + dockerc, err := NewNegotiatedClientWithOpts(ctx, client.FromEnv) if err != nil { return fmt.Errorf("could not create a client with the local docker system: %w", err) } diff --git a/pkg/utils/docker/docker.go b/pkg/utils/docker/docker.go index 338d08c7..5156b889 100644 --- a/pkg/utils/docker/docker.go +++ b/pkg/utils/docker/docker.go @@ -16,11 +16,12 @@ import ( // InspectDockerContainer is a helper function that uses the local docker environment // provides the full container spec for a container present in that environment by name. func InspectDockerContainer(containerID string) (*types.ContainerJSON, error) { - dockerc, err := client.NewClientWithOpts(client.FromEnv) + ctx := context.Background() + dockerc, err := NewNegotiatedClientWithOpts(ctx, client.FromEnv) if err != nil { return nil, err } - containerJSON, err := dockerc.ContainerInspect(context.Background(), containerID) + containerJSON, err := dockerc.ContainerInspect(ctx, containerID) return &containerJSON, err }