Skip to content

Commit

Permalink
Merge pull request #216 from amartin120/cosign-update
Browse files Browse the repository at this point in the history
update to v2.2.3 of RGS cosign fork
  • Loading branch information
amartin120 authored Mar 29, 2024
2 parents 722851d + 545b3f8 commit 49d705d
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 47 deletions.
2 changes: 1 addition & 1 deletion .goreleaser.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ release:

env:
- vpkg=github.com/rancherfederal/hauler/internal/version
- cosign_version=v2.2.2+carbide.2
- cosign_version=v2.2.3+carbide.1

builds:
- main: cmd/hauler/main.go
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
SHELL:=/bin/bash
GO_FILES=$(shell go list ./... | grep -v /vendor/)

COSIGN_VERSION=v2.2.2+carbide.2
COSIGN_VERSION=v2.2.3+carbide.1

.SILENT:

Expand Down
27 changes: 27 additions & 0 deletions pkg/artifacts/image/image.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package image

import (
"fmt"
"github.com/google/go-containerregistry/pkg/authn"
gname "github.com/google/go-containerregistry/pkg/name"
gv1 "github.com/google/go-containerregistry/pkg/v1"
Expand Down Expand Up @@ -51,3 +52,29 @@ func NewImage(name string, opts ...remote.Option) (*Image, error) {
Image: img,
}, nil
}

func IsMultiArchImage(name string, opts ...remote.Option) (bool, error) {
ref, err := gname.ParseReference(name)
if err != nil {
return false, fmt.Errorf("parsing reference %q: %v", name, err)
}

defaultOpts := []remote.Option{
remote.WithAuthFromKeychain(authn.DefaultKeychain),
}
opts = append(opts, defaultOpts...)

desc, err := remote.Get(ref, opts...)
if err != nil {
return false, fmt.Errorf("getting image %q: %v", name, err)
}

_, err = desc.ImageIndex()
if err != nil {
// If the descriptor could not be converted to an image index, it's not a multi-arch image
return false, nil
}

// If the descriptor could be converted to an image index, it's a multi-arch image
return true, nil
}
121 changes: 76 additions & 45 deletions pkg/cosign/cosign.go
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
package cosign

import (
"bufio"
"context"
"embed"
"fmt"
"os"
"os/exec"
"os/user"
"path/filepath"
"runtime"
"context"
"time"
"bufio"
"embed"
"strings"
"time"

"oras.land/oras-go/pkg/content"
"github.com/rancherfederal/hauler/pkg/store"
"github.com/rancherfederal/hauler/pkg/artifacts/image"
"github.com/rancherfederal/hauler/pkg/log"
"github.com/rancherfederal/hauler/pkg/store"
"oras.land/oras-go/pkg/content"
)

