func containerAddrs(args []string) error { if len(args) < 1 { cmdUsage("container-addrs", "<bridgeName> [containerID ...]") } bridgeName := args[0] client, err := docker.NewVersionedClientFromEnv("1.18") if err != nil { return err } pred, err := common.ConnectedToBridgePredicate(bridgeName) if err != nil { if err == weavenet.ErrLinkNotFound { return nil } return err } var containerIDs []string containers := make(map[string]*docker.Container) for _, cid := range args[1:] { if cid == "weave:expose" { netDev, err := common.GetBridgeNetDev(bridgeName) if err != nil { return err } printNetDevs(cid, []common.NetDev{netDev}) continue } if containers[cid], err = client.InspectContainer(cid); err != nil { if _, ok := err.(*docker.NoSuchContainer); ok { continue } return err } // To output in the right order, we keep the list of container IDs containerIDs = append(containerIDs, cid) } // NB: Because network namespaces (netns) are changed many times inside the loop, // it's NOT safe to exec any code depending on the root netns without // wrapping with WithNetNS*. for _, cid := range containerIDs { netDevs, err := getNetDevs(client, containers[cid], pred) if err != nil { return err } printNetDevs(cid, netDevs) } return nil }
func getNetDevs(procPath, bridgeName string, c *docker.Client, containerID string) ([]common.NetDev, error) { if containerID == "weave:expose" { return common.GetBridgeNetDev(procPath, bridgeName) } container, err := c.InspectContainer(containerID) if err != nil { return nil, err } return common.GetWeaveNetDevs(procPath, container.State.Pid) }
func findBridgeIP(bridgeName string, subnet net.IPNet) (net.IP, error) { netdev, err := common.GetBridgeNetDev(bridgeName) if err != nil { return nil, fmt.Errorf("Failed to get netdev for %q bridge: %s", bridgeName, err) } if len(netdev.CIDRs) == 0 { return nil, errBridgeNoIP } for _, cidr := range netdev.CIDRs { if subnet.Contains(cidr.IP) { return cidr.IP, nil } } // None in the required subnet; just return the first one return netdev.CIDRs[0].IP, nil }