Skip to content

Commit ed18059

Browse files
rakelkarmadhanrm
authored andcommitted
This commit has the following changes
+ windows cni plugins are added (*) hostgw (*) overlay vxlan + windows netconf unit test + Fix appveyor config to run the test + Vendor commit for (*) github.com/Microsoft/hcsshim (*) golang.org/x/sys + Build Release support for windows plugins
1 parent 2b8b1ac commit ed18059

File tree

332 files changed

+79255
-23183
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

332 files changed

+79255
-23183
lines changed

.appveyor.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ environment:
66
install:
77
- echo %PATH%
88
- echo %GOPATH%
9-
- set PATH=%GOPATH%\bin;c:\go\bin;%PATH%
109
- go version
1110
- go env
12-
11+
- ps: $webClient = New-Object System.Net.WebClient; $InstallPath="c:" ; $webClient.DownloadFile("https://raw.githubusercontent.com/jhowardmsft/docker-tdmgcc/master/gcc.zip", "$InstallPath\gcc.zip"); Expand-Archive $InstallPath\gcc.zip -DestinationPath $InstallPath\gcc -Force; $webClient.DownloadFile("https://raw.githubusercontent.com/jhowardmsft/docker-tdmgcc/master/runtime.zip", "$InstallPath\runtime.zip"); Expand-Archive $InstallPath\runtime.zip -DestinationPath $InstallPath\gcc -Force; $webClient.DownloadFile("https://raw.githubusercontent.com/jhowardmsft/docker-tdmgcc/master/binutils.zip","$InstallPath\binutils.zip"); Expand-Archive $InstallPath\binutils.zip -DestinationPath $InstallPath\gcc -Force;
12+
- set PATH=%GOPATH%\bin;c:\go\bin;c:\gcc\bin;%PATH%
1313
build: off
1414

1515
test_script:

Godeps/Godeps.json

+25-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ Some CNI network plugins, maintained by the containernetworking team. For more i
1212
* `macvlan`: Creates a new MAC address, forwards all traffic to that to the container
1313
* `ptp`: Creates a veth pair.
1414
* `vlan`: Allocates a vlan device.
15-
15+
#### Windows: windows specific
16+
* `l2bridge`: Creates a bridge, adds the host and the container to it.
17+
* `overlay`: Creates an overlay interface to the container
1618
### IPAM: IP address allocation
1719
* `dhcp`: Runs a daemon on the host to make DHCP requests on behalf of the container
1820
* `host-local`: maintains a local database of allocated IPs

build.sh

+11-3
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,20 @@ export GO="${GO:-go}"
1919

2020
mkdir -p "${PWD}/bin"
2121

22-
echo "Building plugins"
22+
echo "Building plugins ${GOOS}"
2323
PLUGINS="plugins/meta/* plugins/main/* plugins/ipam/* plugins/sample"
2424
for d in $PLUGINS; do
2525
if [ -d "$d" ]; then
2626
plugin="$(basename "$d")"
27-
echo " $plugin"
28-
$GO build -o "${PWD}/bin/$plugin" "$@" "$REPO_PATH"/$d
27+
if [ $plugin == "windows" ]
28+
then
29+
if [ "$GOARCH" == "amd64" ]
30+
then
31+
GOOS=windows . $d/build.sh
32+
fi
33+
else
34+
echo " $plugin"
35+
$GO build -o "${PWD}/bin/$plugin" "$@" "$REPO_PATH"/$d
36+
fi
2937
fi
3038
done

pkg/hns/endpoint_windows.go

