implement docker trust as plugin
move the `trust` subcommands to a plugin, so that the subcommands can
be installed separate from the `docker trust` integration in push/pull
(for situations where trust verification happens on the daemon side).
make binary
go build -o /usr/libexec/docker/cli-plugins/docker-trust ./cmd/docker-trust
docker info
Client:
Version: 28.2.0-dev
Context: default
Debug Mode: false
Plugins:
buildx: Docker Buildx (Docker Inc.)
Version: v0.24.0
Path: /usr/libexec/docker/cli-plugins/docker-buildx
trust: Manage trust on Docker images (Docker Inc.)
Version: unknown-version
Path: /usr/libexec/docker/cli-plugins/docker-trust
docker trust --help
Usage: docker trust [OPTIONS] COMMAND
Extended build capabilities with BuildKit
Options:
-D, --debug Enable debug logging
Management Commands:
key Manage keys for signing Docker images
signer Manage entities who can sign Docker images
Commands:
inspect Return low-level information about keys and signatures
revoke Remove trust for an image
sign Sign an image
Run 'docker trust COMMAND --help' for more information on a command.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
9
Makefile
9
Makefile
@ -69,6 +69,15 @@ dynbinary: ## build dynamically linked binary
|
||||
plugins: ## build example CLI plugins
|
||||
scripts/build/plugins
|
||||
|
||||
.PHONY: trust-plugin
|
||||
trust-plugin: ## build docker-trust CLI plugins
|
||||
scripts/build/trust-plugin
|
||||
|
||||
.PHONY: install-trust-plugin
|
||||
install-trust-plugin: trust-plugin
|
||||
install-trust-plugin: ## install docker-trust CLI plugins
|
||||
install -D -m 0755 "$$(readlink -f build/docker-trust)" /usr/libexec/docker/cli-plugins/docker-trust
|
||||
|
||||
.PHONY: vendor
|
||||
vendor: ## update vendor with go modules
|
||||
rm -rf vendor
|
||||
|
||||
@ -18,7 +18,6 @@ import (
|
||||
_ "github.com/docker/cli/cli/command/stack"
|
||||
_ "github.com/docker/cli/cli/command/swarm"
|
||||
_ "github.com/docker/cli/cli/command/system"
|
||||
_ "github.com/docker/cli/cli/command/trust"
|
||||
_ "github.com/docker/cli/cli/command/volume"
|
||||
"github.com/docker/cli/internal/commands"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
128
cmd/docker-trust/internal/test/cli.go
Normal file
128
cmd/docker-trust/internal/test/cli.go
Normal file
@ -0,0 +1,128 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/cli/cli/config/configfile"
|
||||
"github.com/docker/cli/cli/streams"
|
||||
"github.com/moby/moby/client"
|
||||
notaryclient "github.com/theupdateframework/notary/client"
|
||||
)
|
||||
|
||||
// NotaryClientFuncType defines a function that returns a fake notary client
|
||||
type NotaryClientFuncType func() (notaryclient.Repository, error)
|
||||
|
||||
// FakeCli emulates the default DockerCli
|
||||
type FakeCli struct {
|
||||
command.DockerCli
|
||||
client client.APIClient
|
||||
configfile *configfile.ConfigFile
|
||||
out *streams.Out
|
||||
outBuffer *bytes.Buffer
|
||||
err *streams.Out
|
||||
errBuffer *bytes.Buffer
|
||||
in *streams.In
|
||||
server command.ServerInfo
|
||||
notaryClientFunc NotaryClientFuncType
|
||||
currentContext string
|
||||
}
|
||||
|
||||
// NewFakeCli returns a fake for the command.Cli interface
|
||||
func NewFakeCli(apiClient client.APIClient, opts ...func(*FakeCli)) *FakeCli {
|
||||
outBuffer := new(bytes.Buffer)
|
||||
errBuffer := new(bytes.Buffer)
|
||||
c := &FakeCli{
|
||||
client: apiClient,
|
||||
out: streams.NewOut(outBuffer),
|
||||
outBuffer: outBuffer,
|
||||
err: streams.NewOut(errBuffer),
|
||||
errBuffer: errBuffer,
|
||||
in: streams.NewIn(io.NopCloser(strings.NewReader(""))),
|
||||
// Use an empty string for filename so that tests don't create configfiles
|
||||
// Set cli.ConfigFile().Filename to a tempfile to support Save.
|
||||
configfile: configfile.New(""),
|
||||
currentContext: command.DefaultContextName,
|
||||
}
|
||||
for _, opt := range opts {
|
||||
opt(c)
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
// SetIn sets the input of the cli to the specified ReadCloser
|
||||
func (c *FakeCli) SetIn(in *streams.In) {
|
||||
c.in = in
|
||||
}
|
||||
|
||||
// SetErr sets the stderr stream for the cli to the specified io.Writer
|
||||
func (c *FakeCli) SetErr(err *streams.Out) {
|
||||
c.err = err
|
||||
}
|
||||
|
||||
// SetOut sets the stdout stream for the cli to the specified io.Writer
|
||||
func (c *FakeCli) SetOut(out *streams.Out) {
|
||||
c.out = out
|
||||
}
|
||||
|
||||
// Client returns a docker API client
|
||||
func (c *FakeCli) Client() client.APIClient {
|
||||
return c.client
|
||||
}
|
||||
|
||||
// CurrentVersion returns the API version used by FakeCli.
|
||||
// func (*FakeCli) CurrentVersion() string {
|
||||
// return client.MaxAPIVersion
|
||||
// }
|
||||
|
||||
// Out returns the output stream (stdout) the cli should write on
|
||||
func (c *FakeCli) Out() *streams.Out {
|
||||
return c.out
|
||||
}
|
||||
|
||||
// Err returns the output stream (stderr) the cli should write on
|
||||
func (c *FakeCli) Err() *streams.Out {
|
||||
return c.err
|
||||
}
|
||||
|
||||
// In returns the input stream the cli will use
|
||||
func (c *FakeCli) In() *streams.In {
|
||||
return c.in
|
||||
}
|
||||
|
||||
// ConfigFile returns the cli configfile object (to get client configuration)
|
||||
func (c *FakeCli) ConfigFile() *configfile.ConfigFile {
|
||||
return c.configfile
|
||||
}
|
||||
|
||||
// OutBuffer returns the stdout buffer
|
||||
func (c *FakeCli) OutBuffer() *bytes.Buffer {
|
||||
return c.outBuffer
|
||||
}
|
||||
|
||||
// ErrBuffer Buffer returns the stderr buffer
|
||||
func (c *FakeCli) ErrBuffer() *bytes.Buffer {
|
||||
return c.errBuffer
|
||||
}
|
||||
|
||||
// ResetOutputBuffers resets the .OutBuffer() and.ErrBuffer() back to empty
|
||||
func (c *FakeCli) ResetOutputBuffers() {
|
||||
c.outBuffer.Reset()
|
||||
c.errBuffer.Reset()
|
||||
}
|
||||
|
||||
// SetNotaryClient sets the internal getter for retrieving a NotaryClient
|
||||
func (c *FakeCli) SetNotaryClient(notaryClientFunc NotaryClientFuncType) {
|
||||
c.notaryClientFunc = notaryClientFunc
|
||||
}
|
||||
|
||||
// NotaryClient returns an err for testing unless defined
|
||||
func (c *FakeCli) NotaryClient() (notaryclient.Repository, error) {
|
||||
if c.notaryClientFunc != nil {
|
||||
return c.notaryClientFunc()
|
||||
}
|
||||
return nil, errors.New("no notary client available unless defined")
|
||||
}
|
||||
15
cmd/docker-trust/internal/test/randomid.go
Normal file
15
cmd/docker-trust/internal/test/randomid.go
Normal file
@ -0,0 +1,15 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
)
|
||||
|
||||
// RandomID returns a unique, 64-character ID consisting of a-z, 0-9.
|
||||
func RandomID() string {
|
||||
b := make([]byte, 32)
|
||||
if _, err := rand.Read(b); err != nil {
|
||||
panic(err) // This shouldn't happen
|
||||
}
|
||||
return hex.EncodeToString(b)
|
||||
}
|
||||
114
cmd/docker-trust/main.go
Normal file
114
cmd/docker-trust/main.go
Normal file
@ -0,0 +1,114 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"syscall"
|
||||
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
"github.com/docker/cli/cli"
|
||||
"github.com/docker/cli/cli-plugins/metadata"
|
||||
"github.com/docker/cli/cli-plugins/plugin"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/cli/cli/version"
|
||||
"github.com/docker/cli/cmd/docker-trust/trust"
|
||||
"go.opentelemetry.io/otel"
|
||||
)
|
||||
|
||||
func runStandalone(cmd *command.DockerCli) error {
|
||||
defer flushMetrics(cmd)
|
||||
executable := os.Args[0]
|
||||
rootCmd := trust.NewRootCmd(filepath.Base(executable), false, cmd)
|
||||
return rootCmd.Execute()
|
||||
}
|
||||
|
||||
// flushMetrics will manually flush metrics from the configured
|
||||
// meter provider. This is needed when running in standalone mode
|
||||
// because the meter provider is initialized by the cli library,
|
||||
// but the mechanism for forcing it to report is not presently
|
||||
// exposed and not invoked when run in standalone mode.
|
||||
// There are plans to fix that in the next release, but this is
|
||||
// needed temporarily until the API for this is more thorough.
|
||||
func flushMetrics(cmd *command.DockerCli) {
|
||||
if mp, ok := cmd.MeterProvider().(command.MeterProvider); ok {
|
||||
if err := mp.ForceFlush(context.Background()); err != nil {
|
||||
otel.Handle(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func runPlugin(cmd *command.DockerCli) error {
|
||||
rootCmd := trust.NewRootCmd("trust", true, cmd)
|
||||
return plugin.RunPlugin(cmd, rootCmd, metadata.Metadata{
|
||||
SchemaVersion: "0.1.0",
|
||||
Vendor: "Docker Inc.",
|
||||
Version: version.Version,
|
||||
})
|
||||
}
|
||||
|
||||
func run(cmd *command.DockerCli) error {
|
||||
if plugin.RunningStandalone() {
|
||||
return runStandalone(cmd)
|
||||
}
|
||||
return runPlugin(cmd)
|
||||
}
|
||||
|
||||
type errCtxSignalTerminated struct {
|
||||
signal os.Signal
|
||||
}
|
||||
|
||||
func (errCtxSignalTerminated) Error() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func main() {
|
||||
cmd, err := command.NewDockerCli()
|
||||
if err != nil {
|
||||
_, _ = fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if err = run(cmd); err == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if errors.As(err, &errCtxSignalTerminated{}) {
|
||||
os.Exit(getExitCode(err))
|
||||
}
|
||||
|
||||
if !cerrdefs.IsCanceled(err) {
|
||||
if err.Error() != "" {
|
||||
_, _ = fmt.Fprintln(cmd.Err(), err)
|
||||
}
|
||||
os.Exit(getExitCode(err))
|
||||
}
|
||||
}
|
||||
|
||||
// getExitCode returns the exit-code to use for the given error.
|
||||
// If err is a [cli.StatusError] and has a StatusCode set, it uses the
|
||||
// status-code from it, otherwise it returns "1" for any error.
|
||||
func getExitCode(err error) int {
|
||||
if err == nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
var userTerminatedErr errCtxSignalTerminated
|
||||
if errors.As(err, &userTerminatedErr) {
|
||||
s, ok := userTerminatedErr.signal.(syscall.Signal)
|
||||
if !ok {
|
||||
return 1
|
||||
}
|
||||
return 128 + int(s)
|
||||
}
|
||||
|
||||
var stErr cli.StatusError
|
||||
if errors.As(err, &stErr) && stErr.StatusCode != 0 { // FIXME(thaJeztah): StatusCode should never be used with a zero status-code. Check if we do this anywhere.
|
||||
return stErr.StatusCode
|
||||
}
|
||||
|
||||
// No status-code provided; all errors should have a non-zero exit code.
|
||||
return 1
|
||||
}
|
||||
81
cmd/docker-trust/trust/commands.go
Normal file
81
cmd/docker-trust/trust/commands.go
Normal file
@ -0,0 +1,81 @@
|
||||
package trust
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/docker/cli-docs-tool/annotation"
|
||||
"github.com/docker/cli/cli"
|
||||
"github.com/docker/cli/cli-plugins/plugin"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/cli/cli/debug"
|
||||
cliflags "github.com/docker/cli/cli/flags"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
func NewRootCmd(name string, isPlugin bool, dockerCLI *command.DockerCli) *cobra.Command {
|
||||
var opt rootOptions
|
||||
cmd := &cobra.Command{
|
||||
Use: name,
|
||||
Short: "Manage trust on Docker images",
|
||||
Long: `Extended build capabilities with BuildKit`,
|
||||
Annotations: map[string]string{
|
||||
annotation.CodeDelimiter: `"`,
|
||||
},
|
||||
CompletionOptions: cobra.CompletionOptions{
|
||||
HiddenDefaultCmd: true,
|
||||
},
|
||||
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
||||
if opt.debug {
|
||||
debug.Enable()
|
||||
}
|
||||
// cmd.SetContext(appcontext.Context())
|
||||
if !isPlugin {
|
||||
// InstallFlags and SetDefaultOptions are necessary to match
|
||||
// the plugin mode behavior to handle env vars such as
|
||||
// DOCKER_TLS, DOCKER_TLS_VERIFY, ... and we also need to use a
|
||||
// new flagset to avoid conflict with the global debug flag
|
||||
// that we already handle in the root command otherwise it
|
||||
// would panic.
|
||||
nflags := pflag.NewFlagSet(cmd.DisplayName(), pflag.ContinueOnError)
|
||||
options := cliflags.NewClientOptions()
|
||||
options.InstallFlags(nflags)
|
||||
options.SetDefaultOptions(nflags)
|
||||
return dockerCLI.Initialize(options)
|
||||
}
|
||||
return plugin.PersistentPreRunE(cmd, args)
|
||||
},
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if len(args) == 0 {
|
||||
return cmd.Help()
|
||||
}
|
||||
_ = cmd.Help()
|
||||
return cli.StatusError{
|
||||
StatusCode: 1,
|
||||
Status: fmt.Sprintf("ERROR: unknown command: %q", args[0]),
|
||||
}
|
||||
},
|
||||
}
|
||||
if !isPlugin {
|
||||
// match plugin behavior for standalone mode
|
||||
// https://github.com/docker/cli/blob/6c9eb708fa6d17765d71965f90e1c59cea686ee9/cli-plugins/plugin/plugin.go#L117-L127
|
||||
cmd.SilenceUsage = true
|
||||
cmd.SilenceErrors = true
|
||||
cmd.TraverseChildren = true
|
||||
cmd.DisableFlagsInUseLine = true
|
||||
}
|
||||
|
||||
cmd.AddCommand(
|
||||
newRevokeCommand(dockerCLI),
|
||||
newSignCommand(dockerCLI),
|
||||
newTrustKeyCommand(dockerCLI),
|
||||
newTrustSignerCommand(dockerCLI),
|
||||
newInspectCommand(dockerCLI),
|
||||
)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
type rootOptions struct {
|
||||
debug bool
|
||||
}
|
||||
@ -10,7 +10,7 @@ import (
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/cli/cli/config"
|
||||
"github.com/docker/cli/cli/config/configfile"
|
||||
"github.com/docker/cli/cli/trust"
|
||||
"github.com/docker/cli/cmd/docker-trust/internal/trust"
|
||||
"github.com/fvbommel/sortorder"
|
||||
registrytypes "github.com/moby/moby/api/types/registry"
|
||||
"github.com/sirupsen/logrus"
|
||||
@ -3,7 +3,7 @@ package trust
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/docker/cli/cli/trust"
|
||||
"github.com/docker/cli/cmd/docker-trust/internal/trust"
|
||||
"github.com/theupdateframework/notary/client"
|
||||
"github.com/theupdateframework/notary/tuf/data"
|
||||
"gotest.tools/v3/assert"
|
||||
@ -5,7 +5,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/docker/cli/cli/command/formatter"
|
||||
"github.com/docker/cli/internal/test"
|
||||
"github.com/docker/cli/cmd/docker-trust/internal/test"
|
||||
"gotest.tools/v3/assert"
|
||||
is "gotest.tools/v3/assert/cmp"
|
||||
)
|
||||
@ -3,7 +3,7 @@ package trust
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/docker/cli/cli/trust"
|
||||
"github.com/docker/cli/cmd/docker-trust/internal/trust"
|
||||
"github.com/theupdateframework/notary/client"
|
||||
"github.com/theupdateframework/notary/tuf/data"
|
||||
)
|
||||
@ -8,9 +8,9 @@ import (
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/cli/cli/trust"
|
||||
"github.com/docker/cli/internal/test"
|
||||
notaryfake "github.com/docker/cli/internal/test/notary"
|
||||
"github.com/docker/cli/cmd/docker-trust/internal/test"
|
||||
notaryfake "github.com/docker/cli/cmd/docker-trust/internal/test/notary"
|
||||
"github.com/docker/cli/cmd/docker-trust/internal/trust"
|
||||
"github.com/moby/moby/client"
|
||||
"github.com/theupdateframework/notary"
|
||||
notaryclient "github.com/theupdateframework/notary/client"
|
||||
@ -4,8 +4,8 @@ import (
|
||||
"io"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/cli/internal/test"
|
||||
"github.com/docker/cli/internal/test/notary"
|
||||
"github.com/docker/cli/cmd/docker-trust/internal/test"
|
||||
"github.com/docker/cli/cmd/docker-trust/internal/test/notary"
|
||||
"github.com/theupdateframework/notary/client"
|
||||
"gotest.tools/v3/assert"
|
||||
"gotest.tools/v3/golden"
|
||||
@ -9,7 +9,7 @@ import (
|
||||
|
||||
"github.com/docker/cli/cli"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/cli/cli/trust"
|
||||
"github.com/docker/cli/cmd/docker-trust/internal/trust"
|
||||
"github.com/docker/cli/internal/lazyregexp"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/theupdateframework/notary"
|
||||
@ -9,7 +9,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/docker/cli/cli/config"
|
||||
"github.com/docker/cli/internal/test"
|
||||
"github.com/docker/cli/cmd/docker-trust/internal/test"
|
||||
"github.com/theupdateframework/notary"
|
||||
"github.com/theupdateframework/notary/trustmanager"
|
||||
tufutils "github.com/theupdateframework/notary/tuf/utils"
|
||||
@ -11,7 +11,7 @@ import (
|
||||
|
||||
"github.com/docker/cli/cli"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/cli/cli/trust"
|
||||
"github.com/docker/cli/cmd/docker-trust/internal/trust"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/theupdateframework/notary"
|
||||
"github.com/theupdateframework/notary/storage"
|
||||
@ -10,7 +10,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/docker/cli/cli/config"
|
||||
"github.com/docker/cli/internal/test"
|
||||
"github.com/docker/cli/cmd/docker-trust/internal/test"
|
||||
"github.com/theupdateframework/notary"
|
||||
"github.com/theupdateframework/notary/storage"
|
||||
"github.com/theupdateframework/notary/trustmanager"
|
||||
@ -7,7 +7,7 @@ import (
|
||||
|
||||
"github.com/docker/cli/cli"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/cli/cli/trust"
|
||||
"github.com/docker/cli/cmd/docker-trust/internal/trust"
|
||||
"github.com/docker/cli/internal/prompt"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/theupdateframework/notary/client"
|
||||
@ -5,8 +5,8 @@ import (
|
||||
"io"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/cli/internal/test"
|
||||
"github.com/docker/cli/internal/test/notary"
|
||||
"github.com/docker/cli/cmd/docker-trust/internal/test"
|
||||
"github.com/docker/cli/cmd/docker-trust/internal/test/notary"
|
||||
"github.com/theupdateframework/notary/client"
|
||||
"gotest.tools/v3/assert"
|
||||
is "gotest.tools/v3/assert/cmp"
|
||||
@ -12,7 +12,7 @@ import (
|
||||
"github.com/distribution/reference"
|
||||
"github.com/docker/cli/cli"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/cli/cli/trust"
|
||||
"github.com/docker/cli/cmd/docker-trust/internal/trust"
|
||||
"github.com/moby/moby/api/pkg/authconfig"
|
||||
"github.com/moby/moby/client"
|
||||
"github.com/spf13/cobra"
|
||||
@ -8,9 +8,9 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/docker/cli/cli/config"
|
||||
"github.com/docker/cli/cli/trust"
|
||||
"github.com/docker/cli/internal/test"
|
||||
notaryfake "github.com/docker/cli/internal/test/notary"
|
||||
"github.com/docker/cli/cmd/docker-trust/internal/test"
|
||||
notaryfake "github.com/docker/cli/cmd/docker-trust/internal/test/notary"
|
||||
"github.com/docker/cli/cmd/docker-trust/internal/trust"
|
||||
"github.com/theupdateframework/notary"
|
||||
"github.com/theupdateframework/notary/client"
|
||||
"github.com/theupdateframework/notary/client/changelist"
|
||||
@ -11,7 +11,7 @@ import (
|
||||
|
||||
"github.com/docker/cli/cli"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/cli/cli/trust"
|
||||
"github.com/docker/cli/cmd/docker-trust/internal/trust"
|
||||
"github.com/docker/cli/internal/lazyregexp"
|
||||
"github.com/docker/cli/opts"
|
||||
"github.com/spf13/cobra"
|
||||
@ -9,8 +9,8 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/docker/cli/cli/config"
|
||||
"github.com/docker/cli/internal/test"
|
||||
notaryfake "github.com/docker/cli/internal/test/notary"
|
||||
"github.com/docker/cli/cmd/docker-trust/internal/test"
|
||||
notaryfake "github.com/docker/cli/cmd/docker-trust/internal/test/notary"
|
||||
"github.com/theupdateframework/notary"
|
||||
"gotest.tools/v3/assert"
|
||||
is "gotest.tools/v3/assert/cmp"
|
||||
@ -8,7 +8,7 @@ import (
|
||||
|
||||
"github.com/docker/cli/cli"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/cli/cli/trust"
|
||||
"github.com/docker/cli/cmd/docker-trust/internal/trust"
|
||||
"github.com/docker/cli/internal/prompt"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/theupdateframework/notary/client"
|
||||
@ -5,8 +5,8 @@ import (
|
||||
"io"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/cli/internal/test"
|
||||
notaryfake "github.com/docker/cli/internal/test/notary"
|
||||
"github.com/docker/cli/cmd/docker-trust/internal/test"
|
||||
notaryfake "github.com/docker/cli/cmd/docker-trust/internal/test/notary"
|
||||
"github.com/theupdateframework/notary/client"
|
||||
"github.com/theupdateframework/notary/tuf/data"
|
||||
"gotest.tools/v3/assert"
|
||||
@ -59,7 +59,6 @@ The base command for the Docker CLI.
|
||||
| [`system`](system.md) | Manage Docker |
|
||||
| [`tag`](tag.md) | Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE |
|
||||
| [`top`](top.md) | Display the running processes of a container |
|
||||
| [`trust`](trust.md) | Manage trust on Docker images |
|
||||
| [`unpause`](unpause.md) | Unpause all processes within one or more containers |
|
||||
| [`update`](update.md) | Update configuration of one or more containers |
|
||||
| [`version`](version.md) | Show the Docker version information |
|
||||
|
||||
@ -2,7 +2,6 @@ package test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
@ -14,29 +13,24 @@ import (
|
||||
"github.com/docker/cli/cli/streams"
|
||||
"github.com/docker/cli/internal/registryclient"
|
||||
"github.com/moby/moby/client"
|
||||
notaryclient "github.com/theupdateframework/notary/client"
|
||||
)
|
||||
|
||||
// NotaryClientFuncType defines a function that returns a fake notary client
|
||||
type NotaryClientFuncType func() (notaryclient.Repository, error)
|
||||
|
||||
// FakeCli emulates the default DockerCli
|
||||
type FakeCli struct {
|
||||
command.DockerCli
|
||||
client client.APIClient
|
||||
configfile *configfile.ConfigFile
|
||||
out *streams.Out
|
||||
outBuffer *bytes.Buffer
|
||||
err *streams.Out
|
||||
errBuffer *bytes.Buffer
|
||||
in *streams.In
|
||||
server command.ServerInfo
|
||||
notaryClientFunc NotaryClientFuncType
|
||||
manifestStore manifeststore.Store
|
||||
registryClient registryclient.RegistryClient
|
||||
contextStore store.Store
|
||||
currentContext string
|
||||
dockerEndpoint docker.Endpoint
|
||||
client client.APIClient
|
||||
configfile *configfile.ConfigFile
|
||||
out *streams.Out
|
||||
outBuffer *bytes.Buffer
|
||||
err *streams.Out
|
||||
errBuffer *bytes.Buffer
|
||||
in *streams.In
|
||||
server command.ServerInfo
|
||||
manifestStore manifeststore.Store
|
||||
registryClient registryclient.RegistryClient
|
||||
contextStore store.Store
|
||||
currentContext string
|
||||
dockerEndpoint docker.Endpoint
|
||||
}
|
||||
|
||||
// NewFakeCli returns a fake for the command.Cli interface
|
||||
@ -162,19 +156,6 @@ func (c *FakeCli) ResetOutputBuffers() {
|
||||
c.errBuffer.Reset()
|
||||
}
|
||||
|
||||
// SetNotaryClient sets the internal getter for retrieving a NotaryClient
|
||||
func (c *FakeCli) SetNotaryClient(notaryClientFunc NotaryClientFuncType) {
|
||||
c.notaryClientFunc = notaryClientFunc
|
||||
}
|
||||
|
||||
// NotaryClient returns an err for testing unless defined
|
||||
func (c *FakeCli) NotaryClient() (notaryclient.Repository, error) {
|
||||
if c.notaryClientFunc != nil {
|
||||
return c.notaryClientFunc()
|
||||
}
|
||||
return nil, errors.New("no notary client available unless defined")
|
||||
}
|
||||
|
||||
// ManifestStore returns a fake store used for testing
|
||||
func (c *FakeCli) ManifestStore() manifeststore.Store {
|
||||
return c.manifestStore
|
||||
|
||||
22
scripts/build/trust-plugin
Executable file
22
scripts/build/trust-plugin
Executable file
@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Build plugins examples for the host OS/ARCH
|
||||
#
|
||||
|
||||
set -eu -o pipefail
|
||||
|
||||
# Disable CGO - we don't need it for these plugins.
|
||||
#
|
||||
# Important: this must be done before sourcing "./scripts/build/.variables",
|
||||
# because some other variables are conditionally set whether CGO is enabled.
|
||||
export CGO_ENABLED=0
|
||||
|
||||
source ./scripts/build/.variables
|
||||
|
||||
TARGET_PLUGIN="$(dirname "${TARGET}")/docker-trust-${GOOS}-${GOARCH}"
|
||||
mkdir -p "$(dirname "${TARGET_PLUGIN}")"
|
||||
|
||||
echo "Building $GO_LINKMODE $(basename "${TARGET_PLUGIN}")"
|
||||
(set -x ; GO111MODULE=auto go build -o "${TARGET_PLUGIN}" -tags "${GO_BUILDTAGS}" -ldflags "${GO_LDFLAGS}" ${GO_BUILDMODE} "github.com/docker/cli/cmd/docker-trust")
|
||||
|
||||
ln -sf "$(basename "${TARGET_PLUGIN}")" "$(dirname "${TARGET}")/docker-trust"
|
||||
Reference in New Issue
Block a user