diff --git a/pkg/hns/endpoint_windows.go b/pkg/hns/endpoint_windows.go index 108d28d0b..010468789 100644 --- a/pkg/hns/endpoint_windows.go +++ b/pkg/hns/endpoint_windows.go @@ -24,18 +24,27 @@ import ( "github.com/juju/errors" ) -// ConstructEndpointName constructs enpointId which is used to identify an endpoint from HNS -// There is a special consideration for netNs name here, which is required for Windows Server 1709 -// containerID is the Id of the container on which the endpoint is worked on -func ConstructEndpointName(containerID string, netNs string, networkName string) string { - if netNs != "" { - splits := strings.Split(netNs, ":") +const ( + pauseContainerNetNS = "none" +) + +// GetSandboxContainerID returns the sandbox ID of this pod +func GetSandboxContainerID(containerID string, netNs string) string { + if len(netNs) != 0 && netNs != pauseContainerNetNS { + splits := strings.SplitN(netNs, ":", 2) if len(splits) == 2 { containerID = splits[1] } } - epName := containerID + "_" + networkName - return epName + + return containerID +} + +// ConstructEndpointName constructs enpointId which is used to identify an endpoint from HNS +// There is a special consideration for netNs name here, which is required for Windows Server 1709 +// containerID is the Id of the container on which the endpoint is worked on +func ConstructEndpointName(containerID string, netNs string, networkName string) string { + return GetSandboxContainerID(containerID, netNs) + "_" + networkName } // DeprovisionEndpoint removes an endpoint from the container by sending a Detach request to HNS @@ -47,7 +56,7 @@ func DeprovisionEndpoint(epName string, netns string, containerID string) error return errors.Annotatef(err, "failed to find HNSEndpoint %s", epName) } - if netns != "none" { + if netns != pauseContainerNetNS { // Shared endpoint removal. Do not remove the endpoint. hnsEndpoint.ContainerDetach(containerID) return nil diff --git a/plugins/meta/flannel/flannel.go b/plugins/meta/flannel/flannel.go index 0e5192f9d..f7d1b957c 100644 --- a/plugins/meta/flannel/flannel.go +++ b/plugins/meta/flannel/flannel.go @@ -26,7 +26,6 @@ import ( "net" "os" "path/filepath" - "runtime" "strconv" "strings" @@ -204,84 +203,7 @@ func cmdAdd(args *skel.CmdArgs) error { } } - if runtime.GOOS == "windows" { - return cmdAddWindows(args.ContainerID, n, fenv) - } - - n.Delegate["name"] = n.Name - - if !hasKey(n.Delegate, "type") { - n.Delegate["type"] = "bridge" - } - - if !hasKey(n.Delegate, "ipMasq") { - // if flannel is not doing ipmasq, we should - ipmasq := !*fenv.ipmasq - n.Delegate["ipMasq"] = ipmasq - } - - if !hasKey(n.Delegate, "mtu") { - mtu := fenv.mtu - n.Delegate["mtu"] = mtu - } - - if n.Delegate["type"].(string) == "bridge" { - if !hasKey(n.Delegate, "isGateway") { - n.Delegate["isGateway"] = true - } - } - if n.CNIVersion != "" { - n.Delegate["cniVersion"] = n.CNIVersion - } - - n.Delegate["ipam"] = map[string]interface{}{ - "type": "host-local", - "subnet": fenv.sn.String(), - "routes": []types.Route{ - { - Dst: *fenv.nw, - }, - }, - } - - return delegateAdd(args.ContainerID, n.DataDir, n.Delegate) -} - -func cmdAddWindows(containerID string, n *NetConf, fenv *subnetEnv) error { - n.Delegate["name"] = n.Name - - if !hasKey(n.Delegate, "type") { - n.Delegate["type"] = "win-l2bridge" - } - - // if flannel needs ipmasq - get the plugin to configure it - // (this is the opposite of how linux works - on linux the flannel daemon configure ipmasq) - if hasKey(n.Delegate, "ipMasq") { - n.Delegate["ipMasq"] = *fenv.ipmasq - } - - n.Delegate["cniVersion"] = "0.2.0" - if n.CNIVersion != "" { - n.Delegate["cniVersion"] = n.CNIVersion - } - - switch n.Delegate["type"] { - case "win-l2bridge": - delete(n.Delegate, "endpointMacPrefix") - n.Delegate["clusterNetworkPrefix"] = fenv.nw.String() - case "win-overlay": - delete(n.Delegate, "clusterNetworkPrefix") - if !hasKey(n.Delegate, "ipMasq") { - n.Delegate["endpointMacPrefix"] = "0E-2A" - } - - } - n.Delegate["ipam"] = map[string]interface{}{ - "type": "host-local", - "subnet": fenv.sn.String(), - } - - return delegateAdd(containerID, n.DataDir, n.Delegate) + return doCmdAdd(args, n, fenv) } func cmdDel(args *skel.CmdArgs) error { @@ -290,21 +212,7 @@ func cmdDel(args *skel.CmdArgs) error { return err } - netconfBytes, err := consumeScratchNetConf(args.ContainerID, nc.DataDir) - if err != nil { - if os.IsNotExist(err) { - // Per spec should ignore error if resources are missing / already removed - return nil - } - return err - } - - n := &types.NetConf{} - if err = json.Unmarshal(netconfBytes, n); err != nil { - return fmt.Errorf("failed to parse netconf: %v", err) - } - - return invoke.DelegateDel(n.Type, netconfBytes, nil) + return doCmdDel(args, nc) } func main() { diff --git a/plugins/meta/flannel/flannel_linux.go b/plugins/meta/flannel/flannel_linux.go new file mode 100644 index 000000000..f89a55494 --- /dev/null +++ b/plugins/meta/flannel/flannel_linux.go @@ -0,0 +1,86 @@ +// Copyright 2018 CNI authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// This is a "meta-plugin". It reads in its own netconf, combines it with +// the data from flannel generated subnet file and then invokes a plugin +// like bridge or ipvlan to do the real work. + +package main + +import ( + "encoding/json" + "fmt" + "github.com/containernetworking/cni/pkg/invoke" + "github.com/containernetworking/cni/pkg/skel" + "github.com/containernetworking/cni/pkg/types" + "os" +) + +func doCmdAdd(args *skel.CmdArgs, n *NetConf, fenv *subnetEnv) error { + n.Delegate["name"] = n.Name + + if !hasKey(n.Delegate, "type") { + n.Delegate["type"] = "bridge" + } + + if !hasKey(n.Delegate, "ipMasq") { + // if flannel is not doing ipmasq, we should + ipmasq := !*fenv.ipmasq + n.Delegate["ipMasq"] = ipmasq + } + + if !hasKey(n.Delegate, "mtu") { + mtu := fenv.mtu + n.Delegate["mtu"] = mtu + } + + if n.Delegate["type"].(string) == "bridge" { + if !hasKey(n.Delegate, "isGateway") { + n.Delegate["isGateway"] = true + } + } + if n.CNIVersion != "" { + n.Delegate["cniVersion"] = n.CNIVersion + } + + n.Delegate["ipam"] = map[string]interface{}{ + "type": "host-local", + "subnet": fenv.sn.String(), + "routes": []types.Route{ + { + Dst: *fenv.nw, + }, + }, + } + + return delegateAdd(args.ContainerID, n.DataDir, n.Delegate) +} + +func doCmdDel(args *skel.CmdArgs, n *NetConf) error { + netconfBytes, err := consumeScratchNetConf(args.ContainerID, n.DataDir) + if err != nil { + if os.IsNotExist(err) { + // Per spec should ignore error if resources are missing / already removed + return nil + } + return err + } + + nc := &types.NetConf{} + if err = json.Unmarshal(netconfBytes, nc); err != nil { + return fmt.Errorf("failed to parse netconf: %v", err) + } + + return invoke.DelegateDel(nc.Type, netconfBytes, nil) +} diff --git a/plugins/meta/flannel/flannel_windows.go b/plugins/meta/flannel/flannel_windows.go new file mode 100644 index 000000000..fb0149a0c --- /dev/null +++ b/plugins/meta/flannel/flannel_windows.go @@ -0,0 +1,85 @@ +// Copyright 2018 CNI authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// This is a "meta-plugin". It reads in its own netconf, combines it with +// the data from flannel generated subnet file and then invokes a plugin +// like bridge or ipvlan to do the real work. + +package main + +import ( + "encoding/json" + "fmt" + "github.com/containernetworking/cni/pkg/invoke" + "github.com/containernetworking/cni/pkg/skel" + "github.com/containernetworking/cni/pkg/types" + "github.com/containernetworking/cni/pkg/types/020" + "github.com/containernetworking/plugins/pkg/hns" + "os" +) + +func doCmdAdd(args *skel.CmdArgs, n *NetConf, fenv *subnetEnv) error { + n.Delegate["name"] = n.Name + + if !hasKey(n.Delegate, "type") { + n.Delegate["type"] = "win-l2bridge" + } + + // if flannel needs ipmasq - get the plugin to configure it + // (this is the opposite of how linux works - on linux the flannel daemon configure ipmasq) + if hasKey(n.Delegate, "ipMasq") { + n.Delegate["ipMasq"] = *fenv.ipmasq + } + + n.Delegate["cniVersion"] = types020.ImplementedSpecVersion + if n.CNIVersion != "" { + n.Delegate["cniVersion"] = n.CNIVersion + } + + switch n.Delegate["type"] { + case "win-l2bridge": + delete(n.Delegate, "endpointMacPrefix") + n.Delegate["clusterNetworkPrefix"] = fenv.nw.String() + case "win-overlay": + delete(n.Delegate, "clusterNetworkPrefix") + if !hasKey(n.Delegate, "ipMasq") { + n.Delegate["endpointMacPrefix"] = "0E-2A" + } + + } + n.Delegate["ipam"] = map[string]interface{}{ + "type": "host-local", + "subnet": fenv.sn.String(), + } + + return delegateAdd(hns.GetSandboxContainerID(args.ContainerID, args.Netns), n.DataDir, n.Delegate) +} + +func doCmdDel(args *skel.CmdArgs, n *NetConf) error { + netconfBytes, err := consumeScratchNetConf(hns.GetSandboxContainerID(args.ContainerID, args.Netns), n.DataDir) + if err != nil { + if os.IsNotExist(err) { + // Per spec should ignore error if resources are missing / already removed + return nil + } + return err + } + + nc := &types.NetConf{} + if err = json.Unmarshal(netconfBytes, nc); err != nil { + return fmt.Errorf("failed to parse netconf: %v", err) + } + + return invoke.DelegateDel(nc.Type, netconfBytes, nil) +}