1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Merge pull request #37874 from justincormack/remove-libtrust

Remove the rest of v1 manifest support
This commit is contained in:
Akihiro Suda 2019-03-06 14:41:27 +09:00 committed by GitHub
commit fc01c2b481
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 54 additions and 577 deletions

View file

@ -49,11 +49,6 @@ RUN apt-get update && apt-get install -y \
&& make PREFIX=/build/ install-criu
FROM base AS registry
# Install two versions of the registry. The first is an older version that
# only supports schema1 manifests. The second is a newer version that supports
# both. This allows integration-cli tests to cover push/pull with both schema1
# and schema2 manifests.
ENV REGISTRY_COMMIT_SCHEMA1 ec87e9b6971d831f0eff752ddb54fb64693e51cd
ENV REGISTRY_COMMIT 47a064d4195a9b56133891bbb13620c3ac83a827
RUN set -x \
&& export GOPATH="$(mktemp -d)" \
@ -61,13 +56,6 @@ RUN set -x \
&& (cd "$GOPATH/src/github.com/docker/distribution" && git checkout -q "$REGISTRY_COMMIT") \
&& GOPATH="$GOPATH/src/github.com/docker/distribution/Godeps/_workspace:$GOPATH" \
go build -buildmode=pie -o /build/registry-v2 github.com/docker/distribution/cmd/registry \
&& case $(dpkg --print-architecture) in \
amd64|ppc64*|s390x) \
(cd "$GOPATH/src/github.com/docker/distribution" && git checkout -q "$REGISTRY_COMMIT_SCHEMA1"); \
GOPATH="$GOPATH/src/github.com/docker/distribution/Godeps/_workspace:$GOPATH"; \
go build -buildmode=pie -o /build/registry-v2-schema1 github.com/docker/distribution/cmd/registry; \
;; \
esac \
&& rm -rf "$GOPATH"

View file

