Merge pull request #21410 from ashley-cui/cnici

Do not test CNI in CI
This commit is contained in:
openshift-merge-bot[bot]
2024-02-06 10:41:48 +00:00
committed by GitHub
20 changed files with 242 additions and 286 deletions

View File

@ -105,13 +105,11 @@ build_task:
CTR_FQIN: ${FEDORA_CONTAINER_FQIN}
# ID for re-use of build output
CI_DESIRED_RUNTIME: crun
CI_DESIRED_NETWORK: netavark
- env:
DISTRO_NV: ${PRIOR_FEDORA_NAME}
VM_IMAGE_NAME: ${PRIOR_FEDORA_CACHE_IMAGE_NAME}
CTR_FQIN: ${PRIOR_FEDORA_CONTAINER_FQIN}
CI_DESIRED_RUNTIME: crun
CI_DESIRED_NETWORK: cni
CI_DESIRED_DATABASE: boltdb
CI_DESIRED_STORAGE: vfs
# Catch invalid "TMPDIR == /tmp" assumptions; PR #19281
@ -125,7 +123,6 @@ build_task:
DISTRO_NV: ${DEBIAN_NAME}
VM_IMAGE_NAME: ${DEBIAN_CACHE_IMAGE_NAME}
CI_DESIRED_RUNTIME: runc
CI_DESIRED_NETWORK: netavark
env:
TEST_FLAVOR: build
# NOTE: The default way Cirrus-CI clones is *NOT* compatible with
@ -186,7 +183,6 @@ build_aarch64_task:
VM_IMAGE_NAME: ${FEDORA_AARCH64_AMI}
CTR_FQIN: ${FEDORA_CONTAINER_FQIN}
CI_DESIRED_RUNTIME: crun
CI_DESIRED_NETWORK: netavark
TEST_FLAVOR: build
clone_script: *full_clone
prebuild_script: *prebuild
@ -682,13 +678,11 @@ container_integration_test_task:
VM_IMAGE_NAME: ${FEDORA_CACHE_IMAGE_NAME}
CTR_FQIN: ${FEDORA_CONTAINER_FQIN}
CI_DESIRED_RUNTIME: crun
CI_DESIRED_NETWORK: netavark
- env:
DISTRO_NV: ${PRIOR_FEDORA_NAME}
VM_IMAGE_NAME: ${PRIOR_FEDORA_CACHE_IMAGE_NAME}
CTR_FQIN: ${PRIOR_FEDORA_CONTAINER_FQIN}
CI_DESIRED_RUNTIME: crun
CI_DESIRED_NETWORK: cni
CI_DESIRED_DATABASE: boltdb
gce_instance: *standardvm
timeout_in: 50m
@ -746,7 +740,6 @@ podman_machine_task:
PRIV_NAME: "rootless" # intended use-case
DISTRO_NV: "${FEDORA_NAME}"
VM_IMAGE_NAME: "${FEDORA_AMI}"
CI_DESIRED_NETWORK: netavark
clone_script: *get_gosrc
setup_script: *setup
main_script: *main
@ -772,7 +765,6 @@ podman_machine_aarch64_task:
PRIV_NAME: "rootless" # intended use-case
DISTRO_NV: "${FEDORA_AARCH64_NAME}"
VM_IMAGE_NAME: "${FEDORA_AARCH64_AMI}"
CI_DESIRED_NETWORK: netavark
clone_script: *get_gosrc_aarch64
setup_script: *setup
main_script: *main
@ -922,7 +914,6 @@ rootless_remote_system_test_task:
VM_IMAGE_NAME: ${FEDORA_CACHE_IMAGE_NAME}
CTR_FQIN: ${FEDORA_CONTAINER_FQIN}
CI_DESIRED_RUNTIME: crun
CI_DESIRED_NETWORK: netavark
<<: *local_system_test_task
alias: rootless_remote_system_test
gce_instance: *standardvm
@ -1007,37 +998,6 @@ buildah_bud_test_task:
main_script: *main
always: *int_logs_artifacts
upgrade_test_task:
name: "Upgrade test: from $PODMAN_UPGRADE_FROM"
alias: upgrade_test
# Docs: ./contrib/cirrus/CIModes.md
only_if: *not_tag_magic
depends_on:
- build
- local_system_test
matrix:
- env:
PODMAN_UPGRADE_FROM: v2.1.1
CI_DESIRED_NETWORK: cni
- env:
PODMAN_UPGRADE_FROM: v3.1.2
CI_DESIRED_NETWORK: cni
- env:
PODMAN_UPGRADE_FROM: v3.4.4
CI_DESIRED_NETWORK: cni
gce_instance: *standardvm
env:
TEST_FLAVOR: upgrade_test
DISTRO_NV: ${FEDORA_NAME}
VM_IMAGE_NAME: ${FEDORA_CACHE_IMAGE_NAME}
# FIXME: remove this once we have VMs with podman >= 4.8
CI_DESIRED_DATABASE: boltdb
clone_script: *get_gosrc
setup_script: *setup
main_script: *main
always: *logs_artifacts
# This task is critical. It updates the "last-used by" timestamp stored
# in metadata for all VM images. This mechanism functions in tandem with
# an out-of-band pruning operation to remove disused VM images.
@ -1111,7 +1071,6 @@ success_task:
- minikube_test
- farm_test
- buildah_bud_test
- upgrade_test
- meta
container: &smallcontainer
image: ${CTR_FQIN}

