@@ -3,17 +3,14 @@ package image
3
3
import (
4
4
"context"
5
5
"encoding/hex"
6
- "encoding/json"
7
6
"fmt"
8
7
"io"
9
- "sort"
10
8
11
9
"github.com/distribution/reference"
12
10
"github.com/docker/cli/cli/command"
13
11
"github.com/docker/cli/cli/internal/jsonstream"
14
12
"github.com/docker/cli/cli/streams"
15
13
"github.com/docker/cli/cli/trust"
16
- "github.com/docker/docker/api/types"
17
14
"github.com/docker/docker/api/types/image"
18
15
registrytypes "github.com/docker/docker/api/types/registry"
19
16
"github.com/docker/docker/registry"
@@ -44,7 +41,9 @@ func newNotaryClient(cli command.Streams, imgRefAndAuth trust.ImageRefAndAuth) (
44
41
return trust .GetNotaryRepository (cli .In (), cli .Out (), command .UserAgent (), imgRefAndAuth .RepoInfo (), imgRefAndAuth .AuthConfig (), "pull" )
45
42
}
46
43
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.
48
47
func TrustedPush (ctx context.Context , cli command.Cli , repoInfo * registry.RepositoryInfo , ref reference.Named , authConfig registrytypes.AuthConfig , options image.PushOptions ) error {
49
48
responseBody , err := cli .Client ().ImagePush (ctx , reference .FamiliarString (ref ), options )
50
49
if err != nil {
@@ -53,120 +52,19 @@ func TrustedPush(ctx context.Context, cli command.Cli, repoInfo *registry.Reposi
53
52
54
53
defer responseBody .Close ()
55
54
56
- return PushTrustedReference (ctx , cli , repoInfo , ref , authConfig , responseBody )
55
+ return trust . PushTrustedReference (ctx , cli , repoInfo , ref , authConfig , responseBody , command . UserAgent () )
57
56
}
58
57
59
58
// PushTrustedReference pushes a canonical reference to the trust server.
60
59
//
61
- //nolint:gocyclo
60
+ // Deprecated: use [trust.PushTrustedReference] instead. this function was only used internally and will be removed in the next release.
62
61
func 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
+ }
167
64
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 ())
170
68
}
171
69
172
70
// trustedPull handles content trust pulling of an image
@@ -206,7 +104,11 @@ func trustedPull(ctx context.Context, cli command.Cli, imgRefAndAuth trust.Image
206
104
return err
207
105
}
208
106
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 {
210
112
return err
211
113
}
212
114
}
@@ -327,15 +229,13 @@ func convertTarget(t client.Target) (target, error) {
327
229
}, nil
328
230
}
329
231
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.
331
237
func 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 )
339
239
}
340
240
341
241
// AuthResolver returns an auth resolver function from a command.Cli
0 commit comments