func (daemon *Daemon) initNetworkController(config *Config, activeSandboxes map[string]interface{}) (libnetwork.NetworkController, error) { netOptions, err := daemon.networkOptions(config, nil, nil) if err != nil { return nil, err } controller, err := libnetwork.New(netOptions...) if err != nil { return nil, fmt.Errorf("error obtaining controller instance: %v", err) } hnsresponse, err := hcsshim.HNSListNetworkRequest("GET", "", "") if err != nil { return nil, err } // Remove networks not present in HNS for _, v := range controller.Networks() { options := v.Info().DriverOptions() hnsid := options[winlibnetwork.HNSID] found := false for _, v := range hnsresponse { if v.Id == hnsid { found = true break } } if !found { // global networks should not be deleted by local HNS if v.Info().Scope() != datastore.GlobalScope { err = v.Delete() if err != nil { logrus.Errorf("Error occurred when removing network %v", err) } } } } _, err = controller.NewNetwork("null", "none", "", libnetwork.NetworkOptionPersist(false)) if err != nil { return nil, err } defaultNetworkExists := false if network, err := controller.NetworkByName(runconfig.DefaultDaemonNetworkMode().NetworkName()); err == nil { options := network.Info().DriverOptions() for _, v := range hnsresponse { if options[winlibnetwork.HNSID] == v.Id { defaultNetworkExists = true break } } } // discover and add HNS networks to windows // network that exist are removed and added again for _, v := range hnsresponse { var n libnetwork.Network s := func(current libnetwork.Network) bool { options := current.Info().DriverOptions() if options[winlibnetwork.HNSID] == v.Id { n = current return true } return false } controller.WalkNetworks(s) if n != nil { // global networks should not be deleted by local HNS if n.Info().Scope() == datastore.GlobalScope { continue } v.Name = n.Name() // This will not cause network delete from HNS as the network // is not yet populated in the libnetwork windows driver n.Delete() } netOption := map[string]string{ winlibnetwork.NetworkName: v.Name, winlibnetwork.HNSID: v.Id, } v4Conf := []*libnetwork.IpamConf{} for _, subnet := range v.Subnets { ipamV4Conf := libnetwork.IpamConf{} ipamV4Conf.PreferredPool = subnet.AddressPrefix ipamV4Conf.Gateway = subnet.GatewayAddress v4Conf = append(v4Conf, &ipamV4Conf) } name := v.Name // If there is no nat network create one from the first NAT network // encountered if !defaultNetworkExists && runconfig.DefaultDaemonNetworkMode() == containertypes.NetworkMode(strings.ToLower(v.Type)) { name = runconfig.DefaultDaemonNetworkMode().NetworkName() defaultNetworkExists = true } v6Conf := []*libnetwork.IpamConf{} _, err := controller.NewNetwork(strings.ToLower(v.Type), name, "", libnetwork.NetworkOptionGeneric(options.Generic{ netlabel.GenericData: netOption, }), libnetwork.NetworkOptionIpam("default", "", v4Conf, v6Conf, nil), ) if err != nil { logrus.Errorf("Error occurred when creating network %v", err) } } if !config.DisableBridge { // Initialize default driver "bridge" if err := initBridgeDriver(controller, config); err != nil { return nil, err } } return controller, nil }
func (daemon *Daemon) initNetworkController(config *Config) (libnetwork.NetworkController, error) { netOptions, err := daemon.networkOptions(config) if err != nil { return nil, err } controller, err := libnetwork.New(netOptions...) if err != nil { return nil, fmt.Errorf("error obtaining controller instance: %v", err) } hnsresponse, err := hcsshim.HNSListNetworkRequest("GET", "", "") if err != nil { return nil, err } // Remove networks not present in HNS for _, v := range controller.Networks() { options := v.Info().DriverOptions() hnsid := options[winlibnetwork.HNSID] found := false for _, v := range hnsresponse { if v.Id == hnsid { found = true break } } if !found { err = v.Delete() if err != nil { return nil, err } } } _, err = controller.NewNetwork("null", "none", libnetwork.NetworkOptionPersist(false)) if err != nil { return nil, err } // discover and add HNS networks to windows // network that exist are removed and added again for _, v := range hnsresponse { var n libnetwork.Network s := func(current libnetwork.Network) bool { options := current.Info().DriverOptions() if options[winlibnetwork.HNSID] == v.Id { n = current return true } return false } controller.WalkNetworks(s) if n != nil { v.Name = n.Name() n.Delete() } netOption := map[string]string{ winlibnetwork.NetworkName: v.Name, winlibnetwork.HNSID: v.Id, } v4Conf := []*libnetwork.IpamConf{} for _, subnet := range v.Subnets { ipamV4Conf := libnetwork.IpamConf{} ipamV4Conf.PreferredPool = subnet.AddressPrefix ipamV4Conf.Gateway = subnet.GatewayAddress v4Conf = append(v4Conf, &ipamV4Conf) } name := v.Name // There is only one nat network supported in windows. // If it exists with a different name add it as the default name if runconfig.DefaultDaemonNetworkMode() == containertypes.NetworkMode(strings.ToLower(v.Type)) { name = runconfig.DefaultDaemonNetworkMode().NetworkName() } v6Conf := []*libnetwork.IpamConf{} _, err := controller.NewNetwork(strings.ToLower(v.Type), name, libnetwork.NetworkOptionGeneric(options.Generic{ netlabel.GenericData: netOption, }), libnetwork.NetworkOptionIpam("default", "", v4Conf, v6Conf, nil), ) if err != nil { logrus.Errorf("Error occurred when creating network %v", err) } } if !config.DisableBridge { // Initialize default driver "bridge" if err := initBridgeDriver(controller, config); err != nil { return nil, err } } return controller, nil }
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) }