Make cloud provider return disappearence of slave to the node controller

- implement ExternalID in Mesos cloud provider. This is used by the node
  controller to detect disappeared nodes.
- add test case for ExternalID
This commit is contained in:
Dr. Stefan Schimanski 2015-10-20 14:39:19 +01:00
parent 229f0f22ad
commit 6a2602a51b
3 changed files with 45 additions and 6 deletions

View File

@ -55,7 +55,7 @@ type slaveNode struct {
type mesosState struct {
clusterName string
nodes []*slaveNode
nodes map[string]*slaveNode
}
type stateCache struct {
@ -94,7 +94,7 @@ func (c *stateCache) clusterName(ctx context.Context) (string, error) {
}
// nodes returns the cached list of slave nodes.
func (c *stateCache) nodes(ctx context.Context) ([]*slaveNode, error) {
func (c *stateCache) nodes(ctx context.Context) (map[string]*slaveNode, error) {
cached, err := c.cachedState(ctx)
return cached.nodes, err
}
@ -162,7 +162,7 @@ func unpackIPv4(ip uint32) string {
// listSlaves returns a (possibly cached) list of slave nodes.
// Callers must not mutate the contents of the returned slice.
func (c *mesosClient) listSlaves(ctx context.Context) ([]*slaveNode, error) {
func (c *mesosClient) listSlaves(ctx context.Context) (map[string]*slaveNode, error) {
return c.state.nodes(ctx)
}
@ -230,7 +230,7 @@ func parseMesosState(blob []byte) (*mesosState, error) {
if err := json.Unmarshal(blob, state); err != nil {
return nil, err
}
nodes := []*slaveNode{}
nodes := map[string]*slaveNode{}
for _, slave := range state.Slaves {
if slave.Hostname == "" {
continue
@ -264,7 +264,7 @@ func parseMesosState(blob []byte) (*mesosState, error) {
}
log.V(4).Infof("node %q reporting capacity %v", node.hostname, cap)
}
nodes = append(nodes, node)
nodes[node.hostname] = node
}
result := &mesosState{

View File

@ -182,7 +182,21 @@ func ipAddress(name string) (net.IP, error) {
// ExternalID returns the cloud provider ID of the specified instance (deprecated).
func (c *MesosCloud) ExternalID(instance string) (string, error) {
ip, err := ipAddress(instance)
//TODO(jdef) use a timeout here? 15s?
ctx, cancel := context.WithCancel(context.TODO())
defer cancel()
nodes, err := c.client.listSlaves(ctx)
if err != nil {
return "", err
}
node := nodes[instance]
if node == nil {
return "", cloudprovider.InstanceNotFound
}
ip, err := ipAddress(node.hostname)
if err != nil {
return "", err
}

View File

@ -24,6 +24,7 @@ import (
"time"
log "github.com/golang/glog"
"k8s.io/kubernetes/pkg/cloudprovider"
)
func TestIPAddress(t *testing.T) {
@ -252,3 +253,27 @@ func Test_List(t *testing.T) {
t.Fatalf("List with a reject-all filter should return a list of size 0: (actual: %#v)", clusters)
}
}
func Test_ExternalID(t *testing.T) {
defer log.Flush()
md := FakeMasterDetector{}
httpServer, httpClient, httpTransport := makeHttpMocks()
defer httpServer.Close()
cacheTTL := 500 * time.Millisecond
mesosClient, err := createMesosClient(md, httpClient, httpTransport, cacheTTL)
mesosCloud := &MesosCloud{client: mesosClient, config: createDefaultConfig()}
_, err = mesosCloud.ExternalID("unknown")
if err != cloudprovider.InstanceNotFound {
t.Fatalf("ExternalID did not return InstanceNotFound on an unknown instance")
}
slaveName := "mesos3.internal.company.com"
id, err := mesosCloud.ExternalID(slaveName)
if id != "" {
t.Fatalf("ExternalID should not be able to resolve %q", slaveName)
}
if err == cloudprovider.InstanceNotFound {
t.Fatalf("ExternalID should find %q", slaveName)
}
}