Skip to content

Commit

Permalink
Refactor upload-blob to use File interface (#535)
Browse files Browse the repository at this point in the history
this way, Chains can use this library to upload files to an OCI registry.

Signed-off-by: Priya Wadhwa <priyawadhwa@google.com>
  • Loading branch information
priyawadhwa committed Aug 12, 2021
1 parent de056ab commit 03f3f4d
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 46 deletions.
24 changes: 3 additions & 21 deletions cmd/cosign/cli/upload/blob.go
Original file line number Diff line number Diff line change
Expand Up @@ -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())
}
}
}
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -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=
Expand Down
63 changes: 49 additions & 14 deletions pkg/cosign/remote/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand All @@ -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
Expand All @@ -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(),
},
})
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,46 +13,45 @@
// 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",
}},
},
}
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)
}
})
Expand Down
4 changes: 1 addition & 3 deletions test/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 03f3f4d

Please sign in to comment.