@ -12,8 +12,6 @@ import (
const (
// defaultShutdownTimeout is the default shutdown timeout for the daemon
defaultShutdownTimeout = 15
// defaultTrustKeyFile is the default filename for the trust key
defaultTrustKeyFile = "key.json"
)
// installCommonConfigFlags adds flags to the pflag.FlagSet to configure the daemon
@ -83,13 +81,6 @@ func installCommonConfigFlags(conf *config.Config, flags *pflag.FlagSet) error {
flags.IntVar(&conf.NetworkControlPlaneMTU, "network-control-plane-mtu", config.DefaultNetworkMtu, "Network Control plane MTU")
// "--deprecated-key-path" is to allow configuration of the key used
// for the daemon ID and the deprecated image signing. It was never
// exposed as a command line option but is added here to allow
// overriding the default path in configuration.
flags.Var(opts.NewQuotedString(&conf.TrustKeyPath), "deprecated-key-path", "Path to key file for ID and image signing")
flags.MarkHidden("deprecated-key-path")
conf.MaxConcurrentDownloads = &maxConcurrentDownloads
conf.MaxConcurrentUploads = &maxConcurrentUploads
return nil
@ -103,10 +94,4 @@ func installRegistryServiceFlags(options *registry.ServiceOptions, flags *pflag.
flags.Var(ana, "allow-nondistributable-artifacts", "Allow push of nondistributable artifacts to registry")
flags.Var(mirrors, "registry-mirror", "Preferred Docker registry mirror")
flags.Var(insecureRegistries, "insecure-registry", "Enable insecure registry communication")
if runtime.GOOS != "windows" {
// TODO: Remove this flag after 3 release cycles (18.03)
flags.BoolVar(&options.V2Only, "disable-legacy-registry", true, "Disable contacting legacy registries")
flags.MarkHidden("disable-legacy-registry")
}
}

View file

@ -432,14 +432,6 @@ func loadDaemonCliConfig(opts *daemonOptions) (*config.Config, error) {
conf.CommonTLSOptions.KeyFile = opts.TLSOptions.KeyFile
}
if conf.TrustKeyPath == "" {
daemonConfDir, err := getDaemonConfDir(conf.Root)
if err != nil {
return nil, err
}
conf.TrustKeyPath = filepath.Join(daemonConfDir, defaultTrustKeyFile)
}
if flags.Changed("graph") && flags.Changed("data-root") {
return nil, errors.New(`cannot specify both "--graph" and "--data-root" option`)
}
@ -462,17 +454,6 @@ func loadDaemonCliConfig(opts *daemonOptions) (*config.Config, error) {
return nil, err
}
if runtime.GOOS != "windows" {
if flags.Changed("disable-legacy-registry") {
// TODO: Remove this error after 3 release cycles (18.03)
return nil, errors.New("ERROR: The '--disable-legacy-registry' flag has been removed. Interacting with legacy (v1) registries is no longer supported")
}
if !conf.V2Only {
// TODO: Remove this error after 3 release cycles (18.03)
return nil, errors.New("ERROR: The 'disable-legacy-registry' configuration option has been removed. Interacting with legacy (v1) registries is no longer supported")
}
}
if flags.Changed("graph") {
logrus.Warnf(`The "-g / --graph" flag is deprecated. Please use "--data-root" instead`)
}

View file

@ -55,10 +55,6 @@ func setDefaultUmask() error {
return nil
}
func getDaemonConfDir(_ string) (string, error) {
return getDefaultDaemonConfigDir()
}
func (cli *DaemonCli) getPlatformContainerdDaemonOpts() ([]supervisor.DaemonOpt, error) {
opts := []supervisor.DaemonOpt{
supervisor.WithOOMScore(cli.Config.OOMScoreAdjust),

View file

@ -4,7 +4,6 @@ import (
"fmt"
"net"
"os"
"path/filepath"
"github.com/docker/docker/daemon/config"
"github.com/docker/docker/libcontainerd/supervisor"
@ -21,10 +20,6 @@ func setDefaultUmask() error {
return nil
}
func getDaemonConfDir(root string) (string, error) {
return filepath.Join(root, `\config`), nil
}
// preNotifySystem sends a message to the host when the API is active, but before the daemon is
func preNotifySystem() {
// start the service now to prevent timeouts waiting for daemon to start

View file

@ -8,7 +8,6 @@ import (
"io/ioutil"
"os"
"reflect"
"runtime"
"strings"
"sync"
@ -135,12 +134,6 @@ type CommonConfig struct {
SocketGroup string `json:"group,omitempty"`
CorsHeaders string `json:"api-cors-header,omitempty"`
// TrustKeyPath is used to generate the daemon ID and for signing schema 1 manifests
// when pushing to a registry which does not support schema 2. This field is marked as
// deprecated because schema 1 manifests are deprecated in favor of schema 2 and the
// daemon ID will use a dedicated identifier not shared with exported signatures.
TrustKeyPath string `json:"deprecated-key-path,omitempty"`
// LiveRestoreEnabled determines whether we should keep containers
// alive upon daemon shutdown/start
LiveRestoreEnabled bool `json:"live-restore,omitempty"`
@ -247,9 +240,6 @@ func New() *Config {
config.LogConfig.Config = make(map[string]string)
config.ClusterOpts = make(map[string]string)
if runtime.GOOS != "linux" {
config.V2Only = true
}
return &config
}

View file

@ -953,7 +953,7 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S
return nil, err
}
trustKey, err := loadOrCreateTrustKey(config.TrustKeyPath)
uuid, err := loadOrCreateUUID(filepath.Join(config.Root, "engine_uuid"))
if err != nil {
return nil, err
}
@ -998,7 +998,7 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S
return nil, errors.New("Devices cgroup isn't mounted")
}
d.ID = trustKey.PublicKey().KeyID()
d.ID = uuid
d.repository = daemonRepo
d.containers = container.NewMemoryStore()
if d.containersReplica, err = container.NewViewDB(); err != nil {
@ -1029,7 +1029,6 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S
MaxConcurrentUploads: *config.MaxConcurrentUploads,
ReferenceStore: rs,
RegistryService: registryService,
TrustKey: trustKey,
})
go d.execCommandGC()

View file

@ -54,7 +54,6 @@ func (i *ImageService) PushImage(ctx context.Context, image, tag string, metaHea
},
ConfigMediaType: schema2.MediaTypeImageConfig,
LayerStores: distribution.NewLayerProvidersFromStores(i.layerStores),
TrustKey: i.trustKey,
UploadManager: i.uploadManager,
}

View file

@ -14,7 +14,6 @@ import (
"github.com/docker/docker/layer"
dockerreference "github.com/docker/docker/reference"
"github.com/docker/docker/registry"
"github.com/docker/libtrust"
"github.com/opencontainers/go-digest"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@ -40,7 +39,6 @@ type ImageServiceConfig struct {
MaxConcurrentUploads int
ReferenceStore dockerreference.Store
RegistryService registry.Service
TrustKey libtrust.PrivateKey
}
// NewImageService returns a new ImageService from a configuration
@ -56,7 +54,6 @@ func NewImageService(config ImageServiceConfig) *ImageService {
layerStores: config.LayerStores,
referenceStore: config.ReferenceStore,
registryService: config.RegistryService,
trustKey: config.TrustKey,
uploadManager: xfer.NewLayerUploadManager(config.MaxConcurrentUploads),
}
}
@ -72,7 +69,6 @@ type ImageService struct {
pruneRunning int32
referenceStore dockerreference.Store
registryService registry.Service
trustKey libtrust.PrivateKey
uploadManager *xfer.LayerUploadManager
}

View file

@ -1,57 +0,0 @@
package daemon // import "github.com/docker/docker/daemon"
import (
"encoding/json"
"encoding/pem"
"fmt"
"os"
"path/filepath"
"github.com/docker/docker/pkg/ioutils"
"github.com/docker/docker/pkg/system"
"github.com/docker/libtrust"
)
// LoadOrCreateTrustKey attempts to load the libtrust key at the given path,
// otherwise generates a new one
// TODO: this should use more of libtrust.LoadOrCreateTrustKey which may need
// a refactor or this function to be moved into libtrust
func loadOrCreateTrustKey(trustKeyPath string) (libtrust.PrivateKey, error) {
err := system.MkdirAll(filepath.Dir(trustKeyPath), 0755, "")
if err != nil {
return nil, err
}
trustKey, err := libtrust.LoadKeyFile(trustKeyPath)
if err == libtrust.ErrKeyFileDoesNotExist {
trustKey, err = libtrust.GenerateECP256PrivateKey()
if err != nil {
return nil, fmt.Errorf("Error generating key: %s", err)
}
encodedKey, err := serializePrivateKey(trustKey, filepath.Ext(trustKeyPath))
if err != nil {
return nil, fmt.Errorf("Error serializing key: %s", err)
}
if err := ioutils.AtomicWriteFile(trustKeyPath, encodedKey, os.FileMode(0600)); err != nil {
return nil, fmt.Errorf("Error saving key file: %s", err)
}
} else if err != nil {
return nil, fmt.Errorf("Error loading key file %s: %s", trustKeyPath, err)
}
return trustKey, nil
}
func serializePrivateKey(key libtrust.PrivateKey, ext string) (encoded []byte, err error) {
if ext == ".json" || ext == ".jwk" {
encoded, err = json.Marshal(key)
if err != nil {
return nil, fmt.Errorf("unable to encode private key JWK: %s", err)
}
} else {
pemBlock, err := key.PEMBlock()
if err != nil {
return nil, fmt.Errorf("unable to encode private key PEM: %s", err)
}
encoded = pem.EncodeToMemory(pemBlock)
}
return
}

View file

@ -1,71 +0,0 @@
package daemon // import "github.com/docker/docker/daemon"
import (
"io/ioutil"
"os"
"path/filepath"
"testing"
"gotest.tools/assert"
is "gotest.tools/assert/cmp"
"gotest.tools/fs"
)
// LoadOrCreateTrustKey
func TestLoadOrCreateTrustKeyInvalidKeyFile(t *testing.T) {
tmpKeyFolderPath, err := ioutil.TempDir("", "api-trustkey-test")
assert.NilError(t, err)
defer os.RemoveAll(tmpKeyFolderPath)
tmpKeyFile, err := ioutil.TempFile(tmpKeyFolderPath, "keyfile")
assert.NilError(t, err)
_, err = loadOrCreateTrustKey(tmpKeyFile.Name())
assert.Check(t, is.ErrorContains(err, "Error loading key file"))
}
func TestLoadOrCreateTrustKeyCreateKeyWhenFileDoesNotExist(t *testing.T) {
tmpKeyFolderPath := fs.NewDir(t, "api-trustkey-test")
defer tmpKeyFolderPath.Remove()
// Without the need to create the folder hierarchy
tmpKeyFile := tmpKeyFolderPath.Join("keyfile")
key, err := loadOrCreateTrustKey(tmpKeyFile)
assert.NilError(t, err)
assert.Check(t, key != nil)
_, err = os.Stat(tmpKeyFile)
assert.NilError(t, err, "key file doesn't exist")
}
func TestLoadOrCreateTrustKeyCreateKeyWhenDirectoryDoesNotExist(t *testing.T) {
tmpKeyFolderPath := fs.NewDir(t, "api-trustkey-test")
defer tmpKeyFolderPath.Remove()
tmpKeyFile := tmpKeyFolderPath.Join("folder/hierarchy/keyfile")
key, err := loadOrCreateTrustKey(tmpKeyFile)
assert.NilError(t, err)
assert.Check(t, key != nil)
_, err = os.Stat(tmpKeyFile)
assert.NilError(t, err, "key file doesn't exist")
}
func TestLoadOrCreateTrustKeyCreateKeyNoPath(t *testing.T) {
defer os.Remove("keyfile")
key, err := loadOrCreateTrustKey("keyfile")
assert.NilError(t, err)
assert.Check(t, key != nil)
_, err = os.Stat("keyfile")
assert.NilError(t, err, "key file doesn't exist")
}
func TestLoadOrCreateTrustKeyLoadValidKey(t *testing.T) {
tmpKeyFile := filepath.Join("testdata", "keyfile")
key, err := loadOrCreateTrustKey(tmpKeyFile)
assert.NilError(t, err)
expected := "AWX2:I27X:WQFX:IOMK:CNAK:O7PW:VYNB:ZLKC:CVAE:YJP2:SI4A:XXAY"
assert.Check(t, is.Contains(key.String(), expected))
}

28
daemon/uuid.go Normal file
View file

@ -0,0 +1,28 @@
package daemon // import "github.com/docker/docker/daemon"
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"github.com/docker/docker/pkg/ioutils"
"github.com/pborman/uuid"
)
func loadOrCreateUUID(path string) (string, error) {
err := os.MkdirAll(filepath.Dir(path), 0755)
if err != nil {
return "", err
}
id, err := ioutil.ReadFile(path)
if os.IsNotExist(err) {
id = []byte(uuid.New())
if err := ioutils.AtomicWriteFile(path, id, os.FileMode(0600)); err != nil {
return "", fmt.Errorf("Error saving uuid file: %s", err)
}
} else if err != nil {
return "", fmt.Errorf("Error loading uuid file %s: %s", path, err)
}
return string(id), nil
}

View file

@ -18,7 +18,6 @@ import (
"github.com/docker/docker/pkg/system"
refstore "github.com/docker/docker/reference"
"github.com/docker/docker/registry"
"github.com/docker/libtrust"
"github.com/opencontainers/go-digest"
specs "github.com/opencontainers/image-spec/specs-go/v1"
)
@ -73,9 +72,6 @@ type ImagePushConfig struct {
ConfigMediaType string
// LayerStores (indexed by operating system) manages layers.
LayerStores map[string]PushLayerProvider
// TrustKey is the private key for legacy signatures. This is typically
// an ephemeral key, since these signatures are no longer verified.
TrustKey libtrust.PrivateKey
// UploadManager dispatches uploads.
UploadManager *xfer.LayerUploadManager
}

View file

@ -5,7 +5,6 @@ import (
"errors"
"fmt"
"io"
"runtime"
"sort"
"strings"
"sync"
@ -181,28 +180,10 @@ func (p *v2Pusher) pushV2Tag(ctx context.Context, ref reference.NamedTagged, id
putOptions := []distribution.ManifestServiceOption{distribution.WithTag(ref.Tag())}
if _, err = manSvc.Put(ctx, manifest, putOptions...); err != nil {
if runtime.GOOS == "windows" || p.config.TrustKey == nil || p.config.RequireSchema2 {
logrus.Warnf("failed to upload schema2 manifest: %v", err)
return err
}
logrus.Warnf("failed to upload schema2 manifest: %v - falling back to schema1", err)
manifestRef, err := reference.WithTag(p.repo.Named(), ref.Tag())
if err != nil {
return err
}
builder = schema1.NewConfigManifestBuilder(p.repo.Blobs(ctx), p.config.TrustKey, manifestRef, imgConfig)
manifest, err = manifestFromBuilder(ctx, builder, descriptors)
if err != nil {
return err
}
if _, err = manSvc.Put(ctx, manifest, putOptions...); err != nil {
return err
}
}
var canonicalManifest []byte
switch v := manifest.(type) {

View file

@ -141,39 +141,6 @@ func (s *DockerRegistrySuite) TearDownTest(c *check.C) {
s.ds.TearDownTest(c)
}
func init() {
check.Suite(&DockerSchema1RegistrySuite{
ds: &DockerSuite{},
})
}
type DockerSchema1RegistrySuite struct {
ds *DockerSuite
reg *registry.V2
d *daemon.Daemon
}
func (s *DockerSchema1RegistrySuite) OnTimeout(c *check.C) {
s.d.DumpStackAndQuit()
}
func (s *DockerSchema1RegistrySuite) SetUpTest(c *check.C) {
testRequires(c, DaemonIsLinux, RegistryHosting, NotArm64, testEnv.IsLocalDaemon)
s.reg = registry.NewV2(c, registry.Schema1)
s.reg.WaitReady(c)
s.d = daemon.New(c, dockerBinary, dockerdBinary, testdaemon.WithEnvironment(testEnv.Execution))
}
func (s *DockerSchema1RegistrySuite) TearDownTest(c *check.C) {
if s.reg != nil {
s.reg.Close()
}
if s.d != nil {
s.d.Stop(c)
}
s.ds.TearDownTest(c)
}
func init() {
check.Suite(&DockerRegistryAuthHtpasswdSuite{
ds: &DockerSuite{},

View file

@ -3,12 +3,9 @@ package main
import (
"encoding/json"
"fmt"
"os"
"path/filepath"
"regexp"
"strings"
"github.com/docker/distribution/manifest/schema1"
"github.com/docker/distribution/manifest/schema2"
"github.com/docker/docker/api/types"
"github.com/docker/docker/integration-cli/checker"
@ -80,10 +77,6 @@ func (s *DockerRegistrySuite) TestPullByTagDisplaysDigest(c *check.C) {
testPullByTagDisplaysDigest(c)
}
func (s *DockerSchema1RegistrySuite) TestPullByTagDisplaysDigest(c *check.C) {
testPullByTagDisplaysDigest(c)
}
func testPullByDigest(c *check.C) {
testRequires(c, DaemonIsLinux)
pushDigest, err := setupImage(c)
@ -106,10 +99,6 @@ func (s *DockerRegistrySuite) TestPullByDigest(c *check.C) {
testPullByDigest(c)
}
func (s *DockerSchema1RegistrySuite) TestPullByDigest(c *check.C) {
testPullByDigest(c)
}
func testPullByDigestNoFallback(c *check.C) {
testRequires(c, DaemonIsLinux)
// pull from the registry using the <name>@<digest> reference
@ -123,10 +112,6 @@ func (s *DockerRegistrySuite) TestPullByDigestNoFallback(c *check.C) {
testPullByDigestNoFallback(c)
}
func (s *DockerSchema1RegistrySuite) TestPullByDigestNoFallback(c *check.C) {
testPullByDigestNoFallback(c)
}
func (s *DockerRegistrySuite) TestCreateByDigest(c *check.C) {
pushDigest, err := setupImage(c)
c.Assert(err, checker.IsNil, check.Commentf("error setting up image"))
@ -563,131 +548,3 @@ func (s *DockerRegistrySuite) TestPullFailsWithAlteredManifest(c *check.C) {
expectedErrorMsg := fmt.Sprintf("manifest verification failed for digest %s", manifestDigest)
c.Assert(out, checker.Contains, expectedErrorMsg)
}
// TestPullFailsWithAlteredManifest tests that a `docker pull` fails when
// we have modified a manifest blob and its digest cannot be verified.
// This is the schema1 version of the test.
func (s *DockerSchema1RegistrySuite) TestPullFailsWithAlteredManifest(c *check.C) {
testRequires(c, DaemonIsLinux)
manifestDigest, err := setupImage(c)
c.Assert(err, checker.IsNil, check.Commentf("error setting up image"))
// Load the target manifest blob.
manifestBlob := s.reg.ReadBlobContents(c, manifestDigest)
var imgManifest schema1.Manifest
err = json.Unmarshal(manifestBlob, &imgManifest)
c.Assert(err, checker.IsNil, check.Commentf("unable to decode image manifest from blob"))
// Change a layer in the manifest.
imgManifest.FSLayers[0] = schema1.FSLayer{
BlobSum: digest.Digest("sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"),
}
// Move the existing data file aside, so that we can replace it with a
// malicious blob of data. NOTE: we defer the returned undo func.
undo := s.reg.TempMoveBlobData(c, manifestDigest)
defer undo()
alteredManifestBlob, err := json.MarshalIndent(imgManifest, "", " ")
c.Assert(err, checker.IsNil, check.Commentf("unable to encode altered image manifest to JSON"))
s.reg.WriteBlobContents(c, manifestDigest, alteredManifestBlob)
// Now try pulling that image by digest. We should get an error about
// digest verification for the manifest digest.
// Pull from the registry using the <name>@<digest> reference.
imageReference := fmt.Sprintf("%s@%s", repoName, manifestDigest)
out, exitStatus, _ := dockerCmdWithError("pull", imageReference)
c.Assert(exitStatus, checker.Not(check.Equals), 0)
expectedErrorMsg := fmt.Sprintf("image verification failed for digest %s", manifestDigest)
c.Assert(out, checker.Contains, expectedErrorMsg)
}
// TestPullFailsWithAlteredLayer tests that a `docker pull` fails when
// we have modified a layer blob and its digest cannot be verified.
// This is the schema2 version of the test.
func (s *DockerRegistrySuite) TestPullFailsWithAlteredLayer(c *check.C) {
testRequires(c, DaemonIsLinux)
manifestDigest, err := setupImage(c)
c.Assert(err, checker.IsNil)
// Load the target manifest blob.
manifestBlob := s.reg.ReadBlobContents(c, manifestDigest)
var imgManifest schema2.Manifest
err = json.Unmarshal(manifestBlob, &imgManifest)
c.Assert(err, checker.IsNil)
// Next, get the digest of one of the layers from the manifest.
targetLayerDigest := imgManifest.Layers[0].Digest
// Move the existing data file aside, so that we can replace it with a
// malicious blob of data. NOTE: we defer the returned undo func.
undo := s.reg.TempMoveBlobData(c, targetLayerDigest)
defer undo()
// Now make a fake data blob in this directory.
s.reg.WriteBlobContents(c, targetLayerDigest, []byte("This is not the data you are looking for."))
// Now try pulling that image by digest. We should get an error about
// digest verification for the target layer digest.
// Remove distribution cache to force a re-pull of the blobs
if err := os.RemoveAll(filepath.Join(testEnv.DaemonInfo.DockerRootDir, "image", s.d.StorageDriver(), "distribution")); err != nil {
c.Fatalf("error clearing distribution cache: %v", err)
}
// Pull from the registry using the <name>@<digest> reference.
imageReference := fmt.Sprintf("%s@%s", repoName, manifestDigest)
out, exitStatus, _ := dockerCmdWithError("pull", imageReference)
c.Assert(exitStatus, checker.Not(check.Equals), 0, check.Commentf("expected a non-zero exit status"))
expectedErrorMsg := fmt.Sprintf("filesystem layer verification failed for digest %s", targetLayerDigest)
c.Assert(out, checker.Contains, expectedErrorMsg, check.Commentf("expected error message in output: %s", out))
}
// TestPullFailsWithAlteredLayer tests that a `docker pull` fails when
// we have modified a layer blob and its digest cannot be verified.
// This is the schema1 version of the test.
func (s *DockerSchema1RegistrySuite) TestPullFailsWithAlteredLayer(c *check.C) {
testRequires(c, DaemonIsLinux)
manifestDigest, err := setupImage(c)
c.Assert(err, checker.IsNil)
// Load the target manifest blob.
manifestBlob := s.reg.ReadBlobContents(c, manifestDigest)
var imgManifest schema1.Manifest
err = json.Unmarshal(manifestBlob, &imgManifest)
c.Assert(err, checker.IsNil)
// Next, get the digest of one of the layers from the manifest.
targetLayerDigest := imgManifest.FSLayers[0].BlobSum
// Move the existing data file aside, so that we can replace it with a
// malicious blob of data. NOTE: we defer the returned undo func.
undo := s.reg.TempMoveBlobData(c, targetLayerDigest)
defer undo()
// Now make a fake data blob in this directory.
s.reg.WriteBlobContents(c, targetLayerDigest, []byte("This is not the data you are looking for."))
// Now try pulling that image by digest. We should get an error about
// digest verification for the target layer digest.
// Remove distribution cache to force a re-pull of the blobs
if err := os.RemoveAll(filepath.Join(testEnv.DaemonInfo.DockerRootDir, "image", s.d.StorageDriver(), "distribution")); err != nil {
c.Fatalf("error clearing distribution cache: %v", err)
}
// Pull from the registry using the <name>@<digest> reference.
imageReference := fmt.Sprintf("%s@%s", repoName, manifestDigest)
out, exitStatus, _ := dockerCmdWithError("pull", imageReference)
c.Assert(exitStatus, checker.Not(check.Equals), 0, check.Commentf("expected a non-zero exit status"))
expectedErrorMsg := fmt.Sprintf("filesystem layer verification failed for digest %s", targetLayerDigest)
c.Assert(out, checker.Contains, expectedErrorMsg, check.Commentf("expected error message in output: %s", out))
}

View file

@ -35,7 +35,6 @@ import (
"github.com/docker/docker/pkg/mount"
"github.com/docker/go-units"
"github.com/docker/libnetwork/iptables"
"github.com/docker/libtrust"
"github.com/go-check/check"
"github.com/kr/pty"
"golang.org/x/sys/unix"
@ -551,23 +550,6 @@ func (s *DockerDaemonSuite) TestDaemonAllocatesListeningPort(c *check.C) {
}
}
func (s *DockerDaemonSuite) TestDaemonKeyGeneration(c *check.C) {
// TODO: skip or update for Windows daemon
os.Remove("/etc/docker/key.json")
s.d.Start(c)
s.d.Stop(c)
k, err := libtrust.LoadKeyFile("/etc/docker/key.json")
if err != nil {
c.Fatalf("Error opening key file")
}
kid := k.KeyID()
// Test Key ID is a valid fingerprint (e.g. QQXN:JY5W:TBXI:MK3X:GX6P:PD5D:F56N:NHCS:LVRZ:JA46:R24J:XEFF)
if len(kid) != 59 {
c.Fatalf("Bad key ID: %s", kid)
}
}
// GH#11320 - verify that the daemon exits on failure properly
// Note that this explicitly tests the conflict of {-b,--bridge} and {--bip} options as the means
// to get a daemon init failure; no other tests for -b/--bip conflict are therefore required
@ -1195,59 +1177,6 @@ func (s *DockerDaemonSuite) TestDaemonUnixSockCleanedUp(c *check.C) {
}
}
func (s *DockerDaemonSuite) TestDaemonWithWrongkey(c *check.C) {
type Config struct {
Crv string `json:"crv"`
D string `json:"d"`
Kid string `json:"kid"`
Kty string `json:"kty"`
X string `json:"x"`
Y string `json:"y"`
}
os.Remove("/etc/docker/key.json")
s.d.Start(c)
s.d.Stop(c)
config := &Config{}
bytes, err := ioutil.ReadFile("/etc/docker/key.json")
if err != nil {
c.Fatalf("Error reading key.json file: %s", err)
}
// byte[] to Data-Struct
if err := json.Unmarshal(bytes, &config); err != nil {
c.Fatalf("Error Unmarshal: %s", err)
}
//replace config.Kid with the fake value
config.Kid = "VSAJ:FUYR:X3H2:B2VZ:KZ6U:CJD5:K7BX:ZXHY:UZXT:P4FT:MJWG:HRJ4"
// NEW Data-Struct to byte[]
newBytes, err := json.Marshal(&config)
if err != nil {
c.Fatalf("Error Marshal: %s", err)
}
// write back
if err := ioutil.WriteFile("/etc/docker/key.json", newBytes, 0400); err != nil {
c.Fatalf("Error ioutil.WriteFile: %s", err)
}
defer os.Remove("/etc/docker/key.json")
if err := s.d.StartWithError(); err == nil {
c.Fatalf("It should not be successful to start daemon with wrong key: %v", err)
}
content, err := s.d.ReadLogFile()
c.Assert(err, checker.IsNil)
if !strings.Contains(string(content), "Public Key ID does not match") {
c.Fatalf("Missing KeyID message from daemon logs: %s", string(content))
}
}
func (s *DockerDaemonSuite) TestDaemonRestartKillWait(c *check.C) {
s.d.StartWithBusybox(c)

View file

@ -55,10 +55,6 @@ func (s *DockerRegistrySuite) TestPullImageWithAliases(c *check.C) {
testPullImageWithAliases(c)
}
func (s *DockerSchema1RegistrySuite) TestPullImageWithAliases(c *check.C) {
testPullImageWithAliases(c)
}
// testConcurrentPullWholeRepo pulls the same repo concurrently.
func testConcurrentPullWholeRepo(c *check.C) {
repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL)
@ -111,10 +107,6 @@ func (s *DockerRegistrySuite) testConcurrentPullWholeRepo(c *check.C) {
testConcurrentPullWholeRepo(c)
}
func (s *DockerSchema1RegistrySuite) testConcurrentPullWholeRepo(c *check.C) {
testConcurrentPullWholeRepo(c)
}
// testConcurrentFailingPull tries a concurrent pull that doesn't succeed.
func testConcurrentFailingPull(c *check.C) {
repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL)
@ -142,10 +134,6 @@ func (s *DockerRegistrySuite) testConcurrentFailingPull(c *check.C) {
testConcurrentFailingPull(c)
}
func (s *DockerSchema1RegistrySuite) testConcurrentFailingPull(c *check.C) {
testConcurrentFailingPull(c)
}
// testConcurrentPullMultipleTags pulls multiple tags from the same repo
// concurrently.
func testConcurrentPullMultipleTags(c *check.C) {
@ -198,10 +186,6 @@ func (s *DockerRegistrySuite) TestConcurrentPullMultipleTags(c *check.C) {
testConcurrentPullMultipleTags(c)
}
func (s *DockerSchema1RegistrySuite) TestConcurrentPullMultipleTags(c *check.C) {
testConcurrentPullMultipleTags(c)
}
// testPullIDStability verifies that pushing an image and pulling it back
// preserves the image ID.
func testPullIDStability(c *check.C) {
@ -259,10 +243,6 @@ func (s *DockerRegistrySuite) TestPullIDStability(c *check.C) {
testPullIDStability(c)
}
func (s *DockerSchema1RegistrySuite) TestPullIDStability(c *check.C) {
testPullIDStability(c)
}
// #21213
func testPullNoLayers(c *check.C) {
repoName := fmt.Sprintf("%v/dockercli/scratch", privateRegistryURL)
@ -279,10 +259,6 @@ func (s *DockerRegistrySuite) TestPullNoLayers(c *check.C) {
testPullNoLayers(c)
}
func (s *DockerSchema1RegistrySuite) TestPullNoLayers(c *check.C) {
testPullNoLayers(c)
}
func (s *DockerRegistrySuite) TestPullManifestList(c *check.C) {
testRequires(c, NotArm)
pushDigest, err := setupImage(c)

View file

@ -30,10 +30,6 @@ func (s *DockerRegistrySuite) TestPushBusyboxImage(c *check.C) {
testPushBusyboxImage(c)
}
func (s *DockerSchema1RegistrySuite) TestPushBusyboxImage(c *check.C) {
testPushBusyboxImage(c)
}
// pushing an image without a prefix should throw an error
func (s *DockerSuite) TestPushUnprefixedRepo(c *check.C) {
out, _, err := dockerCmdWithError("push", "busybox")
@ -53,10 +49,6 @@ func (s *DockerRegistrySuite) TestPushUntagged(c *check.C) {
testPushUntagged(c)
}
func (s *DockerSchema1RegistrySuite) TestPushUntagged(c *check.C) {
testPushUntagged(c)
}
func testPushBadTag(c *check.C) {
repoName := fmt.Sprintf("%v/dockercli/busybox:latest", privateRegistryURL)
expected := "does not exist"
@ -70,10 +62,6 @@ func (s *DockerRegistrySuite) TestPushBadTag(c *check.C) {
testPushBadTag(c)
}
func (s *DockerSchema1RegistrySuite) TestPushBadTag(c *check.C) {
testPushBadTag(c)
}
func testPushMultipleTags(c *check.C) {
repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL)
repoTag1 := fmt.Sprintf("%v/dockercli/busybox:t1", privateRegistryURL)
@ -115,10 +103,6 @@ func (s *DockerRegistrySuite) TestPushMultipleTags(c *check.C) {
testPushMultipleTags(c)
}
func (s *DockerSchema1RegistrySuite) TestPushMultipleTags(c *check.C) {
testPushMultipleTags(c)
}
func testPushEmptyLayer(c *check.C) {
repoName := fmt.Sprintf("%v/dockercli/emptylayer", privateRegistryURL)
emptyTarball, err := ioutil.TempFile("", "empty_tarball")
@ -146,10 +130,6 @@ func (s *DockerRegistrySuite) TestPushEmptyLayer(c *check.C) {
testPushEmptyLayer(c)
}
func (s *DockerSchema1RegistrySuite) TestPushEmptyLayer(c *check.C) {
testPushEmptyLayer(c)
}
// testConcurrentPush pushes multiple tags to the same repo
// concurrently.
func testConcurrentPush(c *check.C) {
@ -200,10 +180,6 @@ func (s *DockerRegistrySuite) TestConcurrentPush(c *check.C) {
testConcurrentPush(c)
}
func (s *DockerSchema1RegistrySuite) TestConcurrentPush(c *check.C) {
testConcurrentPush(c)
}
func (s *DockerRegistrySuite) TestCrossRepositoryLayerPush(c *check.C) {
sourceRepoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL)
// tag the image to upload it to the private registry
@ -245,39 +221,6 @@ func (s *DockerRegistrySuite) TestCrossRepositoryLayerPush(c *check.C) {
c.Assert(out4, check.Equals, "hello world")
}
func (s *DockerSchema1RegistrySuite) TestCrossRepositoryLayerPushNotSupported(c *check.C) {
sourceRepoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL)
// tag the image to upload it to the private registry
dockerCmd(c, "tag", "busybox", sourceRepoName)
// push the image to the registry
out1, _, err := dockerCmdWithError("push", sourceRepoName)
c.Assert(err, check.IsNil, check.Commentf("pushing the image to the private registry has failed: %s", out1))
// ensure that none of the layers were mounted from another repository during push
c.Assert(strings.Contains(out1, "Mounted from"), check.Equals, false)
digest1 := reference.DigestRegexp.FindString(out1)
c.Assert(len(digest1), checker.GreaterThan, 0, check.Commentf("no digest found for pushed manifest"))
destRepoName := fmt.Sprintf("%v/dockercli/crossrepopush", privateRegistryURL)
// retag the image to upload the same layers to another repo in the same registry
dockerCmd(c, "tag", "busybox", destRepoName)
// push the image to the registry
out2, _, err := dockerCmdWithError("push", destRepoName)
c.Assert(err, check.IsNil, check.Commentf("pushing the image to the private registry has failed: %s", out2))
// schema1 registry should not support cross-repo layer mounts, so ensure that this does not happen
c.Assert(strings.Contains(out2, "Mounted from"), check.Equals, false)
digest2 := reference.DigestRegexp.FindString(out2)
c.Assert(len(digest2), checker.GreaterThan, 0, check.Commentf("no digest found for pushed manifest"))
c.Assert(digest1, check.Not(check.Equals), digest2)
// ensure that we can pull and run the second pushed repository
dockerCmd(c, "rmi", destRepoName)
dockerCmd(c, "pull", destRepoName)
out3, _ := dockerCmd(c, "run", destRepoName, "echo", "-n", "hello world")
c.Assert(out3, check.Equals, "hello world")
}
func (s *DockerRegistryAuthHtpasswdSuite) TestPushNoCredentialsNoRetry(c *check.C) {
repoName := fmt.Sprintf("%s/busybox", privateRegistryURL)
dockerCmd(c, "tag", "busybox", repoName)

View file

@ -0,0 +1,20 @@
package system
import (
"context"
"testing"
"github.com/pborman/uuid"
"gotest.tools/assert"
)
func TestUUIDGeneration(t *testing.T) {
defer setupTest(t)()
c := testEnv.APIClient()
info, err := c.Info(context.Background())
assert.NilError(t, err)
id := uuid.Parse(info.ID)
assert.Equal(t, id != nil, true)
}

View file

@ -92,7 +92,7 @@ func CreateInRegistry(ctx context.Context, repo string, auth *types.AuthConfig,
return nil, nil
}
regService, err := registry.NewService(registry.ServiceOptions{V2Only: true})
regService, err := registry.NewService(registry.ServiceOptions{})
if err != nil {
return err
}

View file

@ -19,16 +19,11 @@ type ServiceOptions struct {
AllowNondistributableArtifacts []string `json:"allow-nondistributable-artifacts,omitempty"`
Mirrors []string `json:"registry-mirrors,omitempty"`
InsecureRegistries []string `json:"insecure-registries,omitempty"`
// V2Only controls access to legacy registries. If it is set to true via the
// command line flag the daemon will not attempt to contact v1 legacy registries
V2Only bool `json:"disable-legacy-registry,omitempty"`
}
// serviceConfig holds daemon configuration for the registry service.
type serviceConfig struct {
registrytypes.ServiceConfig
V2Only bool
}
var (
@ -76,7 +71,6 @@ func newServiceConfig(options ServiceOptions) (*serviceConfig, error) {
// Hack: Bypass setting the mirrors to IndexConfigs since they are going away
// and Mirrors are only for the official registry anyways.
},
V2Only: options.V2Only,
}
if err := config.LoadAllowNondistributableArtifacts(options.AllowNondistributableArtifacts); err != nil {
return nil, err

View file

@ -309,20 +309,5 @@ func (s *DefaultService) LookupPushEndpoints(hostname string) (endpoints []APIEn
}
func (s *DefaultService) lookupEndpoints(hostname string) (endpoints []APIEndpoint, err error) {
endpoints, err = s.lookupV2Endpoints(hostname)
if err != nil {
return nil, err
}
if s.config.V2Only {
return endpoints, nil
}
legacyEndpoints, err := s.lookupV1Endpoints(hostname)
if err != nil {
return nil, err
}
endpoints = append(endpoints, legacyEndpoints...)
return endpoints, nil
return s.lookupV2Endpoints(hostname)
}