Skip to content

Commit

Permalink
Fix failing push/pull commands in CI
Browse files Browse the repository at this point in the history
Signed-off-by: Santosh <[email protected]>
  • Loading branch information
santoshkal committed Jun 24, 2024
1 parent 5704fc8 commit dce80a8
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 35 deletions.
4 changes: 0 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -390,10 +390,6 @@ Genval offers comprehensive management capabilities for the configuration files

To bolster supply chain security workflows, Genval enables users to sign the artifacts after storing them in the registry. Similarly, when pulling any artifact, Genval provides functionality to verify the signatures of the artifacts. This feature leverages **Sigstore's Cosign keyless mode** of signing and verifying artifacts. However, users can also utilize their own private and public keys for signing and verifying the artifacts respectively.

To facilitate authentication with container registries, Genval initially looks for the `~/.docker/config.json` file in the user's
`$HOME` directory. If this file is found, Genval utilizes it for authentication with the registry. However, if the file is not present,
users must set the `ARTIFACT_REGISTRY_USERNAME` and `ARTIFACT_REGISTRY_PASSWORD` environment variables to authenticate with the container registry.

#### Building, pushing, and signing generated and/or verified config files and OCI artifacts

The following command demonstrates building and pushing the OCI artifact (genval:test) to GitHub Container Registry (ghcr.io) while signing the artifact with Cosign in Keyless mode:
Expand Down
4 changes: 2 additions & 2 deletions cmd/artifact_pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,8 @@ func runPullArtifactCmd(cmd *cobra.Command, args []string) error {
defer spin.Stop()

if err := oci.PullArtifact(context.Background(), pullArgs.creds, pullArgs.dest, pullArgs.path); err != nil {
color.Red("Error pulling artifact from remote : %v", err)
return err
fe := color.RedString("Error pulling artifact from remote: %v", err)
return fmt.Errorf(fe)
}
spin.Stop()
color.Green("Artifact from %s pulled and stored in :%s", pullArgs.dest, pullArgs.path)
Expand Down
29 changes: 21 additions & 8 deletions cmd/artifact_push.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package cmd

import (
"context"
"fmt"
"os"
"path/filepath"
"time"

"github.com/fatih/color"
"github.com/google/go-containerregistry/pkg/authn"
"github.com/google/go-containerregistry/pkg/compression"
"github.com/google/go-containerregistry/pkg/crane"
Expand Down Expand Up @@ -155,21 +157,31 @@ func runPushCmd(cmd *cobra.Command, args []string) error {
if err != nil {
log.Errorf("appending content to artifact failed: %v", err)
}

spin := utils.StartSpinner("pushing artifact")
defer spin.Stop()

var opts []crane.Option
auth, err := oci.GetCreds(pushArgs.creds)
if err != nil {
return fmt.Errorf("error getting credentials: %v", err)
return err
}
opts, err := oci.GenerateCraneOptions(ref, auth, []string{ref.Context().Scope(transport.PushScope)})
if err != nil {
log.Errorf("Error creating options required for push: %v", err)

if pushArgs.creds == "" || auth == nil {
auth, err = authn.DefaultKeychain.Resolve(ref.Context())
if err != nil {
return err
}
}

opts = append(opts, crane.WithAuth(auth))
if pushArgs.creds == "" {
opts = append(opts, crane.WithAuthFromKeychain(authn.DefaultKeychain))

topts, err := oci.GenerateCraneOptions(context.Background(), ref.Context().Registry, auth, []string{ref.Context().Scope(transport.PushScope)})
if err != nil {
return fmt.Errorf("error creating transport for push operation: %v", err)
}

opts = append(opts, topts)
if err := crane.Push(img, ref.String(), opts...); err != nil {
log.Fatalf("Error pushing artifact: %v", err)
}
Expand All @@ -188,7 +200,8 @@ func runPushCmd(cmd *cobra.Command, args []string) error {
}
}

log.Infof("✔ Artifact pushed successfully to: %v\n,Artifact Digest: %v\n", source, digest)
log.Infof("Digest URL: %v\n", digestURL)
log.Infof(color.GreenString("✔ Artifact pushed successfully to: %v", pushArgs.dest))
log.Infof(color.GreenString("✔ Digest: %v", digest))
log.Infof(color.GreenString("✔ Digest URL: %v\n", digestURL))
return nil
}
57 changes: 36 additions & 21 deletions pkg/oci/ociClient.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,18 +52,26 @@ func CheckTagAndPullArchive(url, tool, creds string, archivePath *os.File) error
ociref := parts[0]
desiredTag := parts[1]

var opts []crane.Option
auth, err := GetCreds(creds)
if err != nil {
return fmt.Errorf("error getting credentials: %v", err)
return fmt.Errorf("error fetching credentials: %v", err)
}
opts, err := GenerateCraneOptions(ref, auth, []string{ref.Context().Scope(transport.PullScope)})
if err != nil {
log.Errorf("Error reading credentials: %v", err)

if creds == "" || auth == nil {
auth, err = authn.DefaultKeychain.Resolve(ref.Context())
if err != nil {
return fmt.Errorf("error fetching default keychain: %v", err)
}
}

opts = append(opts, crane.WithAuth(auth))
if creds == "" {
opts = append(opts, crane.WithAuthFromKeychain(authn.DefaultKeychain))

topts, err := GenerateCraneOptions(context.Background(), ref.Context().Registry, auth, []string{ref.Context().Scope(transport.PullScope)})
if err != nil {
return fmt.Errorf("error creating transport for pull: %v", err)
}
opts = append(opts, topts)

tags, err := crane.ListTags(ociref, opts...)
if err != nil {
Expand Down Expand Up @@ -204,18 +212,26 @@ func PullArtifact(ctx context.Context, creds, dest, path string) error {
url := parts[0]
desiredTag := parts[1]

var opts []crane.Option
auth, err := GetCreds(creds)
if err != nil {
return fmt.Errorf("error getting credentials: %v", err)
return fmt.Errorf("error fetching credentials: %v", err)
}
opts, err := GenerateCraneOptions(ref, auth, []string{ref.Context().Scope(transport.PullScope)})
if err != nil {
return fmt.Errorf("error getting credentials: %v", err)

if creds == "" || auth == nil {
auth, err = authn.DefaultKeychain.Resolve(ref.Context())
if err != nil {
return fmt.Errorf("error fetching default keychain: %v", err)
}
}

opts = append(opts, crane.WithAuth(auth))
if creds == "" {
opts = append(opts, crane.WithAuthFromKeychain(authn.DefaultKeychain))

topts, err := GenerateCraneOptions(context.Background(), ref.Context().Registry, auth, []string{ref.Context().Scope(transport.PullScope)})
if err != nil {
return fmt.Errorf("error creating transport for pull:%v", err)
}
opts = append(opts, topts)

tags, err := crane.ListTags(url, opts...)
if err != nil {
Expand Down Expand Up @@ -297,11 +313,11 @@ func GetCreds(creds string) (authn.Authenticator, error) {
}

// Most parts of GenerateCraneOptions and its related funcs are copied from https://github.com/google/go-containerregistry/blob/1b4e4078a545f2b6f96766a064b45ee77cdbefdd/pkg/v1/remote/options.go#L128
func GenerateCraneOptions(ref name.Reference, auth authn.Authenticator, scopes []string) ([]crane.Option, error) {
opts := []crane.Option{}
// GenerateCraneOptions generates an crane options object to perform remote operations
func GenerateCraneOptions(ctx context.Context, ref name.Registry, auth authn.Authenticator, scopes []string) (crane.Option, error) {
var retryTransport http.RoundTripper

userAgent := fmt.Sprintf("intelops/genval/%s (%s; %s)", version.GetVersionInfo().GitVersion, runtime.GOOS, runtime.GOARCH)
userAgent := fmt.Sprintf("genval/%s (%s; %s)", version.GetVersionInfo().GitVersion, runtime.GOOS, runtime.GOARCH)
retryTransport = remote.DefaultTransport.(*http.Transport).Clone()
if logs.Enabled(logs.Debug) {
retryTransport = transport.NewLogger(retryTransport)
Expand All @@ -319,13 +335,12 @@ func GenerateCraneOptions(ref name.Reference, auth authn.Authenticator, scopes [
}))
retryTransport = transport.NewUserAgent(retryTransport, userAgent)

// t, err := transport.NewWithContext(ref.Context().Registry, auth, retryTransport, scopes)
// if err != nil {
// return nil, err
// }
opts = append(opts, crane.WithTransport(retryTransport))
t, err := transport.NewWithContext(ctx, ref, auth, retryTransport, scopes)
if err != nil {
return nil, err
}

return opts, nil
return crane.WithTransport(t), nil
}

var defaultRetryPredicate = func(err error) bool {
Expand Down

0 comments on commit dce80a8

Please sign in to comment.