-
Notifications
You must be signed in to change notification settings - Fork 49
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
302 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package main | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"net" | ||
|
||
"github.com/containernetworking/cni/pkg/types" | ||
) | ||
|
||
// IPAMConfig represents the IP related network configuration. | ||
type IPAMConfig struct { | ||
Name string | ||
Type string `json:"type"` | ||
Subnet types.IPNet `json:"subnet"` | ||
Gateway net.IP `json:"gateway"` | ||
Routes []types.Route `json:"routes"` | ||
Args *IPAMArgs `json:"-"` | ||
} | ||
|
||
type IPAMArgs struct { | ||
types.CommonArgs | ||
IP net.IP `json:"ip,omitempty"` | ||
} | ||
|
||
type Net struct { | ||
Name string `json:"name"` | ||
IPAM *IPAMConfig `json:"ipam"` | ||
} | ||
|
||
// NewIPAMConfig creates a NetworkConfig from the given network name. | ||
func LoadIPAMConfig(bytes []byte, args string) (*IPAMConfig, error) { | ||
n := Net{} | ||
if err := json.Unmarshal(bytes, &n); err != nil { | ||
return nil, err | ||
} | ||
|
||
if args != "" { | ||
n.IPAM.Args = &IPAMArgs{} | ||
err := types.LoadArgs(args, n.IPAM.Args) | ||
if err != nil { | ||
return nil, err | ||
} | ||
} | ||
|
||
if n.IPAM == nil { | ||
return nil, fmt.Errorf("IPAM config missing 'ipam' key") | ||
} | ||
|
||
// Copy net name into IPAM so not to drag Net struct around | ||
n.IPAM.Name = n.Name | ||
|
||
return n.IPAM, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"github.com/containernetworking/cni/pkg/skel" | ||
"github.com/containernetworking/cni/pkg/types" | ||
"net" | ||
) | ||
|
||
func main() { | ||
skel.PluginMain(cmdAdd, cmdDel) | ||
} | ||
|
||
func validateRangeIP(ip net.IP, ipnet *net.IPNet) error { | ||
if !ipnet.Contains(ip) { | ||
return fmt.Errorf("%s not in network: %s", ip, ipnet) | ||
} | ||
return nil | ||
} | ||
|
||
func cmdAdd(args *skel.CmdArgs) error { | ||
ipamConf, err := LoadIPAMConfig(args.StdinData, args.Args) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
var requestIP net.IP | ||
if ipamConf.Args != nil { | ||
requestIP = ipamConf.Args.IP | ||
} | ||
|
||
if requestIP == nil { | ||
return fmt.Errorf("request IP can not be empty") | ||
} | ||
|
||
gw := ipamConf.Gateway | ||
|
||
if gw == nil { | ||
return fmt.Errorf("gateway can not be empty") | ||
} | ||
|
||
if gw != nil && gw.Equal(ipamConf.Args.IP) { | ||
return fmt.Errorf("requested IP must differ gateway IP") | ||
} | ||
|
||
subnet := net.IPNet{ | ||
IP: ipamConf.Subnet.IP, | ||
Mask: ipamConf.Subnet.Mask, | ||
} | ||
err = validateRangeIP(requestIP, &subnet) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
ipConf := &types.IPConfig{ | ||
IP: net.IPNet{IP: requestIP, Mask: ipamConf.Subnet.Mask}, | ||
Gateway: gw, | ||
Routes: ipamConf.Routes, | ||
} | ||
r := &types.Result{ | ||
IP4: ipConf, | ||
} | ||
return r.Print() | ||
} | ||
|
||
func cmdDel(args *skel.CmdArgs) error { | ||
_, err := LoadIPAMConfig(args.StdinData, args.Args) | ||
if err != nil { | ||
return err | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
#!/bin/bash | ||
|
||
# Run a docker container with network namespace set up by the | ||
# CNI plugins. | ||
|
||
# Example usage: ./docker-run.sh --rm busybox /sbin/ifconfig | ||
|
||
contid=$(docker run -d --net=none busybox:latest /bin/sleep 10000000) | ||
pid=$(docker inspect -f '{{ .State.Pid }}' $contid) | ||
netnspath=/proc/$pid/ns/net | ||
|
||
./exec-plugins.sh add $contid $netnspath | ||
|
||
function cleanup() { | ||
./exec-plugins.sh del $contid $netnspath | ||
docker kill $contid >/dev/null | ||
} | ||
trap cleanup EXIT | ||
|
||
docker run --net=container:$contid $@ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
#!/usr/bin/env bash | ||
|
||
if [[ ${DEBUG} -gt 0 ]]; then set -x; fi | ||
|
||
NETCONFPATH=${NETCONFPATH-/etc/cni/net.d} | ||
|
||
function exec_plugins() { | ||
i=0 | ||
contid=$2 | ||
netns=$3 | ||
export CNI_COMMAND=$(echo $1 | tr '[:lower:]' '[:upper:]') | ||
export PATH=$CNI_PATH:$PATH | ||
export CNI_CONTAINERID=$contid | ||
export CNI_NETNS=$netns | ||
|
||
for netconf in $(echo $NETCONFPATH/*.conf | sort); do | ||
name=$(jq -r '.name' <$netconf) | ||
plugin=$(jq -r '.type' <$netconf) | ||
export CNI_IFNAME=$(printf eth%d $i) | ||
|
||
res=$($plugin <$netconf) | ||
if [ $? -ne 0 ]; then | ||
errmsg=$(echo $res | jq -r '.msg') | ||
if [ -z "$errmsg" ]; then | ||
errmsg=$res | ||
fi | ||
|
||
echo "${name} : error executing $CNI_COMMAND: $errmsg" | ||
exit 1 | ||
elif [[ ${DEBUG} -gt 0 ]]; then | ||
echo ${res} | jq -r . | ||
fi | ||
|
||
let "i=i+1" | ||
done | ||
} | ||
|
||
if [ $# -ne 3 ]; then | ||
echo "Usage: $0 add|del CONTAINER-ID NETNS-PATH" | ||
echo " Adds or deletes the container specified by NETNS-PATH to the networks" | ||
echo " specified in \$NETCONFPATH directory" | ||
exit 1 | ||
fi | ||
|
||
exec_plugins $1 $2 $3 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
#!/usr/bin/env bash | ||
set -e | ||
if [[ ${DEBUG} -gt 0 ]]; then set -x; fi | ||
|
||
# Run a command in a private network namespace | ||
# set up by CNI plugins | ||
contid=$(printf '%x%x%x%x' $RANDOM $RANDOM $RANDOM $RANDOM) | ||
netnspath=/var/run/netns/$contid | ||
|
||
ip netns add $contid | ||
./exec-plugins.sh add $contid $netnspath | ||
|
||
|
||
function cleanup() { | ||
./exec-plugins.sh del $contid $netnspath | ||
ip netns delete $contid | ||
} | ||
trap cleanup EXIT | ||
|
||
ip netns exec $contid "$@" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
#!/usr/bin/env bash | ||
# | ||
# Run all CNI tests | ||
# ./test | ||
# ./test -v | ||
# | ||
# Run tests for one package | ||
# PKG=./sriov ./test | ||
# | ||
set -e | ||
|
||
source ./build | ||
|
||
TESTABLE="sriov" | ||
FORMATTABLE="$TESTABLE fixipam" | ||
|
||
# user has not provided PKG override | ||
if [ -z "$PKG" ]; then | ||
TEST=$TESTABLE | ||
FMT=$FORMATTABLE | ||
|
||
# user has provided PKG override | ||
else | ||
# strip out slashes and dots from PKG=./foo/ | ||
TEST=${PKG//\//} | ||
TEST=${TEST//./} | ||
|
||
# only run gofmt on packages provided by user | ||
FMT="$TEST" | ||
fi | ||
|
||
# split TEST into an array and prepend REPO_PATH to each local package | ||
split=(${TEST// / }) | ||
TEST=${split[@]/#/${REPO_PATH}/} | ||
|
||
echo -n "Running tests " | ||
function testrun { | ||
sudo -E bash -c "umask 0; PATH=$GOROOT/bin:$GOBIN:$PATH go test -covermode set $@" | ||
} | ||
if [ ! -z "${COVERALLS}" ]; then | ||
echo "with coverage profile generation..." | ||
i=0 | ||
for t in ${TEST}; do | ||
testrun "-coverprofile ${i}.coverprofile ${t}" | ||
i=$((i+1)) | ||
done | ||
gover | ||
goveralls -service=travis-ci -coverprofile=gover.coverprofile -repotoken=$COVERALLS_TOKEN | ||
else | ||
echo "without coverage profile generation..." | ||
testrun "${TEST}" | ||
fi | ||
|
||
echo "Checking gofmt..." | ||
fmtRes=$(gofmt -l $FMT) | ||
if [ -n "${fmtRes}" ]; then | ||
echo -e "gofmt checking failed:\n${fmtRes}" | ||
exit 255 | ||
fi | ||
|
||
echo "Checking govet..." | ||
vetRes=$(go vet $TEST) | ||
if [ -n "${vetRes}" ]; then | ||
echo -e "govet checking failed:\n${vetRes}" | ||
exit 255 | ||
fi | ||
|
||
#echo "Checking license header..." | ||
#licRes=$( | ||
# for file in $(find . -type f -iname '*.go' ! -path './vendor/*'); do | ||
# head -n1 "${file}" | grep -Eq "(Copyright|generated)" || echo -e " ${file}" | ||
# done | ||
#) | ||
#if [ -n "${licRes}" ]; then | ||
# echo -e "license header checking failed:\n${licRes}" | ||
# exit 255 | ||
#fi | ||
|
||
|
||
echo "Success" |