diff --git a/cmd/kosli/cli_utils.go b/cmd/kosli/cli_utils.go index fdc418e6..d1f39861 100644 --- a/cmd/kosli/cli_utils.go +++ b/cmd/kosli/cli_utils.go @@ -382,7 +382,7 @@ func getDockerRegistryAPIToken(providerInfo *registryProviderEndpoints, username } if err != nil { - return "", fmt.Errorf("failed to create an authentication token for the docker registry: %v", err) + return "", fmt.Errorf("failed to create an authentication token for the docker registry: %v %v", err, res) } var responseData map[string]interface{} @@ -407,6 +407,8 @@ func GetSha256Digest(artifactName string, o *fingerprintOptions, logger *log.Log fingerprint, err = digest.FileSha256(artifactName) case "dir": fingerprint, err = digest.DirSha256(artifactName, o.excludePaths, logger) + case "oci": + fingerprint, err = digest.OciSha256(artifactName, o.registryUsername, o.registryPassword) case "docker": if o.registryProvider != "" { var providerInfo *registryProviderEndpoints diff --git a/cmd/kosli/fingerprint.go b/cmd/kosli/fingerprint.go index 20fc52e5..3af301dd 100644 --- a/cmd/kosli/fingerprint.go +++ b/cmd/kosli/fingerprint.go @@ -1,10 +1,6 @@ package main -import ( - "io" - - "github.com/spf13/cobra" -) +import "github.com/spf13/cobra" const fingerprintShortDesc = `Calculate the SHA256 fingerprint of an artifact.` @@ -40,6 +36,10 @@ kosli fingerprint --artifact-type dir --exclude logs --exclude *.exe mydir kosli fingerprint --artifact-type docker nginx:latest ` +//# fingerprint a container image from a remote registry +//kosli fingerprint --artifact-type oci nginx:latest \ +// --SOME-AUTHENTICATION + type fingerprintOptions struct { artifactType string registryProvider string diff --git a/internal/digest/digest.go b/internal/digest/digest.go index 5f8d9954..2b1bc413 100644 --- a/internal/digest/digest.go +++ b/internal/digest/digest.go @@ -20,6 +20,9 @@ import ( "github.com/kosli-dev/cli/internal/requests" "github.com/kosli-dev/cli/internal/utils" "github.com/yargevad/filepathx" + + "github.com/containers/image/v5/docker" + containerImageTypes "github.com/containers/image/v5/types" ) var ( @@ -67,6 +70,30 @@ func DirSha256(dirPath string, excludePaths []string, logger *logger.Logger) (st return FileSha256(digestsFile.Name()) } +func OciSha256(artifactName string, registryUsername string, registryPassword string) (string, error) { + imageName := fmt.Sprintf("//%s", artifactName) + ctx := context.Background() + sysCtx := &containerImageTypes.SystemContext{ + DockerAuthConfig: &containerImageTypes.DockerAuthConfig{ + Username: registryUsername, + Password: registryPassword, + }, + } + + // Parse image reference + ref, err := docker.ParseReference(imageName) + if err != nil { + return "", err + } + + // Compute digest + digest, err := docker.GetDigest(ctx, sysCtx, ref) + if err != nil { + return "", fmt.Errorf("failed to get digest for %s: %w", imageName, err) + } + return strings.Split(digest.String(), "sha256:")[1], nil +} + // calculateDirContentSha256 calculates a sha256 digest for a directory content func calculateDirContentSha256(digestsFile *os.File, dirPath, tmpDir string, excludePaths []string, logger *logger.Logger) error { pathsToExclude := []string{} diff --git a/internal/requests/requests.go b/internal/requests/requests.go index 4340fd90..c7877ac7 100644 --- a/internal/requests/requests.go +++ b/internal/requests/requests.go @@ -249,6 +249,7 @@ func (c *Client) Do(p *RequestParams) (*HTTPResponse, error) { cleanedErrorMessage = fmt.Sprintf("%s", respBodyMap) } } + fmt.Printf("RESPONSE %v", resp) return nil, fmt.Errorf("%s", cleanedErrorMessage) } return &HTTPResponse{string(body), resp}, nil