add DHCP IPAM plugin
authorEugene Yakubovich <eugene.yakubovich@coreos.com>
Tue, 19 May 2015 19:02:41 +0000 (12:02 -0700)
committerEugene Yakubovich <eugene.yakubovich@coreos.com>
Thu, 21 May 2015 20:36:51 +0000 (13:36 -0700)
The plugin binary actually functions in two modes. The first mode
is a regular CNI plugin. The second mode (when stared with "daemon" arg)
runs a DHCP client daemon. When executed as a CNI plugin, it issues
an RPC request to the daemon for actual processing. The daemon is
required since a DHCP lease needs to be maintained by periodically
renewing it. One instance of the daemon can server arbitrary number
of containers/leases.

ns/ns.go

index 82291f9..20548b9 100644 (file)
--- a/ns/ns.go
+++ b/ns/ns.go
@@ -48,19 +48,30 @@ func SetNS(f *os.File, flags uintptr) error {
 
 // WithNetNSPath executes the passed closure under the given network
 // namespace, restoring the original namespace afterwards.
-func WithNetNSPath(nspath string, f func(*os.File) error) error {
+// Changing namespaces must be done on a goroutine that has been
+// locked to an OS thread. If lockThread arg is true, this function
+// locks the goroutine prior to change namespace and unlocks before
+// returning
+func WithNetNSPath(nspath string, lockThread bool, f func(*os.File) error) error {
        ns, err := os.Open(nspath)
        if err != nil {
                return fmt.Errorf("Failed to open %v: %v", nspath, err)
        }
        defer ns.Close()
-
-       return WithNetNS(ns, f)
+       return WithNetNS(ns, lockThread, f)
 }
 
 // WithNetNS executes the passed closure under the given network
 // namespace, restoring the original namespace afterwards.
-func WithNetNS(ns *os.File, f func(*os.File) error) error {
+// Changing namespaces must be done on a goroutine that has been
+// locked to an OS thread. If lockThread arg is true, this function
+// locks the goroutine prior to change namespace and unlocks before
+// returning
+func WithNetNS(ns *os.File, lockThread bool, f func(*os.File) error) error {
+       if lockThread {
+               runtime.LockOSThread()
+               defer runtime.UnlockOSThread()
+       }
        // save a handle to current (host) network namespace
        thisNS, err := os.Open("/proc/self/ns/net")
        if err != nil {