+149
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
// +build windows
2+
3+
// Copyright 2017 CNI authors
4+
//
5+
// Licensed under the Apache License, Version 2.0 (the "License");
6+
// you may not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing, software
12+
// distributed under the License is distributed on an "AS IS" BASIS,
13+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
// See the License for the specific language governing permissions and
15+
// limitations under the License.
16+
17+
package hns
18+
19+
import (
20+
"fmt"
21+
"log"
22+
"net"
23+
"strings"
24+
25+
"github.com/Microsoft/hcsshim"
26+
"github.com/containernetworking/cni/pkg/types/current"
27+
)
28+
29+
// ConstructEndpointName constructs enpointId which is used to identify an endpoint from HNS
30+
// There is a special consideration for netNs name here, which is required for Windows Server 1709
31+
// containerID is the Id of the container on which the endpoint is worked on
32+
func ConstructEndpointName(containerID string, netNs string, networkName string) string {
33+
if netNs != "" {
34+
splits := strings.Split(netNs, ":")
35+
if len(splits) == 2 {
36+
containerID = splits[1]
37+
}
38+
}
39+
epName := containerID + "_" + networkName
40+
return epName
41+
}
42+
43+
// DeprovisionEndpoint removes an endpoint from the container by sending a Detach request to HNS
44+
// For shared endpoint, ContainerDetach is used
45+
// for removing the endpoint completely, HotDetachEndpoint is used
46+
func DeprovisionEndpoint(epName string, netns string, containerID string) error {
47+
hnsEndpoint, err := hcsshim.GetHNSEndpointByName(epName)
48+
if err != nil {
49+
log.Printf("[win-cni] Failed to find endpoint %v, err:%v", epName, err)
50+
return err
51+
}
52+
53+
if netns != "none" {
54+
// Shared endpoint removal. Do not remove the endpoint.
55+
err := hnsEndpoint.ContainerDetach(containerID)
56+
if err != nil {
57+
log.Printf("[win-cni] Failed to detach the container endpoint %v, err:%v", epName, err)
58+
}
59+
return nil
60+
}
61+
62+
err = hcsshim.HotDetachEndpoint(containerID, hnsEndpoint.Id)
63+
if err != nil {
64+
log.Printf("[win-cni] Failed to detach endpoint %v, err:%v", epName, err)
65+
// Do not consider this as failure, else this would leak endpoints
66+
}
67+
68+
_, err = hnsEndpoint.Delete()
69+
if err != nil {
70+
log.Printf("[win-cni] Failed to delete endpoint %v, err:%v", epName, err)
71+
// Do not return error
72+
}
73+
74+
return nil
75+
}
76+
77+
type EndpointMakerFunc func() (*hcsshim.HNSEndpoint, error)
78+
79+
// ProvisionEndpoint provisions an endpoint to a container specified by containerID.
80+
// If an endpoint already exists, the endpoint is reused.
81+
// This call is idempotent
82+
func ProvisionEndpoint(epName string, expectedNetworkId string, containerID string, makeEndpoint EndpointMakerFunc) (*hcsshim.HNSEndpoint, error) {
83+
// check if endpoint already exists
84+
createEndpoint := true
85+
hnsEndpoint, err := hcsshim.GetHNSEndpointByName(epName)
86+
if hnsEndpoint != nil && hnsEndpoint.VirtualNetwork == expectedNetworkId {
87+
log.Printf("[win-cni] Found existing endpoint %v", epName)
88+
createEndpoint = false
89+
}
90+
91+
if createEndpoint {
92+
if hnsEndpoint != nil {
93+
_, err = hnsEndpoint.Delete()
94+
if err != nil {
95+
log.Printf("[win-cni] Failed to delete stale endpoint %v, err:%v", epName, err)
96+
}
97+
}
98+
99+
if hnsEndpoint, err = makeEndpoint(); err != nil {
100+
return nil, err
101+
}
102+
103+
if hnsEndpoint, err = hnsEndpoint.Create(); err != nil {
104+
return nil, err
105+
}
106+
107+
}
108+
109+
// hot attach
110+
if err = hcsshim.HotAttachEndpoint(containerID, hnsEndpoint.Id); err != nil {
111+
return nil, err
112+
}
113+
114+
return hnsEndpoint, nil
115+
}
116+
117+
// ConstructResult constructs the CNI result for the endpoint
118+
func ConstructResult(hnsNetwork *hcsshim.HNSNetwork, hnsEndpoint *hcsshim.HNSEndpoint) (*current.Result, error) {
119+
resultInterface := &current.Interface{
120+
Name: hnsEndpoint.Name,
121+
Mac: hnsEndpoint.MacAddress,
122+
}
123+
_, ipSubnet, err := net.ParseCIDR(hnsNetwork.Subnets[0].AddressPrefix)
124+
if err != nil {
125+
return nil, err
126+
}
127+
128+
var ipVersion string
129+
if ipv4 := hnsEndpoint.IPAddress.To4(); ipv4 != nil {
130+
ipVersion = "4"
131+
} else if ipv6 := hnsEndpoint.IPAddress.To16(); ipv6 != nil {
132+
ipVersion = "6"
133+
} else {
134+
return nil, fmt.Errorf("[win-cni] The IPAddress of hnsEndpoint isn't a valid ipv4 or ipv6 Address.")
135+
}
136+
137+
resultIPConfig := &current.IPConfig{
138+
Version: ipVersion,
139+
Address: net.IPNet{
140+
IP: hnsEndpoint.IPAddress,
141+
Mask: ipSubnet.Mask},
142+
Gateway: net.ParseIP(hnsEndpoint.GatewayAddress),
143+
}
144+
result := &current.Result{}
145+
result.Interfaces = []*current.Interface{resultInterface}
146+
result.IPs = []*current.IPConfig{resultIPConfig}
147+
148+
return result, nil
149+
}

