diff --git a/daemon/cluster/errors.go b/daemon/cluster/errors.go index 1698229427..0ffe78b98b 100644 --- a/daemon/cluster/errors.go +++ b/daemon/cluster/errors.go @@ -15,6 +15,9 @@ const ( // errSwarmCertificatesExpired is returned if docker was not started for the whole validity period and they had no chance to renew automatically. errSwarmCertificatesExpired notAvailableError = "Swarm certificates have expired. To replace them, leave the swarm and join again." + + // errSwarmNotManager is returned if the node is not a swarm manager. + errSwarmNotManager notAvailableError = "This node is not a swarm manager. Worker nodes can't be used to view or modify cluster state. Please run this command on a manager node or promote the current node to a manager." ) type notFoundError struct { diff --git a/daemon/cluster/swarm.go b/daemon/cluster/swarm.go index 1fa62920e3..e3fffe983d 100644 --- a/daemon/cluster/swarm.go +++ b/daemon/cluster/swarm.go @@ -26,9 +26,13 @@ func (c *Cluster) Init(req types.InitRequest) (string, error) { defer c.controlMutex.Unlock() if c.nr != nil { if req.ForceNewCluster { + // Take c.mu temporarily to wait for presently running // API handlers to finish before shutting down the node. c.mu.Lock() + if !c.nr.nodeState.IsManager() { + return "", errSwarmNotManager + } c.mu.Unlock() if err := c.nr.Stop(); err != nil {