Parcourir la source

Clearing up windows overlay driver to just work in swarm mode

Signed-off-by: msabansal <sabansal@microsoft.com>
msabansal il y a 8 ans
Parent
commit
66895dfdfc

+ 0 - 9
libnetwork/drivers/windows/overlay/joinleave_windows.go

@@ -26,10 +26,6 @@ func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo,
 		return fmt.Errorf("could not find endpoint with id %s", eid)
 	}
 
-	if err := d.writeEndpointToStore(ep); err != nil {
-		return fmt.Errorf("failed to update overlay endpoint %s to local data store: %v", ep.id[0:7], err)
-	}
-
 	buf, err := proto.Marshal(&PeerRecord{
 		EndpointIP:       ep.addr.String(),
 		EndpointMAC:      ep.mac.String(),
@@ -43,9 +39,6 @@ func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo,
 	if err := jinfo.AddTableEntry(ovPeerTable, eid, buf); err != nil {
 		logrus.Errorf("overlay: Failed adding table entry to joininfo: %v", err)
 	}
-
-	d.pushLocalEndpointEvent("join", nid, eid)
-
 	return nil
 }
 
@@ -106,7 +99,5 @@ func (d *driver) Leave(nid, eid string) error {
 		return err
 	}
 
-	d.pushLocalEndpointEvent("leave", nid, eid)
-
 	return nil
 }

+ 14 - 144
libnetwork/drivers/windows/overlay/ov_endpoint_windows.go

@@ -7,9 +7,7 @@ import (
 
 	"github.com/Microsoft/hcsshim"
 	"github.com/Sirupsen/logrus"
-	"github.com/docker/libnetwork/datastore"
 	"github.com/docker/libnetwork/driverapi"
-	"github.com/docker/libnetwork/types"
 )
 
 type endpointTable map[string]*endpoint
@@ -23,8 +21,6 @@ type endpoint struct {
 	remote    bool
 	mac       net.HardwareAddr
 	addr      *net.IPNet
-	dbExists  bool
-	dbIndex   uint64
 }
 
 func validateID(nid, eid string) error {
@@ -67,6 +63,7 @@ func (n *network) removeEndpointWithAddress(addr *net.IPNet) {
 			break
 		}
 	}
+
 	if networkEndpoint != nil {
 		delete(n.endpoints, networkEndpoint.id)
 	}
@@ -79,10 +76,6 @@ func (n *network) removeEndpointWithAddress(addr *net.IPNet) {
 		if err != nil {
 			logrus.Debugf("Failed to delete stale overlay endpoint (%s) from hns", networkEndpoint.id[0:7])
 		}
-
-		if err := n.driver.deleteEndpointFromStore(networkEndpoint); err != nil {
-			logrus.Debugf("Failed to delete stale overlay endpoint (%s) from store", networkEndpoint.id[0:7])
-		}
 	}
 }
 
@@ -93,19 +86,23 @@ func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo,
 		return err
 	}
 
-	// Since we perform lazy configuration make sure we try
-	// configuring the driver when we enter CreateEndpoint since
-	// CreateNetwork may not be called in every node.
-	if err := d.configure(); err != nil {
-		return err
-	}
-
 	n := d.network(nid)
 	if n == nil {
 		return fmt.Errorf("network id %q not found", nid)
 	}
 
