Skip to content

Commit

Permalink
feat: OCI 1.1 support (#1192)
Browse files Browse the repository at this point in the history
Signed-off-by: Patrick Zheng <patrickzheng@microsoft.com>
  • Loading branch information
Two-Hearts authored Feb 25, 2025
1 parent db697f2 commit ae0d432
Show file tree
Hide file tree
Showing 13 changed files with 33 additions and 250 deletions.
13 changes: 3 additions & 10 deletions cmd/notation/inspect.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import (
"github.com/notaryproject/notation-core-go/signature"
"github.com/notaryproject/notation/cmd/notation/internal/display"
cmderr "github.com/notaryproject/notation/cmd/notation/internal/errors"
"github.com/notaryproject/notation/cmd/notation/internal/experimental"
"github.com/notaryproject/notation/cmd/notation/internal/option"
"github.com/notaryproject/notation/internal/cmd"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
Expand All @@ -33,9 +32,8 @@ type inspectOpts struct {
SecureFlagOpts
option.Common
option.Format
reference string
allowReferrersAPI bool
maxSignatures int
reference string
maxSignatures int
}

func inspectCommand(opts *inspectOpts) *cobra.Command {
Expand Down Expand Up @@ -69,23 +67,18 @@ Example - Inspect signatures on an OCI artifact identified by a digest and outpu
return err
}
opts.Common.Parse(cmd)
return experimental.CheckFlagsAndWarn(cmd, "allow-referrers-api")
return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
if opts.maxSignatures <= 0 {
return fmt.Errorf("max-signatures value %d must be a positive number", opts.maxSignatures)
}
if cmd.Flags().Changed("allow-referrers-api") {
fmt.Fprintln(os.Stderr, "Warning: flag '--allow-referrers-api' is deprecated and will be removed in future versions.")
}
return runInspect(cmd, opts)
},
}

opts.LoggingFlagOpts.ApplyFlags(command.Flags())
opts.SecureFlagOpts.ApplyFlags(command.Flags())
command.Flags().IntVar(&opts.maxSignatures, "max-signatures", 100, "maximum number of signatures to evaluate or examine")
cmd.SetPflagReferrersAPI(command.Flags(), &opts.allowReferrersAPI, fmt.Sprintf(cmd.PflagReferrersUsageFormat, "inspect"))

// set output format
opts.Format.ApplyFlags(command.Flags(), option.FormatTypeTree, option.FormatTypeJSON)
Expand Down
16 changes: 5 additions & 11 deletions cmd/notation/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import (
"context"
"errors"
"fmt"
"os"

notationregistry "github.com/notaryproject/notation-go/registry"
cmderr "github.com/notaryproject/notation/cmd/notation/internal/errors"
Expand All @@ -31,11 +30,10 @@ import (
type listOpts struct {
cmd.LoggingFlagOpts
SecureFlagOpts
reference string
allowReferrersAPI bool
ociLayout bool
inputType inputType
maxSignatures int
reference string
ociLayout bool
inputType inputType
maxSignatures int
}

func listCommand(opts *listOpts) *cobra.Command {
Expand Down Expand Up @@ -75,21 +73,17 @@ Example - [Experimental] List signatures of an OCI artifact identified by a tag
if opts.ociLayout {
opts.inputType = inputTypeOCILayout
}
return experimental.CheckFlagsAndWarn(cmd, "allow-referrers-api", "oci-layout")
return experimental.CheckFlagsAndWarn(cmd, "oci-layout")
},
RunE: func(cmd *cobra.Command, args []string) error {
if opts.maxSignatures <= 0 {
return fmt.Errorf("max-signatures value %d must be a positive number", opts.maxSignatures)
}
if cmd.Flags().Changed("allow-referrers-api") {
fmt.Fprintln(os.Stderr, "Warning: flag '--allow-referrers-api' is deprecated and will be removed in future versions.")
}
return runList(cmd.Context(), opts)
},
}
opts.LoggingFlagOpts.ApplyFlags(command.Flags())
opts.SecureFlagOpts.ApplyFlags(command.Flags())
cmd.SetPflagReferrersAPI(command.Flags(), &opts.allowReferrersAPI, fmt.Sprintf(cmd.PflagReferrersUsageFormat, "list"))
command.Flags().BoolVar(&opts.ociLayout, "oci-layout", false, "[Experimental] list signatures stored in OCI image layout")
command.Flags().IntVar(&opts.maxSignatures, "max-signatures", 100, "maximum number of signatures to evaluate or examine")
experimental.HideFlags(command, experimentalExamples, []string{"oci-layout"})
Expand Down
4 changes: 1 addition & 3 deletions cmd/notation/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,10 @@ func getRemoteRepository(ctx context.Context, opts *SecureFlagOpts, reference st
}

if forceReferrersTag {
logger.Info("The referrers tag schema is always attempted")
logger.Info("Force to store signatures using the referrers tag schema")
if err := remoteRepo.SetReferrersCapability(false); err != nil {
return nil, err
}
} else {
logger.Info("Allowed to access the referrers API, fallback if not supported")
}
return notationregistry.NewRepository(remoteRepo), nil
}
Expand Down
15 changes: 2 additions & 13 deletions cmd/notation/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ type signOpts struct {
pluginConfig []string
userMetadata []string
reference string
allowReferrersAPI bool
forceReferrersTag bool
ociLayout bool
inputType inputType
Expand Down Expand Up @@ -116,7 +115,7 @@ Example - [Experimental] Sign an OCI artifact identified by a tag and referenced
if opts.ociLayout {
opts.inputType = inputTypeOCILayout
}
return experimental.CheckFlagsAndWarn(cmd, "allow-referrers-api", "oci-layout")
return experimental.CheckFlagsAndWarn(cmd, "oci-layout")
},
RunE: func(cmd *cobra.Command, args []string) error {
// timestamping
Expand All @@ -129,15 +128,6 @@ Example - [Experimental] Sign an OCI artifact identified by a tag and referenced
}
}

