Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reorganize the upload and attach CLI commands. #378

Merged
merged 1 commit into from
Jun 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

### Enhancements

* BREAKING: Move `cosign upload-blob` to `cosign upload blob`.
* BREAKING: Move `cosign upload` to `cosign attach signature`.

### Bug Fixes

### Contributors
Expand Down
2 changes: 1 addition & 1 deletion EXAMPLES.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Use `cosign` to generate the payload, sign it with `gcloud kms`, then use `cosig
$ cosign generate us-central1-docker.pkg.dev/dlorenc-vmtest2/test/taskrun > payload.json
$ gcloud kms asymmetric-sign --digest-algorithm=sha256 --input-file=payload.json --signature-file=gcpkms.sig --key=foo --keyring=foo --version=1 --location=us-central
# We have to base64 encode the signature
$ cat gcpkms.sig | base64 | cosign upload -signature - us-central1-docker.pkg.dev/dlorenc-vmtest2/test/taskrun
$ cat gcpkms.sig | base64 | cosign attach signature -signature - us-central1-docker.pkg.dev/dlorenc-vmtest2/test/taskrun
```

Now (on another machine) download the public key, payload, signatures and verify it!
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,11 @@ OCI registries are useful for storing more than just container images!

This section shows how to leverage these for an easy-to-use, backwards-compatible artifact distribution system that integrates well with the rest of Sigstore.

You can publish an artifact with `cosign upload-blob`:
You can publish an artifact with `cosign upload blob`:

```shell
$ echo "my first artifact" > artifact
$ cosign upload-blob -f artifact gcr.io/dlorenc-vmtest2/artifact
$ cosign upload blob -f artifact gcr.io/dlorenc-vmtest2/artifact
Uploading file from [artifact] to [gcr.io/dlorenc-vmtest2/artifact:latest] with media type [text/plain; charset=utf-8]
File is available directly at [us.gcr.io/v2/dlorenc-vmtest2/readme/blobs/sha256:b57400c0ad852a7c2f6f7da4a1f94547692c61f3e921a49ba3a41805ae8e1e99]
us.gcr.io/dlorenc-vmtest2/readme@sha256:4aa3054270f7a70b4528f2064ee90961788e1e1518703592ae4463de3b889dec
Expand Down
6 changes: 3 additions & 3 deletions USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,21 +125,21 @@ The signature is passed via the -signature flag.
It can be a file:

```shell
$ cosign upload -signature file.sig dlorenc/demo
$ cosign attach signature -signature file.sig dlorenc/demo
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can drop -signature in this case and just have 2 positionals

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just went back and forth on this one and decided against it. -signature is long but two positionals is uglier

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/shrug

