language: go
+sudo: required
go:
- 1.4
- go get ${TOOLS_CMD}/vet
script:
- - ./test
+ - sudo -E /bin/bash -c 'PATH=$GOROOT/bin:$PATH ./test'
+
+notifications:
+ email: false
{
"ImportPath": "github.com/appc/cni",
- "GoVersion": "go1.5.3",
+ "GoVersion": "go1.4.2",
"Packages": [
"./..."
],
Please see Documentation/ folder for documentation about particular plugins.
## Running the plugins
-The scripts/ directory contains two scripts, priv-net-run.sh and docker-run.sh, that can be used to exercise the plugins.
+The scripts/ directory contains two scripts, `priv-net-run.sh` and `docker-run.sh`, that can be used to exercise the plugins.
+
+**note - priv-net-run.sh depends on `jq`**
Start out by creating a netconf file to describe a network:
}
}
EOF
+$ cat >/etc/cni/net.d/99-loopback.conf <<EOF
+{
+ "type": "loopback"
+}
+EOF
```
The directory `/etc/cni/net.d` is the default location in which the scripts will look for net configurations.
--- /dev/null
+package main
+
+import (
+ "os"
+
+ "github.com/appc/cni/pkg/ns"
+ "github.com/appc/cni/pkg/skel"
+ "github.com/vishvananda/netlink"
+)
+
+func cmdAdd(args *skel.CmdArgs) error {
+ args.IfName = "lo" // ignore config, this only works for loopback
+ err := ns.WithNetNSPath(args.Netns, false, func(hostNS *os.File) error {
+ link, err := netlink.LinkByName(args.IfName)
+ if err != nil {
+ return err // not tested
+ }
+
+ err = netlink.LinkSetUp(link)
+ if err != nil {
+ return err // not tested
+ }
+
+ return nil
+ })
+ if err != nil {
+ return err // not tested
+ }
+
+ return nil
+}
+
+func cmdDel(args *skel.CmdArgs) error {
+ // del does nothing, we're going to destroy the device anyway
+ return nil
+}
+
+func main() {
+ skel.PluginMain(cmdAdd, cmdDel)
+}
--- /dev/null
+package main_test
+
+import (
+ "os"
+
+ "github.com/onsi/gomega/gexec"
+
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+
+ "testing"
+
+ "golang.org/x/sys/unix"
+)
+
+var pathToLoPlugin string
+
+func TestLoopback(t *testing.T) {
+ RegisterFailHandler(Fail)
+ RunSpecs(t, "Loopback Suite")
+}
+
+var _ = BeforeSuite(func() {
+ var err error
+ pathToLoPlugin, err = gexec.Build("github.com/appc/cni/plugins/main/loopback")
+ Expect(err).NotTo(HaveOccurred())
+})
+
+var _ = AfterSuite(func() {
+ gexec.CleanupBuildArtifacts()
+})
+
+func makeNetworkNS(containerID string) string {
+ namespace := "/var/run/netns/" + containerID
+
+ err := os.MkdirAll("/var/run/netns", 0600)
+ Expect(err).NotTo(HaveOccurred())
+
+ err = unix.Unshare(unix.CLONE_NEWNET)
+ Expect(err).NotTo(HaveOccurred())
+
+ fd, err := os.Create(namespace)
+ Expect(err).NotTo(HaveOccurred())
+ defer fd.Close()
+
+ err = unix.Mount("/proc/self/ns/net", namespace, "none", unix.MS_BIND, "")
+ Expect(err).NotTo(HaveOccurred())
+
+ Expect(namespace).To(BeAnExistingFile())
+ return namespace
+}
+
+func removeNetworkNS(networkNS string) error {
+ err := unix.Unmount(networkNS, unix.MNT_DETACH)
+
+ err = os.RemoveAll(networkNS)
+ return err
+}
--- /dev/null
+package main_test
+
+import (
+ "fmt"
+ "net"
+ "os"
+ "os/exec"
+ "strings"
+
+ "github.com/appc/cni/pkg/ns"
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+ "github.com/onsi/gomega/gexec"
+)
+
+var _ = Describe("Loopback", func() {
+ var (
+ networkNS string
+ containerID string
+ command *exec.Cmd
+ )
+
+ BeforeEach(func() {
+ command = exec.Command(pathToLoPlugin)
+
+ environ := os.Environ()
+
+ containerID = "some-container-id"
+ networkNS = makeNetworkNS(containerID)
+
+ cniEnvVars := []string{
+ fmt.Sprintf("CNI_COMMAND=%s", "ADD"),
+ fmt.Sprintf("CNI_CONTAINERID=%s", containerID),
+ fmt.Sprintf("CNI_NETNS=%s", networkNS),
+ fmt.Sprintf("CNI_IFNAME=%s", "this is ignored"),
+ fmt.Sprintf("CNI_ARGS=%s", "none"),
+ fmt.Sprintf("CNI_PATH=%s", "/some/test/path"),
+ }
+
+ for _, v := range cniEnvVars {
+ environ = append(environ, v)
+ }
+
+ command.Env = environ
+ command.Stdin = strings.NewReader("this doesn't matter")
+ })
+
+ AfterEach(func() {
+ Expect(removeNetworkNS(networkNS)).To(Succeed())
+ })
+
+ Context("when given a network namespace", func() {
+ It("sets the lo device to UP", func() {
+ session, err := gexec.Start(command, GinkgoWriter, GinkgoWriter)
+ Expect(err).NotTo(HaveOccurred())
+
+ Eventually(session).Should(gexec.Exit(0))
+
+ var lo *net.Interface
+ err = ns.WithNetNSPath(networkNS, false, func(hostNS *os.File) error {
+ var err error
+ lo, err = net.InterfaceByName("lo")
+ return err
+ })
+ Expect(err).NotTo(HaveOccurred())
+
+ Expect(lo.Flags & net.FlagUp).To(Equal(net.FlagUp))
+ })
+ })
+})
netnspath=/var/run/netns/$contid
ip netns add $contid
-ip netns exec $contid ip link set lo up
./exec-plugins.sh add $contid $netnspath