File: interface_cni.go

package info (click to toggle)
golang-github-containers-common 0.64.1%2Bds1-2
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 5,932 kB
  • sloc: makefile: 132; sh: 111
file content (119 lines) | stat: -rw-r--r-- 2,874 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
//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)
	}
}