View File

@ -95,7 +95,7 @@ EPOCH_TEST_COMMIT="$CIRRUS_BASE_SHA"
# contexts, such as host->container or root->rootless user
#
# List of envariables which must be EXACT matches
PASSTHROUGH_ENV_EXACT='CGROUP_MANAGER|DEST_BRANCH|DISTRO_NV|GOCACHE|GOPATH|GOSRC|NETWORK_BACKEND|OCI_RUNTIME|ROOTLESS_USER|SCRIPT_BASE|SKIP_USERNS|EC2_INST_TYPE|PODMAN_DB|STORAGE_FS'
PASSTHROUGH_ENV_EXACT='CGROUP_MANAGER|DEST_BRANCH|DISTRO_NV|GOCACHE|GOPATH|GOSRC|OCI_RUNTIME|ROOTLESS_USER|SCRIPT_BASE|SKIP_USERNS|EC2_INST_TYPE|PODMAN_DB|STORAGE_FS'
# List of envariable patterns which must match AT THE BEGINNING of the name.
PASSTHROUGH_ENV_ATSTART='CI|LANG|LC_|TEST'
@ -202,61 +202,6 @@ install_test_configs() {
install -v -D -m 644 ./test/registries.conf /etc/containers/
}
use_cni() {
req_env_vars OS_RELEASE_ID PACKAGE_DOWNLOAD_DIR SCRIPT_BASE
# Defined by common automation library
# shellcheck disable=SC2154
if [[ "$OS_RELEASE_ID" =~ "debian" ]]; then
# Supporting it involves swapping the rpm & dnf commands below
die "Testing debian w/ CNI networking currently not supported"
fi
msg "Forcing NETWORK_BACKEND=cni for all subsequent environments."
echo "NETWORK_BACKEND=cni" >> /etc/ci_environment
export NETWORK_BACKEND=cni
# While it's possible a user may want both installed, for CNI CI testing
# purposes we only care about backward-compatibility, not forward.
# If both CNI & netavark are present, in some situations where --root
# is used it's possible for podman to pick the "wrong" networking stack.
msg "Force-removing netavark and aardvark-dns"
# Other packages depend on nv/av, but we're testing with podman
# binaries built from source, so it's safe to ignore these deps.
#
# Do not fail when netavark and aardvark-dns are not installed.
for pkg in aardvark-dns netavark
do
[ -z "$(rpm -qa | grep $pkg)" ] && echo "$pkg not installed" || rpm -e --nodeps $pkg
done
msg "Installing default CNI configuration"
showrun dnf install -y $PACKAGE_DOWNLOAD_DIR/podman-plugins*
cd $GOSRC || exit 1
rm -rvf /etc/cni/net.d
mkdir -p /etc/cni/net.d
showrun install -v -D -m 644 ./cni/87-podman-bridge.conflist \
/etc/cni/net.d/
# This config must always sort last in the list of networks (podman picks
# first one as the default). This config prevents allocation of network
# address space used by default in google cloud.
# https://cloud.google.com/vpc/docs/vpc#ip-ranges
showrun install -v -D -m 644 $SCRIPT_BASE/99-do-not-use-google-subnets.conflist \
/etc/cni/net.d/
}
use_netavark() {
req_env_vars OS_RELEASE_ID PRIOR_FEDORA_NAME DISTRO_NV
local magickind repokind
msg "Unsetting NETWORK_BACKEND for all subsequent environments."
echo "export -n NETWORK_BACKEND" >> /etc/ci_environment
echo "unset NETWORK_BACKEND" >> /etc/ci_environment
export -n NETWORK_BACKEND
unset NETWORK_BACKEND
msg "Removing any/all CNI configuration"
showrun rm -rvf /etc/cni/net.d/*
# N/B: The CNI packages are still installed and available. This is
# on purpose, since CI needs to verify the selection mechanisms are
# functional when both are available.
}
# Remove all files provided by the distro version of podman.
# All VM cache-images used for testing include the distro podman because (1) it's
# required for podman-in-podman testing and (2) it somewhat simplifies the task

View File

@ -158,16 +158,6 @@ case "$OS_RELEASE_ID" in
*) die_unknown OS_RELEASE_ID
esac
# Networking: force CNI or Netavark as requested in .cirrus.yml
# (this variable is mandatory).
# shellcheck disable=SC2154
showrun echo "about to set up for CI_DESIRED_NETWORK [=$CI_DESIRED_NETWORK]"
case "$CI_DESIRED_NETWORK" in
netavark) use_netavark ;;
cni) use_cni ;;
*) die_unknown CI_DESIRED_NETWORK ;;
esac
# Database: force SQLite or BoltDB as requested in .cirrus.yml.
# If unset, will default to SQLite.
# shellcheck disable=SC2154

4
go.mod
View File

@ -11,7 +11,7 @@ require (
github.com/checkpoint-restore/go-criu/v7 v7.0.0
github.com/containernetworking/plugins v1.4.0
github.com/containers/buildah v1.34.1-0.20240201124221-b850c711ff5c
github.com/containers/common v0.57.1-0.20240130143645-b26099256b92
github.com/containers/common v0.57.1-0.20240205132223-de5cb00e891c
github.com/containers/conmon v2.0.20+incompatible
github.com/containers/gvisor-tap-vsock v0.7.2
github.com/containers/image/v5 v5.29.2-0.20240130233108-e66a1ade2efc
@ -93,7 +93,7 @@ require (
github.com/chenzhuoyu/iasm v0.9.0 // indirect
github.com/chzyer/readline v1.5.1 // indirect
github.com/containerd/cgroups/v3 v3.0.2 // indirect
github.com/containerd/containerd v1.7.12 // indirect
github.com/containerd/containerd v1.7.13 // indirect
github.com/containerd/log v0.1.0 // indirect
github.com/containerd/stargz-snapshotter/estargz v0.15.1 // indirect
github.com/containerd/typeurl/v2 v2.1.1 // indirect

8
go.sum
View File

@ -194,8 +194,8 @@ github.com/containerd/containerd v1.5.0-beta.4/go.mod h1:GmdgZd2zA2GYIBZ0w09Zvgq
github.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoTJseu1FGOKuoA4nNb2s=
github.com/containerd/containerd v1.5.1/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g=
github.com/containerd/containerd v1.5.7/go.mod h1:gyvv6+ugqY25TiXxcZC3L5yOeYgEw0QMhscqVp1AR9c=
github.com/containerd/containerd v1.7.12 h1:+KQsnv4VnzyxWcfO9mlxxELaoztsDEjOuCMPAuPqgU0=
github.com/containerd/containerd v1.7.12/go.mod h1:/5OMpE1p0ylxtEUGY8kuCYkDRzJm9NO1TFMWjUpdevk=
github.com/containerd/containerd v1.7.13 h1:wPYKIeGMN8vaggSKuV1X0wZulpMz4CrgEsZdaCyB6Is=
github.com/containerd/containerd v1.7.13/go.mod h1:zT3up6yTRfEUa6+GsITYIJNgSVL9NQ4x4h1RPzk0Wu4=
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
@ -257,8 +257,8 @@ github.com/containernetworking/plugins v1.4.0 h1:+w22VPYgk7nQHw7KT92lsRmuToHvb7w
github.com/containernetworking/plugins v1.4.0/go.mod h1:UYhcOyjefnrQvKvmmyEKsUA+M9Nfn7tqULPpH0Pkcj0=
github.com/containers/buildah v1.34.1-0.20240201124221-b850c711ff5c h1:r+1vFyTAoXptJrsPsnOMI3G0jm4+BCfXAcIyuA33lzo=
github.com/containers/buildah v1.34.1-0.20240201124221-b850c711ff5c/go.mod h1:Hw4qo2URFpWvZ2tjLstoQMpNC6+gR4PtxQefvV/UKaA=
github.com/containers/common v0.57.1-0.20240130143645-b26099256b92 h1:Q60+ofGhDjVxY5lvYmmcVN8aeS9gtQ6pAn/pyLh7rRM=
github.com/containers/common v0.57.1-0.20240130143645-b26099256b92/go.mod h1:Na7hGh5WnmB0RdGkKyb6JQb6DtKrs5qoIGrPucuR8t0=
github.com/containers/common v0.57.1-0.20240205132223-de5cb00e891c h1:Xzo9t4eIalkeilcmYTz0YEgL7hMrGQ12GK6UlSHrEsU=
github.com/containers/common v0.57.1-0.20240205132223-de5cb00e891c/go.mod h1:s1gEyucR3ryIex1aDMo1KzbfpvRl0CaGER6s5jqXRkI=
github.com/containers/conmon v2.0.20+incompatible h1:YbCVSFSCqFjjVwHTPINGdMX1F6JXHGTUje2ZYobNrkg=
github.com/containers/conmon v2.0.20+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I=
github.com/containers/gvisor-tap-vsock v0.7.2 h1:6CyU5D85C0/DciRRd7W0bPljK4FAS+DPrrHEQMHfZKY=

View File

@ -152,23 +152,15 @@ var _ = Describe("Podman Info", func() {
})
It("Podman info: check desired network backend", func() {
// defined in .cirrus.yml
want := os.Getenv("CI_DESIRED_NETWORK")
if want == "" {
if os.Getenv("CIRRUS_CI") == "" {
Skip("CI_DESIRED_NETWORK is not set--this is OK because we're not running under Cirrus")
}
Fail("CIRRUS_CI is set, but CI_DESIRED_NETWORK is not! See #16389")
}
session := podmanTest.Podman([]string{"info", "--format", "{{.Host.NetworkBackend}}"})
session.WaitWithDefaultTimeout()
Expect(session).To(ExitCleanly())
Expect(session.OutputToString()).To(Equal(want))
Expect(session.OutputToString()).To(Equal("netavark"))
session = podmanTest.Podman([]string{"info", "--format", "{{.Host.NetworkBackendInfo.Backend}}"})
session.WaitWithDefaultTimeout()
Expect(session).To(ExitCleanly())
Expect(session.OutputToString()).To(Equal(want))
Expect(session.OutputToString()).To(Equal("netavark"))
})
It("Podman info: check desired database backend", func() {

View File

@ -82,21 +82,8 @@ host.slirp4netns.executable | $expr_path
}
@test "podman info - confirm desired network backend" {
if [[ -z "$CI_DESIRED_NETWORK" ]]; then
# When running in Cirrus, CI_DESIRED_NETWORK *must* be defined
# in .cirrus.yml so we can double-check that all CI VMs are
# using netavark or cni as desired.
if [[ -n "$CIRRUS_CI" ]]; then
die "CIRRUS_CI is set, but CI_DESIRED_NETWORK is not! See #16389"
fi
# Not running under Cirrus (e.g., gating tests, or dev laptop).
# Totally OK to skip this test.
skip "CI_DESIRED_NETWORK is unset--OK, because we're not in Cirrus"
fi
run_podman info --format '{{.Host.NetworkBackend}}'
is "$output" "$CI_DESIRED_NETWORK" "CI_DESIRED_NETWORK (from .cirrus.yml)"
is "$output" "netavark" "netavark backend"
}
@test "podman info - confirm desired database" {

View File

@ -125,10 +125,6 @@ while :;do
echo STOPPING
podman \$opts stop -t 0 myrunningcontainer || true
podman \$opts rm -f myrunningcontainer || true
# sigh, network rm fails with exec: "ip": executable file not found in $PATH
# we cannot change the images afterwards so we remove it manually (#11403)
# hardcode /etc/cni/net.d dir for now
podman \$opts network rm -f mynetwork || rm -f /etc/cni/net.d/mynetwork.conflist
exit 0
fi
sleep 0.5
@ -143,10 +139,7 @@ EOF
# Also use --network host to prevent any netavark/cni conflicts
$PODMAN run --rm --network host $OLD_PODMAN true
# Podman 4.0 might no longer use cni so /run/cni and /run/containers will no be created in this case
# Create directories manually to fix this. Also running with netavark can
# cause connectivity issues since cni and netavark should never be mixed.
mkdir -p /run/netns /run/cni /run/containers /var/lib/cni /etc/cni/net.d
mkdir -p /run/netns
# Containers-common around release 1-55 no-longer supplies this file
sconf=/etc/containers/storage.conf
@ -165,7 +158,6 @@ EOF
#
# mount /etc/containers/storage.conf to use the same storage settings as on the host
# mount /dev/shm because the container locks are stored there
# mount /var/lib/cni, /run/cni and /etc/cni/net.d for cni networking
# mount /run/containers for the dnsname plugin
#
$PODMAN run -d --name podman_parent --pid=host \
@ -178,9 +170,6 @@ EOF
-v /run/crun:/run/crun \
-v /run/netns:/run/netns:rshared \
-v /run/containers:/run/containers \
-v /run/cni:/run/cni \
-v /var/lib/cni:/var/lib/cni \
-v /etc/cni/net.d:/etc/cni/net.d \
-v /dev/shm:/dev/shm \
-v $pmroot:$pmroot:rshared \
$OLD_PODMAN $pmroot/setup
@ -200,10 +189,8 @@ EOF
}
@test "info" {
# check network backend, since this is an old version we should use CNI
# when we start testing from 4.0 we should have netavark as backend
run_podman info --format '{{.Host.NetworkBackend}}'
is "$output" "cni" "correct network backend"
is "$output" "netavark" "correct network backend"
}
@test "images" {

View File

@ -1,4 +1,4 @@
//go:build linux || freebsd
//go:build (linux || freebsd) && cni
package cni

View File

@ -16,7 +16,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build linux || freebsd
//go:build (linux || freebsd) && cni
package cni

View File

@ -1,4 +1,4 @@
//go:build linux || freebsd
//go:build (linux || freebsd) && cni
package cni

View File

@ -1,4 +1,4 @@
//go:build linux || freebsd
//go:build (linux || freebsd) && cni
package cni

View File

@ -1,4 +1,4 @@
//go:build freebsd
//go:build (linux || freebsd) && cni
package cni

View File

@ -1,4 +1,4 @@
//go:build linux
//go:build (linux || freebsd) && cni
package cni

View File

@ -1,4 +1,4 @@
//go:build linux || freebsd
//go:build (linux || freebsd) && cni
package cni

View File

@ -1,4 +1,4 @@
//go:build linux || freebsd
//go:build (linux || freebsd) && cni
package cni

View File

@ -8,13 +8,10 @@ import (
"os"
"path/filepath"
"github.com/containers/common/libnetwork/cni"
"github.com/containers/common/libnetwork/netavark"
"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/ioutils"
"github.com/containers/storage/pkg/unshare"
"github.com/sirupsen/logrus"
@ -23,8 +20,6 @@ import (
const (
// defaultNetworkBackendFileName is the file name for sentinel file to store the backend
defaultNetworkBackendFileName = "defaultNetworkBackend"
// cniConfigDirRootless is the directory in XDG_CONFIG_HOME for cni plugins
cniConfigDirRootless = "cni/net.d/"
// netavarkBinary is the name of the netavark binary
netavarkBinary = "netavark"
@ -52,146 +47,94 @@ func NetworkBackend(store storage.Store, conf *config.Config, syslog bool) (type
}
}
switch backend {
case types.Netavark:
netavarkBin, err := conf.FindHelperBinary(netavarkBinary, false)
if err != nil {
return "", nil, err
}
return backendFromType(backend, store, conf, syslog)
}
aardvarkBin, _ := conf.FindHelperBinary(aardvarkBinary, false)
confDir := conf.Network.NetworkConfigDir
if confDir == "" {
confDir = getDefaultNetavarkConfigDir(store)
}
// We cannot use the runroot for rootful since the network namespace is shared for all
// libpod instances they also have to share the same ipam db.
// For rootless we have our own network namespace per libpod instances,
// so this is not a problem there.
runDir := netavarkRunDir
if unshare.IsRootless() {
runDir = filepath.Join(store.RunRoot(), "networks")
}
netInt, err := netavark.NewNetworkInterface(&netavark.InitConfig{
Config: conf,
NetworkConfigDir: confDir,
NetworkRunDir: runDir,
NetavarkBinary: netavarkBin,
AardvarkBinary: aardvarkBin,
Syslog: syslog,
})
return types.Netavark, netInt, err
case types.CNI:
netInt, err := getCniInterface(conf)
return types.CNI, netInt, err
default:
return "", nil, fmt.Errorf("unsupported network backend %q, check network_backend in containers.conf", backend)
func netavarkBackendFromConf(store storage.Store, conf *config.Config, syslog bool) (types.ContainerNetwork, error) {
netavarkBin, err := conf.FindHelperBinary(netavarkBinary, false)
if err != nil {
return nil, err
}
aardvarkBin, _ := conf.FindHelperBinary(aardvarkBinary, false)
confDir := conf.Network.NetworkConfigDir
if confDir == "" {
confDir = getDefaultNetavarkConfigDir(store)
}
// We cannot use the runroot for rootful since the network namespace is shared for all
// libpod instances they also have to share the same ipam db.
// For rootless we have our own network namespace per libpod instances,
// so this is not a problem there.
runDir := netavarkRunDir
if unshare.IsRootless() {
runDir = filepath.Join(store.RunRoot(), "networks")
}
netInt, err := netavark.NewNetworkInterface(&netavark.InitConfig{
Config: conf,
NetworkConfigDir: confDir,
NetworkRunDir: runDir,
NetavarkBinary: netavarkBin,
AardvarkBinary: aardvarkBin,
Syslog: syslog,
})
return netInt, err
}
func defaultNetworkBackend(store storage.Store, conf *config.Config) (backend types.NetworkBackend, err error) {
// read defaultNetworkBackend file
err = nil
file := filepath.Join(store.GraphRoot(), defaultNetworkBackendFileName)
writeBackendToFile := func(backendT types.NetworkBackend) {
// only write when there is no error
if err == nil {
if err := ioutils.AtomicWriteFile(file, []byte(backendT), 0o644); err != nil {
logrus.Errorf("could not write network backend to file: %v", err)
}
}
}
// read defaultNetworkBackend file
b, err := os.ReadFile(file)
if err == nil {
val := string(b)
// if the network backend has been already set previously,
// handle the values depending on whether CNI is supported and
// whether the network backend is explicitly configured
if val == string(types.Netavark) {
// netavark is always good
return types.Netavark, nil
} else if val == string(types.CNI) {
if cniSupported {
return types.CNI, nil
}
// the user has *not* configured a network
// backend explicitly but used CNI in the past
// => we upgrade them in this case to netavark only
writeBackendToFile(types.Netavark)
logrus.Info("Migrating network backend to netavark as no backend has been configured previously")
return types.Netavark, nil
}
if val == string(types.CNI) {
return types.CNI, nil
}
return "", fmt.Errorf("unknown network backend value %q in %q", val, file)
}
// fail for all errors except ENOENT
if !errors.Is(err, os.ErrNotExist) {
return "", fmt.Errorf("could not read network backend value: %w", err)
}
backend, err = networkBackendFromStore(store, conf)
if err != nil {
return "", err
}
// cache the network backend to make sure always the same one will be used
defer func() {
// only write when there is no error
if err == nil {
if err := ioutils.AtomicWriteFile(file, []byte(backend), 0o644); err != nil {
logrus.Errorf("could not write network backend to file: %v", err)
}
}
}()
writeBackendToFile(backend)
_, 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 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
return backend, nil
}
// getDefaultNetavarkConfigDir return the netavark config dir. For rootful it will

View File

@ -0,0 +1,121 @@
//go:build (linux || freebsd) && cni
// +build linux freebsd
// +build 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)
}
}

View File

@ -0,0 +1,32 @@
//go:build (linux || freebsd) && !cni
// +build linux freebsd
// +build !cni
package network
import (
"fmt"
"github.com/containers/common/libnetwork/types"
"github.com/containers/common/pkg/config"
"github.com/containers/storage"
)
const (
cniSupported = false
)
func networkBackendFromStore(_store storage.Store, _conf *config.Config) (backend types.NetworkBackend, err error) {
return types.Netavark, nil
}
func backendFromType(backend types.NetworkBackend, store storage.Store, conf *config.Config, syslog bool) (types.NetworkBackend, types.ContainerNetwork, error) {
if backend != types.Netavark {
return "", nil, fmt.Errorf("cni support is not enabled in this build, only netavark. Got unsupported network backend %q", backend)
}
cn, err := netavarkBackendFromConf(store, conf, syslog)
if err != nil {
return "", nil, err
}
return types.Netavark, cn, err
}

4
vendor/modules.txt vendored
View File

@ -107,7 +107,7 @@ github.com/chzyer/readline
# github.com/containerd/cgroups/v3 v3.0.2
## explicit; go 1.18
github.com/containerd/cgroups/v3/cgroup1/stats
# github.com/containerd/containerd v1.7.12
# github.com/containerd/containerd v1.7.13
## explicit; go 1.19
github.com/containerd/containerd/errdefs
github.com/containerd/containerd/log
@ -168,7 +168,7 @@ github.com/containers/buildah/pkg/sshagent
github.com/containers/buildah/pkg/util
github.com/containers/buildah/pkg/volumes
github.com/containers/buildah/util
# github.com/containers/common v0.57.1-0.20240130143645-b26099256b92
# github.com/containers/common v0.57.1-0.20240205132223-de5cb00e891c
## explicit; go 1.20
github.com/containers/common/internal/attributedstring
github.com/containers/common/libimage