Skip to content

Commit ceef542

Browse files
authored
Merge pull request docker#5894 from thaJeztah/more_internalize
move some trust-related code to trust package
2 parents f9b3c8c + e37d814 commit ceef542

File tree

8 files changed

+201
-128
lines changed

8 files changed

+201
-128
lines changed

cli/command/container/create.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"github.com/docker/cli/cli/command/image"
1616
"github.com/docker/cli/cli/internal/jsonstream"
1717
"github.com/docker/cli/cli/streams"
18+
"github.com/docker/cli/cli/trust"
1819
"github.com/docker/cli/opts"
1920
"github.com/docker/docker/api/types/container"
2021
imagetypes "github.com/docker/docker/api/types/image"
@@ -242,7 +243,7 @@ func createContainer(ctx context.Context, dockerCli command.Cli, containerCfg *c
242243
return err
243244
}
244245
if taggedRef, ok := namedRef.(reference.NamedTagged); ok && trustedRef != nil {
245-
return image.TagTrusted(ctx, dockerCli, trustedRef, taggedRef)
246+
return trust.TagTrusted(ctx, dockerCli.Client(), dockerCli.Err(), trustedRef, taggedRef)
246247
}
247248
return nil
248249
}

cli/command/image/build.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"github.com/docker/cli/cli/command/image/build"
2323
"github.com/docker/cli/cli/internal/jsonstream"
2424
"github.com/docker/cli/cli/streams"
25+
"github.com/docker/cli/cli/trust"
2526
"github.com/docker/cli/opts"
2627
"github.com/docker/docker/api"
2728
"github.com/docker/docker/api/types"
@@ -406,7 +407,7 @@ func runBuild(ctx context.Context, dockerCli command.Cli, options buildOptions)
406407
// Since the build was successful, now we must tag any of the resolved
407408
// images from the above Dockerfile rewrite.
408409
for _, resolved := range resolvedTags {
409-
if err := TagTrusted(ctx, dockerCli, resolved.digestRef, resolved.tagRef); err != nil {
410+
if err := trust.TagTrusted(ctx, dockerCli.Client(), dockerCli.Err(), resolved.digestRef, resolved.tagRef); err != nil {
410411
return err
411412
}
412413
}

cli/command/image/push.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,8 @@ To push the complete multi-platform image, remove the --platform flag.
139139

140140
defer responseBody.Close()
141141
if !opts.untrusted {
142-
// TODO PushTrustedReference currently doesn't respect `--quiet`
143-
return PushTrustedReference(ctx, dockerCli, repoInfo, ref, authConfig, responseBody)
142+
// TODO pushTrustedReference currently doesn't respect `--quiet`
143+
return pushTrustedReference(ctx, dockerCli, repoInfo, ref, authConfig, responseBody)
144144
}
145145

146146
if opts.quiet {

cli/command/image/trust.go

Lines changed: 21 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,14 @@ package image
33
import (
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.
4847
func 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.
6261
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+
}
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.
331237
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)
339239
}
340240

341241
// AuthResolver returns an auth resolver function from a command.Cli

cli/command/plugin/push.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ import (
66
"github.com/distribution/reference"
77
"github.com/docker/cli/cli"
88
"github.com/docker/cli/cli/command"
9-
"github.com/docker/cli/cli/command/image"
109
"github.com/docker/cli/cli/internal/jsonstream"
10+
"github.com/docker/cli/cli/trust"
1111
registrytypes "github.com/docker/docker/api/types/registry"
1212
"github.com/docker/docker/registry"
1313
"github.com/pkg/errors"
@@ -66,7 +66,7 @@ func runPush(ctx context.Context, dockerCli command.Cli, opts pushOptions) error
6666
defer responseBody.Close()
6767

6868
if !opts.untrusted {
69-
return image.PushTrustedReference(ctx, dockerCli, repoInfo, named, authConfig, responseBody)
69+
return trust.PushTrustedReference(ctx, dockerCli, repoInfo, named, authConfig, responseBody, command.UserAgent())
7070
}
7171

7272
return jsonstream.Display(ctx, responseBody, dockerCli.Out())

cli/command/trust/sign.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"sort"
99
"strings"
1010

11+
"github.com/distribution/reference"
1112
"github.com/docker/cli/cli"
1213
"github.com/docker/cli/cli/command"
1314
"github.com/docker/cli/cli/command/image"
@@ -98,10 +99,15 @@ func runSignImage(ctx context.Context, dockerCLI command.Cli, options signOption
9899
if err != nil {
99100
return err
100101
}
101-
return image.TrustedPush(ctx, dockerCLI, imgRefAndAuth.RepoInfo(), imgRefAndAuth.Reference(), *imgRefAndAuth.AuthConfig(), imagetypes.PushOptions{
102+
responseBody, err := dockerCLI.Client().ImagePush(ctx, reference.FamiliarString(imgRefAndAuth.Reference()), imagetypes.PushOptions{
102103
RegistryAuth: encodedAuth,
103104
PrivilegeFunc: requestPrivilege,
104105
})
106+
if err != nil {
107+
return err
108+
}
109+
defer responseBody.Close()
110+
return trust.PushTrustedReference(ctx, dockerCLI, imgRefAndAuth.RepoInfo(), imgRefAndAuth.Reference(), authConfig, responseBody, command.UserAgent())
105111
default:
106112
return err
107113
}

0 commit comments

Comments
 (0)