@@ -3,17 +3,14 @@ package image
33import (
44 "context"
55 "encoding/hex"
6- "encoding/json"
76 "fmt"
87 "io"
9- "sort"
108
119 "github.com/distribution/reference"
1210 "github.com/docker/cli/cli/command"
1311 "github.com/docker/cli/cli/internal/jsonstream"
1412 "github.com/docker/cli/cli/streams"
1513 "github.com/docker/cli/cli/trust"
16- "github.com/docker/docker/api/types"
1714 "github.com/docker/docker/api/types/image"
1815 registrytypes "github.com/docker/docker/api/types/registry"
1916 "github.com/docker/docker/registry"
@@ -44,7 +41,9 @@ func newNotaryClient(cli command.Streams, imgRefAndAuth trust.ImageRefAndAuth) (
4441 return trust .GetNotaryRepository (cli .In (), cli .Out (), command .UserAgent (), imgRefAndAuth .RepoInfo (), imgRefAndAuth .AuthConfig (), "pull" )
4542}
4643
47- // TrustedPush handles content trust pushing of an image
44+ // TrustedPush handles content trust pushing of an image.
45+ //
46+ // Deprecated: this function was only used internally and will be removed in the next release.
4847func TrustedPush (ctx context.Context , cli command.Cli , repoInfo * registry.RepositoryInfo , ref reference.Named , authConfig registrytypes.AuthConfig , options image.PushOptions ) error {
4948 responseBody , err := cli .Client ().ImagePush (ctx , reference .FamiliarString (ref ), options )
5049 if err != nil {
@@ -53,120 +52,19 @@ func TrustedPush(ctx context.Context, cli command.Cli, repoInfo *registry.Reposi
5352
5453 defer responseBody .Close ()
5554
56- return PushTrustedReference (ctx , cli , repoInfo , ref , authConfig , responseBody )
55+ return trust . PushTrustedReference (ctx , cli , repoInfo , ref , authConfig , responseBody , command . UserAgent () )
5756}
5857
5958// PushTrustedReference pushes a canonical reference to the trust server.
6059//
61- //nolint:gocyclo
60+ // Deprecated: use [trust.PushTrustedReference] instead. this function was only used internally and will be removed in the next release.
6261func PushTrustedReference (ctx context.Context , ioStreams command.Streams , repoInfo * registry.RepositoryInfo , ref reference.Named , authConfig registrytypes.AuthConfig , in io.Reader ) error {
63- // If it is a trusted push we would like to find the target entry which match the
64- // tag provided in the function and then do an AddTarget later.
65- notaryTarget := & client.Target {}
66- // Count the times of calling for handleTarget,
67- // if it is called more that once, that should be considered an error in a trusted push.
68- cnt := 0
69- handleTarget := func (msg jsonstream.JSONMessage ) {
70- cnt ++
71- if cnt > 1 {
72- // handleTarget should only be called once. This will be treated as an error.
73- return
74- }
75-
76- var pushResult types.PushResult
77- err := json .Unmarshal (* msg .Aux , & pushResult )
78- if err == nil && pushResult .Tag != "" {
79- if dgst , err := digest .Parse (pushResult .Digest ); err == nil {
80- h , err := hex .DecodeString (dgst .Hex ())
81- if err != nil {
82- notaryTarget = nil
83- return
84- }
85- notaryTarget .Name = pushResult .Tag
86- notaryTarget .Hashes = data.Hashes {string (dgst .Algorithm ()): h }
87- notaryTarget .Length = int64 (pushResult .Size )
88- }
89- }
90- }
91-
92- var tag string
93- switch x := ref .(type ) {
94- case reference.Canonical :
95- return errors .New ("cannot push a digest reference" )
96- case reference.NamedTagged :
97- tag = x .Tag ()
98- default :
99- // We want trust signatures to always take an explicit tag,
100- // otherwise it will act as an untrusted push.
101- if err := jsonstream .Display (ctx , in , ioStreams .Out ()); err != nil {
102- return err
103- }
104- _ , _ = fmt .Fprintln (ioStreams .Err (), "No tag specified, skipping trust metadata push" )
105- return nil
106- }
107-
108- if err := jsonstream .Display (ctx , in , ioStreams .Out (), jsonstream .WithAuxCallback (handleTarget )); err != nil {
109- return err
110- }
111-
112- if cnt > 1 {
113- return errors .Errorf ("internal error: only one call to handleTarget expected" )
114- }
115-
116- if notaryTarget == nil {
117- return errors .Errorf ("no targets found, provide a specific tag in order to sign it" )
118- }
119-
120- _ , _ = fmt .Fprintln (ioStreams .Out (), "Signing and pushing trust metadata" )
121-
122- repo , err := trust .GetNotaryRepository (ioStreams .In (), ioStreams .Out (), command .UserAgent (), repoInfo , & authConfig , "push" , "pull" )
123- if err != nil {
124- return errors .Wrap (err , "error establishing connection to trust repository" )
125- }
126-
127- // get the latest repository metadata so we can figure out which roles to sign
128- _ , err = repo .ListTargets ()
129-
130- switch err .(type ) {
131- case client.ErrRepoNotInitialized , client.ErrRepositoryNotExist :
132- keys := repo .GetCryptoService ().ListKeys (data .CanonicalRootRole )
133- var rootKeyID string
134- // always select the first root key
135- if len (keys ) > 0 {
136- sort .Strings (keys )
137- rootKeyID = keys [0 ]
138- } else {
139- rootPublicKey , err := repo .GetCryptoService ().Create (data .CanonicalRootRole , "" , data .ECDSAKey )
140- if err != nil {
141- return err
142- }
143- rootKeyID = rootPublicKey .ID ()
144- }
145-
146- // Initialize the notary repository with a remotely managed snapshot key
147- if err := repo .Initialize ([]string {rootKeyID }, data .CanonicalSnapshotRole ); err != nil {
148- return trust .NotaryError (repoInfo .Name .Name (), err )
149- }
150- _ , _ = fmt .Fprintf (ioStreams .Out (), "Finished initializing %q\n " , repoInfo .Name .Name ())
151- err = repo .AddTarget (notaryTarget , data .CanonicalTargetsRole )
152- case nil :
153- // already initialized and we have successfully downloaded the latest metadata
154- err = trust .AddToAllSignableRoles (repo , notaryTarget )
155- default :
156- return trust .NotaryError (repoInfo .Name .Name (), err )
157- }
158-
159- if err == nil {
160- err = repo .Publish ()
161- }
162-
163- if err != nil {
164- err = errors .Wrapf (err , "failed to sign %s:%s" , repoInfo .Name .Name (), tag )
165- return trust .NotaryError (repoInfo .Name .Name (), err )
166- }
62+ return pushTrustedReference (ctx , ioStreams , repoInfo , ref , authConfig , in )
63+ }
16764
168- _ , _ = fmt .Fprintf (ioStreams .Out (), "Successfully signed %s:%s\n " , repoInfo .Name .Name (), tag )
169- return nil
65+ // pushTrustedReference pushes a canonical reference to the trust server.
66+ func pushTrustedReference (ctx context.Context , ioStreams command.Streams , repoInfo * registry.RepositoryInfo , ref reference.Named , authConfig registrytypes.AuthConfig , in io.Reader ) error {
67+ return trust .PushTrustedReference (ctx , ioStreams , repoInfo , ref , authConfig , in , command .UserAgent ())
17068}
17169
17270// trustedPull handles content trust pulling of an image
@@ -206,7 +104,11 @@ func trustedPull(ctx context.Context, cli command.Cli, imgRefAndAuth trust.Image
206104 return err
207105 }
208106
209- if err := TagTrusted (ctx , cli , trustedRef , tagged ); err != nil {
107+ // Use familiar references when interacting with client and output
108+ familiarRef := reference .FamiliarString (tagged )
109+ trustedFamiliarRef := reference .FamiliarString (trustedRef )
110+ _ , _ = fmt .Fprintf (cli .Err (), "Tagging %s as %s\n " , trustedFamiliarRef , familiarRef )
111+ if err := cli .Client ().ImageTag (ctx , trustedFamiliarRef , familiarRef ); err != nil {
210112 return err
211113 }
212114 }
@@ -327,15 +229,13 @@ func convertTarget(t client.Target) (target, error) {
327229 }, nil
328230}
329231
330- // TagTrusted tags a trusted ref
232+ // TagTrusted tags a trusted ref. It is a shallow wrapper around APIClient.ImageTag
233+ // that updates the given image references to their familiar format for tagging
234+ // and printing.
235+ //
236+ // Deprecated: this function was only used internally, and will be removed in the next release.
331237func TagTrusted (ctx context.Context , cli command.Cli , trustedRef reference.Canonical , ref reference.NamedTagged ) error {
332- // Use familiar references when interacting with client and output
333- familiarRef := reference .FamiliarString (ref )
334- trustedFamiliarRef := reference .FamiliarString (trustedRef )
335-
336- _ , _ = fmt .Fprintf (cli .Err (), "Tagging %s as %s\n " , trustedFamiliarRef , familiarRef )
337-
338- return cli .Client ().ImageTag (ctx , trustedFamiliarRef , familiarRef )
238+ return trust .TagTrusted (ctx , cli .Client (), cli .Err (), trustedRef , ref )
339239}
340240
341241// AuthResolver returns an auth resolver function from a command.Cli
0 commit comments