const maxRetries = 3
Expand All @@ -24,7 +25,7 @@ const retryDelay = time.Second * 5
// VerifyFileSignature verifies the digital signature of a file using Sigstore/Cosign.
func VerifySignature(ctx context.Context, s *store.Layout, keyPath string, ref string) error {
operation := func() error {
cosignBinaryPath, err := getCosignPath(ctx)
cosignBinaryPath, err := getCosignPath()
if err != nil {
return err
}
Expand All @@ -45,30 +46,62 @@ func VerifySignature(ctx context.Context, s *store.Layout, keyPath string, ref s
func SaveImage(ctx context.Context, s *store.Layout, ref string, platform string) error {
l := log.FromContext(ctx)
operation := func() error {
cosignBinaryPath, err := getCosignPath(ctx)
cosignBinaryPath, err := getCosignPath()
if err != nil {
return err
}

// check to see if the image is multi-arch
isMultiArch, err := image.IsMultiArchImage(ref)
if err != nil {
return err
}
l.Debugf("multi-arch image: %v", isMultiArch)

cmd := exec.Command(cosignBinaryPath, "save", ref, "--dir", s.Root)
// Conditionally add platform.
if platform != "" {
if platform != "" && isMultiArch {
l.Debugf("platform for image [%s]", platform)
cmd.Args = append(cmd.Args, "--platform", platform)
}
output, err := cmd.CombinedOutput()

stdout, err := cmd.StdoutPipe()
if err != nil {
if strings.Contains(string(output), "specified reference is not a multiarch image") {
l.Debugf(fmt.Sprintf("specified image [%s] is not a multiarch image. (choosing default)", ref))
// Rerun the command without the platform flag
cmd = exec.Command(cosignBinaryPath, "save", ref, "--dir", s.Root)
output, err = cmd.CombinedOutput()
if err != nil {
return fmt.Errorf("error adding image to store: %v, output: %s", err, output)
}
} else {
return fmt.Errorf("error adding image to store: %v, output: %s", err, output)
}
return err
}
stderr, err := cmd.StderrPipe()
if err != nil {
return err
}
// start the command after having set up the pipe
if err := cmd.Start(); err != nil {
return err
}

// read command's stdout line by line
output := bufio.NewScanner(stdout)
for output.Scan() {
l.Debugf(output.Text()) // write each line to your log, or anything you need
}
if err := output.Err(); err != nil {
cmd.Wait()
return err
}

// read command's stderr line by line
errors := bufio.NewScanner(stderr)
for errors.Scan() {
l.Errorf(errors.Text()) // write each line to your log, or anything you need
}
if err := errors.Err(); err != nil {
cmd.Wait()
return err
}

// Wait for the command to finish
err = cmd.Wait()
if err != nil {
return err
}

return nil
Expand All @@ -81,7 +114,7 @@ func SaveImage(ctx context.Context, s *store.Layout, ref string, platform string
func LoadImages(ctx context.Context, s *store.Layout, registry string, ropts content.RegistryOptions) error {
l := log.FromContext(ctx)

cosignBinaryPath, err := getCosignPath(ctx)
cosignBinaryPath, err := getCosignPath()
if err != nil {
return err
}
Expand All @@ -108,7 +141,7 @@ func LoadImages(ctx context.Context, s *store.Layout, registry string, ropts con
if err := cmd.Start(); err != nil {
return err
}

// read command's stdout line by line
output := bufio.NewScanner(stdout)
for output.Scan() {
Expand Down Expand Up @@ -141,7 +174,7 @@ func LoadImages(ctx context.Context, s *store.Layout, registry string, ropts con
// RegistryLogin - performs cosign login
func RegistryLogin(ctx context.Context, s *store.Layout, registry string, ropts content.RegistryOptions) error {
log := log.FromContext(ctx)
cosignBinaryPath, err := getCosignPath(ctx)
cosignBinaryPath, err := getCosignPath()
if err != nil {
return err
}
Expand All @@ -166,7 +199,7 @@ func RetryOperation(ctx context.Context, operation func() error) error {
}

// Log the error for the current attempt.
l.Errorf("Error (attempt %d/%d): %v", attempt, maxRetries, err)
l.Errorf("error (attempt %d/%d): %v", attempt, maxRetries, err)

// If this is not the last attempt, wait before retrying.
if attempt < maxRetries {
Expand All @@ -178,14 +211,13 @@ func RetryOperation(ctx context.Context, operation func() error) error {
return fmt.Errorf("operation failed after %d attempts", maxRetries)
}


func EnsureBinaryExists(ctx context.Context, bin embed.FS) (error) {
func EnsureBinaryExists(ctx context.Context, bin embed.FS) error {
// Set up a path for the binary to be copied.
binaryPath, err := getCosignPath(ctx)
binaryPath, err := getCosignPath()
if err != nil {
return fmt.Errorf("Error: %v\n", err)
return fmt.Errorf("error: %v", err)
}

// Determine the architecture so that we pull the correct embedded binary.
arch := runtime.GOARCH
rOS := runtime.GOOS
Expand All @@ -199,40 +231,39 @@ func EnsureBinaryExists(ctx context.Context, bin embed.FS) (error) {
// retrieve the embedded binary
f, err := bin.ReadFile(fmt.Sprintf("binaries/%s", binaryName))
if err != nil {
return fmt.Errorf("Error: %v\n", err)
return fmt.Errorf("error: %v", err)
}

// write the binary to the filesystem
err = os.WriteFile(binaryPath, f, 0755)
if err != nil {
return fmt.Errorf("Error: %v\n", err)
return fmt.Errorf("error: %v", err)
}

return nil
}


// getCosignPath returns the binary path
func getCosignPath(ctx context.Context) (string, error) {
func getCosignPath() (string, error) {
// Get the current user's information
currentUser, err := user.Current()
if err != nil {
return "", fmt.Errorf("Error: %v\n", err)
return "", fmt.Errorf("error: %v", err)
}

// Get the user's home directory
homeDir := currentUser.HomeDir

// Construct the path to the .hauler directory
haulerDir := filepath.Join(homeDir, ".hauler")
// Create the .hauler directory if it doesn't exist
if _, err := os.Stat(haulerDir); os.IsNotExist(err) {
// .hauler directory does not exist, create it
if err := os.MkdirAll(haulerDir, 0755); err != nil {
return "", fmt.Errorf("Error creating .hauler directory: %v\n", err)
}
}

// Create the .hauler directory if it doesn't exist
if _, err := os.Stat(haulerDir); os.IsNotExist(err) {
// .hauler directory does not exist, create it
if err := os.MkdirAll(haulerDir, 0755); err != nil {
return "", fmt.Errorf("error creating .hauler directory: %v", err)
}
}

// Determine the binary name.
rOS := runtime.GOOS
Expand All @@ -242,7 +273,7 @@ func getCosignPath(ctx context.Context) (string, error) {
}

// construct path to binary
binaryPath := filepath.Join(haulerDir, binaryName)
binaryPath := filepath.Join(haulerDir, binaryName)

return binaryPath, nil
}

0 comments on commit 49d705d

Please sign in to comment.