-	ep := &endpoint{
+	ep := n.endpoint(eid)
+	if ep != nil {
+		logrus.Debugf("Deleting stale endpoint %s", eid)
+		n.deleteEndpoint(eid)
+
+		_, err := hcsshim.HNSEndpointRequest("DELETE", ep.profileId, "")
+		if err != nil {
+			return err
+		}
+	}
+
+	ep = &endpoint{
 		id:   eid,
 		nid:  n.id,
 		addr: ifInfo.Address(),
@@ -123,6 +120,7 @@ func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo,
 	// Todo: Add port bindings and qos policies here
 
 	hnsEndpoint := &hcsshim.HNSEndpoint{
+		Name:              eid,
 		VirtualNetwork:    n.hnsId,
 		IPAddress:         ep.addr.IP,
 		EnableInternalDNS: true,
@@ -167,9 +165,6 @@ func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo,
 	}
 
 	n.addEndpoint(ep)
-	if err := d.writeEndpointToStore(ep); err != nil {
-		return fmt.Errorf("failed to update overlay endpoint %s to local store: %v", ep.id[0:7], err)
-	}
 
 	return nil
 }
@@ -191,10 +186,6 @@ func (d *driver) DeleteEndpoint(nid, eid string) error {
 
 	n.deleteEndpoint(eid)
 
-	if err := d.deleteEndpointFromStore(ep); err != nil {
-		logrus.Warnf("Failed to delete overlay endpoint %s from local store: %v", ep.id[0:7], err)
-	}
-
 	_, err := hcsshim.HNSEndpointRequest("DELETE", ep.profileId, "")
 	if err != nil {
 		return err
@@ -223,124 +214,3 @@ func (d *driver) EndpointOperInfo(nid, eid string) (map[string]interface{}, erro
 	data["AllowUnqualifiedDNSQuery"] = true
 	return data, nil
 }
-
-func (d *driver) deleteEndpointFromStore(e *endpoint) error {
-	if d.localStore == nil {
-		return fmt.Errorf("overlay local store not initialized, ep not deleted")
-	}
-
-	if err := d.localStore.DeleteObjectAtomic(e); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func (d *driver) writeEndpointToStore(e *endpoint) error {
-	if d.localStore == nil {
-		return fmt.Errorf("overlay local store not initialized, ep not added")
-	}
-
-	if err := d.localStore.PutObjectAtomic(e); err != nil {
-		return err
-	}
-	return nil
-}
-
-func (ep *endpoint) DataScope() string {
-	return datastore.LocalScope
-}
-
-func (ep *endpoint) New() datastore.KVObject {
-	return &endpoint{}
-}
-
-func (ep *endpoint) CopyTo(o datastore.KVObject) error {
-	dstep := o.(*endpoint)
-	*dstep = *ep
-	return nil
-}
-
-func (ep *endpoint) Key() []string {
-	return []string{overlayEndpointPrefix, ep.id}
-}
-
-func (ep *endpoint) KeyPrefix() []string {
-	return []string{overlayEndpointPrefix}
-}
-
-func (ep *endpoint) Index() uint64 {
-	return ep.dbIndex
-}
-
-func (ep *endpoint) SetIndex(index uint64) {
-	ep.dbIndex = index
-	ep.dbExists = true
-}
-
-func (ep *endpoint) Exists() bool {
-	return ep.dbExists
-}
-
-func (ep *endpoint) Skip() bool {
-	return false
-}
-
-func (ep *endpoint) Value() []byte {
-	b, err := json.Marshal(ep)
-	if err != nil {
-		return nil
-	}
-	return b
-}
-
-func (ep *endpoint) SetValue(value []byte) error {
-	return json.Unmarshal(value, ep)
-}
-
-func (ep *endpoint) MarshalJSON() ([]byte, error) {
-	epMap := make(map[string]interface{})
-
-	epMap["id"] = ep.id
-	epMap["nid"] = ep.nid
-	epMap["remote"] = ep.remote
-	if ep.profileId != "" {
-		epMap["profileId"] = ep.profileId
-	}
-
-	if ep.addr != nil {
-		epMap["addr"] = ep.addr.String()
-	}
-	if len(ep.mac) != 0 {
-		epMap["mac"] = ep.mac.String()
-	}
-
-	return json.Marshal(epMap)
-}
-
-func (ep *endpoint) UnmarshalJSON(value []byte) error {
-	var (
-		err   error
-		epMap map[string]interface{}
-	)
-
-	json.Unmarshal(value, &epMap)
-
-	ep.id = epMap["id"].(string)
-	ep.nid = epMap["nid"].(string)
-	ep.remote = epMap["remote"].(bool)
-	if v, ok := epMap["profileId"]; ok {
-		ep.profileId = v.(string)
-	}
-	if v, ok := epMap["mac"]; ok {
-		if ep.mac, err = net.ParseMAC(v.(string)); err != nil {
-			return types.InternalErrorf("failed to decode endpoint interface mac address after json unmarshal: %s", v.(string))
-		}
-	}
-	if v, ok := epMap["addr"]; ok {
-		if ep.addr, err = types.ParseCIDR(v.(string)); err != nil {
-			return types.InternalErrorf("failed to decode endpoint interface ipv4 address after json unmarshal: %v", err)
-		}
-	}
-	return nil
-}

+ 0 - 209
libnetwork/drivers/windows/overlay/ov_network_local_windows.go

@@ -1,209 +0,0 @@
-package overlay
-
-import (
-	"encoding/json"
-	"fmt"
-	"sync"
-
-	"github.com/Microsoft/hcsshim"
-	"github.com/Sirupsen/logrus"
-	"github.com/docker/libnetwork/datastore"
-)
-
-const overlayNetworkPrefix = "overlay/network"
-
-type localNetwork struct {
-	id              string
-	hnsID           string
-	providerAddress string
-	dbIndex         uint64
-	dbExists        bool
-	sync.Mutex
-}
-
-func (d *driver) findHnsNetwork(n *network) error {
-	ln, err := d.getLocalNetworkFromStore(n.id)
-
-	if err != nil {
-		return err
-	}
-
-	if ln == nil {
-		subnets := []hcsshim.Subnet{}
-
-		for _, s := range n.subnets {
-			subnet := hcsshim.Subnet{
-				AddressPrefix: s.subnetIP.String(),
-			}
-
-			if s.gwIP != nil {
-				subnet.GatewayAddress = s.gwIP.IP.String()
-			}
-
-			vsidPolicy, err := json.Marshal(hcsshim.VsidPolicy{
-				Type: "VSID",
-				VSID: uint(s.vni),
-			})
-
-			if err != nil {
-				return err
-			}
-
-			subnet.Policies = append(subnet.Policies, vsidPolicy)
-			subnets = append(subnets, subnet)
-		}
-
-		network := &hcsshim.HNSNetwork{
-			Name:               n.name,
-			Type:               d.Type(),
-			Subnets:            subnets,
-			NetworkAdapterName: n.interfaceName,
-		}
-
-		configurationb, err := json.Marshal(network)
-		if err != nil {
-			return err
-		}
-
-		configuration := string(configurationb)
-		logrus.Infof("HNSNetwork Request =%v", configuration)
-
-		hnsresponse, err := hcsshim.HNSNetworkRequest("POST", "", configuration)
-		if err != nil {
-			return err
-		}
-
-		n.hnsId = hnsresponse.Id
-		n.providerAddress = hnsresponse.ManagementIP
-
-		// Save local host specific info
-		if err := d.writeLocalNetworkToStore(n); err != nil {
-			return fmt.Errorf("failed to update data store for network %v: %v", n.id, err)
-		}
-	} else {
-		n.hnsId = ln.hnsID
-		n.providerAddress = ln.providerAddress
-	}
-
-	return nil
-}
-
-func (d *driver) getLocalNetworkFromStore(nid string) (*localNetwork, error) {
-
-	if d.localStore == nil {
-		return nil, fmt.Errorf("overlay local store not initialized, network not found")
-	}
-
-	n := &localNetwork{id: nid}
-	if err := d.localStore.GetObject(datastore.Key(n.Key()...), n); err != nil {
-		return nil, nil
-	}
-
-	return n, nil
-}
-
-func (d *driver) deleteLocalNetworkFromStore(n *network) error {
-	if d.localStore == nil {
-		return fmt.Errorf("overlay local store not initialized, network not deleted")
-	}
-
-	ln, err := d.getLocalNetworkFromStore(n.id)
-
-	if err != nil {
-		return err
-	}
-
-	if err = d.localStore.DeleteObjectAtomic(ln); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func (d *driver) writeLocalNetworkToStore(n *network) error {
-	if d.localStore == nil {
-		return fmt.Errorf("overlay local store not initialized, network not added")
-	}
-
-	ln := &localNetwork{
-		id:              n.id,
-		hnsID:           n.hnsId,
-		providerAddress: n.providerAddress,
-	}
-
-	if err := d.localStore.PutObjectAtomic(ln); err != nil {
-		return err
-	}
-	return nil
-}
-
-func (n *localNetwork) DataScope() string {
-	return datastore.LocalScope
-}
-
-func (n *localNetwork) New() datastore.KVObject {
-	return &localNetwork{}
-}
-
-func (n *localNetwork) CopyTo(o datastore.KVObject) error {
-	dstep := o.(*localNetwork)
-	*dstep = *n
-	return nil
-}
-
-func (n *localNetwork) Key() []string {
-	return []string{overlayNetworkPrefix, n.id}
-}
-
-func (n *localNetwork) KeyPrefix() []string {
-	return []string{overlayNetworkPrefix}
-}
-
-func (n *localNetwork) Index() uint64 {
-	return n.dbIndex
-}
-
-func (n *localNetwork) SetIndex(index uint64) {
-	n.dbIndex = index
-	n.dbExists = true
-}
-
-func (n *localNetwork) Exists() bool {
-	return n.dbExists
-}
-
-func (n *localNetwork) Skip() bool {
-	return false
-}
-
-func (n *localNetwork) Value() []byte {
-	b, err := json.Marshal(n)
-	if err != nil {
-		return nil
-	}
-	return b
-}
-
-func (n *localNetwork) SetValue(value []byte) error {
-	return json.Unmarshal(value, n)
-}
-
-func (n *localNetwork) MarshalJSON() ([]byte, error) {
-	networkMap := make(map[string]interface{})
-
-	networkMap["id"] = n.id
-	networkMap["hnsID"] = n.hnsID
-	networkMap["providerAddress"] = n.providerAddress
-	return json.Marshal(networkMap)
-}
-
-func (n *localNetwork) UnmarshalJSON(value []byte) error {
-	var networkMap map[string]interface{}
-
-	json.Unmarshal(value, &networkMap)
-
-	n.id = networkMap["id"].(string)
-	n.hnsID = networkMap["hnsID"].(string)
-	n.providerAddress = networkMap["providerAddress"].(string)
-	return nil
-}

+ 110 - 242
libnetwork/drivers/windows/overlay/ov_network_windows.go

@@ -10,7 +10,6 @@ import (
 
 	"github.com/Microsoft/hcsshim"
 	"github.com/Sirupsen/logrus"
-	"github.com/docker/libnetwork/datastore"
 	"github.com/docker/libnetwork/driverapi"
 	"github.com/docker/libnetwork/netlabel"
 	"github.com/docker/libnetwork/types"
@@ -25,9 +24,8 @@ type networkTable map[string]*network
 
 type subnet struct {
 	vni      uint32
-	initErr  error
 	subnetIP *net.IPNet
-	gwIP     *net.IPNet
+	gwIP     *net.IP
 }
 
 type subnetJSON struct {
@@ -40,8 +38,6 @@ type network struct {
 	id              string
 	name            string
 	hnsId           string
-	dbIndex         uint64
-	dbExists        bool
 	providerAddress string
 	interfaceName   string
 	endpoints       endpointTable
@@ -65,22 +61,31 @@ func (d *driver) CreateNetwork(id string, option map[string]interface{}, nInfo d
 	var (
 		networkName   string
 		interfaceName string
+		staleNetworks []string
 	)
 
 	if id == "" {
 		return fmt.Errorf("invalid network id")
 	}
 
+	if nInfo == nil {
+		return fmt.Errorf("invalid network info structure")
+	}
+
 	if len(ipV4Data) == 0 || ipV4Data[0].Pool.String() == "0.0.0.0/0" {
 		return types.BadRequestErrorf("ipv4 pool is empty")
 	}
 
+	staleNetworks = make([]string, 0)
 	vnis := make([]uint32, 0, len(ipV4Data))
 
-	// Since we perform lazy configuration make sure we try
-	// configuring the driver when we enter CreateNetwork
-	if err := d.configure(); err != nil {
-		return err
+	existingNetwork := d.network(id)
+	if existingNetwork != nil {
+		logrus.Debugf("Network preexists. Deleting %s", id)
+		err := d.DeleteNetwork(id)
+		if err != nil {
+			logrus.Errorf("Error deleting stale network %s", err.Error())
+		}
 	}
 
 	n := &network{
@@ -119,23 +124,43 @@ func (d *driver) CreateNetwork(id string, option map[string]interface{}, nInfo d
 
 	// If we are getting vnis from libnetwork, either we get for
 	// all subnets or none.
-	if len(vnis) != 0 && len(vnis) < len(ipV4Data) {
-		return fmt.Errorf("insufficient vnis(%d) passed to overlay", len(vnis))
+	if len(vnis) < len(ipV4Data) {
+		return fmt.Errorf("insufficient vnis(%d) passed to overlay. Windows driver requires VNIs to be prepopulated", len(vnis))
 	}
 
 	for i, ipd := range ipV4Data {
 		s := &subnet{
 			subnetIP: ipd.Pool,
-			gwIP:     ipd.Gateway,
+			gwIP:     &ipd.Gateway.IP,
 		}
 
 		if len(vnis) != 0 {
 			s.vni = vnis[i]
 		}
 
+		d.Lock()
+		for _, network := range d.networks {
+			found := false
+			for _, sub := range network.subnets {
+				if sub.vni == s.vni {
+					staleNetworks = append(staleNetworks, network.id)
+					found = true
+					break
+				}
+			}
+			if found {
+				break
+			}
+		}
+		d.Unlock()
+
 		n.subnets = append(n.subnets, s)
 	}
 
+	for _, staleNetwork := range staleNetworks {
+		d.DeleteNetwork(staleNetwork)
+	}
+
 	n.name = networkName
 	if n.name == "" {
 		n.name = id
@@ -143,10 +168,6 @@ func (d *driver) CreateNetwork(id string, option map[string]interface{}, nInfo d
 
 	n.interfaceName = interfaceName
 
-	if err := n.writeToStore(); err != nil {
-		return fmt.Errorf("failed to update data store for network %v: %v", n.id, err)
-	}
-
 	if nInfo != nil {
 		if err := nInfo.TableEventRegister(ovPeerTable); err != nil {
 			return err
@@ -155,8 +176,13 @@ func (d *driver) CreateNetwork(id string, option map[string]interface{}, nInfo d
 
 	d.addNetwork(n)
 
-	err := d.findHnsNetwork(n)
-	genData["com.docker.network.windowsshim.hnsid"] = n.hnsId
+	err := d.createHnsNetwork(n)
+
+	if err != nil {
+		d.deleteNetwork(id)
+	} else {
+		genData["com.docker.network.windowsshim.hnsid"] = n.hnsId
+	}
 
 	return err
 }
@@ -166,23 +192,17 @@ func (d *driver) DeleteNetwork(nid string) error {
 		return fmt.Errorf("invalid network id")
 	}
 
-	// Make sure driver resources are initialized before proceeding
-	if err := d.configure(); err != nil {
-		return err
-	}
-
 	n := d.network(nid)
 	if n == nil {
-		return fmt.Errorf("could not find network with id %s", nid)
+		return types.ForbiddenErrorf("could not find network with id %s", nid)
 	}
 
 	_, err := hcsshim.HNSNetworkRequest("DELETE", n.hnsId, "")
 	if err != nil {
-		return err
+		return types.ForbiddenErrorf(err.Error())
 	}
 
 	d.deleteNetwork(nid)
-	d.deleteLocalNetworkFromStore(n)
 
 	return nil
 }
@@ -209,259 +229,107 @@ func (d *driver) deleteNetwork(nid string) {
 
 func (d *driver) network(nid string) *network {
 	d.Lock()
-	networks := d.networks
-	d.Unlock()
-
-	n, ok := networks[nid]
-	if !ok {
-		n = d.getNetworkFromStore(nid)
-		if n != nil {
-			n.driver = d
-			n.endpoints = endpointTable{}
-			networks[nid] = n
-		}
-	}
-
-	return n
+	defer d.Unlock()
+	return d.networks[nid]
 }
 
-func (d *driver) getNetworkFromStore(nid string) *network {
-	if d.store == nil {
-		return nil
-	}
-
-	n := &network{id: nid}
-	if err := d.store.GetObject(datastore.Key(n.Key()...), n); err != nil {
-		return nil
-	}
-
-	// As the network is being discovered from the global store, HNS may not be aware of it yet
-	err := d.findHnsNetwork(n)
-	if err != nil {
-		logrus.Errorf("Failed to find hns network: %v", err)
-		return nil
-	}
+// func (n *network) restoreNetworkEndpoints() error {
+// 	logrus.Infof("Restoring endpoints for overlay network: %s", n.id)
 
-	return n
-}
+// 	hnsresponse, err := hcsshim.HNSListEndpointRequest("GET", "", "")
+// 	if err != nil {
+// 		return err
+// 	}
 
-func (n *network) vxlanID(s *subnet) uint32 {
-	n.Lock()
-	defer n.Unlock()
+// 	for _, endpoint := range hnsresponse {
+// 		if endpoint.VirtualNetwork != n.hnsId {
+// 			continue
+// 		}
 
-	return s.vni
-}
+// 		ep := n.convertToOverlayEndpoint(&endpoint)
 
-func (n *network) setVxlanID(s *subnet, vni uint32) {
-	n.Lock()
-	s.vni = vni
-	n.Unlock()
-}
+// 		if ep != nil {
+// 			logrus.Debugf("Restored endpoint:%s Remote:%t", ep.id, ep.remote)
+// 			n.addEndpoint(ep)
+// 		}
+// 	}
 
-func (n *network) Key() []string {
-	return []string{"overlay", "network", n.id}
-}
-
-func (n *network) KeyPrefix() []string {
-	return []string{"overlay", "network"}
-}
+// 	return nil
+// }
 
-func (n *network) Value() []byte {
-	m := map[string]interface{}{}
-
-	netJSON := []*subnetJSON{}
-
-	for _, s := range n.subnets {
-		sj := &subnetJSON{
-			SubnetIP: s.subnetIP.String(),
-			GwIP:     s.gwIP.String(),
-			Vni:      s.vni,
-		}
-		netJSON = append(netJSON, sj)
+func (n *network) convertToOverlayEndpoint(v *hcsshim.HNSEndpoint) *endpoint {
+	ep := &endpoint{
+		id:        v.Name,
+		profileId: v.Id,
+		nid:       n.id,
+		remote:    v.IsRemoteEndpoint,
 	}
 
-	b, err := json.Marshal(netJSON)
-	if err != nil {
-		return []byte{}
-	}
+	mac, err := net.ParseMAC(v.MacAddress)
 
-	m["secure"] = n.secure
-	m["subnets"] = netJSON
-	m["interfaceName"] = n.interfaceName
-	m["providerAddress"] = n.providerAddress
-	m["hnsId"] = n.hnsId
-	m["name"] = n.name
-	b, err = json.Marshal(m)
 	if err != nil {
-		return []byte{}
+		return nil
 	}
 
-	return b
-}
-
-func (n *network) Index() uint64 {
-	return n.dbIndex
-}
+	ep.mac = mac
+	ep.addr = &net.IPNet{
+		IP:   v.IPAddress,
+		Mask: net.CIDRMask(32, 32),
+	}
 
-func (n *network) SetIndex(index uint64) {
-	n.dbIndex = index
-	n.dbExists = true
+	return ep
 }
 
-func (n *network) Exists() bool {
-	return n.dbExists
-}
+func (d *driver) createHnsNetwork(n *network) error {
 
-func (n *network) Skip() bool {
-	return false
-}
+	subnets := []hcsshim.Subnet{}
 
-func (n *network) SetValue(value []byte) error {
-	var (
-		m       map[string]interface{}
-		newNet  bool
-		isMap   = true
-		netJSON = []*subnetJSON{}
-	)
+	for _, s := range n.subnets {
+		subnet := hcsshim.Subnet{
+			AddressPrefix: s.subnetIP.String(),
+		}
 
-	if err := json.Unmarshal(value, &m); err != nil {
-		err := json.Unmarshal(value, &netJSON)
-		if err != nil {
-			return err
+		if s.gwIP != nil {
+			subnet.GatewayAddress = s.gwIP.String()
 		}
-		isMap = false
-	}
 
-	if len(n.subnets) == 0 {
-		newNet = true
-	}
+		vsidPolicy, err := json.Marshal(hcsshim.VsidPolicy{
+			Type: "VSID",
+			VSID: uint(s.vni),
+		})
 
-	if isMap {
-		if val, ok := m["secure"]; ok {
-			n.secure = val.(bool)
-		}
-		if val, ok := m["providerAddress"]; ok {
-			n.providerAddress = val.(string)
-		}
-		if val, ok := m["interfaceName"]; ok {
-			n.interfaceName = val.(string)
-		}
-		if val, ok := m["hnsId"]; ok {
-			n.hnsId = val.(string)
-		}
-		if val, ok := m["name"]; ok {
-			n.name = val.(string)
-		}
-		bytes, err := json.Marshal(m["subnets"])
 		if err != nil {
 			return err
 		}
-		if err := json.Unmarshal(bytes, &netJSON); err != nil {
-			return err
-		}
-	}
-
-	for _, sj := range netJSON {
-		subnetIPstr := sj.SubnetIP
-		gwIPstr := sj.GwIP
-		vni := sj.Vni
 
-		subnetIP, _ := types.ParseCIDR(subnetIPstr)
-		gwIP, _ := types.ParseCIDR(gwIPstr)
-
-		if newNet {
-			s := &subnet{
-				subnetIP: subnetIP,
-				gwIP:     gwIP,
-				vni:      vni,
-			}
-			n.subnets = append(n.subnets, s)
-		} else {
-			sNet := n.getMatchingSubnet(subnetIP)
-			if sNet != nil {
-				sNet.vni = vni
-			}
-		}
+		subnet.Policies = append(subnet.Policies, vsidPolicy)
+		subnets = append(subnets, subnet)
 	}
-	return nil
-}
 
-func (n *network) DataScope() string {
-	return datastore.GlobalScope
-}
-
-func (n *network) writeToStore() error {
-	if n.driver.store == nil {
-		return nil
+	network := &hcsshim.HNSNetwork{
+		Name:               n.name,
+		Type:               d.Type(),
+		Subnets:            subnets,
+		NetworkAdapterName: n.interfaceName,
 	}
 
-	return n.driver.store.PutObjectAtomic(n)
-}
-
-func (n *network) releaseVxlanID() ([]uint32, error) {
-	if len(n.subnets) == 0 {
-		return nil, nil
-	}
-
-	if n.driver.store != nil {
-		if err := n.driver.store.DeleteObjectAtomic(n); err != nil {
-			if err == datastore.ErrKeyModified || err == datastore.ErrKeyNotFound {
-				// In both the above cases we can safely assume that the key has been removed by some other
-				// instance and so simply get out of here
-				return nil, nil
-			}
-
-			return nil, fmt.Errorf("failed to delete network to vxlan id map: %v", err)
-		}
-	}
-	var vnis []uint32
-	for _, s := range n.subnets {
-		if n.driver.vxlanIdm != nil {
-			vni := n.vxlanID(s)
-			vnis = append(vnis, vni)
-			n.driver.vxlanIdm.Release(uint64(vni))
-		}
-
-		n.setVxlanID(s, 0)
+	configurationb, err := json.Marshal(network)
+	if err != nil {
+		return err
 	}
 
-	return vnis, nil
-}
+	configuration := string(configurationb)
+	logrus.Infof("HNSNetwork Request =%v", configuration)
 
-func (n *network) obtainVxlanID(s *subnet) error {
-	//return if the subnet already has a vxlan id assigned
-	if s.vni != 0 {
-		return nil
-	}
-
-	if n.driver.store == nil {
-		return fmt.Errorf("no valid vxlan id and no datastore configured, cannot obtain vxlan id")
+	hnsresponse, err := hcsshim.HNSNetworkRequest("POST", "", configuration)
+	if err != nil {
+		return err
 	}
 
-	for {
-		if err := n.driver.store.GetObject(datastore.Key(n.Key()...), n); err != nil {
-			return fmt.Errorf("getting network %q from datastore failed %v", n.id, err)
-		}
-
-		if s.vni == 0 {
-			vxlanID, err := n.driver.vxlanIdm.GetID()
-			if err != nil {
-				return fmt.Errorf("failed to allocate vxlan id: %v", err)
-			}
+	n.hnsId = hnsresponse.Id
+	n.providerAddress = hnsresponse.ManagementIP
 
-			n.setVxlanID(s, uint32(vxlanID))
-			if err := n.writeToStore(); err != nil {
-				n.driver.vxlanIdm.Release(uint64(n.vxlanID(s)))
-				n.setVxlanID(s, 0)
-				if err == datastore.ErrKeyModified {
-					continue
-				}
-				return fmt.Errorf("network %q failed to update data store: %v", n.id, err)
-			}
-			return nil
-		}
-		return nil
-	}
+	return nil
 }
 
 // contains return true if the passed ip belongs to one the network's

+ 0 - 179
libnetwork/drivers/windows/overlay/ov_serf_windows.go

@@ -1,179 +0,0 @@
-package overlay
-
-import (
-	"fmt"
-	"net"
-	"strings"
-	"time"
-
-	"github.com/Sirupsen/logrus"
-	"github.com/hashicorp/serf/serf"
-)
-
-type ovNotify struct {
-	action string
-	ep     *endpoint
-	nw     *network
-}
-
-type logWriter struct{}
-
-func (l *logWriter) Write(p []byte) (int, error) {
-	str := string(p)
-
-	switch {
-	case strings.Contains(str, "[WARN]"):
-		logrus.Warn(str)
-	case strings.Contains(str, "[DEBUG]"):
-		logrus.Debug(str)
-	case strings.Contains(str, "[INFO]"):
-		logrus.Info(str)
-	case strings.Contains(str, "[ERR]"):
-		logrus.Error(str)
-	}
-
-	return len(p), nil
-}
-
-func (d *driver) serfInit() error {
-	var err error
-
-	config := serf.DefaultConfig()
-	config.Init()
-	config.MemberlistConfig.BindAddr = d.bindAddress
-
-	d.eventCh = make(chan serf.Event, 4)
-	config.EventCh = d.eventCh
-	config.UserCoalescePeriod = 1 * time.Second
-	config.UserQuiescentPeriod = 50 * time.Millisecond
-
-	config.LogOutput = &logWriter{}
-	config.MemberlistConfig.LogOutput = config.LogOutput
-
-	s, err := serf.Create(config)
-	if err != nil {
-		return fmt.Errorf("failed to create cluster node: %v", err)
-	}
-	defer func() {
-		if err != nil {
-			s.Shutdown()
-		}
-	}()
-
-	d.serfInstance = s
-
-	d.notifyCh = make(chan ovNotify)
-	d.exitCh = make(chan chan struct{})
-
-	go d.startSerfLoop(d.eventCh, d.notifyCh, d.exitCh)
-	return nil
-}
-
-func (d *driver) serfJoin(neighIP string) error {
-	if neighIP == "" {
-		return fmt.Errorf("no neighbor to join")
-	}
-	if _, err := d.serfInstance.Join([]string{neighIP}, false); err != nil {
-		return fmt.Errorf("Failed to join the cluster at neigh IP %s: %v",
-			neighIP, err)
-	}
-	return nil
-}
-
-func (d *driver) notifyEvent(event ovNotify) {
-	ep := event.ep
-
-	ePayload := fmt.Sprintf("%s %s %s %s", event.action, ep.addr.IP.String(),
-		net.IP(ep.addr.Mask).String(), ep.mac.String())
-	eName := fmt.Sprintf("jl %s %s %s", d.serfInstance.LocalMember().Addr.String(),
-		event.nw.id, ep.id)
-
-	if err := d.serfInstance.UserEvent(eName, []byte(ePayload), true); err != nil {
-		logrus.Errorf("Sending user event failed: %v\n", err)
-	}
-}
-
-func (d *driver) processEvent(u serf.UserEvent) {
-	logrus.Debugf("Received user event name:%s, payload:%s\n", u.Name,
-		string(u.Payload))
-
-	var dummy, action, vtepStr, nid, eid, ipStr, maskStr, macStr string
-	if _, err := fmt.Sscan(u.Name, &dummy, &vtepStr, &nid, &eid); err != nil {
-		fmt.Printf("Failed to scan name string: %v\n", err)
-	}
-
-	if _, err := fmt.Sscan(string(u.Payload), &action,
-		&ipStr, &maskStr, &macStr); err != nil {
-		fmt.Printf("Failed to scan value string: %v\n", err)
-	}
-
-	logrus.Debugf("Parsed data = %s/%s/%s/%s/%s/%s\n", nid, eid, vtepStr, ipStr, maskStr, macStr)
-
-	mac, err := net.ParseMAC(macStr)
-	if err != nil {
-		logrus.Errorf("Failed to parse mac: %v\n", err)
-	}
-
-	if d.serfInstance.LocalMember().Addr.String() == vtepStr {
-		return
-	}
-
-	switch action {
-	case "join":
-		if err := d.peerAdd(nid, eid, net.ParseIP(ipStr), net.IPMask(net.ParseIP(maskStr).To4()), mac,
-			net.ParseIP(vtepStr), true); err != nil {
-			logrus.Errorf("Peer add failed in the driver: %v\n", err)
-		}
-	case "leave":
-		if err := d.peerDelete(nid, eid, net.ParseIP(ipStr), net.IPMask(net.ParseIP(maskStr).To4()), mac,
-			net.ParseIP(vtepStr), true); err != nil {
-			logrus.Errorf("Peer delete failed in the driver: %v\n", err)
-		}
-	}
-}
-
-func (d *driver) startSerfLoop(eventCh chan serf.Event, notifyCh chan ovNotify,
-	exitCh chan chan struct{}) {
-
-	for {
-		select {
-		case notify, ok := <-notifyCh:
-			if !ok {
-				break
-			}
-
-			d.notifyEvent(notify)
-		case ch, ok := <-exitCh:
-			if !ok {
-				break
-			}
-
-			if err := d.serfInstance.Leave(); err != nil {
-				logrus.Errorf("failed leaving the cluster: %v\n", err)
-			}
-
-			d.serfInstance.Shutdown()
-			close(ch)
-			return
-		case e, ok := <-eventCh:
-			if !ok {
-				break
-			}
-			u, ok := e.(serf.UserEvent)
-			if !ok {
-				break
-			}
-			d.processEvent(u)
-		}
-	}
-}
-
-func (d *driver) isSerfAlive() bool {
-	d.Lock()
-	serfInstance := d.serfInstance
-	d.Unlock()
-	if serfInstance == nil || serfInstance.State() != serf.SerfAlive {
-		return false
-	}
-	return true
-}

+ 56 - 199
libnetwork/drivers/windows/overlay/overlay_windows.go

@@ -3,7 +3,7 @@ package overlay
 //go:generate protoc -I.:../../Godeps/_workspace/src/github.com/gogo/protobuf  --gogo_out=import_path=github.com/docker/libnetwork/drivers/overlay,Mgogoproto/gogo.proto=github.com/gogo/protobuf/gogoproto:. overlay.proto
 
 import (
-	"fmt"
+	"encoding/json"
 	"net"
 	"sync"
 
@@ -12,40 +12,24 @@ import (
 	"github.com/docker/libnetwork/datastore"
 	"github.com/docker/libnetwork/discoverapi"
 	"github.com/docker/libnetwork/driverapi"
-	"github.com/docker/libnetwork/idm"
 	"github.com/docker/libnetwork/netlabel"
 	"github.com/docker/libnetwork/types"
-	"github.com/hashicorp/serf/serf"
 )
 
 const (
 	networkType  = "overlay"
 	vethPrefix   = "veth"
 	vethLen      = 7
-	vxlanIDStart = 4096
-	vxlanIDEnd   = (1 << 24) - 1
-	vxlanPort    = 4789
-	vxlanEncap   = 50
 	secureOption = "encrypted"
 )
 
-var initVxlanIdm = make(chan (bool), 1)
-
 type driver struct {
-	eventCh          chan serf.Event
-	notifyCh         chan ovNotify
-	exitCh           chan chan struct{}
-	bindAddress      string
-	advertiseAddress string
-	neighIP          string
-	config           map[string]interface{}
-	serfInstance     *serf.Serf
-	networks         networkTable
-	store            datastore.DataStore
-	localStore       datastore.DataStore
-	vxlanIdm         *idm.Idm
-	once             sync.Once
-	joinOnce         sync.Once
+	config     map[string]interface{}
+	networks   networkTable
+	store      datastore.DataStore
+	localStore datastore.DataStore
+	once       sync.Once
+	joinOnce   sync.Once
 	sync.Mutex
 }
 
@@ -84,92 +68,75 @@ func Init(dc driverapi.DriverCallback, config map[string]interface{}) error {
 		}
 	}
 
-	d.restoreEndpoints()
+	d.restoreHNSNetworks()
 
 	return dc.RegisterDriver(networkType, d, c)
 }
 
-// Endpoints are stored in the local store. Restore them and reconstruct the overlay sandbox
-func (d *driver) restoreEndpoints() error {
-	if d.localStore == nil {
-		logrus.Warnf("Cannot restore overlay endpoints because local datastore is missing")
-		return nil
-	}
-	kvol, err := d.localStore.List(datastore.Key(overlayEndpointPrefix), &endpoint{})
-	if err != nil && err != datastore.ErrKeyNotFound {
-		return fmt.Errorf("failed to read overlay endpoint from store: %v", err)
-	}
+func (d *driver) restoreHNSNetworks() error {
+	logrus.Infof("Restoring existing overlay networks from HNS into docker")
 
-	if err == datastore.ErrKeyNotFound {
-		return nil
+	hnsresponse, err := hcsshim.HNSListNetworkRequest("GET", "", "")
+	if err != nil {
+		return err
 	}
 
-	for _, kvo := range kvol {
-		ep := kvo.(*endpoint)
-
-		n := d.network(ep.nid)
-		if n == nil || ep.remote {
-			if !ep.remote {
-				logrus.Debugf("Network (%s) not found for restored endpoint (%s)", ep.nid[0:7], ep.id[0:7])
-				logrus.Debugf("Deleting stale overlay endpoint (%s) from store", ep.id[0:7])
-			}
-
-			hcsshim.HNSEndpointRequest("DELETE", ep.profileId, "")
-
-			if err := d.deleteEndpointFromStore(ep); err != nil {
-				logrus.Debugf("Failed to delete stale overlay endpoint (%s) from store", ep.id[0:7])
-			}
-
+	for _, v := range hnsresponse {
+		if v.Type != networkType {
 			continue
 		}
 
-		n.addEndpoint(ep)
+		logrus.Infof("Restoring overlay network: %s", v.Name)
+		n := d.convertToOverlayNetwork(&v)
+		d.addNetwork(n)
+
+		//
+		// We assume that any network will be recreated on daemon restart
+		// and therefore don't restore hns endpoints for now
+		//
+		//n.restoreNetworkEndpoints()
 	}
 
 	return nil
 }
 
-// Fini cleans up the driver resources
-func Fini(drv driverapi.Driver) {
-	d := drv.(*driver)
-
-	if d.exitCh != nil {
-		waitCh := make(chan struct{})
-
-		d.exitCh <- waitCh
-
-		<-waitCh
-	}
-}
-
-func (d *driver) configure() error {
-	if d.store == nil {
-		return nil
-	}
-
-	if d.vxlanIdm == nil {
-		return d.initializeVxlanIdm()
-	}
+func (d *driver) convertToOverlayNetwork(v *hcsshim.HNSNetwork) *network {
+	n := &network{
+		id:              v.Name,
+		hnsId:           v.Id,
+		driver:          d,
+		endpoints:       endpointTable{},
+		subnets:         []*subnet{},
+		providerAddress: v.ManagementIP,
+	}
+
+	for _, hnsSubnet := range v.Subnets {
+		vsidPolicy := &hcsshim.VsidPolicy{}
+		for _, policy := range hnsSubnet.Policies {
+			if err := json.Unmarshal([]byte(policy), &vsidPolicy); err == nil && vsidPolicy.Type == "VSID" {
+				break
+			}
+		}
 
-	return nil
-}
+		gwIP := net.ParseIP(hnsSubnet.GatewayAddress)
+		localsubnet := &subnet{
+			vni:  uint32(vsidPolicy.VSID),
+			gwIP: &gwIP,
+		}
 
-func (d *driver) initializeVxlanIdm() error {
-	var err error
+		_, subnetIP, err := net.ParseCIDR(hnsSubnet.AddressPrefix)
 
-	initVxlanIdm <- true
-	defer func() { <-initVxlanIdm }()
+		if err != nil {
+			logrus.Errorf("Error parsing subnet address %s ", hnsSubnet.AddressPrefix)
+			continue
+		}
 
-	if d.vxlanIdm != nil {
-		return nil
-	}
+		localsubnet.subnetIP = subnetIP
 
-	d.vxlanIdm, err = idm.New(d.store, "vxlan-id", vxlanIDStart, vxlanIDEnd)
-	if err != nil {
-		return fmt.Errorf("failed to initialize vxlan id manager: %v", err)
+		n.subnets = append(n.subnets, localsubnet)
 	}
 
-	return nil
+	return n
 }
 
 func (d *driver) Type() string {
@@ -180,122 +147,12 @@ func (d *driver) IsBuiltIn() bool {
 	return true
 }
 
-func validateSelf(node string) error {
-	advIP := net.ParseIP(node)
-	if advIP == nil {
-		return fmt.Errorf("invalid self address (%s)", node)
-	}
-
-	addrs, err := net.InterfaceAddrs()
-	if err != nil {
-		return fmt.Errorf("Unable to get interface addresses %v", err)
-	}
-	for _, addr := range addrs {
-		ip, _, err := net.ParseCIDR(addr.String())
-		if err == nil && ip.Equal(advIP) {
-			return nil
-		}
-	}
-	return fmt.Errorf("Multi-Host overlay networking requires cluster-advertise(%s) to be configured with a local ip-address that is reachable within the cluster", advIP.String())
-}
-
-func (d *driver) nodeJoin(advertiseAddress, bindAddress string, self bool) {
-	if self && !d.isSerfAlive() {
-		if err := validateSelf(advertiseAddress); err != nil {
-			logrus.Errorf("%s", err.Error())
-		}
-
-		d.Lock()
-		d.advertiseAddress = advertiseAddress
-		d.bindAddress = bindAddress
-		d.Unlock()
-
-		// If there is no cluster store there is no need to start serf.
-		if d.store != nil {
-			err := d.serfInit()
-			if err != nil {
-				logrus.Errorf("initializing serf instance failed: %v", err)
-				return
-			}
-		}
-	}
-
-	d.Lock()
-	if !self {
-		d.neighIP = advertiseAddress
-	}
-	neighIP := d.neighIP
-	d.Unlock()
-
-	if d.serfInstance != nil && neighIP != "" {
-		var err error
-		d.joinOnce.Do(func() {
-			err = d.serfJoin(neighIP)
-			if err == nil {
-				d.pushLocalDb()
-			}
-		})
-		if err != nil {
-			logrus.Errorf("joining serf neighbor %s failed: %v", advertiseAddress, err)
-			d.Lock()
-			d.joinOnce = sync.Once{}
-			d.Unlock()
-			return
-		}
-	}
-}
-
-func (d *driver) pushLocalEndpointEvent(action, nid, eid string) {
-	n := d.network(nid)
-	if n == nil {
-		logrus.Debugf("Error pushing local endpoint event for network %s", nid)
-		return
-	}
-	ep := n.endpoint(eid)
-	if ep == nil {
-		logrus.Debugf("Error pushing local endpoint event for ep %s / %s", nid, eid)
-		return
-	}
-
-	if !d.isSerfAlive() {
-		return
-	}
-	d.notifyCh <- ovNotify{
-		action: action,
-		nw:     n,
-		ep:     ep,
-	}
-}
-
 // DiscoverNew is a notification for a new discovery event, such as a new node joining a cluster
 func (d *driver) DiscoverNew(dType discoverapi.DiscoveryType, data interface{}) error {
-
-	var err error
-	switch dType {
-	case discoverapi.NodeDiscovery:
-		nodeData, ok := data.(discoverapi.NodeDiscoveryData)
-		if !ok || nodeData.Address == "" {
-			return fmt.Errorf("invalid discovery data")
-		}
-		d.nodeJoin(nodeData.Address, nodeData.BindAddress, nodeData.Self)
-	case discoverapi.DatastoreConfig:
-		if d.store != nil {
-			return types.ForbiddenErrorf("cannot accept datastore configuration: Overlay driver has a datastore configured already")
-		}
-		dsc, ok := data.(discoverapi.DatastoreConfigData)
-		if !ok {
-			return types.InternalErrorf("incorrect data in datastore configuration: %v", data)
-		}
-		d.store, err = datastore.NewDataStoreFromConfig(dsc)
-		if err != nil {
-			return types.InternalErrorf("failed to initialize data store: %v", err)
-		}
-	default:
-	}
-	return nil
+	return types.NotImplementedErrorf("not implemented")
 }
 
 // DiscoverDelete is a notification for a discovery delete event, such as a node leaving a cluster
 func (d *driver) DiscoverDelete(dType discoverapi.DiscoveryType, data interface{}) error {
-	return nil
+	return types.NotImplementedErrorf("not implemented")
 }

+ 2 - 36
libnetwork/drivers/windows/overlay/peerdb_windows.go

@@ -7,40 +7,13 @@ import (
 	"encoding/json"
 
 	"github.com/Sirupsen/logrus"
+	"github.com/docker/libnetwork/types"
 
 	"github.com/Microsoft/hcsshim"
-	"github.com/docker/libnetwork/types"
 )
 
 const ovPeerTable = "overlay_peer_table"
 
-func (d *driver) pushLocalDb() {
-	if !d.isSerfAlive() {
-		return
-	}
-
-	d.Lock()
-	networks := d.networks
-	d.Unlock()
-
-	for _, n := range networks {
-		n.Lock()
-		endpoints := n.endpoints
-		n.Unlock()
-
-		for _, ep := range endpoints {
-			if !ep.remote {
-				d.notifyCh <- ovNotify{
-					action: "join",
-					nw:     n,
-					ep:     ep,
-				}
-
-			}
-		}
-	}
-}
-
 func (d *driver) peerAdd(nid, eid string, peerIP net.IP, peerIPMask net.IPMask,
 	peerMac net.HardwareAddr, vtep net.IP, updateDb bool) error {
 
@@ -59,6 +32,7 @@ func (d *driver) peerAdd(nid, eid string, peerIP net.IP, peerIPMask net.IPMask,
 		logrus.Info("WINOVERLAY: peerAdd: notifying HNS of the REMOTE endpoint")
 
 		hnsEndpoint := &hcsshim.HNSEndpoint{
+			Name:             eid,
 			VirtualNetwork:   n.hnsId,
 			MacAddress:       peerMac.String(),
 			IPAddress:        peerIP,
@@ -109,10 +83,6 @@ func (d *driver) peerAdd(nid, eid string, peerIP net.IP, peerIPMask net.IPMask,
 		}
 
 		n.addEndpoint(ep)
-
-		if err := d.writeEndpointToStore(ep); err != nil {
-			return fmt.Errorf("failed to update overlay endpoint %s to local store: %v", ep.id[0:7], err)
-		}
 	}
 
 	return nil
@@ -144,10 +114,6 @@ func (d *driver) peerDelete(nid, eid string, peerIP net.IP, peerIPMask net.IPMas
 		}
 
 		n.deleteEndpoint(eid)
-
-		if err := d.deleteEndpointFromStore(ep); err != nil {
-			logrus.Debugf("Failed to delete stale overlay endpoint (%s) from store", ep.id[0:7])
-		}
 	}
 
 	return nil

+ 1 - 1
libnetwork/drivers/windows/windows.go

@@ -309,7 +309,7 @@ func (d *driver) DeleteNetwork(nid string) error {
 
 	_, err = hcsshim.HNSNetworkRequest("DELETE", config.HnsID, "")
 	if err != nil {
-		return err
+		return types.ForbiddenErrorf(err.Error())
 	}
 
 	d.Lock()