diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6488bb7d2..1fcc42ba0 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -163,7 +163,6 @@ jobs: INTEGRATION_TEST_AZURE_CLIENT_SECRET: ${{ secrets.azure_client_secret }} INTEGRATION_TEST_AZURE_CLIENT_ID: ${{ secrets.azure_client_id }} KOSLI_SONAR_API_TOKEN: ${{ secrets.sonarqube_token }} - DOCKER_API_VERSION: "1.45" KOSLI_API_TOKEN_PROD: ${{ secrets.kosli_querying_api_token }} run: | # some tests use git operations, therefore the git author on the CI VM needs to be set @@ -273,4 +272,3 @@ jobs: --trail ${{ inputs.TRAIL_NAME }} --scan-results snyk-dependency.json --org ${{ inputs.KOSLI_ORG }} - diff --git a/cmd/kosli/snapshotDocker.go b/cmd/kosli/snapshotDocker.go index 125224d7e..4ad545cb7 100644 --- a/cmd/kosli/snapshotDocker.go +++ b/cmd/kosli/snapshotDocker.go @@ -88,7 +88,7 @@ func (o *snapshotDockerOptions) run(args []string) error { func CreateDockerArtifactsData() ([]*server.ServerData, error) { result := []*server.ServerData{} - cli, err := client.NewClientWithOpts(client.FromEnv) + cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) if err != nil { return result, err } diff --git a/internal/digest/digest.go b/internal/digest/digest.go index d8581d69d..d534ee94c 100644 --- a/internal/digest/digest.go +++ b/internal/digest/digest.go @@ -251,7 +251,7 @@ func FileSha256(filepath string, logger *logger.Logger) (string, error) { // It requires the docker daemon to be accessible and the docker image to be locally present. // The docker image must have been pushed into a registry to have a digest. func DockerImageSha256(imageID string) (string, error) { - cli, err := client.NewClientWithOpts(client.FromEnv) + cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) if err != nil { return "", err } @@ -323,7 +323,7 @@ func requestManifestFromRegistry(registryEndPoint, imageName, imageTag, registry // RemoteDockerImageSha256 returns a sha256 digest of a docker image by reading it from // remote docker registry func RemoteDockerImageSha256(imageName, imageTag, registryEndPoint, registryToken string, logger *logger.Logger) (string, error) { - // Some docker images have Manifest list, aka “fat manifest” which combines + // Some docker images have Manifest list, aka "fat manifest" which combines // image manifests for one or more platforms. Other images don't have such manifest. // The response Content-Type header specifies whether an image has it or not. // More details here: https://docs.docker.com/registry/spec/manifest-v2-2/ diff --git a/internal/docker/docker.go b/internal/docker/docker.go index cd1f3a70d..bc348d392 100644 --- a/internal/docker/docker.go +++ b/internal/docker/docker.go @@ -14,9 +14,17 @@ import ( "github.com/docker/docker/client" ) +// newDockerClient creates a Docker client with API version negotiation enabled. +// This ensures the client automatically downgrades its API version to match +// the daemon, preventing "client version X is too new" errors when the SDK +// is newer than the Docker Engine. +func newDockerClient() (*client.Client, error) { + return client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) +} + // PullDockerImage pulls a docker image or returns an error func PullDockerImage(imageName string) error { - cli, err := client.NewClientWithOpts(client.FromEnv) + cli, err := newDockerClient() if err != nil { return err } @@ -41,7 +49,7 @@ func PullDockerImage(imageName string) error { // PushDockerImage pushes a docker image to the local registry or returns an error func PushDockerImage(imageName string) error { - cli, err := client.NewClientWithOpts(client.FromEnv) + cli, err := newDockerClient() if err != nil { return err } @@ -73,7 +81,7 @@ func PushDockerImage(imageName string) error { // TagDockerImage tags a docker image or returns an error func TagDockerImage(sourceName, targetName string) error { - cli, err := client.NewClientWithOpts(client.FromEnv) + cli, err := newDockerClient() if err != nil { return err } @@ -83,7 +91,7 @@ func TagDockerImage(sourceName, targetName string) error { // RemoveDockerImage deletes a docker image or return an error func RemoveDockerImage(imageName string) error { - cli, err := client.NewClientWithOpts(client.FromEnv) + cli, err := newDockerClient() if err != nil { return err } @@ -98,7 +106,7 @@ func RemoveDockerImage(imageName string) error { // RunDockerContainer runs a docker container that sleeps for 6 minutes and returns its ID or returns an error func RunDockerContainer(imageName string) (string, error) { - cli, err := client.NewClientWithOpts(client.FromEnv) + cli, err := newDockerClient() if err != nil { return "", err } @@ -117,7 +125,7 @@ func RunDockerContainer(imageName string) (string, error) { // RemoveDockerContainer remove a docker container or returns an error func RemoveDockerContainer(containerID string) error { - cli, err := client.NewClientWithOpts(client.FromEnv) + cli, err := newDockerClient() if err != nil { return err }