func attach(args []string) error { if len(args) < 4 { cmdUsage("attach-container", "[--no-multicast-route] [--keep-tx-on] <container-id> <bridge-name> <mtu> <cidr>...") } keepTXOn := false withMulticastRoute := true for i := 0; i < len(args); { switch args[i] { case "--no-multicast-route": withMulticastRoute = false args = append(args[:i], args[i+1:]...) case "--keep-tx-on": keepTXOn = true args = append(args[:i], args[i+1:]...) default: i++ } } pid, nsContainer, err := containerPidAndNs(args[0]) if err != nil { return err } if nsHost, err := netns.GetFromPid(1); err != nil { return fmt.Errorf("unable to open host namespace: %s", err) } else if nsHost.Equal(nsContainer) { return fmt.Errorf("Container is running in the host network namespace, and therefore cannot be\nconnected to weave. Perhaps the container was started with --net=host.") } mtu, err := strconv.Atoi(args[2]) if err != nil && args[3] != "" { return fmt.Errorf("unable to parse mtu %q: %s", args[2], err) } cidrs, err := parseCIDRs(args[3:]) if err != nil { return err } err = weavenet.AttachContainer(nsContainer, fmt.Sprint(pid), weavenet.VethName, args[1], mtu, withMulticastRoute, cidrs, keepTXOn) // If we detected an error but the container has died, tell the user that instead. if err != nil && !processExists(pid) { err = fmt.Errorf("Container %s died", args[0]) } return err }
func (c *CNIPlugin) CmdAdd(args *skel.CmdArgs) error { conf, err := loadNetConf(args.StdinData) if err != nil { return err } if conf.IsGW { return fmt.Errorf("Gateway functionality not supported") } if conf.IPMasq { return fmt.Errorf("IP Masquerading functionality not supported") } result, err := c.getIP(conf.IPAM.Type, args) if err != nil { return fmt.Errorf("unable to allocate IP address: %s", err) } // If config says nothing about routes or gateway, default one will be via the bridge if result.IP4.Routes == nil && result.IP4.Gateway == nil { bridgeIP, err := findBridgeIP(conf.BrName, result.IP4.IP) if err == errBridgeNoIP { bridgeArgs := *args bridgeArgs.ContainerID = "weave:expose" bridgeIPResult, err := c.getIP(conf.IPAM.Type, &bridgeArgs) if err != nil { return fmt.Errorf("unable to allocate IP address for bridge: %s", err) } if err := assignBridgeIP(conf.BrName, bridgeIPResult.IP4.IP); err != nil { return fmt.Errorf("unable to assign IP address to bridge: %s", err) } bridgeIP = bridgeIPResult.IP4.IP.IP } else if err != nil { return err } result.IP4.Gateway = bridgeIP } ns, err := netns.GetFromPath(args.Netns) if err != nil { return err } defer ns.Close() id := args.ContainerID if len(id) < 5 { data := make([]byte, 5) _, err := rand.Reader.Read(data) if err != nil { return err } id = fmt.Sprintf("%x", data) } if err := weavenet.AttachContainer(ns, id, args.IfName, conf.BrName, conf.MTU, false, []*net.IPNet{&result.IP4.IP}, false); err != nil { return err } if err := weavenet.WithNetNSLinkUnsafe(ns, args.IfName, func(link netlink.Link) error { return setupRoutes(link, args.IfName, result.IP4.IP, result.IP4.Gateway, result.IP4.Routes) }); err != nil { return fmt.Errorf("error setting up routes: %s", err) } result.DNS = conf.DNS return result.Print() }