diff --git a/plugin/ipam/cni.go b/plugin/ipam/cni.go index 8abcabcd..a5d407b8 100644 --- a/plugin/ipam/cni.go +++ b/plugin/ipam/cni.go @@ -10,10 +10,18 @@ import ( ) func (i *Ipam) CmdAdd(args *skel.CmdArgs) error { + result, err := i.Allocate(args) + if err != nil { + return err + } + return result.Print() +} + +func (i *Ipam) Allocate(args *skel.CmdArgs) (*types.Result, error) { // extract the things we care about conf, err := loadIPAMConf(args.StdinData) if err != nil { - return err + return nil, err } if conf == nil { conf = &ipamConf{} @@ -27,25 +35,29 @@ func (i *Ipam) CmdAdd(args *skel.CmdArgs) error { var subnet *net.IPNet subnet, err = types.ParseCIDR(conf.Subnet) if err != nil { - return fmt.Errorf("subnet given in config, but not parseable: %s", err) + return nil, fmt.Errorf("subnet given in config, but not parseable: %s", err) } ipnet, err = i.weave.AllocateIPInSubnet(containerID, subnet) } if err != nil { - return err + return nil, err } - result := types.Result{ + result := &types.Result{ IP4: &types.IPConfig{ IP: *ipnet, Gateway: conf.Gateway, Routes: conf.Routes, }, } - return result.Print() + return result, nil } func (i *Ipam) CmdDel(args *skel.CmdArgs) error { + return i.Release(args) +} + +func (i *Ipam) Release(args *skel.CmdArgs) error { return i.weave.ReleaseIPsFor(args.ContainerID) } diff --git a/plugin/net/driver.go b/plugin/net/driver.go index 3c0f76b0..034721c8 100644 --- a/plugin/net/driver.go +++ b/plugin/net/driver.go @@ -107,39 +107,11 @@ func (driver *driver) EndpointInfo(req *api.EndpointInfoRequest) (*api.EndpointI } func (driver *driver) JoinEndpoint(j *api.JoinRequest) (*api.JoinResponse, error) { - endID := j.EndpointID - - maybeBridge, err := netlink.LinkByName(WeaveBridge) + local, err := createAndAttach(j.EndpointID, WeaveBridge, 0) if err != nil { - return nil, errorf(`bridge "%s" not present; did you launch weave?`, WeaveBridge) + return nil, err } - // create and attach local name to the bridge - local := vethPair(endID[:5]) - local.Attrs().MTU = maybeBridge.Attrs().MTU - if err := netlink.LinkAdd(local); err != nil { - return nil, errorf("could not create veth pair: %s", err) - } - - switch maybeBridge.(type) { - case *netlink.Bridge: - if err := netlink.LinkSetMasterByIndex(local, maybeBridge.Attrs().Index); err != nil { - return nil, errorf(`unable to set master: %s`, err) - } - case *netlink.GenericLink: - if maybeBridge.Type() != "openvswitch" { - Log.Errorf("device %s is %+v", WeaveBridge, maybeBridge) - return nil, errorf(`device "%s" is of type "%s"`, WeaveBridge, maybeBridge.Type()) - } - odp.AddDatapathInterface(WeaveBridge, local.Name) - case *netlink.Device: - Log.Warnf("kernel does not report what kind of device %s is, just %+v", WeaveBridge, maybeBridge) - // Assume it's our openvswitch device, and the kernel has not been updated to report the kind. - odp.AddDatapathInterface(WeaveBridge, local.Name) - default: - Log.Errorf("device %s is %+v", WeaveBridge, maybeBridge) - return nil, errorf(`device "%s" not a bridge`, WeaveBridge) - } if err := netlink.LinkSetUp(local); err != nil { return nil, errorf(`unable to bring veth up: %s`, err) } @@ -163,6 +135,43 @@ func (driver *driver) JoinEndpoint(j *api.JoinRequest) (*api.JoinResponse, error return response, nil } +// create and attach local name to the Weave bridge +func createAndAttach(id, bridgeName string, mtu int) (*netlink.Veth, error) { + maybeBridge, err := netlink.LinkByName(bridgeName) + if err != nil { + return nil, errorf(`bridge "%s" not present; did you launch weave?`, bridgeName) + } + + local := vethPair(id[:5]) + if mtu == 0 { + local.Attrs().MTU = maybeBridge.Attrs().MTU + } else { + local.Attrs().MTU = mtu + } + if err := netlink.LinkAdd(local); err != nil { + return nil, errorf("could not create veth pair: %s", err) + } + + switch maybeBridge.(type) { + case *netlink.Bridge: + if err := netlink.LinkSetMasterByIndex(local, maybeBridge.Attrs().Index); err != nil { + return nil, errorf(`unable to set master: %s`, err) + } + case *netlink.GenericLink: + if maybeBridge.Type() != "openvswitch" { + return nil, errorf(`device "%s" is of type "%s"`, bridgeName, maybeBridge.Type()) + } + odp.AddDatapathInterface(bridgeName, local.Name) + case *netlink.Device: + Log.Warnf("kernel does not report what kind of device %s is, just %+v", bridgeName, maybeBridge) + // Assume it's our openvswitch device, and the kernel has not been updated to report the kind. + odp.AddDatapathInterface(bridgeName, local.Name) + default: + return nil, errorf(`device "%s" not a bridge`, bridgeName) + } + return local, nil +} + func (driver *driver) LeaveEndpoint(leave *api.LeaveRequest) error { Log.Debugf("Leave request: %+v", leave)