Pushing signature to: dlorenc/demo:sha256-87ef60f558bad79beea6425a3b28989f01dd417164150ab3baab98dcbf04def8.sig
```

the base64-encoded signature:

```shell
$ cosign upload -signature Qr883oPOj0dj82PZ0d9mQ2lrdM0lbyLSXUkjt6ejrxtHxwe7bU6Gr27Sysgk1jagf1htO/gvkkg71oJiwWryCQ== dlorenc/demo
$ cosign attach signature -signature Qr883oPOj0dj82PZ0d9mQ2lrdM0lbyLSXUkjt6ejrxtHxwe7bU6Gr27Sysgk1jagf1htO/gvkkg71oJiwWryCQ== dlorenc/demo
Pushing signature to: dlorenc/demo:sha256-87ef60f558bad79beea6425a3b28989f01dd417164150ab3baab98dcbf04def.sig
```

or, `-` for stdin for chaining from other commands:

```shell
$ cosign generate dlorenc/demo | openssl... | cosign upload -signature -- dlorenc/demo
$ cosign generate dlorenc/demo | openssl... | cosign attach signature -signature -- dlorenc/demo
dlorenc marked this conversation as resolved.
Show resolved Hide resolved
Pushing signature to: dlorenc/demo:sha256-87ef60f558bad79beea6425a3b28989f01dd417164150ab3baab98dcbf04def.sig
```

Expand Down
40 changes: 40 additions & 0 deletions cmd/cosign/cli/attach/attach.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//
// Copyright 2021 The Sigstore Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package attach

import (
"context"
"flag"

"github.com/peterbourgon/ff/v3/ffcli"
)

func Attach() *ffcli.Command {
var (
flagset = flag.NewFlagSet("cosign attach", flag.ExitOnError)
)

return &ffcli.Command{
Name: "attach",
ShortUsage: "cosign attach",
ShortHelp: "attach contains tools to attach artifacts to other artifacts in a registry",
FlagSet: flagset,
Subcommands: []*ffcli.Command{Signature()},
Exec: func(ctx context.Context, args []string) error {
return flag.ErrHelp
},
}
}
16 changes: 8 additions & 8 deletions cmd/cosign/cli/upload.go → cmd/cosign/cli/attach/sig.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

package cli
package attach

import (
"context"
Expand All @@ -34,28 +34,28 @@ import (
sigPayload "github.com/sigstore/sigstore/pkg/signature/payload"
)

func Upload() *ffcli.Command {
func Signature() *ffcli.Command {
var (
flagset = flag.NewFlagSet("cosign upload", flag.ExitOnError)
flagset = flag.NewFlagSet("cosign attach signature", flag.ExitOnError)
signature = flagset.String("signature", "", "the signature, path to the signature, or {-} for stdin")
payload = flagset.String("payload", "", "path to the payload covered by the signature (if using another format)")
)
return &ffcli.Command{
Name: "upload",
ShortUsage: "cosign upload <image uri>",
ShortHelp: "upload signatures to the supplied container image",
Name: "signature",
ShortUsage: "cosign attach signature <image uri>",
ShortHelp: "attach signatures to the supplied container image",
FlagSet: flagset,
Exec: func(ctx context.Context, args []string) error {
if len(args) != 1 {
return flag.ErrHelp
}

return UploadCmd(ctx, *signature, *payload, args[0])
return SignatureCmd(ctx, *signature, *payload, args[0])
},
}
}

func UploadCmd(ctx context.Context, sigRef, payloadRef, imageRef string) error {
func SignatureCmd(ctx context.Context, sigRef, payloadRef, imageRef string) error {
var b64SigBytes []byte

b64SigBytes, err := signatureBytes(sigRef)
Expand Down
22 changes: 11 additions & 11 deletions cmd/cosign/cli/upload_blob.go → cmd/cosign/cli/upload/blob.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

package cli
package upload

import (
"context"
Expand Down Expand Up @@ -72,44 +72,44 @@ func (fs *Files) String() string {
return strings.Join(s, ",")
}

func UploadBlob() *ffcli.Command {
func Blob() *ffcli.Command {
var (
flagset = flag.NewFlagSet("cosign upload-blob", flag.ExitOnError)
flagset = flag.NewFlagSet("cosign upload blob", flag.ExitOnError)
ct = flagset.String("ct", "", "content type to set")
)
fmap := Files{}
flagset.Var(&fmap, "f", "<filepath>:[platform/arch]")
return &ffcli.Command{
Name: "upload-blob",
ShortUsage: "cosign upload-blob -f <blob ref> <image uri>",
Name: "blob",
ShortUsage: "cosign upload blob -f <blob ref> <image uri>",
ShortHelp: "Upload one or more blobs to the supplied container image address",
LongHelp: `Upload one or more blobs to the supplied container image address.

EXAMPLES
# upload a blob named foo to the location specified by <IMAGE>
cosign upload-blob -f foo <IMAGE>
cosign upload blob -f foo <IMAGE>

# upload a blob named foo to the location specified by <IMAGE>, setting the os field to "MYOS".
cosign upload-blob -f foo:MYOS <IMAGE>
cosign upload blob -f foo:MYOS <IMAGE>

# upload a blob named foo to the location specified by <IMAGE>, setting the os field to "MYOS" and the platform field to "MYPLATFORM".
cosign upload-blob -f foo:MYOS/MYPLATFORM <IMAGE>
cosign upload blob -f foo:MYOS/MYPLATFORM <IMAGE>

