func (d *driver) peerDelete(nid, eid string, peerIP net.IP, peerIPMask net.IPMask,
	peerMac net.HardwareAddr, vtep net.IP, updateDb bool) error {

	log.Infof("WINOVERLAY: Enter peerDelete for endpoint %s and peer ip %s", eid, peerIP.String())

	if err := validateID(nid, eid); err != nil {
		return err
	}

	n := d.network(nid)
	if n == nil {
		return nil
	}

	ep := n.endpoint(eid)
	if ep == nil {
		return fmt.Errorf("could not find endpoint with id %s", eid)
	}

	if updateDb {
		_, err := hcsshim.HNSEndpointRequest("DELETE", ep.profileId, "")
		if err != nil {
			return err
		}

		n.deleteEndpoint(eid)

		if err := d.deleteEndpointFromStore(ep); err != nil {
			log.Debugf("Failed to delete stale overlay endpoint (%s) from store", ep.id[0:7])
		}
	}

	return nil
}
func (n *network) removeEndpointWithAddress(addr *net.IPNet) {
	var networkEndpoint *endpoint
	n.Lock()
	for _, ep := range n.endpoints {
		if ep.addr.IP.Equal(addr.IP) {
			networkEndpoint = ep
			break
		}
	}
	if networkEndpoint != nil {
		delete(n.endpoints, networkEndpoint.id)
	}
	n.Unlock()

	if networkEndpoint != nil {
		logrus.Debugf("Removing stale endpoint from HNS")
		_, err := hcsshim.HNSEndpointRequest("DELETE", networkEndpoint.profileId, "")

		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])
		}
	}
}
func (d *driver) DeleteEndpoint(nid, eid string) error {
	if err := validateID(nid, eid); err != nil {
		return err
	}

	n := d.network(nid)
	if n == nil {
		return fmt.Errorf("network id %q not found", nid)
	}

	ep := n.endpoint(eid)
	if ep == nil {
		return fmt.Errorf("endpoint id %q not found", eid)
	}

	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
	}

	return nil
}
Exemple #4
0
func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo, epOptions map[string]interface{}) error {
	n, err := d.getNetwork(nid)
	if err != nil {
		return err
	}

	// Check if endpoint id is good and retrieve corresponding endpoint
	ep, err := n.getEndpoint(eid)
	if err == nil && ep != nil {
		return driverapi.ErrEndpointExists(eid)
	}

	endpointStruct := &hcsshim.HNSEndpoint{
		VirtualNetwork: n.config.HnsID,
	}

	// Convert the port mapping for the network
	if opt, ok := epOptions[netlabel.PortMap]; ok {
		if bs, ok := opt.([]types.PortBinding); ok {
			endpointStruct.Policies, err = convertPortBindings(bs)
			if err != nil {
				return err
			}
		} else {
			return fmt.Errorf("Invalid endpoint configuration for endpoint id%s", eid)
		}
	}

	configurationb, err := json.Marshal(endpointStruct)
	if err != nil {
		return err
	}

	hnsresponse, err := hcsshim.HNSEndpointRequest("POST", "", string(configurationb))
	if err != nil {
		return err
	}

	mac, err := net.ParseMAC(hnsresponse.MacAddress)
	if err != nil {
		return err
	}

	// TODO For now the ip mask is not in the info generated by HNS
	endpoint := &hnsEndpoint{
		id:         eid,
		addr:       &net.IPNet{IP: hnsresponse.IPAddress, Mask: hnsresponse.IPAddress.DefaultMask()},
		macAddress: mac,
	}
	endpoint.profileID = hnsresponse.Id
	n.Lock()
	n.endpoints[eid] = endpoint
	n.Unlock()

	ifInfo.SetIPAddress(endpoint.addr)
	ifInfo.SetMacAddress(endpoint.macAddress)

	return nil
}
Exemple #5
0
func (d *driver) DeleteEndpoint(nid, eid string) error {
	n, err := d.getNetwork(nid)
	if err != nil {
		return types.InternalMaskableErrorf("%s", err)
	}

	ep, err := n.getEndpoint(eid)
	if err != nil {
		return err
	}

	n.Lock()
	delete(n.endpoints, eid)
	n.Unlock()

	_, err = hcsshim.HNSEndpointRequest("DELETE", ep.profileID, "")
	if err != nil {
		return err
	}

	return nil
}
Exemple #6
0
// 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)
	}

	if err == datastore.ErrKeyNotFound {
		return nil
	}

	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])
			}

			continue
		}

		n.addEndpoint(ep)
	}

	return nil
}
Exemple #7
0
func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo, epOptions map[string]interface{}) error {
	n, err := d.getNetwork(nid)
	if err != nil {
		return err
	}

	// Check if endpoint id is good and retrieve corresponding endpoint
	ep, err := n.getEndpoint(eid)
	if err == nil && ep != nil {
		return driverapi.ErrEndpointExists(eid)
	}

	endpointStruct := &hcsshim.HNSEndpoint{
		VirtualNetwork: n.config.HnsID,
	}

	ec, err := parseEndpointOptions(epOptions)

	macAddress := ifInfo.MacAddress()
	// Use the macaddress if it was provided
	if macAddress != nil {
		endpointStruct.MacAddress = strings.Replace(macAddress.String(), ":", "-", -1)
	}

	endpointStruct.Policies, err = convertPortBindings(ec.PortBindings)
	if err != nil {
		return err
	}

	qosPolicies, err := convertQosPolicies(ec.QosPolicies)
	if err != nil {
		return err
	}
	endpointStruct.Policies = append(endpointStruct.Policies, qosPolicies...)

	if ifInfo.Address() != nil {
		endpointStruct.IPAddress = ifInfo.Address().IP
	}

	configurationb, err := json.Marshal(endpointStruct)
	if err != nil {
		return err
	}

	hnsresponse, err := hcsshim.HNSEndpointRequest("POST", "", string(configurationb))
	if err != nil {
		return err
	}

	mac, err := net.ParseMAC(hnsresponse.MacAddress)
	if err != nil {
		return err
	}

	// TODO For now the ip mask is not in the info generated by HNS
	endpoint := &hnsEndpoint{
		id:         eid,
		addr:       &net.IPNet{IP: hnsresponse.IPAddress, Mask: hnsresponse.IPAddress.DefaultMask()},
		macAddress: mac,
	}

	endpoint.profileID = hnsresponse.Id
	endpoint.config = ec
	endpoint.portMapping, err = parsePortBindingPolicies(hnsresponse.Policies)

	if err != nil {
		hcsshim.HNSEndpointRequest("DELETE", hnsresponse.Id, "")
		return err
	}

	n.Lock()
	n.endpoints[eid] = endpoint
	n.Unlock()

	if ifInfo.Address() == nil {
		ifInfo.SetIPAddress(endpoint.addr)
	}

	if macAddress == nil {
		ifInfo.SetMacAddress(endpoint.macAddress)
	}

	return nil
}
Exemple #8
0
func main() {
	if len(os.Args) != 2 {
		fmt.Print(`
This sample create a new container runs ping and then destroys the container.
		
Usage:
  sample.exe <base container Id>

To get the base container id for "microsoft/windowsservercore" use the following PS snippet:
  Split-Path -Leaf (docker inspect microsoft/windowsservercore  | ConvertFrom-Json).GraphDriver.Data.Dir

`)
		os.Exit(1)
	}

	windowsbaseId := os.Args[1]

	di := hcsshim.DriverInfo{
		HomeDir: homeDir,
		Flavour: filterDriver,
	}

	imgData, err := hcsshim.GetSharedBaseImages()
	panicIf(err)
	fmt.Println(imgData)

	hcsNets, err := hcsshim.HNSListNetworkRequest("GET", "", "")
	panicIf(err)
	fmt.Println(hcsNets)

	virtualNetworkId := ""
	for _, n := range hcsNets {
		if n.Name == "nat" {
			virtualNetworkId = n.Id
		}
	}

	// https://github.com/docker/libnetwork/blob/f9a1590164b878e668eabf889dd79fb6af8eaced/drivers/windows/windows.go#L284
	endpointRequest := hcsshim.HNSEndpoint{
		VirtualNetwork: virtualNetworkId,
	}
	endpointRequestJson, err := json.Marshal(endpointRequest)
	panicIf(err)

	endpoint, err := hcsshim.HNSEndpointRequest("POST", "", string(endpointRequestJson))
	panicIf(err)
	fmt.Println(*endpoint)

	windowsservercorePath, err := hcsshim.GetLayerMountPath(di, windowsbaseId)
	panicIf(err)
	fmt.Println(windowsservercorePath)

	layerChain, err := GetLayerChain(windowsservercorePath)
	panicIf(err)
	fmt.Println(layerChain)

	newContainerId := stringid.GenerateNonCryptoID()

	layerFolderPath, volumeMountPath, err := CreateAndActivateContainerLayer(di, newContainerId, windowsservercorePath)
	panicIf(err)

	containerConfig := hcsshim.ContainerConfig{
		SystemType:              "Container",
		Name:                    newContainerId,
		Owner:                   "Garden",
		LayerFolderPath:         layerFolderPath,
		VolumePath:              volumeMountPath,
		IgnoreFlushesDuringBoot: true,
		EndpointList:            []string{endpoint.Id},
	}

	// https://github.com/docker/docker/blob/cf58eb437c4229e876f2d952a228b603a074e584/libcontainerd/client_windows.go#L111-L121
	for _, layerPath := range layerChain {
		id, err := hcsshim.NameToGuid(GetLayerId(layerPath))
		panicIf(err)

		containerConfig.Layers = append(containerConfig.Layers, hcsshim.Layer{
			Path: layerPath,
			ID:   id.ToString(),
		})
	}

	c, err := hcsshim.CreateContainer(newContainerId, &containerConfig)
	panicIf(err)
	fmt.Println(c)

	err = c.Start()
	panicIf(err)

	stats, err := c.Statistics()
	panicIf(err)
	fmt.Println(stats)

	processConfig := hcsshim.ProcessConfig{
		CommandLine:      "ping 127.0.0.1",
		WorkingDirectory: "C:\\",
		//CreateStdErrPipe: true,
		//CreateStdInPipe:  true,
		//CreateStdOutPipe: true,
	}

	p, err := c.CreateProcess(&processConfig)
	panicIf(err)
	fmt.Println(p)

	err = p.Wait()
	panicIf(err)

	err = c.Shutdown()
	warnIf(err)

	err = c.Terminate()
	warnIf(err)

	endpoint, err = hcsshim.HNSEndpointRequest("DELETE", endpoint.Id, "")
	warnIf(err)

	err = hcsshim.UnprepareLayer(di, newContainerId)
	warnIf(err)

	err = hcsshim.DeactivateLayer(di, newContainerId)
	warnIf(err)

	err = hcsshim.DestroyLayer(di, newContainerId)
	warnIf(err)
}
func (d *driver) peerAdd(nid, eid string, peerIP net.IP, peerIPMask net.IPMask,
	peerMac net.HardwareAddr, vtep net.IP, updateDb bool) error {

	log.Debugf("WINOVERLAY: Enter peerAdd for ca ip %s with ca mac %s", peerIP.String(), peerMac.String())

	if err := validateID(nid, eid); err != nil {
		return err
	}

	n := d.network(nid)
	if n == nil {
		return nil
	}

	if updateDb {
		log.Info("WINOVERLAY: peerAdd: notifying HNS of the REMOTE endpoint")

		hnsEndpoint := &hcsshim.HNSEndpoint{
			VirtualNetwork:   n.hnsId,
			MacAddress:       peerMac.String(),
			IPAddress:        peerIP,
			IsRemoteEndpoint: true,
		}

		paPolicy, err := json.Marshal(hcsshim.PaPolicy{
			Type: "PA",
			PA:   vtep.String(),
		})

		if err != nil {
			return err
		}

		hnsEndpoint.Policies = append(hnsEndpoint.Policies, paPolicy)

		configurationb, err := json.Marshal(hnsEndpoint)
		if err != nil {
			return err
		}

		// Temp: We have to create a endpoint object to keep track of the HNS ID for
		// this endpoint so that we can retrieve it later when the endpoint is deleted.
		// This seems unnecessary when we already have dockers EID. See if we can pass
		// the global EID to HNS to use as it's ID, rather than having each HNS assign
		// it's own local ID for the endpoint

		addr, err := types.ParseCIDR(peerIP.String() + "/32")
		if err != nil {
			return err
		}

		n.removeEndpointWithAddress(addr)

		hnsresponse, err := hcsshim.HNSEndpointRequest("POST", "", string(configurationb))
		if err != nil {
			return err
		}

		ep := &endpoint{
			id:        eid,
			nid:       nid,
			addr:      addr,
			mac:       peerMac,
			profileId: hnsresponse.Id,
			remote:    true,
		}

		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
}
func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo,
	epOptions map[string]interface{}) error {
	var err error
	if err = validateID(nid, eid); err != nil {
		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{
		id:   eid,
		nid:  n.id,
		addr: ifInfo.Address(),
		mac:  ifInfo.MacAddress(),
	}

	if ep.addr == nil {
		return fmt.Errorf("create endpoint was not passed interface IP address")
	}

	if s := n.getSubnetforIP(ep.addr); s == nil {
		return fmt.Errorf("no matching subnet for IP %q in network %q\n", ep.addr, nid)
	}

	// Todo: Add port bindings and qos policies here

	hnsEndpoint := &hcsshim.HNSEndpoint{
		VirtualNetwork:    n.hnsId,
		IPAddress:         ep.addr.IP,
		EnableInternalDNS: true,
	}

	if ep.mac != nil {
		hnsEndpoint.MacAddress = ep.mac.String()
	}

	paPolicy, err := json.Marshal(hcsshim.PaPolicy{
		Type: "PA",
		PA:   n.providerAddress,
	})

	if err != nil {
		return err
	}

	hnsEndpoint.Policies = append(hnsEndpoint.Policies, paPolicy)

	configurationb, err := json.Marshal(hnsEndpoint)
	if err != nil {
		return err
	}

	hnsresponse, err := hcsshim.HNSEndpointRequest("POST", "", string(configurationb))
	if err != nil {
		return err
	}

	ep.profileId = hnsresponse.Id

	if ep.mac == nil {
		ep.mac, err = net.ParseMAC(hnsresponse.MacAddress)
		if err != nil {
			return err
		}

		if err := ifInfo.SetMacAddress(ep.mac); err != nil {
			return err
		}
	}

	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
}