automation-tests/common/libnetwork/network/interface_cni.go

120 lines
2.8 KiB
Go

//go:build (linux || freebsd) && cni
package network
import (
"errors"
"fmt"
"os"
"path/filepath"
"github.com/containers/common/libnetwork/cni"
"github.com/containers/common/libnetwork/types"
"github.com/containers/common/pkg/config"
"github.com/containers/common/pkg/machine"
"github.com/containers/storage"
"github.com/containers/storage/pkg/homedir"
"github.com/containers/storage/pkg/unshare"
)
const (
// cniConfigDirRootless is the directory in XDG_CONFIG_HOME for cni plugins
cniConfigDirRootless = "cni/net.d/"
cniSupported = true
)
func getCniInterface(conf *config.Config) (types.ContainerNetwork, error) {
confDir := conf.Network.NetworkConfigDir
if confDir == "" {
var err error
confDir, err = getDefaultCNIConfigDir()
if err != nil {
return nil, err
}
}
return cni.NewCNINetworkInterface(&cni.InitConfig{
Config: conf,
CNIConfigDir: confDir,
RunDir: conf.Engine.TmpDir,
IsMachine: machine.IsGvProxyBased(),
})
}
func getDefaultCNIConfigDir() (string, error) {
if !unshare.IsRootless() {
return cniConfigDir, nil
}
configHome, err := homedir.GetConfigHome()
if err != nil {
return "", err
}
return filepath.Join(configHome, cniConfigDirRootless), nil
}
func networkBackendFromStore(store storage.Store, conf *config.Config) (backend types.NetworkBackend, err error) {
_, err = conf.FindHelperBinary("netavark", false)
if err != nil {
// if we cannot find netavark use CNI
return types.CNI, nil
}
// If there are any containers then return CNI
cons, err := store.Containers()
if err != nil {
return "", err
}
if len(cons) != 0 {
return types.CNI, nil
}
// If there are any non ReadOnly images then return CNI
imgs, err := store.Images()
if err != nil {
return "", err
}
for _, i := range imgs {
if !i.ReadOnly {
return types.CNI, nil
}
}
// If there are CNI Networks then return CNI
cniInterface, err := getCniInterface(conf)
if err == nil {
nets, err := cniInterface.NetworkList()
// there is always a default network so check > 1
if err != nil && !errors.Is(err, os.ErrNotExist) {
return "", err
}
if len(nets) > 1 {
// we do not have a fresh system so use CNI
return types.CNI, nil
}
}
return types.Netavark, nil
}
func backendFromType(backend types.NetworkBackend, store storage.Store, conf *config.Config, syslog bool) (types.NetworkBackend, types.ContainerNetwork, error) {
switch backend {
case types.Netavark:
netInt, err := netavarkBackendFromConf(store, conf, syslog)
if err != nil {
return "", nil, err
}
return types.Netavark, netInt, err
case types.CNI:
netInt, err := getCniInterface(conf)
if err != nil {
return "", nil, err
}
return types.CNI, netInt, err
default:
return "", nil, fmt.Errorf("unsupported network backend %q, check network_backend in containers.conf", backend)
}
}