diff --git a/cmd/dockerd/daemon.go b/cmd/dockerd/daemon.go index 53e7e61dfb..d4a90a4e7c 100644 --- a/cmd/dockerd/daemon.go +++ b/cmd/dockerd/daemon.go @@ -275,6 +275,7 @@ func (cli *DaemonCli) start() (err error) { Backend: d, NetworkSubnetsProvider: d, DefaultAdvertiseAddr: cli.Config.SwarmDefaultAdvertiseAddr, + RuntimeRoot: cli.getSwarmRunRoot(), }) if err != nil { logrus.Fatalf("Error creating cluster component: %v", err) diff --git a/cmd/dockerd/daemon_solaris.go b/cmd/dockerd/daemon_solaris.go index a0f4908601..70f3ca519e 100644 --- a/cmd/dockerd/daemon_solaris.go +++ b/cmd/dockerd/daemon_solaris.go @@ -61,6 +61,12 @@ func (cli *DaemonCli) getLibcontainerdRoot() string { return filepath.Join(cli.Config.ExecRoot, "libcontainerd") } +// getSwarmRunRoot gets the root directory for swarm to store runtime state +// For example, the control socket +func (cli *DaemonCli) getSwarmRunRoot() string { + return filepath.Join(cli.Config.ExecRoot, "swarm") +} + func allocateDaemonPort(addr string) error { return nil } diff --git a/cmd/dockerd/daemon_unix.go b/cmd/dockerd/daemon_unix.go index 5fa5f55dae..83156dae16 100644 --- a/cmd/dockerd/daemon_unix.go +++ b/cmd/dockerd/daemon_unix.go @@ -85,6 +85,12 @@ func (cli *DaemonCli) getLibcontainerdRoot() string { return filepath.Join(cli.Config.ExecRoot, "libcontainerd") } +// getSwarmRunRoot gets the root directory for swarm to store runtime state +// For example, the control socket +func (cli *DaemonCli) getSwarmRunRoot() string { + return filepath.Join(cli.Config.ExecRoot, "swarm") +} + // allocateDaemonPort ensures that there are no containers // that try to use any port allocated for the docker server. func allocateDaemonPort(addr string) error { diff --git a/cmd/dockerd/daemon_windows.go b/cmd/dockerd/daemon_windows.go index 9772f2b2ef..babf05a847 100644 --- a/cmd/dockerd/daemon_windows.go +++ b/cmd/dockerd/daemon_windows.go @@ -73,6 +73,12 @@ func (cli *DaemonCli) getLibcontainerdRoot() string { return "" } +// getSwarmRunRoot gets the root directory for swarm to store runtime state +// For example, the control socket +func (cli *DaemonCli) getSwarmRunRoot() string { + return "" +} + func allocateDaemonPort(addr string) error { return nil } diff --git a/daemon/cluster/cluster.go b/daemon/cluster/cluster.go index a0816316b1..323a89abc8 100644 --- a/daemon/cluster/cluster.go +++ b/daemon/cluster/cluster.go @@ -103,6 +103,9 @@ type Config struct { // DefaultAdvertiseAddr is the default host/IP or network interface to use // if no AdvertiseAddr value is specified. DefaultAdvertiseAddr string + + // path to store runtime state, such as the swarm control socket + RuntimeRoot string } // Cluster provides capabilities to participate in a cluster as a worker or a @@ -111,6 +114,7 @@ type Cluster struct { sync.RWMutex *node root string + runtimeRoot string config Config configEvent chan struct{} // todo: make this array and goroutine safe localAddr string @@ -138,10 +142,17 @@ func New(config Config) (*Cluster, error) { if err := os.MkdirAll(root, 0700); err != nil { return nil, err } + if config.RuntimeRoot == "" { + config.RuntimeRoot = root + } + if err := os.MkdirAll(config.RuntimeRoot, 0700); err != nil { + return nil, err + } c := &Cluster{ root: root, config: config, configEvent: make(chan struct{}, 10), + runtimeRoot: config.RuntimeRoot, } st, err := c.loadState() @@ -275,7 +286,7 @@ func (c *Cluster) startNewNode(forceNewCluster bool, localAddr, remoteAddr, list n, err := swarmagent.NewNode(&swarmagent.NodeConfig{ Hostname: c.config.Name, ForceNewCluster: forceNewCluster, - ListenControlAPI: filepath.Join(c.root, controlSocket), + ListenControlAPI: filepath.Join(c.runtimeRoot, controlSocket), ListenRemoteAPI: listenAddr, AdvertiseRemoteAPI: advertiseAddr, JoinAddr: joinAddr, diff --git a/integration-cli/daemon.go b/integration-cli/daemon.go index 5348b97c00..35fa1ff8fd 100644 --- a/integration-cli/daemon.go +++ b/integration-cli/daemon.go @@ -41,6 +41,7 @@ type Daemon struct { userlandProxy bool useDefaultHost bool useDefaultTLSHost bool + execRoot string } type clientConfig struct { @@ -81,6 +82,7 @@ func NewDaemon(c *check.C) *Daemon { root: daemonRoot, storageDriver: os.Getenv("DOCKER_GRAPHDRIVER"), userlandProxy: userlandProxy, + execRoot: filepath.Join(os.TempDir(), "docker-execroot", id), } } @@ -145,7 +147,7 @@ func (d *Daemon) StartWithLogFile(out *os.File, providedArgs ...string) error { args := append(d.GlobalFlags, "--containerd", "/var/run/docker/libcontainerd/docker-containerd.sock", "--graph", d.root, - "--exec-root", filepath.Join(d.folder, "exec-root"), + "--exec-root", d.execRoot, "--pidfile", fmt.Sprintf("%s/docker.pid", d.folder), fmt.Sprintf("--userland-proxy=%t", d.userlandProxy), )