From 803733120a1f9f080c6403f2a3717987393f1f0d Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Thu, 23 Jun 2016 13:52:41 -0700 Subject: [PATCH] Add better error messages for unavailable swarm commands Signed-off-by: Tonis Tiigi --- daemon/cluster/cluster.go | 49 +++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/daemon/cluster/cluster.go b/daemon/cluster/cluster.go index f8b7a85e1a..69b87d7641 100644 --- a/daemon/cluster/cluster.go +++ b/daemon/cluster/cluster.go @@ -39,9 +39,6 @@ const ( maxReconnectDelay = 30 * time.Second ) -// ErrNoManager is returned then a manager-only function is called on non-manager -var ErrNoManager = fmt.Errorf("This node is not participating as a Swarm manager") - // ErrNoSwarm is returned on leaving a cluster that was never initialized var ErrNoSwarm = fmt.Errorf("This node is not part of Swarm") @@ -476,7 +473,7 @@ func (c *Cluster) Inspect() (types.Swarm, error) { defer c.RUnlock() if !c.isActiveManager() { - return types.Swarm{}, ErrNoManager + return types.Swarm{}, c.errNoManager() } swarm, err := getSwarm(c.getRequestContext(), c.client) @@ -497,7 +494,7 @@ func (c *Cluster) Update(version uint64, spec types.Spec) error { defer c.RUnlock() if !c.isActiveManager() { - return ErrNoManager + return c.errNoManager() } swarm, err := getSwarm(c.getRequestContext(), c.client) @@ -629,13 +626,25 @@ func (c *Cluster) isActiveManager() bool { return c.conn != nil } +// errNoManager returns error describing why manager commands can't be used. +// Call with read lock. +func (c *Cluster) errNoManager() error { + if c.node == nil { + return fmt.Errorf("This node is not a Swarm manager. Use \"docker swarm init\" or \"docker swarm join --manager\" to connect this node to Swarm and try again.") + } + if c.node.Manager() != nil { + return fmt.Errorf("This node is not a Swarm manager. Manager is being prepared or has trouble connecting to the cluster.") + } + return fmt.Errorf("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.") +} + // GetServices returns all services of a managed swarm cluster. func (c *Cluster) GetServices(options apitypes.ServiceListOptions) ([]types.Service, error) { c.RLock() defer c.RUnlock() if !c.isActiveManager() { - return nil, ErrNoManager + return nil, c.errNoManager() } filters, err := newListServicesFilters(options.Filter) @@ -664,7 +673,7 @@ func (c *Cluster) CreateService(s types.ServiceSpec) (string, error) { defer c.RUnlock() if !c.isActiveManager() { - return "", ErrNoManager + return "", c.errNoManager() } ctx := c.getRequestContext() @@ -692,7 +701,7 @@ func (c *Cluster) GetService(input string) (types.Service, error) { defer c.RUnlock() if !c.isActiveManager() { - return types.Service{}, ErrNoManager + return types.Service{}, c.errNoManager() } service, err := getService(c.getRequestContext(), c.client, input) @@ -708,7 +717,7 @@ func (c *Cluster) UpdateService(serviceID string, version uint64, spec types.Ser defer c.RUnlock() if !c.isActiveManager() { - return ErrNoManager + return c.errNoManager() } serviceSpec, err := convert.ServiceSpecToGRPC(spec) @@ -735,7 +744,7 @@ func (c *Cluster) RemoveService(input string) error { defer c.RUnlock() if !c.isActiveManager() { - return ErrNoManager + return c.errNoManager() } service, err := getService(c.getRequestContext(), c.client, input) @@ -755,7 +764,7 @@ func (c *Cluster) GetNodes(options apitypes.NodeListOptions) ([]types.Node, erro defer c.RUnlock() if !c.isActiveManager() { - return nil, ErrNoManager + return nil, c.errNoManager() } filters, err := newListNodesFilters(options.Filter) @@ -783,7 +792,7 @@ func (c *Cluster) GetNode(input string) (types.Node, error) { defer c.RUnlock() if !c.isActiveManager() { - return types.Node{}, ErrNoManager + return types.Node{}, c.errNoManager() } node, err := getNode(c.getRequestContext(), c.client, input) @@ -799,7 +808,7 @@ func (c *Cluster) UpdateNode(nodeID string, version uint64, spec types.NodeSpec) defer c.RUnlock() if !c.isActiveManager() { - return ErrNoManager + return c.errNoManager() } nodeSpec, err := convert.NodeSpecToGRPC(spec) @@ -826,7 +835,7 @@ func (c *Cluster) RemoveNode(input string) error { defer c.RUnlock() if !c.isActiveManager() { - return ErrNoManager + return c.errNoManager() } ctx := c.getRequestContext() @@ -848,7 +857,7 @@ func (c *Cluster) GetTasks(options apitypes.TaskListOptions) ([]types.Task, erro defer c.RUnlock() if !c.isActiveManager() { - return nil, ErrNoManager + return nil, c.errNoManager() } filters, err := newListTasksFilters(options.Filter) @@ -876,7 +885,7 @@ func (c *Cluster) GetTask(input string) (types.Task, error) { defer c.RUnlock() if !c.isActiveManager() { - return types.Task{}, ErrNoManager + return types.Task{}, c.errNoManager() } task, err := getTask(c.getRequestContext(), c.client, input) @@ -892,7 +901,7 @@ func (c *Cluster) GetNetwork(input string) (apitypes.NetworkResource, error) { defer c.RUnlock() if !c.isActiveManager() { - return apitypes.NetworkResource{}, ErrNoManager + return apitypes.NetworkResource{}, c.errNoManager() } network, err := getNetwork(c.getRequestContext(), c.client, input) @@ -908,7 +917,7 @@ func (c *Cluster) GetNetworks() ([]apitypes.NetworkResource, error) { defer c.RUnlock() if !c.isActiveManager() { - return nil, ErrNoManager + return nil, c.errNoManager() } r, err := c.client.ListNetworks(c.getRequestContext(), &swarmapi.ListNetworksRequest{}) @@ -931,7 +940,7 @@ func (c *Cluster) CreateNetwork(s apitypes.NetworkCreateRequest) (string, error) defer c.RUnlock() if !c.isActiveManager() { - return "", ErrNoManager + return "", c.errNoManager() } if runconfig.IsPreDefinedNetwork(s.Name) { @@ -954,7 +963,7 @@ func (c *Cluster) RemoveNetwork(input string) error { defer c.RUnlock() if !c.isActiveManager() { - return ErrNoManager + return c.errNoManager() } network, err := getNetwork(c.getRequestContext(), c.client, input)