// allow-referrers-api flag is set
if cmd.Flags().Changed("allow-referrers-api") {
if opts.allowReferrersAPI {
fmt.Fprintln(os.Stderr, "Warning: flag '--allow-referrers-api' is deprecated and will be removed in future versions, use '--force-referrers-tag=false' instead.")
opts.forceReferrersTag = false
} else {
fmt.Fprintln(os.Stderr, "Warning: flag '--allow-referrers-api' is deprecated and will be removed in future versions.")
}
}
return runSign(cmd, opts)
},
}
Expand All @@ -147,12 +137,11 @@ Example - [Experimental] Sign an OCI artifact identified by a tag and referenced
cmd.SetPflagExpiry(command.Flags(), &opts.expiry)
cmd.SetPflagPluginConfig(command.Flags(), &opts.pluginConfig)
cmd.SetPflagUserMetadata(command.Flags(), &opts.userMetadata, cmd.PflagUserMetadataSignUsage)
cmd.SetPflagReferrersAPI(command.Flags(), &opts.allowReferrersAPI, fmt.Sprintf(cmd.PflagReferrersUsageFormat, "sign"))
command.Flags().StringVar(&opts.tsaServerURL, "timestamp-url", "", "RFC 3161 Timestamping Authority (TSA) server URL")
command.Flags().StringVar(&opts.tsaRootCertificatePath, "timestamp-root-cert", "", "filepath of timestamp authority root certificate")
cmd.SetPflagReferrersTag(command.Flags(), &opts.forceReferrersTag, "force to store signatures using the referrers tag schema")
command.Flags().BoolVar(&opts.ociLayout, "oci-layout", false, "[Experimental] sign the artifact stored as OCI image layout")
command.MarkFlagsMutuallyExclusive("oci-layout", "force-referrers-tag", "allow-referrers-api")
command.MarkFlagsMutuallyExclusive("oci-layout", "force-referrers-tag")
command.MarkFlagsRequiredTogether("timestamp-url", "timestamp-root-cert")
experimental.HideFlags(command, experimentalExamples, []string{"oci-layout"})
return command
Expand Down
2 changes: 1 addition & 1 deletion cmd/notation/sign_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func TestSignCommand_BasicArgs(t *testing.T) {
Key: "key",
SignatureFormat: envelope.JWS,
},
forceReferrersTag: true,
forceReferrersTag: false,
}
if err := command.ParseFlags([]string{
expected.reference,
Expand Down
8 changes: 1 addition & 7 deletions cmd/notation/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ package main
import (
"errors"
"fmt"
"os"

"github.com/notaryproject/notation-go"
"github.com/notaryproject/notation/cmd/notation/internal/display"
Expand All @@ -36,7 +35,6 @@ type verifyOpts struct {
reference string
pluginConfig []string
userMetadata []string
allowReferrersAPI bool
ociLayout bool
trustPolicyScope string
inputType inputType
Expand Down Expand Up @@ -82,23 +80,19 @@ Example - [Experimental] Verify a signature on an OCI artifact identified by a t
opts.inputType = inputTypeOCILayout
}
opts.Common.Parse(cmd)
return experimental.CheckFlagsAndWarn(cmd, "allow-referrers-api", "oci-layout", "scope")
return experimental.CheckFlagsAndWarn(cmd, "oci-layout", "scope")
},
RunE: func(cmd *cobra.Command, args []string) error {
if opts.maxSignatureAttempts <= 0 {
return fmt.Errorf("max-signatures value %d must be a positive number", opts.maxSignatureAttempts)
}
if cmd.Flags().Changed("allow-referrers-api") {
fmt.Fprintln(os.Stderr, "Warning: flag '--allow-referrers-api' is deprecated and will be removed in future versions.")
}
return runVerify(cmd, opts)
},
}
opts.LoggingFlagOpts.ApplyFlags(command.Flags())
opts.SecureFlagOpts.ApplyFlags(command.Flags())
command.Flags().StringArrayVar(&opts.pluginConfig, "plugin-config", nil, "{key}={value} pairs that are passed as it is to a plugin, if the verification is associated with a verification plugin, refer plugin documentation to set appropriate values")
cmd.SetPflagUserMetadata(command.Flags(), &opts.userMetadata, cmd.PflagUserMetadataVerifyUsage)
cmd.SetPflagReferrersAPI(command.Flags(), &opts.allowReferrersAPI, fmt.Sprintf(cmd.PflagReferrersUsageFormat, "verify"))
command.Flags().IntVar(&opts.maxSignatureAttempts, "max-signatures", 100, "maximum number of signatures to evaluate or examine")
command.Flags().BoolVar(&opts.ociLayout, "oci-layout", false, "[Experimental] verify the artifact stored as OCI image layout")
command.Flags().StringVar(&opts.trustPolicyScope, "scope", "", "[Experimental] set trust policy scope for artifact verification, required and can only be used when flag \"--oci-layout\" is set")
Expand Down
11 changes: 1 addition & 10 deletions internal/cmd/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,20 +101,11 @@ var (
fs.StringArrayVarP(p, PflagUserMetadata.Name, PflagUserMetadata.Shorthand, nil, usage)
}

PflagReferrersAPI = &pflag.Flag{
Name: "allow-referrers-api",
}
PflagReferrersUsageFormat = "[Experimental] use the Referrers API to %s signatures, if not supported (returns 404), fallback to the Referrers tag schema"
SetPflagReferrersAPI = func(fs *pflag.FlagSet, p *bool, usage string) {
fs.BoolVar(p, PflagReferrersAPI.Name, false, usage)
fs.MarkHidden(PflagReferrersAPI.Name)
}

PflagReferrersTag = &pflag.Flag{
Name: "force-referrers-tag",
}
SetPflagReferrersTag = func(fs *pflag.FlagSet, p *bool, usage string) {
fs.BoolVar(p, PflagReferrersTag.Name, true, usage)
fs.BoolVar(p, PflagReferrersTag.Name, false, usage)
}
)

