diff --git a/README.md b/README.md index 0800136cf..c23e96a20 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,13 @@ [![codecov](https://codecov.io/gh/kosli-dev/cli/branch/main/graph/badge.svg?token=Z4Y53XIOKJ)](https://codecov.io/gh/kosli-dev/cli) [![Static Badge](https://img.shields.io/badge/provenance-blue?style=plastic&link=https%3A%2F%2Fapp.kosli.com%2Fkosli-public%2Fflows%2Fcli-release%2Ftrails%2F)](https://app.kosli.com/kosli-public/flows/cli-release/trails/) +[![Main](https://github.com/kosli-dev/cli/actions/workflows/main.yml/badge.svg)](https://github.com/kosli-dev/cli/actions/workflows/main.yml) +[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) # Kosli CLI -This repo contains the Kosli CLI, for recording and querying software delivery events [Kosli](www.kosli.com) +This repo contains the Kosli CLI, for recording and querying software delivery events to [Kosli](www.kosli.com). -Some useful links: +Some useful links: * [Documentation site](https://docs.kosli.com/) for full details on usage. * [Developer guide](/dev-guide.md) for details on working with the code in this repo. diff --git a/cmd/kosli/snapshotDocker.go b/cmd/kosli/snapshotDocker.go index 0fd1d3ba3..4f80a03f4 100644 --- a/cmd/kosli/snapshotDocker.go +++ b/cmd/kosli/snapshotDocker.go @@ -9,8 +9,8 @@ import ( "strings" cerrdefs "github.com/containerd/errdefs" - "github.com/docker/docker/api/types/container" - "github.com/docker/docker/client" + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/client" "github.com/kosli-dev/cli/internal/digest" log "github.com/kosli-dev/cli/internal/logger" "github.com/kosli-dev/cli/internal/requests" @@ -89,17 +89,17 @@ func (o *snapshotDockerOptions) run(args []string) error { } func CreateDockerArtifactsData() ([]*server.ServerData, error) { - cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + cli, err := client.New(client.FromEnv) if err != nil { return []*server.ServerData{}, err } - containers, err := cli.ContainerList(context.Background(), container.ListOptions{}) + containers, err := cli.ContainerList(context.Background(), client.ContainerListOptions{}) if err != nil { return []*server.ServerData{}, err } - return dockerArtifactsFromContainers(containers, digest.DockerImageSha256, logger) + return dockerArtifactsFromContainers(containers.Items, digest.DockerImageSha256, logger) } func dockerArtifactsFromContainers( diff --git a/cmd/kosli/snapshotDocker_test.go b/cmd/kosli/snapshotDocker_test.go index 7e1d9e929..fbc6e233d 100644 --- a/cmd/kosli/snapshotDocker_test.go +++ b/cmd/kosli/snapshotDocker_test.go @@ -7,7 +7,7 @@ import ( "testing" cerrdefs "github.com/containerd/errdefs" - "github.com/docker/docker/api/types/container" + "github.com/moby/moby/api/types/container" "github.com/kosli-dev/cli/internal/digest" "github.com/kosli-dev/cli/internal/docker" log "github.com/kosli-dev/cli/internal/logger" diff --git a/go.mod b/go.mod index c8f558391..540d0d66a 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,6 @@ require ( github.com/aws/smithy-go v1.25.1 github.com/containerd/errdefs v1.0.0 github.com/containers/image/v5 v5.36.2 - github.com/docker/docker v28.5.2+incompatible github.com/go-git/go-billy/v5 v5.9.0 github.com/go-git/go-git/v5 v5.19.0 github.com/go-playground/validator/v10 v10.30.2 @@ -31,6 +30,8 @@ require ( github.com/maxcnunes/httpfake v1.2.4 github.com/microsoft/azure-devops-go-api/azuredevops v1.0.0-b5 github.com/mitchellh/go-homedir v1.1.0 + github.com/moby/moby/api v1.54.2 + github.com/moby/moby/client v0.4.1 github.com/open-policy-agent/opa v1.16.1 github.com/otiai10/copy v1.14.1 github.com/owenrumney/go-sarif/v2 v2.3.3 @@ -104,8 +105,9 @@ require ( github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.1 // indirect github.com/distribution/reference v0.6.0 // indirect github.com/docker/distribution v2.8.3+incompatible // indirect + github.com/docker/docker v28.3.2+incompatible // indirect github.com/docker/docker-credential-helpers v0.9.3 // indirect - github.com/docker/go-connections v0.5.0 // indirect + github.com/docker/go-connections v0.7.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/emicklei/go-restful/v3 v3.13.0 // indirect github.com/emirpasic/gods v1.18.1 // indirect @@ -165,11 +167,9 @@ require ( github.com/moby/spdystream v0.5.1 // indirect github.com/moby/sys/capability v0.4.0 // indirect github.com/moby/sys/mountinfo v0.7.2 // indirect - github.com/moby/sys/sequential v0.6.0 // indirect github.com/moby/sys/user v0.4.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect - github.com/morikuni/aec v1.0.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/onsi/ginkgo/v2 v2.28.1 // indirect github.com/onsi/gomega v1.39.1 // indirect @@ -321,3 +321,5 @@ replace k8s.io/cri-client => k8s.io/cri-client v0.36.0 replace k8s.io/externaljwt => k8s.io/externaljwt v0.36.0 replace k8s.io/streaming => k8s.io/streaming v0.36.0 + +replace github.com/docker/docker => github.com/moby/moby v28.5.2+incompatible diff --git a/go.sum b/go.sum index 84d6233c6..3e5111cee 100644 --- a/go.sum +++ b/go.sum @@ -30,8 +30,6 @@ github.com/Azure/azure-sdk-for-go/sdk/internal v1.12.0 h1:fhqpLE3UEXi9lPaBRpQ6Xu github.com/Azure/azure-sdk-for-go/sdk/internal v1.12.0/go.mod h1:7dCRMLwisfRH3dBupKeNCioWYUZ4SS09Z14H+7i8ZoY= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/appservice/armappservice/v2 v2.3.0 h1:JI8PcWOImyvIUEZ0Bbmfe05FOlWkMi2KhjG+cAKaUms= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/appservice/armappservice/v2 v2.3.0/go.mod h1:nJLFPGJkyKfDDyJiPuHIXsCi/gpJkm07EvRgiX7SGlI= -github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= -github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1 h1:WJTmL004Abzc5wDB5VtZG2PJk5ndYDgVacGqfirKxjM= github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1/go.mod h1:tCcJZ0uHAmvjsVYzEFivsRTN00oz5BEsRgQHu5JZ9WE= github.com/AzureAD/microsoft-authentication-library-for-go v1.6.0 h1:XRzhVemXdgvJqCH0sFfrBUTnUJSBrBf7++ypk+twtRs= @@ -155,12 +153,10 @@ github.com/docker/cli v28.3.2+incompatible h1:mOt9fcLE7zaACbxW1GeS65RI67wIJrTnqS github.com/docker/cli v28.3.2+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v28.5.2+incompatible h1:DBX0Y0zAjZbSrm1uzOkdr1onVghKaftjlSWt4AFexzM= -github.com/docker/docker v28.5.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqIjCBS4wrsOh9yRqcz8= github.com/docker/docker-credential-helpers v0.9.3/go.mod h1:x+4Gbw9aGmChi3qTLZj8Dfn0TD20M/fuWy0E5+WDeCo= -github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= -github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= +github.com/docker/go-connections v0.7.0 h1:6SsRfJddP22WMrCkj19x9WKjEDTB+ahsdiGYf0mN39c= +github.com/docker/go-connections v0.7.0/go.mod h1:no1qkHdjq7kLMGUXYAduOhYPSJxxvgWBh7ogVvptn3Q= github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8= github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= @@ -367,28 +363,26 @@ github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= +github.com/moby/moby v28.5.2+incompatible h1:hIn6qcenb3JY1E3STwqEbBvJ8bha+u1LpqjX4CBvNCk= +github.com/moby/moby v28.5.2+incompatible/go.mod h1:fDXVQ6+S340veQPv35CzDahGBmHsiclFwfEygB/TWMc= +github.com/moby/moby/api v1.54.2 h1:wiat9QAhnDQjA7wk1kh/TqHz2I1uUA7M7t9SAl/JNXg= +github.com/moby/moby/api v1.54.2/go.mod h1:+RQ6wluLwtYaTd1WnPLykIDPekkuyD/ROWQClE83pzs= +github.com/moby/moby/client v0.4.1 h1:DMQgisVoMkmMs7fp3ROSdiBnoAu8+vo3GggFl06M/wY= +github.com/moby/moby/client v0.4.1/go.mod h1:z52C9O2POPOsnxZAy//WtKcQ32P+jT/NGeXu/7nfjGQ= github.com/moby/spdystream v0.5.1 h1:9sNYeYZUcci9R6/w7KDaFWEWeV4LStVG78Mpyq/Zm/Y= github.com/moby/spdystream v0.5.1/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI= -github.com/moby/sys/atomicwriter v0.1.0 h1:kw5D/EqkBwsBFi0ss9v1VG3wIkVhzGvLklJ+w3A14Sw= -github.com/moby/sys/atomicwriter v0.1.0/go.mod h1:Ul8oqv2ZMNHOceF643P6FKPXeCmYtlQMvpizfsSoaWs= github.com/moby/sys/capability v0.4.0 h1:4D4mI6KlNtWMCM1Z/K0i7RV1FkX+DBDHKVJpCndZoHk= github.com/moby/sys/capability v0.4.0/go.mod h1:4g9IK291rVkms3LKCDOoYlnV8xKwoDTpIrNEE35Wq0I= github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg= github.com/moby/sys/mountinfo v0.7.2/go.mod h1:1YOa8w8Ih7uW0wALDUgT1dTTSBrZ+HiBLGws92L2RU4= -github.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7zgvCU= -github.com/moby/sys/sequential v0.6.0/go.mod h1:uyv8EUTrca5PnDsdMGXhZe6CCe8U/UiTWd+lL+7b/Ko= github.com/moby/sys/user v0.4.0 h1:jhcMKit7SA80hivmFJcbB1vqmw//wU61Zdui2eQXuMs= github.com/moby/sys/user v0.4.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs= -github.com/moby/term v0.5.2 h1:6qk3FJAFDs6i/q3W/pQ97SX192qKfZgGjCQqfCJkgzQ= -github.com/moby/term v0.5.2/go.mod h1:d3djjFCrjnB+fl8NJux+EJzu0msscUP+f8it8hPkFLc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8= github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= -github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/onsi/ginkgo/v2 v2.28.1 h1:S4hj+HbZp40fNKuLUQOYLDgZLwNUVn19N3Atb98NCyI= @@ -535,8 +529,6 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.43.0 h1:88Y4s2C8oTui1LGM6bT go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.43.0/go.mod h1:Vl1/iaggsuRlrHf/hfPJPvVag77kKyvrLeD10kpMl+A= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.43.0 h1:RAE+JPfvEmvy+0LzyUA25/SGawPwIUbZ6u0Wug54sLc= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.43.0/go.mod h1:AGmbycVGEsRx9mXMZ75CsOyhSP6MFIcj/6dnG+vhVjk= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.43.0 h1:3iZJKlCZufyRzPzlQhUIWVmfltrXuGyfjREgGP3UUjc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.43.0/go.mod h1:/G+nUPfhq2e+qiXMGxMwumDrP5jtzU+mWN7/sjT2rak= go.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM= go.opentelemetry.io/otel/metric v1.43.0/go.mod h1:RDnPtIxvqlgO8GRW18W6Z/4P462ldprJtfxHxyKd2PY= go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg= @@ -665,6 +657,8 @@ k8s.io/streaming v0.36.0 h1:agnTxU+NFulUrtYzXUGKO3ndEa8jKwht1Kwn9nu9x+4= k8s.io/streaming v0.36.0/go.mod h1:z6fV3D+NVkoeqRMtWwlUZK6U17SY/LqNzOxWL6GyR/s= k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 h1:AZYQSJemyQB5eRxqcPky+/7EdBj0xi3g0ZcxxJ7vbWU= k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk= +pgregory.net/rapid v1.2.0 h1:keKAYRcjm+e1F0oAuU5F5+YPAWcyxNNRK2wud503Gnk= +pgregory.net/rapid v1.2.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 h1:hSfpvjjTQXQY2Fol2CS0QHMNs/WI1MOSGzCm1KhM5ec= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= diff --git a/internal/digest/digest.go b/internal/digest/digest.go index 64dd61286..848222740 100644 --- a/internal/digest/digest.go +++ b/internal/digest/digest.go @@ -18,7 +18,7 @@ import ( "github.com/containers/image/v5/docker" "github.com/containers/image/v5/types" - "github.com/docker/docker/client" + "github.com/moby/moby/client" "github.com/kosli-dev/cli/internal/logger" "github.com/kosli-dev/cli/internal/requests" "github.com/kosli-dev/cli/internal/utils" @@ -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, client.WithAPIVersionNegotiation()) + cli, err := client.New(client.FromEnv) if err != nil { return "", err } diff --git a/internal/docker/docker.go b/internal/docker/docker.go index bc348d392..f009cb190 100644 --- a/internal/docker/docker.go +++ b/internal/docker/docker.go @@ -8,18 +8,13 @@ import ( "io" "os" - "github.com/docker/docker/api/types/container" - "github.com/docker/docker/api/types/image" - "github.com/docker/docker/api/types/registry" - "github.com/docker/docker/client" + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/api/types/registry" + "github.com/moby/moby/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()) + return client.New(client.FromEnv) } // PullDockerImage pulls a docker image or returns an error @@ -29,13 +24,12 @@ func PullDockerImage(imageName string) error { return err } - rc, err := cli.ImagePull(context.Background(), imageName, image.PullOptions{}) + rc, err := cli.ImagePull(context.Background(), imageName, client.ImagePullOptions{}) if err != nil { return err } defer func() { if err := rc.Close(); err != nil { - // Log warning for cleanup error fmt.Printf("warning: failed to close image pull reader: %v\n", err) } }() @@ -59,7 +53,7 @@ func PushDockerImage(imageName string) error { } authConfigBytes, _ := json.Marshal(authConfig) authConfigEncoded := base64.URLEncoding.EncodeToString(authConfigBytes) - opts := image.PushOptions{RegistryAuth: authConfigEncoded} + opts := client.ImagePushOptions{RegistryAuth: authConfigEncoded} rc, err := cli.ImagePush(context.Background(), imageName, opts) if err != nil { @@ -67,7 +61,6 @@ func PushDockerImage(imageName string) error { } defer func() { if err := rc.Close(); err != nil { - // Log warning for cleanup error fmt.Printf("warning: failed to close image push reader: %v\n", err) } }() @@ -86,7 +79,8 @@ func TagDockerImage(sourceName, targetName string) error { return err } - return cli.ImageTag(context.Background(), sourceName, targetName) + _, err = cli.ImageTag(context.Background(), client.ImageTagOptions{Source: sourceName, Target: targetName}) + return err } // RemoveDockerImage deletes a docker image or return an error @@ -96,7 +90,7 @@ func RemoveDockerImage(imageName string) error { return err } - _, err = cli.ImageRemove(context.Background(), imageName, image.RemoveOptions{Force: true}) + _, err = cli.ImageRemove(context.Background(), imageName, client.ImageRemoveOptions{Force: true}) if err != nil { return err } @@ -111,16 +105,19 @@ func RunDockerContainer(imageName string) (string, error) { return "", err } ctx := context.Background() - resp, err := cli.ContainerCreate(ctx, &container.Config{ - Image: imageName, - Cmd: []string{"sleep", "360"}, - }, nil, nil, nil, "") + resp, err := cli.ContainerCreate(ctx, client.ContainerCreateOptions{ + Config: &container.Config{ + Image: imageName, + Cmd: []string{"sleep", "360"}, + }, + }) if err != nil { return "", err } containerID := resp.ID - return containerID, cli.ContainerStart(ctx, containerID, container.StartOptions{}) + _, err = cli.ContainerStart(ctx, containerID, client.ContainerStartOptions{}) + return containerID, err } // RemoveDockerContainer remove a docker container or returns an error @@ -130,5 +127,6 @@ func RemoveDockerContainer(containerID string) error { return err } - return cli.ContainerRemove(context.Background(), containerID, container.RemoveOptions{Force: true}) + _, err = cli.ContainerRemove(context.Background(), containerID, client.ContainerRemoveOptions{Force: true}) + return err }