diff --git a/cli/flags/common.go b/cli/flags/common.go index 6a461bbf17..8f20111dce 100644 --- a/cli/flags/common.go +++ b/cli/flags/common.go @@ -13,8 +13,6 @@ import ( ) const ( - // DefaultTrustKeyFile is the default filename for the trust key - DefaultTrustKeyFile = "key.json" // DefaultCaFile is the default filename for the CA pem file DefaultCaFile = "ca.pem" // DefaultKeyFile is the default filename for the key pem file @@ -38,7 +36,6 @@ type CommonOptions struct { TLS bool TLSVerify bool TLSOptions *tlsconfig.Options - TrustKey string } // NewCommonOptions returns a new CommonOptions diff --git a/cmd/dockerd/config.go b/cmd/dockerd/config.go index 8e0531e53f..da4071e46c 100644 --- a/cmd/dockerd/config.go +++ b/cmd/dockerd/config.go @@ -9,6 +9,8 @@ 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 @@ -53,6 +55,13 @@ func installCommonConfigFlags(conf *config.Config, flags *pflag.FlagSet) { flags.StringVar(&conf.MetricsAddress, "metrics-addr", "", "Set default address and port to serve the metrics api on") + // "--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 } diff --git a/cmd/dockerd/daemon.go b/cmd/dockerd/daemon.go index 3b6d0f014c..751efa27ae 100644 --- a/cmd/dockerd/daemon.go +++ b/cmd/dockerd/daemon.go @@ -3,10 +3,8 @@ package main import ( "crypto/tls" "fmt" - "io" "os" "path/filepath" - "runtime" "strings" "time" @@ -27,7 +25,6 @@ import ( swarmrouter "github.com/docker/docker/api/server/router/swarm" systemrouter "github.com/docker/docker/api/server/router/system" "github.com/docker/docker/api/server/router/volume" - "github.com/docker/docker/cli" "github.com/docker/docker/cli/debug" cliflags "github.com/docker/docker/cli/flags" "github.com/docker/docker/daemon" @@ -43,7 +40,6 @@ import ( "github.com/docker/docker/pkg/pidfile" "github.com/docker/docker/pkg/plugingetter" "github.com/docker/docker/pkg/signal" - "github.com/docker/docker/pkg/system" "github.com/docker/docker/plugin" "github.com/docker/docker/registry" "github.com/docker/docker/runconfig" @@ -67,52 +63,6 @@ func NewDaemonCli() *DaemonCli { return &DaemonCli{} } -func migrateKey(config *config.Config) (err error) { - // No migration necessary on Windows - if runtime.GOOS == "windows" { - return nil - } - - // Migrate trust key if exists at ~/.docker/key.json and owned by current user - oldPath := filepath.Join(cli.ConfigurationDir(), cliflags.DefaultTrustKeyFile) - newPath := filepath.Join(getDaemonConfDir(config.Root), cliflags.DefaultTrustKeyFile) - if _, statErr := os.Stat(newPath); os.IsNotExist(statErr) && currentUserIsOwner(oldPath) { - defer func() { - // Ensure old path is removed if no error occurred - if err == nil { - err = os.Remove(oldPath) - } else { - logrus.Warnf("Key migration failed, key file not removed at %s", oldPath) - os.Remove(newPath) - } - }() - - if err := system.MkdirAll(getDaemonConfDir(config.Root), os.FileMode(0644)); err != nil { - return fmt.Errorf("Unable to create daemon configuration directory: %s", err) - } - - newFile, err := os.OpenFile(newPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600) - if err != nil { - return fmt.Errorf("error creating key file %q: %s", newPath, err) - } - defer newFile.Close() - - oldFile, err := os.Open(oldPath) - if err != nil { - return fmt.Errorf("error opening key file %q: %s", oldPath, err) - } - defer oldFile.Close() - - if _, err := io.Copy(newFile, oldFile); err != nil { - return fmt.Errorf("error copying key: %s", err) - } - - logrus.Infof("Migrated key from %s to %s", oldPath, newPath) - } - - return nil -} - func (cli *DaemonCli) start(opts daemonOptions) (err error) { stopc := make(chan bool) defer close(stopc) @@ -128,12 +78,6 @@ func (cli *DaemonCli) start(opts daemonOptions) (err error) { cli.configFile = &opts.configFile cli.flags = opts.flags - if opts.common.TrustKey == "" { - opts.common.TrustKey = filepath.Join( - getDaemonConfDir(cli.Config.Root), - cliflags.DefaultTrustKeyFile) - } - if cli.Config.Debug { debug.Enable() } @@ -242,13 +186,6 @@ func (cli *DaemonCli) start(opts daemonOptions) (err error) { api.Accept(addr, ls...) } - if err := migrateKey(cli.Config); err != nil { - return err - } - - // FIXME: why is this down here instead of with the other TrustKey logic above? - cli.TrustKeyPath = opts.common.TrustKey - registryService := registry.NewService(cli.Config.ServiceOptions) containerdRemote, err := libcontainerd.New(cli.getLibcontainerdRoot(), cli.getPlatformRemoteOptions()...) if err != nil { @@ -424,6 +361,12 @@ func loadDaemonCliConfig(opts daemonOptions) (*config.Config, error) { conf.CommonTLSOptions.KeyFile = opts.common.TLSOptions.KeyFile } + if conf.TrustKeyPath == "" { + conf.TrustKeyPath = filepath.Join( + getDaemonConfDir(conf.Root), + defaultTrustKeyFile) + } + if flags.Changed("graph") && flags.Changed("data-root") { return nil, fmt.Errorf(`cannot specify both "--graph" and "--data-root" option`) } diff --git a/cmd/dockerd/daemon_unix.go b/cmd/dockerd/daemon_unix.go index bdce98bd26..46ef58541f 100644 --- a/cmd/dockerd/daemon_unix.go +++ b/cmd/dockerd/daemon_unix.go @@ -14,23 +14,11 @@ import ( "github.com/docker/docker/cmd/dockerd/hack" "github.com/docker/docker/daemon" "github.com/docker/docker/libcontainerd" - "github.com/docker/docker/pkg/system" "github.com/docker/libnetwork/portallocator" ) const defaultDaemonConfigFile = "/etc/docker/daemon.json" -// currentUserIsOwner checks whether the current user is the owner of the given -// file. -func currentUserIsOwner(f string) bool { - if fileInfo, err := system.Stat(f); err == nil && fileInfo != nil { - if int(fileInfo.UID()) == os.Getuid() { - return true - } - } - return false -} - // setDefaultUmask sets the umask to 0022 to avoid problems // caused by custom umask func setDefaultUmask() error { diff --git a/daemon/config/config.go b/daemon/config/config.go index 3abf0ae990..beb147224f 100644 --- a/daemon/config/config.go +++ b/daemon/config/config.go @@ -102,10 +102,15 @@ type CommonConfig struct { RootDeprecated string `json:"graph,omitempty"` Root string `json:"data-root,omitempty"` SocketGroup string `json:"group,omitempty"` - TrustKeyPath string `json:"-"` CorsHeaders string `json:"api-cors-header,omitempty"` EnableCors bool `json:"api-enable-cors,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"` diff --git a/integration-cli/docker_cli_daemon_test.go b/integration-cli/docker_cli_daemon_test.go index 95e123b046..edce0b84ab 100644 --- a/integration-cli/docker_cli_daemon_test.go +++ b/integration-cli/docker_cli_daemon_test.go @@ -535,32 +535,6 @@ func (s *DockerDaemonSuite) TestDaemonKeyGeneration(c *check.C) { } } -func (s *DockerDaemonSuite) TestDaemonKeyMigration(c *check.C) { - // TODO: skip or update for Windows daemon - os.Remove("/etc/docker/key.json") - k1, err := libtrust.GenerateECP256PrivateKey() - if err != nil { - c.Fatalf("Error generating private key: %s", err) - } - if err := os.MkdirAll(filepath.Join(os.Getenv("HOME"), ".docker"), 0755); err != nil { - c.Fatalf("Error creating .docker directory: %s", err) - } - if err := libtrust.SaveKey(filepath.Join(os.Getenv("HOME"), ".docker", "key.json"), k1); err != nil { - c.Fatalf("Error saving private key: %s", err) - } - - s.d.Start(c) - s.d.Stop(c) - - k2, err := libtrust.LoadKeyFile("/etc/docker/key.json") - if err != nil { - c.Fatalf("Error opening key file") - } - if k1.KeyID() != k2.KeyID() { - c.Fatalf("Key not migrated") - } -} - // 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