Create a plugin for up'ing a lo device
- Believe we need sudo to create netns - Use syscall instead of relying on ip netns - Add sudo to .travis.yml - Needs more -E - Revert Godeps GoVersion to 1.4.2 - in travis, test command is run with all necessary env vars - Loopback plugin only works on 'lo' interface - Update README, add loopback plugin config - note script dependency on jq Signed-off-by: Gabe Rosenhouse <grosenhouse@pivotal.io>
This commit is contained in:
parent
ebd5be8475
commit
2708bdf2f5
@ -1,4 +1,5 @@
|
||||
language: go
|
||||
sudo: required
|
||||
|
||||
go:
|
||||
- 1.4
|
||||
@ -12,4 +13,7 @@ install:
|
||||
- go get ${TOOLS_CMD}/vet
|
||||
|
||||
script:
|
||||
- ./test
|
||||
- sudo -E /bin/bash -c 'PATH=$GOROOT/bin:$PATH ./test'
|
||||
|
||||
notifications:
|
||||
email: false
|
||||
|
2
Godeps/Godeps.json
generated
2
Godeps/Godeps.json
generated
@ -1,6 +1,6 @@
|
||||
{
|
||||
"ImportPath": "github.com/appc/cni",
|
||||
"GoVersion": "go1.5.3",
|
||||
"GoVersion": "go1.4.2",
|
||||
"Packages": [
|
||||
"./..."
|
||||
],
|
||||
|
@ -24,7 +24,9 @@ This repository includes a number of common plugins that can be found in plugins
|
||||
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:
|
||||
|
||||
@ -46,6 +48,11 @@ $ cat >/etc/cni/net.d/10-mynet.conf <<EOF
|
||||
}
|
||||
}
|
||||
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.
|
||||
|
40
plugins/main/loopback/loopback.go
Normal file
40
plugins/main/loopback/loopback.go
Normal file
@ -0,0 +1,40 @@
|
||||
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)
|
||||
}
|
58
plugins/main/loopback/loopback_suite_test.go
Normal file
58
plugins/main/loopback/loopback_suite_test.go
Normal file
@ -0,0 +1,58 @@
|
||||
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
|
||||
}
|
70
plugins/main/loopback/loopback_test.go
Normal file
70
plugins/main/loopback/loopback_test.go
Normal file
@ -0,0 +1,70 @@
|
||||
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))
|
||||
})
|
||||
})
|
||||
})
|
@ -8,7 +8,6 @@ contid=$(printf '%x%x%x%x' $RANDOM $RANDOM $RANDOM $RANDOM)
|
||||
netnspath=/var/run/netns/$contid
|
||||
|
||||
ip netns add $contid
|
||||
ip netns exec $contid ip link set lo up
|
||||
./exec-plugins.sh add $contid $netnspath
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user