Expand Down
3 changes: 1 addition & 2 deletions specs/commandline/sign.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Usage:
notation sign [flags] <reference>
Flags:
--force-referrers-tag force to store signatures using the referrers tag schema (default true)
--force-referrers-tag force to store signatures using the referrers tag schema
-d, --debug debug mode
-e, --expiry duration optional expiry that provides a "best by use" time for the artifact. The duration is specified in minutes(m) and/or hours(h). For example: 12h, 30m, 3h20m
-h, --help help for sign
Expand Down Expand Up @@ -205,7 +205,6 @@ export NOTATION_EXPERIMENTAL=1
notation list --oci-layout hello-world@sha256:xxx
```

[oci-artifact-manifest]: https://github.com/opencontainers/image-spec/blob/v1.1.0-rc2/artifact.md
[oci-image-spec]: https://github.com/opencontainers/image-spec/blob/v1.1.0/spec.md
[oci-referers-api]: https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#listing-referrers
[oci-image-layout]: https://github.com/opencontainers/image-spec/blob/v1.1.0/image-layout.md
34 changes: 0 additions & 34 deletions test/e2e/suite/command/inspect.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,40 +131,6 @@ var _ = Describe("notation inspect", func() {
})
})

It("sign with --allow-referrers-api set", func() {
Host(BaseOptionsWithExperimental(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) {
notation.Exec("sign", "--allow-referrers-api", artifact.ReferenceWithDigest()).
MatchKeyWords(SignSuccessfully)

notation.Exec("inspect", artifact.ReferenceWithDigest(), "-v").
MatchKeyWords(inspectSuccessfully...)

notation.Exec("inspect", artifact.ReferenceWithDigest(), "--allow-referrers-api", "-v").
MatchErrKeyWords(
"Warning: This feature is experimental and may not be fully tested or completed and may be deprecated.",
"Warning: flag '--allow-referrers-api' is deprecated and will be removed in future versions.",
).
MatchKeyWords(inspectSuccessfully...)
})
})

It("sign with --allow-referrers-api set to false", func() {
Host(BaseOptionsWithExperimental(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) {
notation.Exec("sign", "--allow-referrers-api=false", artifact.ReferenceWithDigest()).
MatchKeyWords(SignSuccessfully)

notation.Exec("inspect", artifact.ReferenceWithDigest(), "-v").
MatchKeyWords(inspectSuccessfully...)

notation.Exec("inspect", artifact.ReferenceWithDigest(), "--allow-referrers-api", "-v").
MatchErrKeyWords(
"Warning: This feature is experimental and may not be fully tested or completed and may be deprecated.",
"Warning: flag '--allow-referrers-api' is deprecated and will be removed in future versions.",
).
MatchKeyWords(inspectSuccessfully...)
})
})

It("with timestamping", func() {
Host(BaseOptions(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) {
notation.Exec("sign", "--timestamp-url", "http://rfc3161timestamp.globalsign.com/advanced", "--timestamp-root-cert", filepath.Join(NotationE2EConfigPath, "timestamp", "globalsignTSARoot.cer"), artifact.ReferenceWithDigest()).
Expand Down
46 changes: 0 additions & 46 deletions test/e2e/suite/command/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,50 +111,4 @@ var _ = Describe("notation list", func() {
)
})
})

It("sign with --allow-referrers-api set", func() {
Host(BaseOptionsWithExperimental(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) {
notation.Exec("sign", "--allow-referrers-api", artifact.ReferenceWithDigest()).
MatchKeyWords(SignSuccessfully)

notation.Exec("list", artifact.ReferenceWithDigest(), "-v").
MatchKeyWords(
"└── application/vnd.cncf.notary.signature",
"└── sha256:",
)

notation.Exec("list", artifact.ReferenceWithDigest(), "--allow-referrers-api", "-v").
MatchErrKeyWords(
"Warning: This feature is experimental and may not be fully tested or completed and may be deprecated.",
"Warning: flag '--allow-referrers-api' is deprecated and will be removed in future versions.",
).
MatchKeyWords(
"└── application/vnd.cncf.notary.signature",
"└── sha256:",
)
})
})

It("sign with --allow-referrers-api set to false", func() {
Host(BaseOptionsWithExperimental(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) {
notation.Exec("sign", "--allow-referrers-api=false", artifact.ReferenceWithDigest()).
MatchKeyWords(SignSuccessfully)

notation.Exec("list", artifact.ReferenceWithDigest(), "-v").
MatchKeyWords(
"└── application/vnd.cncf.notary.signature",
"└── sha256:",
)

notation.Exec("list", artifact.ReferenceWithDigest(), "--allow-referrers-api", "-v").
MatchErrKeyWords(
"Warning: This feature is experimental and may not be fully tested or completed and may be deprecated.",
"Warning: flag '--allow-referrers-api' is deprecated and will be removed in future versions.",
).
MatchKeyWords(
"└── application/vnd.cncf.notary.signature",
"└── sha256:",
)
})
})
})
Loading

0 comments on commit ae0d432

Please # to comment.