Ver Fonte

Start daemon if certificates have been expired

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
Tonis Tiigi há 8 anos atrás
pai
commit
439de7694d
1 ficheiros alterados com 23 adições e 3 exclusões
  1. 23 3
      daemon/cluster/cluster.go

+ 23 - 3
daemon/cluster/cluster.go

@@ -1,6 +1,7 @@
 package cluster
 package cluster
 
 
 import (
 import (
+	"crypto/x509"
 	"encoding/base64"
 	"encoding/base64"
 	"encoding/json"
 	"encoding/json"
 	"fmt"
 	"fmt"
@@ -62,6 +63,9 @@ var ErrSwarmJoinTimeoutReached = fmt.Errorf("Timeout was reached before node was
 // ErrSwarmLocked is returned if the swarm is encrypted and needs a key to unlock it.
 // ErrSwarmLocked is returned if the swarm is encrypted and needs a key to unlock it.
 var ErrSwarmLocked = fmt.Errorf("Swarm is encrypted and needs to be unlocked before it can be used. Please use \"docker swarm unlock\" to unlock it.")
 var ErrSwarmLocked = fmt.Errorf("Swarm is encrypted and needs to be unlocked before it can be used. Please use \"docker swarm unlock\" to unlock it.")
 
 
+// ErrSwarmCertificatesExipred is returned if docker was not started for the whole validity period and they had no chance to renew automatically.
+var ErrSwarmCertificatesExpired = errors.New("Swarm certificates have expired. To replace them, leave the swarm and join again.")
+
 // NetworkSubnetsProvider exposes functions for retrieving the subnets
 // NetworkSubnetsProvider exposes functions for retrieving the subnets
 // of networks managed by Docker, so they can be filtered.
 // of networks managed by Docker, so they can be filtered.
 type NetworkSubnetsProvider interface {
 type NetworkSubnetsProvider interface {
@@ -186,7 +190,10 @@ func New(config Config) (*Cluster, error) {
 		if errors.Cause(c.err) == ErrSwarmLocked {
 		if errors.Cause(c.err) == ErrSwarmLocked {
 			return c, nil
 			return c, nil
 		}
 		}
-
+		if err, ok := errors.Cause(c.err).(x509.CertificateInvalidError); ok && err.Reason == x509.Expired {
+			c.err = ErrSwarmCertificatesExpired
+			return c, nil
+		}
 		return nil, fmt.Errorf("swarm component could not be started: %v", c.err)
 		return nil, fmt.Errorf("swarm component could not be started: %v", c.err)
 	}
 	}
 	go c.reconnectOnFailure(n)
 	go c.reconnectOnFailure(n)
@@ -387,7 +394,7 @@ func (c *Cluster) startNewNode(conf nodeStartConfig) (*node, error) {
 // Init initializes new cluster from user provided request.
 // Init initializes new cluster from user provided request.
 func (c *Cluster) Init(req types.InitRequest) (string, error) {
 func (c *Cluster) Init(req types.InitRequest) (string, error) {
 	c.Lock()
 	c.Lock()
-	if node := c.node; node != nil || c.locked {
+	if c.swarmExists() {
 		if !req.ForceNewCluster {
 		if !req.ForceNewCluster {
 			c.Unlock()
 			c.Unlock()
 			return "", ErrSwarmExists
 			return "", ErrSwarmExists
@@ -480,7 +487,7 @@ func (c *Cluster) Init(req types.InitRequest) (string, error) {
 // Join makes current Cluster part of an existing swarm cluster.
 // Join makes current Cluster part of an existing swarm cluster.
 func (c *Cluster) Join(req types.JoinRequest) error {
 func (c *Cluster) Join(req types.JoinRequest) error {
 	c.Lock()
 	c.Lock()
-	if node := c.node; node != nil || c.locked {
+	if c.swarmExists() {
 		c.Unlock()
 		c.Unlock()
 		return ErrSwarmExists
 		return ErrSwarmExists
 	}
 	}
@@ -642,6 +649,9 @@ func (c *Cluster) Leave(force bool) error {
 			c.locked = false
 			c.locked = false
 			c.lastNodeConfig = nil
 			c.lastNodeConfig = nil
 			c.Unlock()
 			c.Unlock()
+		} else if c.err == ErrSwarmCertificatesExpired {
+			c.err = nil
+			c.Unlock()
 		} else {
 		} else {
 			c.Unlock()
 			c.Unlock()
 			return ErrNoSwarm
 			return ErrNoSwarm
@@ -878,6 +888,8 @@ func (c *Cluster) Info() types.Info {
 		}
 		}
 		if c.locked {
 		if c.locked {
 			info.LocalNodeState = types.LocalNodeStateLocked
 			info.LocalNodeState = types.LocalNodeStateLocked
+		} else if c.err == ErrSwarmCertificatesExpired {
+			info.LocalNodeState = types.LocalNodeStateError
 		}
 		}
 	} else {
 	} else {
 		info.LocalNodeState = types.LocalNodeStatePending
 		info.LocalNodeState = types.LocalNodeStatePending
@@ -929,6 +941,11 @@ func (c *Cluster) isActiveManager() bool {
 	return c.node != nil && c.conn != nil
 	return c.node != nil && c.conn != nil
 }
 }
 
 
+// swarmExists should not be called without a read lock
+func (c *Cluster) swarmExists() bool {
+	return c.node != nil || c.locked || c.err == ErrSwarmCertificatesExpired
+}
+
 // errNoManager returns error describing why manager commands can't be used.
 // errNoManager returns error describing why manager commands can't be used.
 // Call with read lock.
 // Call with read lock.
 func (c *Cluster) errNoManager() error {
 func (c *Cluster) errNoManager() error {
@@ -936,6 +953,9 @@ func (c *Cluster) errNoManager() error {
 		if c.locked {
 		if c.locked {
 			return ErrSwarmLocked
 			return ErrSwarmLocked
 		}
 		}
+		if c.err == ErrSwarmCertificatesExpired {
+			return ErrSwarmCertificatesExpired
+		}
 		return fmt.Errorf("This node is not a swarm manager. Use \"docker swarm init\" or \"docker swarm join\" to connect this node to swarm and try again.")
 		return fmt.Errorf("This node is not a swarm manager. Use \"docker swarm init\" or \"docker swarm join\" to connect this node to swarm and try again.")
 	}
 	}
 	if c.node.Manager() != nil {
 	if c.node.Manager() != nil {