pkg/hns/netconf.go

+142
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
// Copyright 2017 CNI authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package hns
16+
17+
import (
18+
"encoding/json"
19+
"github.com/containernetworking/cni/pkg/types"
20+
"strings"
21+
)
22+
23+
// NetConf is the CNI spec
24+
type NetConf struct {
25+
types.NetConf
26+
AdditionalArgs []policyArgument `json:"AdditionalArgs,omitempty"`
27+
}
28+
29+
type policyArgument struct {
30+
Name string
31+
Value map[string]interface{}
32+
}
33+
34+
// MarshalPolicies converts the Endpoint policies in AdditionalArgs
35+
// to HNS specific policies as Json raw bytes
36+
func (n *NetConf) MarshalPolicies() []json.RawMessage {
37+
if n.AdditionalArgs == nil {
38+
n.AdditionalArgs = []policyArgument{}
39+
}
40+
41+
var result []json.RawMessage
42+
for _, policyArg := range n.AdditionalArgs {
43+
if !strings.EqualFold(policyArg.Name, "EndpointPolicy") {
44+
continue
45+
}
46+
if data, err := json.Marshal(policyArg.Value); err == nil {
47+
result = append(result, data)
48+
}
49+
}
50+
51+
return result
52+
}
53+
54+
// ApplyOutboundNatPolicy applies NAT Policy in VFP using HNS
55+
// Simultaneously an exception is added for the network that has to be Nat'd
56+
func (n *NetConf) ApplyOutboundNatPolicy(nwToNat string) {
57+
if n.AdditionalArgs == nil {
58+
n.AdditionalArgs = []policyArgument{}
59+
}
60+
61+
for _, policy := range n.AdditionalArgs {
62+
if !strings.EqualFold(policy.Name, "EndpointPolicy") {
63+
continue
64+
}
65+
66+
pv := policy.Value
67+
if !hasKey(pv, "Type") {
68+
continue
69+
}
70+
71+
if !strings.EqualFold(pv["Type"].(string), "OutBoundNAT") {
72+
continue
73+
}
74+
75+
if !hasKey(pv, "ExceptionList") {
76+
// add the exception since there weren't any
77+
pv["ExceptionList"] = []interface{}{nwToNat}
78+
return
79+
}
80+
81+
nets := pv["ExceptionList"].([]interface{})
82+
for _, net := range nets {
83+
if net.(string) == nwToNat {
84+
// found it - do nothing
85+
return
86+
}
87+
}
88+
89+
// its not in the list of exceptions, add it and we're done
90+
pv["ExceptionList"] = append(nets, nwToNat)
91+
return
92+
}
93+
94+
// didn't find the policy, add it
95+
natEntry := policyArgument{
96+
Name: "EndpointPolicy",
97+
Value: map[string]interface{}{
98+
"Type": "OutBoundNAT",
99+
"ExceptionList": []interface{}{
100+
nwToNat,
101+
},
102+
},
103+
}
104+
105+
n.AdditionalArgs = append(n.AdditionalArgs, natEntry)
106+
}
107+
108+
// ApplyDefaultPAPolicy is used to configure a endpoint PA policy in HNS
109+
func (n *NetConf) ApplyDefaultPAPolicy(paAddress string) {
110+
if n.AdditionalArgs == nil {
111+
n.AdditionalArgs = []policyArgument{}
112+
}
113+
114+
// if its already present, leave untouched
115+
for _, policy := range n.AdditionalArgs {
116+
if policy.Name == "EndpointPolicy" {
117+
if hasKey(policy.Value, "PA") {
118+
// found it, don't override
119+
return
120+
}
121+
}
122+
}
123+
124+
// did not find, add it now
125+
paPolicyData := map[string]interface{}{
126+
"Type": "PA",
127+
"PA": paAddress,
128+
}
129+
paPolicy := &policyArgument{
130+
Name: "EndpointPolicy",
131+
Value: paPolicyData,
132+
}
133+
134+
n.AdditionalArgs = append(n.AdditionalArgs, *paPolicy)
135+
136+
return
137+
}
138+
139+
func hasKey(m map[string]interface{}, k string) bool {
140+
_, ok := m[k]
141+
return ok
142+
}

0 commit comments

Comments
 (0)