# upload two blobs named foo-darwin and foo-linux to the location specified by <IMAGE>, setting the os fields
cosign upload-blob -f foo-darwin:darwin -f foo-linux:linux <IMAGE>
cosign upload blob -f foo-darwin:darwin -f foo-linux:linux <IMAGE>
`,
FlagSet: flagset,
Exec: func(ctx context.Context, args []string) error {
if len(args) != 1 {
return flag.ErrHelp
}

return UploadBlobCmd(ctx, fmap.Files, *ct, args[0])
return BlobCmd(ctx, fmap.Files, *ct, args[0])
},
}
}

func UploadBlobCmd(ctx context.Context, files []cremote.File, contentType, imageRef string) error {
func BlobCmd(ctx context.Context, files []cremote.File, contentType, imageRef string) error {
ref, err := name.ParseReference(imageRef)
if err != nil {
return err
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

package cli
package upload

import (
"reflect"
Expand Down
40 changes: 40 additions & 0 deletions cmd/cosign/cli/upload/upload.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//
// Copyright 2021 The Sigstore Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package upload

import (
"context"
"flag"

"github.com/peterbourgon/ff/v3/ffcli"
)

func Upload() *ffcli.Command {
var (
flagset = flag.NewFlagSet("cosign upload", flag.ExitOnError)
)

return &ffcli.Command{
Name: "upload",
ShortUsage: "cosign upload",
ShortHelp: "upload contains tools to upload artifacts to a registry",
FlagSet: flagset,
Subcommands: []*ffcli.Command{Blob()},
Exec: func(ctx context.Context, args []string) error {
return flag.ErrHelp
},
}
}
17 changes: 15 additions & 2 deletions cmd/cosign/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ import (
"github.com/pkg/errors"

"github.com/sigstore/cosign/cmd/cosign/cli"
"github.com/sigstore/cosign/cmd/cosign/cli/attach"
"github.com/sigstore/cosign/cmd/cosign/cli/pivcli"
"github.com/sigstore/cosign/cmd/cosign/cli/upload"
)

var (
Expand All @@ -40,8 +42,19 @@ func main() {
ShortUsage: "cosign [flags] <subcommand>",
FlagSet: rootFlagSet,
Subcommands: []*ffcli.Command{
cli.Verify(), cli.Sign(), cli.Upload(), cli.Generate(), cli.Download(), cli.GenerateKeyPair(), cli.SignBlob(),
cli.UploadBlob(), cli.Copy(), cli.Clean(), cli.VerifyBlob(), cli.Triangulate(), cli.Version(), cli.PublicKey(), pivcli.PivKey()},
// Key Management
cli.PublicKey(), cli.GenerateKeyPair(),
// Signing
cli.Verify(), cli.Sign(), cli.Generate(), cli.SignBlob(), cli.VerifyBlob(),
// Upload sub-tree
upload.Upload(),
// Upload sub-tree
attach.Attach(),
// PIV sub-tree
pivcli.PivKey(),
// PIV sub-tree
cli.Copy(), cli.Clean(), cli.Triangulate(), cli.Download(),
cli.Version()},
Exec: func(context.Context, []string) error {
return flag.ErrHelp
},
Expand Down
16 changes: 9 additions & 7 deletions test/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ import (
"github.com/google/go-containerregistry/pkg/v1/remote"

"github.com/sigstore/cosign/cmd/cosign/cli"
"github.com/sigstore/cosign/cmd/cosign/cli/attach"
"github.com/sigstore/cosign/cmd/cosign/cli/upload"
sget "github.com/sigstore/cosign/cmd/sget/cli"
"github.com/sigstore/cosign/pkg/cosign"
"github.com/sigstore/cosign/pkg/cosign/kubernetes"
Expand Down Expand Up @@ -387,22 +389,22 @@ func TestUploadDownload(t *testing.T) {

testCases := map[string]struct {
signature string
signatureType cli.SignatureArgType
signatureType attach.SignatureArgType
expectedErr bool
}{
"file containing signature": {
signature: "testsignaturefile",
signatureType: cli.FileSignature,
signatureType: attach.FileSignature,
expectedErr: false,
},
"raw signature as argument": {
signature: "testsignatureraw",
signatureType: cli.RawSignature,
signatureType: attach.RawSignature,
expectedErr: false,
},
"empty signature as argument": {
signature: "",
signatureType: cli.RawSignature,
signatureType: attach.RawSignature,
expectedErr: true,
},
}
Expand All @@ -416,14 +418,14 @@ func TestUploadDownload(t *testing.T) {
signature := base64.StdEncoding.EncodeToString([]byte(testCase.signature))

var sigRef string
if testCase.signatureType == cli.FileSignature {
if testCase.signatureType == attach.FileSignature {
sigRef = mkfile(signature, td, t)
} else {
sigRef = signature
}

// Upload it!
err := cli.UploadCmd(ctx, sigRef, payloadPath, imgName)
err := attach.SignatureCmd(ctx, sigRef, payloadPath, imgName)
if testCase.expectedErr {
mustErr(err, t)
} else {
Expand Down Expand Up @@ -469,7 +471,7 @@ func TestUploadBlob(t *testing.T) {
files := []cremote.File{{
Path: payloadPath,
}}
must(cli.UploadBlobCmd(ctx, files, "", imgName), t)
must(upload.BlobCmd(ctx, files, "", imgName), t)

// Check it
ref, err := name.ParseReference(imgName)
Expand Down
4 changes: 2 additions & 2 deletions test/e2e_test_secrets.sh
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,8 @@ crane ls ${blobimg} | while read tag ; do crane delete "${blobimg}:${tag}" ; don
# make a random blob
cat /dev/urandom | head -n 10 | base64 > randomblob

# upload-blob and sign it
dgst=$(./cosign upload-blob -f randomblob ${blobimg})
# upload blob and sign it
dgst=$(./cosign upload blob -f randomblob ${blobimg})
./cosign sign -key ${signing_key} ${dgst}
./cosign verify -key ${verification_key} ${dgst} # For sanity

Expand Down