mirror of
https://github.com/openfaas/faasd.git
synced 2025-06-09 00:16:46 +00:00
* Adds depends_on fields to compose YAML * Updates parsing code to copy across depends_on field to openfaas service from compose service definition * Adds algorithm and unit tests for finding order * Applies order to up.go command * Makes unit testing on MacOS possible through build directives Signed-off-by: Alex Ellis (OpenFaaS Ltd) <alexellis2@gmail.com>
119 lines
2.8 KiB
Go
119 lines
2.8 KiB
Go
// Copyright Weaveworks
|
|
// github.com/weaveworks/weave/net
|
|
|
|
package cninetwork
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
"os"
|
|
|
|
"github.com/vishvananda/netlink"
|
|
"github.com/vishvananda/netns"
|
|
)
|
|
|
|
type Dev struct {
|
|
Name string `json:"Name,omitempty"`
|
|
MAC net.HardwareAddr `json:"MAC,omitempty"`
|
|
CIDRs []*net.IPNet `json:"CIDRs,omitempty"`
|
|
}
|
|
|
|
// ConnectedToBridgeVethPeerIds returns peer indexes of veth links connected to
|
|
// the given bridge. The peer index is used to query from a container netns
|
|
// whether the container is connected to the bridge.
|
|
func ConnectedToBridgeVethPeerIds(bridgeName string) ([]int, error) {
|
|
var ids []int
|
|
|
|
br, err := netlink.LinkByName(bridgeName)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
links, err := netlink.LinkList()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
for _, link := range links {
|
|
if _, isveth := link.(*netlink.Veth); isveth && link.Attrs().MasterIndex == br.Attrs().Index {
|
|
peerID := link.Attrs().ParentIndex
|
|
if peerID == 0 {
|
|
// perhaps running on an older kernel where ParentIndex doesn't work.
|
|
// as fall-back, assume the peers are consecutive
|
|
peerID = link.Attrs().Index - 1
|
|
}
|
|
ids = append(ids, peerID)
|
|
}
|
|
}
|
|
|
|
return ids, nil
|
|
}
|
|
|
|
// Lookup the weave interface of a container
|
|
func GetWeaveNetDevs(processID int) ([]Dev, error) {
|
|
peerIDs, err := ConnectedToBridgeVethPeerIds("weave")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return GetNetDevsByVethPeerIds(processID, peerIDs)
|
|
}
|
|
|
|
func GetNetDevsByVethPeerIds(processID int, peerIDs []int) ([]Dev, error) {
|
|
// Bail out if this container is running in the root namespace
|
|
netnsRoot, err := netns.GetFromPid(1)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("unable to open root namespace: %s", err)
|
|
}
|
|
defer netnsRoot.Close()
|
|
netnsContainer, err := netns.GetFromPid(processID)
|
|
if err != nil {
|
|
// Unable to find a namespace for this process - just return nothing
|
|
if os.IsNotExist(err) {
|
|
return nil, nil
|
|
}
|
|
return nil, fmt.Errorf("unable to open process %d namespace: %s", processID, err)
|
|
}
|
|
defer netnsContainer.Close()
|
|
if netnsRoot.Equal(netnsContainer) {
|
|
return nil, nil
|
|
}
|
|
|
|
// convert list of peerIDs into a map for faster lookup
|
|
indexes := make(map[int]struct{})
|
|
for _, id := range peerIDs {
|
|
indexes[id] = struct{}{}
|
|
}
|
|
|
|
var netdevs []Dev
|
|
err = WithNetNS(netnsContainer, func() error {
|
|
links, err := netlink.LinkList()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, link := range links {
|
|
if _, found := indexes[link.Attrs().Index]; found {
|
|
netdev, err := linkToNetDev(link)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
netdevs = append(netdevs, netdev)
|
|
}
|
|
}
|
|
return nil
|
|
})
|
|
|
|
return netdevs, err
|
|
}
|
|
|
|
// Get the weave bridge interface.
|
|
// NB: Should be called from the root network namespace.
|
|
func GetBridgeNetDev(bridgeName string) (Dev, error) {
|
|
link, err := netlink.LinkByName(bridgeName)
|
|
if err != nil {
|
|
return Dev{}, err
|
|
}
|
|
|
|
return linkToNetDev(link)
|
|
}
|