diff --git a/cmd/cosign/cli/upload/blob.go b/cmd/cosign/cli/upload/blob.go index 48307c4b884..5068a7e0425 100644 --- a/cmd/cosign/cli/upload/blob.go +++ b/cmd/cosign/cli/upload/blob.go @@ -23,42 +23,24 @@ import ( "strings" "github.com/google/go-containerregistry/pkg/name" - v1 "github.com/google/go-containerregistry/pkg/v1" "github.com/peterbourgon/ff/v3/ffcli" "github.com/sigstore/cosign/cmd/cosign/cli" cremote "github.com/sigstore/cosign/pkg/cosign/remote" ) -func fileFromFlag(s string) cremote.File { - split := strings.Split(s, ":") - f := cremote.File{ - Path: split[0], - } - if len(split) > 1 { - split = strings.Split(split[1], "/") - f.Platform = &v1.Platform{ - OS: split[0], - } - if len(split) > 1 { - f.Platform.Architecture = split[1] - } - } - return f -} - type Files struct { Files []cremote.File } func (fs *Files) Set(k string) error { - f := fileFromFlag(k) + f := cremote.FileFromFlag(k) fs.Files = append(fs.Files, f) // If we have multiple files, each file must have a platform. if len(fs.Files) > 1 { for _, f := range fs.Files { - if f.Platform == nil { - return fmt.Errorf("each file must include a unique platform, %s had no platform", f.Path) + if f.Platform() == nil { + return fmt.Errorf("each file must include a unique platform, %s had no platform", f.Path()) } } } diff --git a/go.mod b/go.mod index c007cb38d6d..8b1ff28f53e 100644 --- a/go.mod +++ b/go.mod @@ -20,6 +20,7 @@ require ( github.com/open-policy-agent/opa v0.31.0 github.com/peterbourgon/ff/v3 v3.1.0 github.com/pkg/errors v0.9.1 + github.com/prometheus/common v0.29.0 // indirect github.com/sigstore/fulcio v0.1.1 github.com/sigstore/rekor v0.3.0 github.com/sigstore/sigstore v0.0.0-20210729211320-56a91f560f44 diff --git a/go.sum b/go.sum index f34c0797267..e192e864524 100644 --- a/go.sum +++ b/go.sum @@ -1079,6 +1079,7 @@ github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vq github.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= github.com/mattn/go-zglob v0.0.1/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY= github.com/mediocregopher/radix/v4 v4.0.0-beta.1/go.mod h1:Z74pilm773ghbGV4EEoPvi6XWgkAfr0VCNkfa8gI1PU= diff --git a/pkg/cosign/remote/index.go b/pkg/cosign/remote/index.go index 3430c70e46e..e6854018149 100644 --- a/pkg/cosign/remote/index.go +++ b/pkg/cosign/remote/index.go @@ -35,21 +35,56 @@ type Digester interface { Digest() (v1.Hash, error) } -type File struct { - Path string - Platform *v1.Platform +type File interface { + Contents() ([]byte, error) + Platform() *v1.Platform + String() string + Path() string } -func (f *File) String() string { - r := f.Path - if f.Platform == nil { +func FileFromFlag(s string) File { + split := strings.Split(s, ":") + f := file{ + path: split[0], + } + if len(split) > 1 { + split = strings.Split(split[1], "/") + f.platform = &v1.Platform{ + OS: split[0], + } + if len(split) > 1 { + f.platform.Architecture = split[1] + } + } + return &f +} + +type file struct { + path string + platform *v1.Platform +} + +func (f *file) Path() string { + return f.path +} + +func (f *file) Contents() ([]byte, error) { + return ioutil.ReadFile(f.path) +} +func (f *file) Platform() *v1.Platform { + return f.platform +} + +func (f *file) String() string { + r := f.path + if f.platform == nil { return r } - r += ":" + f.Platform.OS - if f.Platform.Architecture == "" { + r += ":" + f.platform.OS + if f.platform.Architecture == "" { return r } - r += "/" + f.Platform.Architecture + r += "/" + f.platform.Architecture return r } @@ -64,12 +99,12 @@ func UploadFiles(ref name.Reference, files []File, getMt MediaTypeGetter, remote var idx v1.ImageIndex = empty.Index for _, f := range files { - b, err := ioutil.ReadFile(f.Path) + b, err := f.Contents() if err != nil { return nil, err } mt := getMt(b) - fmt.Fprintf(os.Stderr, "Uploading file from [%s] to [%s] with media type [%s]\n", f.Path, ref.Name(), mt) + fmt.Fprintf(os.Stderr, "Uploading file from [%s] to [%s] with media type [%s]\n", f.Path(), ref.Name(), mt) _img, err := UploadFile(b, ref, mt, types.OCIConfigJSON, remoteOpts...) if err != nil { return nil, err @@ -84,12 +119,12 @@ func UploadFiles(ref name.Reference, files []File, getMt MediaTypeGetter, remote return nil, err } blobURL := ref.Context().Registry.RegistryStr() + "/v2/" + ref.Context().RepositoryStr() + "/blobs/sha256:" + dgst.Hex - fmt.Fprintf(os.Stderr, "File [%s] is available directly at [%s]\n", f.Path, blobURL) - if f.Platform != nil { + fmt.Fprintf(os.Stderr, "File [%s] is available directly at [%s]\n", f.Path(), blobURL) + if f.Platform() != nil { idx = mutate.AppendManifests(idx, mutate.IndexAddendum{ Add: img, Descriptor: v1.Descriptor{ - Platform: f.Platform, + Platform: f.Platform(), }, }) } diff --git a/cmd/cosign/cli/upload/blob_test.go b/pkg/cosign/remote/index_test.go similarity index 76% rename from cmd/cosign/cli/upload/blob_test.go rename to pkg/cosign/remote/index_test.go index 16754c76e71..52dabf59bfa 100644 --- a/cmd/cosign/cli/upload/blob_test.go +++ b/pkg/cosign/remote/index_test.go @@ -13,38 +13,37 @@ // See the License for the specific language governing permissions and // limitations under the License. -package upload +package remote import ( "reflect" "testing" v1 "github.com/google/go-containerregistry/pkg/v1" - cremote "github.com/sigstore/cosign/pkg/cosign/remote" ) -func Test_fileFromFlag(t *testing.T) { +func TestFileFromFlag(t *testing.T) { tests := []struct { name string s string - want cremote.File + want File }{ { name: "plain", s: "foo", - want: cremote.File{Path: "foo"}, + want: &file{path: "foo"}, }, { name: "os", s: "foo:darwin", - want: cremote.File{Path: "foo", Platform: &v1.Platform{ + want: &file{path: "foo", platform: &v1.Platform{ OS: "darwin", }}, }, { name: "os", s: "foo:darwin/amd64", - want: cremote.File{Path: "foo", Platform: &v1.Platform{ + want: &file{path: "foo", platform: &v1.Platform{ OS: "darwin", Architecture: "amd64", }}, @@ -52,7 +51,7 @@ func Test_fileFromFlag(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got := fileFromFlag(tt.s); !reflect.DeepEqual(got, tt.want) { + if got := FileFromFlag(tt.s); !reflect.DeepEqual(got, tt.want) { t.Errorf("fileFromFlag() = %v, want %v", got, tt.want) } }) diff --git a/test/e2e_test.go b/test/e2e_test.go index 9399b59b637..8a240a69ba6 100644 --- a/test/e2e_test.go +++ b/test/e2e_test.go @@ -539,9 +539,7 @@ func TestUploadBlob(t *testing.T) { payloadPath := mkfile(payload, td, t) // Upload it! - files := []cremote.File{{ - Path: payloadPath, - }} + files := []cremote.File{cremote.FileFromFlag(payloadPath)} must(upload.BlobCmd(ctx, files, "", imgName), t) // Check it