mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-06-25 06:52:13 +00:00
runtime: delete netmon
Netmon is not used anymore. Fixes: #3112 Signed-off-by: bin <bin@hyper.sh>
This commit is contained in:
parent
ac058b3897
commit
ddc68131df
1
src/runtime/.gitignore
vendored
1
src/runtime/.gitignore
vendored
@ -11,7 +11,6 @@ config-generated.go
|
||||
/pkg/containerd-shim-v2/monitor_address
|
||||
/data/kata-collect-data.sh
|
||||
/kata-monitor
|
||||
/kata-netmon
|
||||
/kata-runtime
|
||||
/pkg/katautils/config-settings.go
|
||||
/virtcontainers/hack/virtc/virtc
|
||||
|
@ -55,11 +55,6 @@ RUNTIME_OUTPUT = $(CURDIR)/$(TARGET)
|
||||
RUNTIME_DIR = $(CLI_DIR)/$(TARGET)
|
||||
BINLIST += $(TARGET)
|
||||
|
||||
NETMON_DIR = $(CLI_DIR)/netmon
|
||||
NETMON_TARGET = $(PROJECT_TYPE)-netmon
|
||||
NETMON_RUNTIME_OUTPUT = $(CURDIR)/$(NETMON_TARGET)
|
||||
BINLIBEXECLIST += $(NETMON_TARGET)
|
||||
|
||||
DESTDIR ?= /
|
||||
|
||||
ifeq ($(PREFIX),)
|
||||
@ -142,9 +137,6 @@ ACRNVALIDHYPERVISORPATHS := [\"$(ACRNPATH)\"]
|
||||
ACRNCTLPATH := $(ACRNBINDIR)/$(ACRNCTLCMD)
|
||||
ACRNVALIDCTLPATHS := [\"$(ACRNCTLPATH)\"]
|
||||
|
||||
NETMONCMD := $(BIN_PREFIX)-netmon
|
||||
NETMONPATH := $(PKGLIBEXECDIR)/$(NETMONCMD)
|
||||
|
||||
# Default number of vCPUs
|
||||
DEFVCPUS := 1
|
||||
# Default maximum number of vCPUs
|
||||
@ -416,7 +408,6 @@ USER_VARS += PROJECT_PREFIX
|
||||
USER_VARS += PROJECT_TAG
|
||||
USER_VARS += PROJECT_TYPE
|
||||
USER_VARS += PROJECT_URL
|
||||
USER_VARS += NETMONPATH
|
||||
USER_VARS += QEMUBINDIR
|
||||
USER_VARS += QEMUCMD
|
||||
USER_VARS += QEMUPATH
|
||||
@ -509,7 +500,7 @@ define SHOW_ARCH
|
||||
$(shell printf "\\t%s%s\\\n" "$(1)" $(if $(filter $(ARCH),$(1))," (default)",""))
|
||||
endef
|
||||
|
||||
all: runtime containerd-shim-v2 netmon monitor
|
||||
all: runtime containerd-shim-v2 monitor
|
||||
|
||||
# Targets that depend on .git-commit can use $(shell cat .git-commit) to get a
|
||||
# git revision string. They will only be rebuilt if the revision string
|
||||
@ -525,11 +516,6 @@ containerd-shim-v2: $(SHIMV2_OUTPUT)
|
||||
|
||||
monitor: $(MONITOR_OUTPUT)
|
||||
|
||||
netmon: $(NETMON_RUNTIME_OUTPUT)
|
||||
|
||||
$(NETMON_RUNTIME_OUTPUT): $(SOURCES) VERSION
|
||||
$(QUIET_BUILD)(cd $(NETMON_DIR) && go build $(BUILDFLAGS) -o $@ -ldflags "-X main.version=$(VERSION)" $(KATA_LDFLAGS))
|
||||
|
||||
runtime: $(RUNTIME_OUTPUT) $(CONFIGS)
|
||||
.DEFAULT: default
|
||||
|
||||
@ -638,15 +624,13 @@ coverage:
|
||||
go test -v -mod=vendor -covermode=atomic -coverprofile=coverage.txt ./...
|
||||
go tool cover -html=coverage.txt -o coverage.html
|
||||
|
||||
install: all install-runtime install-containerd-shim-v2 install-monitor install-netmon
|
||||
install: all install-runtime install-containerd-shim-v2 install-monitor
|
||||
|
||||
install-bin: $(BINLIST)
|
||||
$(QUIET_INST)$(foreach f,$(BINLIST),$(call INSTALL_EXEC,$f,$(BINDIR)))
|
||||
|
||||
install-runtime: runtime install-scripts install-completions install-configs install-bin
|
||||
|
||||
install-netmon: install-bin-libexec
|
||||
|
||||
install-containerd-shim-v2: $(SHIMV2)
|
||||
$(QUIET_INST)$(call INSTALL_EXEC,$<,$(BINDIR))
|
||||
|
||||
@ -678,7 +662,6 @@ clean:
|
||||
$(QUIET_CLEAN)rm -f \
|
||||
$(CONFIGS) \
|
||||
$(GENERATED_FILES) \
|
||||
$(NETMON_TARGET) \
|
||||
$(MONITOR) \
|
||||
$(SHIMV2) \
|
||||
$(TARGET) \
|
||||
@ -706,9 +689,7 @@ show-usage: show-header
|
||||
@printf "\tgenerate-config : create configuration file.\n"
|
||||
@printf "\tinstall : install everything.\n"
|
||||
@printf "\tinstall-containerd-shim-v2 : only install containerd shim v2 files.\n"
|
||||
@printf "\tinstall-netmon : only install netmon files.\n"
|
||||
@printf "\tinstall-runtime : only install runtime files.\n"
|
||||
@printf "\tnetmon : only build netmon.\n"
|
||||
@printf "\truntime : only build runtime.\n"
|
||||
@printf "\tshow-arches : show supported architectures (ARCH variable values).\n"
|
||||
@printf "\tshow-summary : show install locations.\n"
|
||||
|
@ -140,14 +140,6 @@ type HostInfo struct {
|
||||
SupportVSocks bool
|
||||
}
|
||||
|
||||
// NetmonInfo stores netmon details
|
||||
type NetmonInfo struct {
|
||||
Path string
|
||||
Version VersionInfo
|
||||
Debug bool
|
||||
Enable bool
|
||||
}
|
||||
|
||||
// EnvInfo collects all information that will be displayed by the
|
||||
// env command.
|
||||
//
|
||||
@ -159,7 +151,6 @@ type EnvInfo struct {
|
||||
Initrd InitrdInfo
|
||||
Hypervisor HypervisorInfo
|
||||
Runtime RuntimeInfo
|
||||
Netmon NetmonInfo
|
||||
Host HostInfo
|
||||
Agent AgentInfo
|
||||
}
|
||||
@ -276,26 +267,6 @@ func getMemoryInfo() MemoryInfo {
|
||||
}
|
||||
}
|
||||
|
||||
func getNetmonInfo(config oci.RuntimeConfig) NetmonInfo {
|
||||
netmonConfig := config.NetmonConfig
|
||||
|
||||
var netmonVersionInfo VersionInfo
|
||||
if version, err := getCommandVersion(netmonConfig.Path); err != nil {
|
||||
netmonVersionInfo = unknownVersionInfo
|
||||
} else {
|
||||
netmonVersionInfo = constructVersionInfo(version)
|
||||
}
|
||||
|
||||
netmon := NetmonInfo{
|
||||
Version: netmonVersionInfo,
|
||||
Path: netmonConfig.Path,
|
||||
Debug: netmonConfig.Debug,
|
||||
Enable: netmonConfig.Enable,
|
||||
}
|
||||
|
||||
return netmon
|
||||
}
|
||||
|
||||
func getCommandVersion(cmd string) (string, error) {
|
||||
return utils.RunCommand([]string{cmd, "--version"})
|
||||
}
|
||||
@ -364,8 +335,6 @@ func getEnvInfo(configFile string, config oci.RuntimeConfig) (env EnvInfo, err e
|
||||
return EnvInfo{}, err
|
||||
}
|
||||
|
||||
netmon := getNetmonInfo(config)
|
||||
|
||||
agent, err := getAgentInfo(config)
|
||||
if err != nil {
|
||||
return EnvInfo{}, err
|
||||
@ -398,7 +367,6 @@ func getEnvInfo(configFile string, config oci.RuntimeConfig) (env EnvInfo, err e
|
||||
Initrd: initrd,
|
||||
Agent: agent,
|
||||
Host: host,
|
||||
Netmon: netmon,
|
||||
}
|
||||
|
||||
return env, nil
|
||||
|
@ -32,7 +32,6 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
testNetmonVersion = "netmon version 0.1"
|
||||
testHypervisorVersion = "QEMU emulator version 2.7.0+git.741f430a96-6.1, Copyright (c) 2003-2016 Fabrice Bellard and the QEMU Project developers"
|
||||
)
|
||||
|
||||
@ -41,7 +40,6 @@ var (
|
||||
enableVirtioFS = false
|
||||
runtimeDebug = false
|
||||
runtimeTrace = false
|
||||
netmonDebug = false
|
||||
agentDebug = false
|
||||
agentTrace = false
|
||||
)
|
||||
@ -83,7 +81,6 @@ func makeRuntimeConfig(prefixDir string) (configFile string, config oci.RuntimeC
|
||||
imagePath := filepath.Join(prefixDir, "image")
|
||||
kernelParams := "foo=bar xyz"
|
||||
machineType := "machineType"
|
||||
netmonPath := filepath.Join(prefixDir, "netmon")
|
||||
disableBlock := true
|
||||
blockStorageDriver := "virtio-scsi"
|
||||
enableIOThreads := true
|
||||
@ -107,11 +104,6 @@ func makeRuntimeConfig(prefixDir string) (configFile string, config oci.RuntimeC
|
||||
}
|
||||
}
|
||||
|
||||
err = makeVersionBinary(netmonPath, testNetmonVersion)
|
||||
if err != nil {
|
||||
return "", oci.RuntimeConfig{}, err
|
||||
}
|
||||
|
||||
err = makeVersionBinary(hypervisorPath, testHypervisorVersion)
|
||||
if err != nil {
|
||||
return "", oci.RuntimeConfig{}, err
|
||||
@ -130,7 +122,6 @@ func makeRuntimeConfig(prefixDir string) (configFile string, config oci.RuntimeC
|
||||
ImagePath: imagePath,
|
||||
KernelParams: kernelParams,
|
||||
MachineType: machineType,
|
||||
NetmonPath: netmonPath,
|
||||
LogPath: logPath,
|
||||
DefaultGuestHookPath: hypConfig.GuestHookPath,
|
||||
DisableBlock: disableBlock,
|
||||
@ -146,7 +137,6 @@ func makeRuntimeConfig(prefixDir string) (configFile string, config oci.RuntimeC
|
||||
HypervisorDebug: hypervisorDebug,
|
||||
RuntimeDebug: runtimeDebug,
|
||||
RuntimeTrace: runtimeTrace,
|
||||
NetmonDebug: netmonDebug,
|
||||
AgentDebug: agentDebug,
|
||||
AgentTrace: agentTrace,
|
||||
SharedFS: sharedFS,
|
||||
@ -169,15 +159,6 @@ func makeRuntimeConfig(prefixDir string) (configFile string, config oci.RuntimeC
|
||||
return configFile, config, nil
|
||||
}
|
||||
|
||||
func getExpectedNetmonDetails(config oci.RuntimeConfig) (NetmonInfo, error) {
|
||||
return NetmonInfo{
|
||||
Version: constructVersionInfo(testNetmonVersion),
|
||||
Path: config.NetmonConfig.Path,
|
||||
Debug: config.NetmonConfig.Debug,
|
||||
Enable: config.NetmonConfig.Enable,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func getExpectedAgentDetails(config oci.RuntimeConfig) (AgentInfo, error) {
|
||||
|
||||
agentConfig := config.AgentConfig
|
||||
@ -352,11 +333,6 @@ func getExpectedSettings(config oci.RuntimeConfig, tmpdir, configFile string) (E
|
||||
return EnvInfo{}, err
|
||||
}
|
||||
|
||||
netmon, err := getExpectedNetmonDetails(config)
|
||||
if err != nil {
|
||||
return EnvInfo{}, err
|
||||
}
|
||||
|
||||
hypervisor := getExpectedHypervisor(config)
|
||||
kernel := getExpectedKernel(config)
|
||||
image := getExpectedImage(config)
|
||||
@ -369,7 +345,6 @@ func getExpectedSettings(config oci.RuntimeConfig, tmpdir, configFile string) (E
|
||||
Kernel: kernel,
|
||||
Agent: agent,
|
||||
Host: host,
|
||||
Netmon: netmon,
|
||||
}
|
||||
|
||||
return env, nil
|
||||
@ -612,50 +587,6 @@ func TestEnvGetRuntimeInfo(t *testing.T) {
|
||||
assert.Equal(t, expectedRuntime, runtime)
|
||||
}
|
||||
|
||||
func TestEnvGetNetmonInfo(t *testing.T) {
|
||||
tmpdir, err := ioutil.TempDir("", "")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer os.RemoveAll(tmpdir)
|
||||
|
||||
_, config, err := makeRuntimeConfig(tmpdir)
|
||||
assert.NoError(t, err)
|
||||
|
||||
expectedNetmon, err := getExpectedNetmonDetails(config)
|
||||
assert.NoError(t, err)
|
||||
|
||||
netmon := getNetmonInfo(config)
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Equal(t, expectedNetmon, netmon)
|
||||
}
|
||||
|
||||
func TestEnvGetNetmonInfoNoVersion(t *testing.T) {
|
||||
tmpdir, err := ioutil.TempDir("", "")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer os.RemoveAll(tmpdir)
|
||||
|
||||
_, config, err := makeRuntimeConfig(tmpdir)
|
||||
assert.NoError(t, err)
|
||||
|
||||
expectedNetmon, err := getExpectedNetmonDetails(config)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// remove the netmon ensuring its version cannot be queried
|
||||
err = os.Remove(config.NetmonConfig.Path)
|
||||
assert.NoError(t, err)
|
||||
|
||||
expectedNetmon.Version = unknownVersionInfo
|
||||
|
||||
netmon := getNetmonInfo(config)
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Equal(t, expectedNetmon, netmon)
|
||||
}
|
||||
|
||||
func TestEnvGetAgentInfo(t *testing.T) {
|
||||
tmpdir, err := ioutil.TempDir("", "")
|
||||
if err != nil {
|
||||
|
@ -1,683 +0,0 @@
|
||||
// Copyright (c) 2018 Intel Corporation
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log/syslog"
|
||||
"net"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/kata-containers/kata-containers/src/runtime/pkg/signals"
|
||||
pbTypes "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/agent/protocols"
|
||||
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/utils"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
lSyslog "github.com/sirupsen/logrus/hooks/syslog"
|
||||
"github.com/vishvananda/netlink"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
const (
|
||||
netmonName = "kata-netmon"
|
||||
|
||||
kataCmd = "kata-network"
|
||||
kataCLIAddIfaceCmd = "add-iface"
|
||||
kataCLIDelIfaceCmd = "del-iface"
|
||||
kataCLIUpdtRoutesCmd = "update-routes"
|
||||
|
||||
kataSuffix = "kata"
|
||||
|
||||
// sharedFile is the name of the file that will be used to share
|
||||
// the data between this process and the kata-runtime process
|
||||
// responsible for updating the network.
|
||||
sharedFile = "shared.json"
|
||||
storageFilePerm = os.FileMode(0640)
|
||||
storageDirPerm = os.FileMode(0750)
|
||||
)
|
||||
|
||||
var (
|
||||
// version is the netmon version. This variable is populated at build time.
|
||||
version = "unknown"
|
||||
|
||||
// For simplicity the code will only focus on IPv4 addresses for now.
|
||||
netlinkFamily = netlink.FAMILY_ALL
|
||||
|
||||
storageParentPath = "/var/run/kata-containers/netmon/sbs"
|
||||
)
|
||||
|
||||
type netmonParams struct {
|
||||
sandboxID string
|
||||
runtimePath string
|
||||
logLevel string
|
||||
debug bool
|
||||
}
|
||||
|
||||
type netmon struct {
|
||||
netIfaces map[int]pbTypes.Interface
|
||||
|
||||
linkUpdateCh chan netlink.LinkUpdate
|
||||
linkDoneCh chan struct{}
|
||||
|
||||
rtUpdateCh chan netlink.RouteUpdate
|
||||
rtDoneCh chan struct{}
|
||||
|
||||
netHandler *netlink.Handle
|
||||
|
||||
storagePath string
|
||||
sharedFile string
|
||||
|
||||
netmonParams
|
||||
}
|
||||
|
||||
var netmonLog = logrus.New()
|
||||
|
||||
func printVersion() {
|
||||
fmt.Printf("%s version %s\n", netmonName, version)
|
||||
}
|
||||
|
||||
const componentDescription = `is a network monitoring process that is intended to be started in the
|
||||
appropriate network namespace so that it can listen to any event related to
|
||||
link and routes. Whenever a new interface or route is created/updated, it is
|
||||
responsible for calling into the kata-runtime CLI to ask for the actual
|
||||
creation/update of the given interface or route.
|
||||
`
|
||||
|
||||
func printComponentDescription() {
|
||||
fmt.Printf("\n%s %s\n", netmonName, componentDescription)
|
||||
}
|
||||
|
||||
func parseOptions() netmonParams {
|
||||
var version, help bool
|
||||
|
||||
params := netmonParams{}
|
||||
|
||||
flag.BoolVar(&help, "h", false, "describe component usage")
|
||||
flag.BoolVar(&help, "help", false, "")
|
||||
flag.BoolVar(¶ms.debug, "d", false, "enable debug mode")
|
||||
flag.BoolVar(&version, "v", false, "display program version and exit")
|
||||
flag.BoolVar(&version, "version", false, "")
|
||||
flag.StringVar(¶ms.sandboxID, "s", "", "sandbox id (required)")
|
||||
flag.StringVar(¶ms.runtimePath, "r", "", "runtime path (required)")
|
||||
flag.StringVar(¶ms.logLevel, "log", "warn",
|
||||
"log messages above specified level: debug, warn, error, fatal or panic")
|
||||
|
||||
flag.Parse()
|
||||
|
||||
if help {
|
||||
printComponentDescription()
|
||||
flag.PrintDefaults()
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
if version {
|
||||
printVersion()
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
if params.sandboxID == "" {
|
||||
fmt.Fprintf(os.Stderr, "Error: sandbox id is empty, one must be provided\n")
|
||||
flag.PrintDefaults()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if params.runtimePath == "" {
|
||||
fmt.Fprintf(os.Stderr, "Error: runtime path is empty, one must be provided\n")
|
||||
flag.PrintDefaults()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
return params
|
||||
}
|
||||
|
||||
func newNetmon(params netmonParams) (*netmon, error) {
|
||||
handler, err := netlink.NewHandle(netlinkFamily)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
n := &netmon{
|
||||
netmonParams: params,
|
||||
storagePath: filepath.Join(storageParentPath, params.sandboxID),
|
||||
sharedFile: filepath.Join(storageParentPath, params.sandboxID, sharedFile),
|
||||
netIfaces: make(map[int]pbTypes.Interface),
|
||||
linkUpdateCh: make(chan netlink.LinkUpdate),
|
||||
linkDoneCh: make(chan struct{}),
|
||||
rtUpdateCh: make(chan netlink.RouteUpdate),
|
||||
rtDoneCh: make(chan struct{}),
|
||||
netHandler: handler,
|
||||
}
|
||||
|
||||
if err := os.MkdirAll(n.storagePath, storageDirPerm); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return n, nil
|
||||
}
|
||||
|
||||
func (n *netmon) cleanup() {
|
||||
os.RemoveAll(n.storagePath)
|
||||
n.netHandler.Close()
|
||||
close(n.linkDoneCh)
|
||||
close(n.rtDoneCh)
|
||||
}
|
||||
|
||||
// setupSignalHandler sets up signal handling, starting a go routine to deal
|
||||
// with signals as they arrive.
|
||||
func (n *netmon) setupSignalHandler() {
|
||||
signals.SetLogger(n.logger())
|
||||
|
||||
sigCh := make(chan os.Signal, 8)
|
||||
|
||||
for _, sig := range signals.HandledSignals() {
|
||||
signal.Notify(sigCh, sig)
|
||||
}
|
||||
|
||||
go func() {
|
||||
for {
|
||||
sig := <-sigCh
|
||||
|
||||
nativeSignal, ok := sig.(syscall.Signal)
|
||||
if !ok {
|
||||
err := errors.New("unknown signal")
|
||||
netmonLog.WithError(err).WithField("signal", sig.String()).Error()
|
||||
continue
|
||||
}
|
||||
|
||||
if signals.FatalSignal(nativeSignal) {
|
||||
netmonLog.WithField("signal", sig).Error("received fatal signal")
|
||||
signals.Die(nil)
|
||||
} else if n.debug && signals.NonFatalSignal(nativeSignal) {
|
||||
netmonLog.WithField("signal", sig).Debug("handling signal")
|
||||
signals.Backtrace()
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func (n *netmon) logger() *logrus.Entry {
|
||||
fields := logrus.Fields{
|
||||
"name": netmonName,
|
||||
"pid": os.Getpid(),
|
||||
"source": "netmon",
|
||||
}
|
||||
|
||||
if n.sandboxID != "" {
|
||||
fields["sandbox"] = n.sandboxID
|
||||
}
|
||||
|
||||
return netmonLog.WithFields(fields)
|
||||
}
|
||||
|
||||
func (n *netmon) setupLogger() error {
|
||||
level, err := logrus.ParseLevel(n.logLevel)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
netmonLog.SetLevel(level)
|
||||
|
||||
netmonLog.Formatter = &logrus.TextFormatter{TimestampFormat: time.RFC3339Nano}
|
||||
|
||||
hook, err := lSyslog.NewSyslogHook("", "", syslog.LOG_INFO|syslog.LOG_USER, netmonName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
netmonLog.AddHook(hook)
|
||||
|
||||
announceFields := logrus.Fields{
|
||||
"runtime-path": n.runtimePath,
|
||||
"debug": n.debug,
|
||||
"log-level": n.logLevel,
|
||||
}
|
||||
|
||||
n.logger().WithFields(announceFields).Info("announce")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *netmon) listenNetlinkEvents() error {
|
||||
if err := netlink.LinkSubscribe(n.linkUpdateCh, n.linkDoneCh); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return netlink.RouteSubscribe(n.rtUpdateCh, n.rtDoneCh)
|
||||
}
|
||||
|
||||
// convertInterface converts a link and its IP addresses as defined by netlink
|
||||
// package, into the Interface structure format expected by kata-runtime to
|
||||
// describe an interface and its associated IP addresses.
|
||||
func convertInterface(linkAttrs *netlink.LinkAttrs, linkType string, addrs []netlink.Addr) pbTypes.Interface {
|
||||
if linkAttrs == nil {
|
||||
netmonLog.Warn("Link attributes are nil")
|
||||
return pbTypes.Interface{}
|
||||
}
|
||||
|
||||
var ipAddrs []*pbTypes.IPAddress
|
||||
|
||||
for _, addr := range addrs {
|
||||
if addr.IPNet == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
netMask, _ := addr.Mask.Size()
|
||||
|
||||
ipAddr := &pbTypes.IPAddress{
|
||||
Address: addr.IP.String(),
|
||||
Mask: fmt.Sprintf("%d", netMask),
|
||||
}
|
||||
|
||||
if addr.IP.To4() != nil {
|
||||
ipAddr.Family = utils.ConvertNetlinkFamily(netlink.FAMILY_V4)
|
||||
} else {
|
||||
ipAddr.Family = utils.ConvertNetlinkFamily(netlink.FAMILY_V6)
|
||||
}
|
||||
|
||||
ipAddrs = append(ipAddrs, ipAddr)
|
||||
}
|
||||
|
||||
iface := pbTypes.Interface{
|
||||
Device: linkAttrs.Name,
|
||||
Name: linkAttrs.Name,
|
||||
IPAddresses: ipAddrs,
|
||||
Mtu: uint64(linkAttrs.MTU),
|
||||
HwAddr: linkAttrs.HardwareAddr.String(),
|
||||
Type: linkType,
|
||||
}
|
||||
|
||||
netmonLog.WithField("interface", iface).Debug("Interface converted")
|
||||
|
||||
return iface
|
||||
}
|
||||
|
||||
// convertRoutes converts a list of routes as defined by netlink package,
|
||||
// into a list of Route structure format expected by kata-runtime to
|
||||
// describe a set of routes.
|
||||
func convertRoutes(netRoutes []netlink.Route) []pbTypes.Route {
|
||||
var routes []pbTypes.Route
|
||||
|
||||
for _, netRoute := range netRoutes {
|
||||
dst := ""
|
||||
|
||||
if netRoute.Protocol == unix.RTPROT_KERNEL {
|
||||
continue
|
||||
}
|
||||
|
||||
if netRoute.Dst != nil {
|
||||
dst = netRoute.Dst.String()
|
||||
if netRoute.Dst.IP.To4() != nil || netRoute.Dst.IP.To16() != nil {
|
||||
dst = netRoute.Dst.String()
|
||||
} else {
|
||||
netmonLog.WithField("destination", netRoute.Dst.IP.String()).Warn("Unexpected network address format")
|
||||
}
|
||||
}
|
||||
|
||||
src := ""
|
||||
if netRoute.Src != nil {
|
||||
if netRoute.Src.To4() != nil || netRoute.Src.To16() != nil {
|
||||
src = netRoute.Src.String()
|
||||
} else {
|
||||
netmonLog.WithField("source", netRoute.Src.String()).Warn("Unexpected network address format")
|
||||
}
|
||||
}
|
||||
|
||||
gw := ""
|
||||
if netRoute.Gw != nil {
|
||||
if netRoute.Gw.To4() != nil || netRoute.Gw.To16() != nil {
|
||||
gw = netRoute.Gw.String()
|
||||
} else {
|
||||
netmonLog.WithField("gateway", netRoute.Gw.String()).Warn("Unexpected network address format")
|
||||
}
|
||||
}
|
||||
|
||||
dev := ""
|
||||
iface, err := net.InterfaceByIndex(netRoute.LinkIndex)
|
||||
if err == nil {
|
||||
dev = iface.Name
|
||||
}
|
||||
|
||||
route := pbTypes.Route{
|
||||
Dest: dst,
|
||||
Gateway: gw,
|
||||
Device: dev,
|
||||
Source: src,
|
||||
Scope: uint32(netRoute.Scope),
|
||||
}
|
||||
|
||||
routes = append(routes, route)
|
||||
}
|
||||
|
||||
netmonLog.WithField("routes", routes).Debug("Routes converted")
|
||||
|
||||
return routes
|
||||
}
|
||||
|
||||
// scanNetwork lists all the interfaces it can find inside the current
|
||||
// network namespace, and store them in-memory to keep track of them.
|
||||
func (n *netmon) scanNetwork() error {
|
||||
links, err := n.netHandler.LinkList()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, link := range links {
|
||||
addrs, err := n.netHandler.AddrList(link, netlinkFamily)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
linkAttrs := link.Attrs()
|
||||
if linkAttrs == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
iface := convertInterface(linkAttrs, link.Type(), addrs)
|
||||
n.netIfaces[linkAttrs.Index] = iface
|
||||
}
|
||||
|
||||
n.logger().Debug("Network scanned")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *netmon) storeDataToSend(data interface{}) error {
|
||||
// Marshal the data structure into a JSON bytes array.
|
||||
jsonArray, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Store the JSON bytes array at the specified path.
|
||||
return ioutil.WriteFile(n.sharedFile, jsonArray, storageFilePerm)
|
||||
}
|
||||
|
||||
func (n *netmon) execKataCmd(subCmd string) error {
|
||||
execCmd := exec.Command(n.runtimePath, kataCmd, subCmd, n.sandboxID, n.sharedFile)
|
||||
|
||||
n.logger().WithField("command", execCmd).Debug("Running runtime command")
|
||||
|
||||
// Make use of Run() to ensure the kata-runtime process has correctly
|
||||
// terminated before to go further.
|
||||
if err := execCmd.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Remove the shared file after the command returned. At this point
|
||||
// we know the content of the file is not going to be used anymore,
|
||||
// and the file path can be reused for further commands.
|
||||
return os.Remove(n.sharedFile)
|
||||
}
|
||||
|
||||
func (n *netmon) addInterfaceCLI(iface pbTypes.Interface) error {
|
||||
if err := n.storeDataToSend(iface); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return n.execKataCmd(kataCLIAddIfaceCmd)
|
||||
}
|
||||
|
||||
func (n *netmon) delInterfaceCLI(iface pbTypes.Interface) error {
|
||||
if err := n.storeDataToSend(iface); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return n.execKataCmd(kataCLIDelIfaceCmd)
|
||||
}
|
||||
|
||||
func (n *netmon) updateRoutesCLI(routes []pbTypes.Route) error {
|
||||
if err := n.storeDataToSend(routes); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return n.execKataCmd(kataCLIUpdtRoutesCmd)
|
||||
}
|
||||
|
||||
func (n *netmon) updateRoutes() error {
|
||||
// Get all the routes.
|
||||
netlinkRoutes, err := n.netHandler.RouteList(nil, netlinkFamily)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Translate them into Route structures.
|
||||
routes := convertRoutes(netlinkRoutes)
|
||||
|
||||
// Update the routes through the Kata CLI.
|
||||
return n.updateRoutesCLI(routes)
|
||||
}
|
||||
|
||||
func (n *netmon) handleRTMNewAddr(ev netlink.LinkUpdate) error {
|
||||
n.logger().Debug("Interface update not supported")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *netmon) handleRTMDelAddr(ev netlink.LinkUpdate) error {
|
||||
n.logger().Debug("Interface update not supported")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *netmon) handleRTMNewLink(ev netlink.LinkUpdate) error {
|
||||
// NEWLINK might be a lot of different things. We're interested in
|
||||
// adding the interface (both to our list and by calling into the
|
||||
// Kata CLI API) only if this has the flags UP and RUNNING, meaning
|
||||
// we don't expect any further change on the interface, and that we
|
||||
// are ready to add it.
|
||||
|
||||
linkAttrs := ev.Link.Attrs()
|
||||
if linkAttrs == nil {
|
||||
n.logger().Warn("The link attributes are nil")
|
||||
return nil
|
||||
}
|
||||
|
||||
// First, ignore if the interface name contains "kata". This way we
|
||||
// are preventing from adding interfaces created by Kata Containers.
|
||||
if strings.HasSuffix(linkAttrs.Name, kataSuffix) {
|
||||
n.logger().Debugf("Ignore the interface %s because found %q",
|
||||
linkAttrs.Name, kataSuffix)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Check if the interface exist in the internal list.
|
||||
if _, exist := n.netIfaces[int(ev.Index)]; exist {
|
||||
n.logger().Debugf("Ignoring interface %s because already exist",
|
||||
linkAttrs.Name)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Now, check if the interface has been enabled to UP and RUNNING.
|
||||
if (ev.Flags&unix.IFF_UP) != unix.IFF_UP ||
|
||||
(ev.Flags&unix.IFF_RUNNING) != unix.IFF_RUNNING {
|
||||
n.logger().Debugf("Ignore the interface %s because not UP and RUNNING",
|
||||
linkAttrs.Name)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get the list of IP addresses associated with this interface.
|
||||
addrs, err := n.netHandler.AddrList(ev.Link, netlinkFamily)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Convert the interfaces in the appropriate structure format.
|
||||
iface := convertInterface(linkAttrs, ev.Link.Type(), addrs)
|
||||
|
||||
// Add the interface through the Kata CLI.
|
||||
if err := n.addInterfaceCLI(iface); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Add the interface to the internal list.
|
||||
n.netIfaces[linkAttrs.Index] = iface
|
||||
|
||||
// Complete by updating the routes.
|
||||
return n.updateRoutes()
|
||||
}
|
||||
|
||||
func (n *netmon) handleRTMDelLink(ev netlink.LinkUpdate) error {
|
||||
// It can only delete if identical interface is found in the internal
|
||||
// list of interfaces. Otherwise, the deletion will be ignored.
|
||||
linkAttrs := ev.Link.Attrs()
|
||||
if linkAttrs == nil {
|
||||
n.logger().Warn("Link attributes are nil")
|
||||
return nil
|
||||
}
|
||||
|
||||
// First, ignore if the interface name contains "kata". This way we
|
||||
// are preventing from deleting interfaces created by Kata Containers.
|
||||
if strings.Contains(linkAttrs.Name, kataSuffix) {
|
||||
n.logger().Debugf("Ignore the interface %s because found %q",
|
||||
linkAttrs.Name, kataSuffix)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Check if the interface exist in the internal list.
|
||||
iface, exist := n.netIfaces[int(ev.Index)]
|
||||
if !exist {
|
||||
n.logger().Debugf("Ignoring interface %s because not found",
|
||||
linkAttrs.Name)
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := n.delInterfaceCLI(iface); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Delete the interface from the internal list.
|
||||
delete(n.netIfaces, linkAttrs.Index)
|
||||
|
||||
// Complete by updating the routes.
|
||||
return n.updateRoutes()
|
||||
}
|
||||
|
||||
func (n *netmon) handleRTMNewRoute(ev netlink.RouteUpdate) error {
|
||||
// Add the route through updateRoutes(), only if the route refer to an
|
||||
// interface that already exists in the internal list of interfaces.
|
||||
if _, exist := n.netIfaces[ev.Route.LinkIndex]; !exist {
|
||||
n.logger().Debugf("Ignoring route %+v since interface %d not found",
|
||||
ev.Route, ev.Route.LinkIndex)
|
||||
return nil
|
||||
}
|
||||
|
||||
return n.updateRoutes()
|
||||
}
|
||||
|
||||
func (n *netmon) handleRTMDelRoute(ev netlink.RouteUpdate) error {
|
||||
// Remove the route through updateRoutes(), only if the route refer to
|
||||
// an interface that already exists in the internal list of interfaces.
|
||||
return n.updateRoutes()
|
||||
}
|
||||
|
||||
func (n *netmon) handleLinkEvent(ev netlink.LinkUpdate) error {
|
||||
n.logger().Debug("handleLinkEvent: netlink event received")
|
||||
|
||||
switch ev.Header.Type {
|
||||
case unix.NLMSG_DONE:
|
||||
n.logger().Debug("NLMSG_DONE")
|
||||
return nil
|
||||
case unix.NLMSG_ERROR:
|
||||
n.logger().Error("NLMSG_ERROR")
|
||||
return fmt.Errorf("Error while listening on netlink socket")
|
||||
case unix.RTM_NEWADDR:
|
||||
n.logger().Debug("RTM_NEWADDR")
|
||||
return n.handleRTMNewAddr(ev)
|
||||
case unix.RTM_DELADDR:
|
||||
n.logger().Debug("RTM_DELADDR")
|
||||
return n.handleRTMDelAddr(ev)
|
||||
case unix.RTM_NEWLINK:
|
||||
n.logger().Debug("RTM_NEWLINK")
|
||||
return n.handleRTMNewLink(ev)
|
||||
case unix.RTM_DELLINK:
|
||||
n.logger().Debug("RTM_DELLINK")
|
||||
return n.handleRTMDelLink(ev)
|
||||
default:
|
||||
n.logger().Warnf("Unknown msg type %v", ev.Header.Type)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *netmon) handleRouteEvent(ev netlink.RouteUpdate) error {
|
||||
n.logger().Debug("handleRouteEvent: netlink event received")
|
||||
|
||||
switch ev.Type {
|
||||
case unix.RTM_NEWROUTE:
|
||||
n.logger().Debug("RTM_NEWROUTE")
|
||||
return n.handleRTMNewRoute(ev)
|
||||
case unix.RTM_DELROUTE:
|
||||
n.logger().Debug("RTM_DELROUTE")
|
||||
return n.handleRTMDelRoute(ev)
|
||||
default:
|
||||
n.logger().Warnf("Unknown msg type %v", ev.Type)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *netmon) handleEvents() (err error) {
|
||||
for {
|
||||
select {
|
||||
case ev := <-n.linkUpdateCh:
|
||||
if err = n.handleLinkEvent(ev); err != nil {
|
||||
return err
|
||||
}
|
||||
case ev := <-n.rtUpdateCh:
|
||||
if err = n.handleRouteEvent(ev); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
// Parse parameters.
|
||||
params := parseOptions()
|
||||
|
||||
// Create netmon handler.
|
||||
n, err := newNetmon(params)
|
||||
if err != nil {
|
||||
netmonLog.WithError(err).Fatal("newNetmon()")
|
||||
os.Exit(1)
|
||||
}
|
||||
defer n.cleanup()
|
||||
|
||||
// Init logger.
|
||||
if err := n.setupLogger(); err != nil {
|
||||
netmonLog.WithError(err).Fatal("setupLogger()")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Setup signal handlers
|
||||
n.setupSignalHandler()
|
||||
|
||||
// Scan the current interfaces.
|
||||
if err := n.scanNetwork(); err != nil {
|
||||
n.logger().WithError(err).Fatal("scanNetwork()")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Subscribe to the link listener.
|
||||
if err := n.listenNetlinkEvents(); err != nil {
|
||||
n.logger().WithError(err).Fatal("listenNetlinkEvents()")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Go into the main loop.
|
||||
if err := n.handleEvents(); err != nil {
|
||||
n.logger().WithError(err).Fatal("handleEvents()")
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
@ -1,701 +0,0 @@
|
||||
// Copyright (c) 2018 Intel Corporation
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
ktu "github.com/kata-containers/kata-containers/src/runtime/pkg/katatestutils"
|
||||
pbTypes "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/agent/protocols"
|
||||
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/utils"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/vishvananda/netlink"
|
||||
"github.com/vishvananda/netns"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
const (
|
||||
testSandboxID = "123456789"
|
||||
testRuntimePath = "/foo/bar/test-runtime"
|
||||
testLogLevel = "info"
|
||||
testStorageParentPath = "/tmp/netmon"
|
||||
testSharedFile = "foo-shared.json"
|
||||
testWrongNetlinkFamily = -1
|
||||
testIfaceName = "test_eth0"
|
||||
testMTU = 12345
|
||||
testHwAddr = "02:00:ca:fe:00:48"
|
||||
testIPAddress = "192.168.0.15"
|
||||
testIPAddressWithMask = "192.168.0.15/32"
|
||||
testIP6Address = "2001:db8:1::242:ac11:2"
|
||||
testIP6AddressWithMask = "2001:db8:1::/64"
|
||||
testScope = 1
|
||||
testTxQLen = -1
|
||||
testIfaceIndex = 5
|
||||
)
|
||||
|
||||
func skipUnlessRoot(t *testing.T) {
|
||||
tc := ktu.NewTestConstraint(false)
|
||||
|
||||
if tc.NotValid(ktu.NeedRoot()) {
|
||||
t.Skip("Test disabled as requires root user")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewNetmon(t *testing.T) {
|
||||
skipUnlessRoot(t)
|
||||
|
||||
// Override storageParentPath
|
||||
savedStorageParentPath := storageParentPath
|
||||
storageParentPath = testStorageParentPath
|
||||
defer func() {
|
||||
storageParentPath = savedStorageParentPath
|
||||
}()
|
||||
|
||||
params := netmonParams{
|
||||
sandboxID: testSandboxID,
|
||||
runtimePath: testRuntimePath,
|
||||
debug: true,
|
||||
logLevel: testLogLevel,
|
||||
}
|
||||
|
||||
expected := &netmon{
|
||||
netmonParams: params,
|
||||
storagePath: filepath.Join(storageParentPath, params.sandboxID),
|
||||
sharedFile: filepath.Join(storageParentPath, params.sandboxID, sharedFile),
|
||||
}
|
||||
|
||||
os.RemoveAll(expected.storagePath)
|
||||
|
||||
got, err := newNetmon(params)
|
||||
assert.Nil(t, err)
|
||||
assert.True(t, reflect.DeepEqual(expected.netmonParams, got.netmonParams),
|
||||
"Got %+v\nExpected %+v", got.netmonParams, expected.netmonParams)
|
||||
assert.True(t, reflect.DeepEqual(expected.storagePath, got.storagePath),
|
||||
"Got %+v\nExpected %+v", got.storagePath, expected.storagePath)
|
||||
assert.True(t, reflect.DeepEqual(expected.sharedFile, got.sharedFile),
|
||||
"Got %+v\nExpected %+v", got.sharedFile, expected.sharedFile)
|
||||
|
||||
_, err = os.Stat(got.storagePath)
|
||||
assert.Nil(t, err)
|
||||
|
||||
os.RemoveAll(got.storagePath)
|
||||
}
|
||||
|
||||
func TestNewNetmonErrorWrongFamilyType(t *testing.T) {
|
||||
// Override netlinkFamily
|
||||
savedNetlinkFamily := netlinkFamily
|
||||
netlinkFamily = testWrongNetlinkFamily
|
||||
defer func() {
|
||||
netlinkFamily = savedNetlinkFamily
|
||||
}()
|
||||
|
||||
n, err := newNetmon(netmonParams{})
|
||||
assert.NotNil(t, err)
|
||||
assert.Nil(t, n)
|
||||
}
|
||||
|
||||
func TestCleanup(t *testing.T) {
|
||||
skipUnlessRoot(t)
|
||||
|
||||
// Override storageParentPath
|
||||
savedStorageParentPath := storageParentPath
|
||||
storageParentPath = testStorageParentPath
|
||||
defer func() {
|
||||
storageParentPath = savedStorageParentPath
|
||||
}()
|
||||
|
||||
handler, err := netlink.NewHandle(netlinkFamily)
|
||||
assert.Nil(t, err)
|
||||
|
||||
n := &netmon{
|
||||
storagePath: filepath.Join(storageParentPath, testSandboxID),
|
||||
linkDoneCh: make(chan struct{}),
|
||||
rtDoneCh: make(chan struct{}),
|
||||
netHandler: handler,
|
||||
}
|
||||
|
||||
err = os.MkdirAll(n.storagePath, storageDirPerm)
|
||||
assert.Nil(t, err)
|
||||
_, err = os.Stat(n.storagePath)
|
||||
assert.Nil(t, err)
|
||||
|
||||
n.cleanup()
|
||||
|
||||
_, err = os.Stat(n.storagePath)
|
||||
assert.NotNil(t, err)
|
||||
_, ok := (<-n.linkDoneCh)
|
||||
assert.False(t, ok)
|
||||
_, ok = (<-n.rtDoneCh)
|
||||
assert.False(t, ok)
|
||||
}
|
||||
|
||||
func TestLogger(t *testing.T) {
|
||||
fields := logrus.Fields{
|
||||
"name": netmonName,
|
||||
"pid": os.Getpid(),
|
||||
"source": "netmon",
|
||||
"sandbox": testSandboxID,
|
||||
}
|
||||
|
||||
expected := netmonLog.WithFields(fields)
|
||||
|
||||
n := &netmon{
|
||||
netmonParams: netmonParams{
|
||||
sandboxID: testSandboxID,
|
||||
},
|
||||
}
|
||||
|
||||
got := n.logger()
|
||||
assert.True(t, reflect.DeepEqual(*expected, *got),
|
||||
"Got %+v\nExpected %+v", *got, *expected)
|
||||
}
|
||||
|
||||
func TestConvertInterface(t *testing.T) {
|
||||
hwAddr, err := net.ParseMAC(testHwAddr)
|
||||
assert.Nil(t, err)
|
||||
|
||||
addrs := []netlink.Addr{
|
||||
{
|
||||
IPNet: &net.IPNet{
|
||||
IP: net.ParseIP(testIPAddress),
|
||||
},
|
||||
},
|
||||
{
|
||||
IPNet: &net.IPNet{
|
||||
IP: net.ParseIP(testIP6Address),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
linkAttrs := &netlink.LinkAttrs{
|
||||
Name: testIfaceName,
|
||||
MTU: testMTU,
|
||||
HardwareAddr: hwAddr,
|
||||
}
|
||||
|
||||
linkType := "link_type_test"
|
||||
|
||||
expected := pbTypes.Interface{
|
||||
Device: testIfaceName,
|
||||
Name: testIfaceName,
|
||||
Mtu: uint64(testMTU),
|
||||
HwAddr: testHwAddr,
|
||||
IPAddresses: []*pbTypes.IPAddress{
|
||||
{
|
||||
Family: utils.ConvertNetlinkFamily(netlink.FAMILY_V4),
|
||||
Address: testIPAddress,
|
||||
Mask: "0",
|
||||
},
|
||||
{
|
||||
Family: utils.ConvertNetlinkFamily(netlink.FAMILY_V6),
|
||||
Address: testIP6Address,
|
||||
Mask: "0",
|
||||
},
|
||||
},
|
||||
Type: linkType,
|
||||
}
|
||||
|
||||
got := convertInterface(linkAttrs, linkType, addrs)
|
||||
|
||||
assert.True(t, reflect.DeepEqual(expected, got),
|
||||
"Got %+v\nExpected %+v", got, expected)
|
||||
}
|
||||
|
||||
func TestConvertRoutes(t *testing.T) {
|
||||
ip, ipNet, err := net.ParseCIDR(testIPAddressWithMask)
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, ipNet)
|
||||
|
||||
_, ip6Net, err := net.ParseCIDR(testIP6AddressWithMask)
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, ipNet)
|
||||
|
||||
routes := []netlink.Route{
|
||||
{
|
||||
Dst: ipNet,
|
||||
Src: ip,
|
||||
Gw: ip,
|
||||
LinkIndex: -1,
|
||||
Scope: testScope,
|
||||
},
|
||||
{
|
||||
Dst: ip6Net,
|
||||
Src: nil,
|
||||
Gw: nil,
|
||||
LinkIndex: -1,
|
||||
Scope: testScope,
|
||||
},
|
||||
}
|
||||
|
||||
expected := []pbTypes.Route{
|
||||
{
|
||||
Dest: testIPAddressWithMask,
|
||||
Gateway: testIPAddress,
|
||||
Source: testIPAddress,
|
||||
Scope: uint32(testScope),
|
||||
},
|
||||
{
|
||||
Dest: testIP6AddressWithMask,
|
||||
Gateway: "",
|
||||
Source: "",
|
||||
Scope: uint32(testScope),
|
||||
},
|
||||
}
|
||||
|
||||
got := convertRoutes(routes)
|
||||
assert.True(t, reflect.DeepEqual(expected, got),
|
||||
"Got %+v\nExpected %+v", got, expected)
|
||||
}
|
||||
|
||||
type testTeardownNetwork func()
|
||||
|
||||
func testSetupNetwork(t *testing.T) testTeardownNetwork {
|
||||
skipUnlessRoot(t)
|
||||
|
||||
// new temporary namespace so we don't pollute the host
|
||||
// lock thread since the namespace is thread local
|
||||
runtime.LockOSThread()
|
||||
var err error
|
||||
ns, err := netns.New()
|
||||
if err != nil {
|
||||
t.Fatal("Failed to create newns", ns)
|
||||
}
|
||||
|
||||
return func() {
|
||||
ns.Close()
|
||||
runtime.UnlockOSThread()
|
||||
}
|
||||
}
|
||||
|
||||
func testCreateDummyNetwork(t *testing.T, handler *netlink.Handle) (int, pbTypes.Interface) {
|
||||
hwAddr, err := net.ParseMAC(testHwAddr)
|
||||
assert.Nil(t, err)
|
||||
|
||||
link := &netlink.Dummy{
|
||||
LinkAttrs: netlink.LinkAttrs{
|
||||
MTU: testMTU,
|
||||
TxQLen: testTxQLen,
|
||||
Name: testIfaceName,
|
||||
HardwareAddr: hwAddr,
|
||||
},
|
||||
}
|
||||
|
||||
err = handler.LinkAdd(link)
|
||||
assert.Nil(t, err)
|
||||
err = handler.LinkSetUp(link)
|
||||
assert.Nil(t, err)
|
||||
|
||||
attrs := link.Attrs()
|
||||
assert.NotNil(t, attrs)
|
||||
|
||||
addrs, err := handler.AddrList(link, netlinkFamily)
|
||||
assert.Nil(t, err)
|
||||
|
||||
var ipAddrs []*pbTypes.IPAddress
|
||||
|
||||
// Scan addresses for ipv6 link local address which is automatically assigned
|
||||
for _, addr := range addrs {
|
||||
if addr.IPNet == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
netMask, _ := addr.Mask.Size()
|
||||
|
||||
ipAddr := &pbTypes.IPAddress{
|
||||
Address: addr.IP.String(),
|
||||
Mask: fmt.Sprintf("%d", netMask),
|
||||
}
|
||||
|
||||
if addr.IP.To4() != nil {
|
||||
ipAddr.Family = utils.ConvertNetlinkFamily(netlink.FAMILY_V4)
|
||||
} else {
|
||||
ipAddr.Family = utils.ConvertNetlinkFamily(netlink.FAMILY_V6)
|
||||
}
|
||||
|
||||
ipAddrs = append(ipAddrs, ipAddr)
|
||||
}
|
||||
|
||||
iface := pbTypes.Interface{
|
||||
Device: testIfaceName,
|
||||
Name: testIfaceName,
|
||||
Mtu: uint64(testMTU),
|
||||
HwAddr: testHwAddr,
|
||||
Type: link.Type(),
|
||||
IPAddresses: ipAddrs,
|
||||
}
|
||||
|
||||
return attrs.Index, iface
|
||||
}
|
||||
|
||||
func TestScanNetwork(t *testing.T) {
|
||||
tearDownNetworkCb := testSetupNetwork(t)
|
||||
defer tearDownNetworkCb()
|
||||
|
||||
handler, err := netlink.NewHandle(netlinkFamily)
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, handler)
|
||||
defer handler.Close()
|
||||
|
||||
idx, expected := testCreateDummyNetwork(t, handler)
|
||||
|
||||
n := &netmon{
|
||||
netIfaces: make(map[int]pbTypes.Interface),
|
||||
netHandler: handler,
|
||||
}
|
||||
|
||||
err = n.scanNetwork()
|
||||
assert.Nil(t, err)
|
||||
assert.True(t, reflect.DeepEqual(expected, n.netIfaces[idx]),
|
||||
"Got %+v\nExpected %+v", n.netIfaces[idx], expected)
|
||||
}
|
||||
|
||||
func TestStoreDataToSend(t *testing.T) {
|
||||
var got pbTypes.Interface
|
||||
|
||||
expected := pbTypes.Interface{
|
||||
Device: testIfaceName,
|
||||
Name: testIfaceName,
|
||||
Mtu: uint64(testMTU),
|
||||
HwAddr: testHwAddr,
|
||||
}
|
||||
|
||||
n := &netmon{
|
||||
sharedFile: filepath.Join(testStorageParentPath, testSharedFile),
|
||||
}
|
||||
|
||||
err := os.MkdirAll(testStorageParentPath, storageDirPerm)
|
||||
defer os.RemoveAll(testStorageParentPath)
|
||||
assert.Nil(t, err)
|
||||
|
||||
err = n.storeDataToSend(expected)
|
||||
assert.Nil(t, err)
|
||||
|
||||
// Check the file has been created, check the content, and delete it.
|
||||
_, err = os.Stat(n.sharedFile)
|
||||
assert.Nil(t, err)
|
||||
byteArray, err := ioutil.ReadFile(n.sharedFile)
|
||||
assert.Nil(t, err)
|
||||
err = json.Unmarshal(byteArray, &got)
|
||||
assert.Nil(t, err)
|
||||
assert.True(t, reflect.DeepEqual(expected, got),
|
||||
"Got %+v\nExpected %+v", got, expected)
|
||||
}
|
||||
|
||||
func TestExecKataCmdSuccess(t *testing.T) {
|
||||
trueBinPath, err := exec.LookPath("true")
|
||||
assert.Nil(t, err)
|
||||
assert.NotEmpty(t, trueBinPath)
|
||||
|
||||
params := netmonParams{
|
||||
runtimePath: trueBinPath,
|
||||
}
|
||||
|
||||
n := &netmon{
|
||||
netmonParams: params,
|
||||
sharedFile: filepath.Join(testStorageParentPath, testSharedFile),
|
||||
}
|
||||
|
||||
err = os.MkdirAll(testStorageParentPath, storageDirPerm)
|
||||
assert.Nil(t, err)
|
||||
defer os.RemoveAll(testStorageParentPath)
|
||||
|
||||
file, err := os.Create(n.sharedFile)
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, file)
|
||||
file.Close()
|
||||
|
||||
_, err = os.Stat(n.sharedFile)
|
||||
assert.Nil(t, err)
|
||||
|
||||
err = n.execKataCmd("")
|
||||
assert.Nil(t, err)
|
||||
_, err = os.Stat(n.sharedFile)
|
||||
assert.NotNil(t, err)
|
||||
}
|
||||
|
||||
func TestExecKataCmdFailure(t *testing.T) {
|
||||
falseBinPath, err := exec.LookPath("false")
|
||||
assert.Nil(t, err)
|
||||
assert.NotEmpty(t, falseBinPath)
|
||||
|
||||
params := netmonParams{
|
||||
runtimePath: falseBinPath,
|
||||
}
|
||||
|
||||
n := &netmon{
|
||||
netmonParams: params,
|
||||
}
|
||||
|
||||
err = n.execKataCmd("")
|
||||
assert.NotNil(t, err)
|
||||
}
|
||||
|
||||
func TestActionsCLI(t *testing.T) {
|
||||
trueBinPath, err := exec.LookPath("true")
|
||||
assert.Nil(t, err)
|
||||
assert.NotEmpty(t, trueBinPath)
|
||||
|
||||
params := netmonParams{
|
||||
runtimePath: trueBinPath,
|
||||
}
|
||||
|
||||
n := &netmon{
|
||||
netmonParams: params,
|
||||
sharedFile: filepath.Join(testStorageParentPath, testSharedFile),
|
||||
}
|
||||
|
||||
err = os.MkdirAll(testStorageParentPath, storageDirPerm)
|
||||
assert.Nil(t, err)
|
||||
defer os.RemoveAll(testStorageParentPath)
|
||||
|
||||
// Test addInterfaceCLI
|
||||
err = n.addInterfaceCLI(pbTypes.Interface{})
|
||||
assert.Nil(t, err)
|
||||
|
||||
// Test delInterfaceCLI
|
||||
err = n.delInterfaceCLI(pbTypes.Interface{})
|
||||
assert.Nil(t, err)
|
||||
|
||||
// Test updateRoutesCLI
|
||||
err = n.updateRoutesCLI([]pbTypes.Route{})
|
||||
assert.Nil(t, err)
|
||||
|
||||
tearDownNetworkCb := testSetupNetwork(t)
|
||||
defer tearDownNetworkCb()
|
||||
|
||||
handler, err := netlink.NewHandle(netlinkFamily)
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, handler)
|
||||
defer handler.Close()
|
||||
|
||||
n.netHandler = handler
|
||||
|
||||
// Test updateRoutes
|
||||
err = n.updateRoutes()
|
||||
assert.Nil(t, err)
|
||||
|
||||
// Test handleRTMDelRoute
|
||||
err = n.handleRTMDelRoute(netlink.RouteUpdate{})
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func TestHandleRTMNewAddr(t *testing.T) {
|
||||
n := &netmon{}
|
||||
|
||||
err := n.handleRTMNewAddr(netlink.LinkUpdate{})
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func TestHandleRTMDelAddr(t *testing.T) {
|
||||
n := &netmon{}
|
||||
|
||||
err := n.handleRTMDelAddr(netlink.LinkUpdate{})
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func TestHandleRTMNewLink(t *testing.T) {
|
||||
n := &netmon{}
|
||||
ev := netlink.LinkUpdate{
|
||||
Link: &netlink.Dummy{},
|
||||
}
|
||||
|
||||
// LinkAttrs is nil
|
||||
err := n.handleRTMNewLink(ev)
|
||||
assert.Nil(t, err)
|
||||
|
||||
// Link name contains "kata" suffix
|
||||
ev = netlink.LinkUpdate{
|
||||
Link: &netlink.Dummy{
|
||||
LinkAttrs: netlink.LinkAttrs{
|
||||
Name: "foo_kata",
|
||||
},
|
||||
},
|
||||
}
|
||||
err = n.handleRTMNewLink(ev)
|
||||
assert.Nil(t, err)
|
||||
|
||||
// Interface already exist in list
|
||||
n.netIfaces = make(map[int]pbTypes.Interface)
|
||||
n.netIfaces[testIfaceIndex] = pbTypes.Interface{}
|
||||
ev = netlink.LinkUpdate{
|
||||
Link: &netlink.Dummy{
|
||||
LinkAttrs: netlink.LinkAttrs{
|
||||
Name: "foo0",
|
||||
},
|
||||
},
|
||||
}
|
||||
ev.Index = testIfaceIndex
|
||||
err = n.handleRTMNewLink(ev)
|
||||
assert.Nil(t, err)
|
||||
|
||||
// Flags are not up and running
|
||||
n.netIfaces = make(map[int]pbTypes.Interface)
|
||||
ev = netlink.LinkUpdate{
|
||||
Link: &netlink.Dummy{
|
||||
LinkAttrs: netlink.LinkAttrs{
|
||||
Name: "foo0",
|
||||
},
|
||||
},
|
||||
}
|
||||
ev.Index = testIfaceIndex
|
||||
err = n.handleRTMNewLink(ev)
|
||||
assert.Nil(t, err)
|
||||
|
||||
// Invalid link
|
||||
n.netIfaces = make(map[int]pbTypes.Interface)
|
||||
ev = netlink.LinkUpdate{
|
||||
Link: &netlink.Dummy{
|
||||
LinkAttrs: netlink.LinkAttrs{
|
||||
Name: "foo0",
|
||||
},
|
||||
},
|
||||
}
|
||||
ev.Index = testIfaceIndex
|
||||
ev.Flags = unix.IFF_UP | unix.IFF_RUNNING
|
||||
handler, err := netlink.NewHandle(netlinkFamily)
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, handler)
|
||||
defer handler.Close()
|
||||
n.netHandler = handler
|
||||
err = n.handleRTMNewLink(ev)
|
||||
assert.NotNil(t, err)
|
||||
}
|
||||
|
||||
func TestHandleRTMDelLink(t *testing.T) {
|
||||
n := &netmon{}
|
||||
ev := netlink.LinkUpdate{
|
||||
Link: &netlink.Dummy{},
|
||||
}
|
||||
|
||||
// LinkAttrs is nil
|
||||
err := n.handleRTMDelLink(ev)
|
||||
assert.Nil(t, err)
|
||||
|
||||
// Link name contains "kata" suffix
|
||||
ev = netlink.LinkUpdate{
|
||||
Link: &netlink.Dummy{
|
||||
LinkAttrs: netlink.LinkAttrs{
|
||||
Name: "foo_kata",
|
||||
},
|
||||
},
|
||||
}
|
||||
err = n.handleRTMDelLink(ev)
|
||||
assert.Nil(t, err)
|
||||
|
||||
// Interface does not exist in list
|
||||
n.netIfaces = make(map[int]pbTypes.Interface)
|
||||
ev = netlink.LinkUpdate{
|
||||
Link: &netlink.Dummy{
|
||||
LinkAttrs: netlink.LinkAttrs{
|
||||
Name: "foo0",
|
||||
},
|
||||
},
|
||||
}
|
||||
ev.Index = testIfaceIndex
|
||||
err = n.handleRTMDelLink(ev)
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func TestHandleRTMNewRouteIfaceNotFound(t *testing.T) {
|
||||
n := &netmon{
|
||||
netIfaces: make(map[int]pbTypes.Interface),
|
||||
}
|
||||
|
||||
err := n.handleRTMNewRoute(netlink.RouteUpdate{})
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func TestHandleLinkEvent(t *testing.T) {
|
||||
n := &netmon{}
|
||||
ev := netlink.LinkUpdate{}
|
||||
|
||||
// Unknown event
|
||||
err := n.handleLinkEvent(ev)
|
||||
assert.Nil(t, err)
|
||||
|
||||
// DONE event
|
||||
ev.Header.Type = unix.NLMSG_DONE
|
||||
err = n.handleLinkEvent(ev)
|
||||
assert.Nil(t, err)
|
||||
|
||||
// ERROR event
|
||||
ev.Header.Type = unix.NLMSG_ERROR
|
||||
err = n.handleLinkEvent(ev)
|
||||
assert.NotNil(t, err)
|
||||
|
||||
// NEWADDR event
|
||||
ev.Header.Type = unix.RTM_NEWADDR
|
||||
err = n.handleLinkEvent(ev)
|
||||
assert.Nil(t, err)
|
||||
|
||||
// DELADDR event
|
||||
ev.Header.Type = unix.RTM_DELADDR
|
||||
err = n.handleLinkEvent(ev)
|
||||
assert.Nil(t, err)
|
||||
|
||||
// NEWLINK event
|
||||
ev.Header.Type = unix.RTM_NEWLINK
|
||||
ev.Link = &netlink.Dummy{}
|
||||
err = n.handleLinkEvent(ev)
|
||||
assert.Nil(t, err)
|
||||
|
||||
// DELLINK event
|
||||
ev.Header.Type = unix.RTM_DELLINK
|
||||
ev.Link = &netlink.Dummy{}
|
||||
err = n.handleLinkEvent(ev)
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func TestHandleRouteEvent(t *testing.T) {
|
||||
n := &netmon{}
|
||||
ev := netlink.RouteUpdate{}
|
||||
|
||||
// Unknown event
|
||||
err := n.handleRouteEvent(ev)
|
||||
assert.Nil(t, err)
|
||||
|
||||
// RTM_NEWROUTE event
|
||||
ev.Type = unix.RTM_NEWROUTE
|
||||
err = n.handleRouteEvent(ev)
|
||||
assert.Nil(t, err)
|
||||
|
||||
trueBinPath, err := exec.LookPath("true")
|
||||
assert.Nil(t, err)
|
||||
assert.NotEmpty(t, trueBinPath)
|
||||
|
||||
n.runtimePath = trueBinPath
|
||||
n.sharedFile = filepath.Join(testStorageParentPath, testSharedFile)
|
||||
|
||||
err = os.MkdirAll(testStorageParentPath, storageDirPerm)
|
||||
assert.Nil(t, err)
|
||||
defer os.RemoveAll(testStorageParentPath)
|
||||
|
||||
tearDownNetworkCb := testSetupNetwork(t)
|
||||
defer tearDownNetworkCb()
|
||||
|
||||
handler, err := netlink.NewHandle(netlinkFamily)
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, handler)
|
||||
defer handler.Close()
|
||||
|
||||
n.netHandler = handler
|
||||
|
||||
// RTM_DELROUTE event
|
||||
ev.Type = unix.RTM_DELROUTE
|
||||
err = n.handleRouteEvent(ev)
|
||||
assert.Nil(t, err)
|
||||
}
|
@ -147,21 +147,6 @@ block_device_driver = "@DEFBLOCKSTORAGEDRIVER_ACRN@"
|
||||
# (default: 30)
|
||||
#dial_timeout = 30
|
||||
|
||||
[netmon]
|
||||
# If enabled, the network monitoring process gets started when the
|
||||
# sandbox is created. This allows for the detection of some additional
|
||||
# network being added to the existing network namespace, after the
|
||||
# sandbox has been created.
|
||||
# (default: disabled)
|
||||
#enable_netmon = true
|
||||
|
||||
# Specify the path to the netmon binary.
|
||||
path = "@NETMONPATH@"
|
||||
|
||||
# If enabled, netmon messages will be sent to the system log
|
||||
# (default: disabled)
|
||||
#enable_debug = true
|
||||
|
||||
[runtime]
|
||||
# If enabled, the runtime will log additional debug messages to the
|
||||
# system log
|
||||
@ -217,7 +202,6 @@ disable_guest_seccomp=@DEFDISABLEGUESTSECCOMP@
|
||||
|
||||
# If enabled, the runtime will not create a network namespace for shim and hypervisor processes.
|
||||
# This option may have some potential impacts to your host. It should only be used when you know what you're doing.
|
||||
# `disable_new_netns` conflicts with `enable_netmon`
|
||||
# `disable_new_netns` conflicts with `internetworking_model=bridged` and `internetworking_model=macvtap`. It works only
|
||||
# with `internetworking_model=none`. The tap device will be in the host network namespace and can connect to a bridge
|
||||
# (like OVS) directly.
|
||||
|
@ -169,22 +169,6 @@ block_device_driver = "virtio-blk"
|
||||
# (default: 30)
|
||||
#dial_timeout = 30
|
||||
|
||||
[netmon]
|
||||
# If enabled, the network monitoring process gets started when the
|
||||
# sandbox is created. This allows for the detection of some additional
|
||||
# network being added to the existing network namespace, after the
|
||||
# sandbox has been created.
|
||||
# (default: disabled)
|
||||
#enable_netmon = true
|
||||
|
||||
# Specify the path to the netmon binary.
|
||||
path = "@NETMONPATH@"
|
||||
|
||||
# If enabled, netmon messages will be sent to the system log
|
||||
# (default: disabled)
|
||||
#enable_debug = true
|
||||
|
||||
|
||||
[runtime]
|
||||
# If enabled, the runtime will log additional debug messages to the
|
||||
# system log
|
||||
@ -240,7 +224,6 @@ disable_guest_seccomp=@DEFDISABLEGUESTSECCOMP@
|
||||
|
||||
# If enabled, the runtime will not create a network namespace for shim and hypervisor processes.
|
||||
# This option may have some potential impacts to your host. It should only be used when you know what you're doing.
|
||||
# `disable_new_netns` conflicts with `enable_netmon`
|
||||
# `disable_new_netns` conflicts with `internetworking_model=bridged` and `internetworking_model=macvtap`. It works only
|
||||
# with `internetworking_model=none`. The tap device will be in the host network namespace and can connect to a bridge
|
||||
# (like OVS) directly.
|
||||
|
@ -282,21 +282,6 @@ kernel_modules=[]
|
||||
# (default: 30)
|
||||
#dial_timeout = 30
|
||||
|
||||
[netmon]
|
||||
# If enabled, the network monitoring process gets started when the
|
||||
# sandbox is created. This allows for the detection of some additional
|
||||
# network being added to the existing network namespace, after the
|
||||
# sandbox has been created.
|
||||
# (default: disabled)
|
||||
#enable_netmon = true
|
||||
|
||||
# Specify the path to the netmon binary.
|
||||
path = "@NETMONPATH@"
|
||||
|
||||
# If enabled, netmon messages will be sent to the system log
|
||||
# (default: disabled)
|
||||
#enable_debug = true
|
||||
|
||||
[runtime]
|
||||
# If enabled, the runtime will log additional debug messages to the
|
||||
# system log
|
||||
@ -345,7 +330,6 @@ disable_guest_seccomp=@DEFDISABLEGUESTSECCOMP@
|
||||
|
||||
# If enabled, the runtime will not create a network namespace for shim and hypervisor processes.
|
||||
# This option may have some potential impacts to your host. It should only be used when you know what you're doing.
|
||||
# `disable_new_netns` conflicts with `enable_netmon`
|
||||
# `disable_new_netns` conflicts with `internetworking_model=tcfilter` and `internetworking_model=macvtap`. It works only
|
||||
# with `internetworking_model=none`. The tap device will be in the host network namespace and can connect to a bridge
|
||||
# (like OVS) directly.
|
||||
|
@ -458,21 +458,6 @@ kernel_modules=[]
|
||||
# (default: 30)
|
||||
#dial_timeout = 30
|
||||
|
||||
[netmon]
|
||||
# If enabled, the network monitoring process gets started when the
|
||||
# sandbox is created. This allows for the detection of some additional
|
||||
# network being added to the existing network namespace, after the
|
||||
# sandbox has been created.
|
||||
# (default: disabled)
|
||||
#enable_netmon = true
|
||||
|
||||
# Specify the path to the netmon binary.
|
||||
path = "@NETMONPATH@"
|
||||
|
||||
# If enabled, netmon messages will be sent to the system log
|
||||
# (default: disabled)
|
||||
#enable_debug = true
|
||||
|
||||
[runtime]
|
||||
# If enabled, the runtime will log additional debug messages to the
|
||||
# system log
|
||||
@ -521,7 +506,6 @@ disable_guest_seccomp=@DEFDISABLEGUESTSECCOMP@
|
||||
|
||||
# If enabled, the runtime will not create a network namespace for shim and hypervisor processes.
|
||||
# This option may have some potential impacts to your host. It should only be used when you know what you're doing.
|
||||
# `disable_new_netns` conflicts with `enable_netmon`
|
||||
# `disable_new_netns` conflicts with `internetworking_model=tcfilter` and `internetworking_model=macvtap`. It works only
|
||||
# with `internetworking_model=none`. The tap device will be in the host network namespace and can connect to a bridge
|
||||
# (like OVS) directly.
|
||||
|
@ -328,7 +328,6 @@ func createAllRuntimeConfigFiles(dir, hypervisor string) (config string, err err
|
||||
kernelParams := "foo=bar xyz"
|
||||
imagePath := path.Join(dir, "image")
|
||||
shimPath := path.Join(dir, "shim")
|
||||
netmonPath := path.Join(dir, "netmon")
|
||||
logDir := path.Join(dir, "logs")
|
||||
logPath := path.Join(logDir, "runtime.log")
|
||||
machineType := "machineType"
|
||||
@ -349,7 +348,6 @@ func createAllRuntimeConfigFiles(dir, hypervisor string) (config string, err err
|
||||
KernelParams: kernelParams,
|
||||
MachineType: machineType,
|
||||
ShimPath: shimPath,
|
||||
NetmonPath: netmonPath,
|
||||
LogPath: logPath,
|
||||
DisableBlock: disableBlockDevice,
|
||||
BlockDeviceDriver: blockDeviceDriver,
|
||||
|
@ -215,7 +215,6 @@ type RuntimeConfigOptions struct {
|
||||
KernelParams string
|
||||
MachineType string
|
||||
ShimPath string
|
||||
NetmonPath string
|
||||
LogPath string
|
||||
BlockDeviceDriver string
|
||||
SharedFS string
|
||||
@ -237,7 +236,6 @@ type RuntimeConfigOptions struct {
|
||||
RuntimeDebug bool
|
||||
RuntimeTrace bool
|
||||
ShimDebug bool
|
||||
NetmonDebug bool
|
||||
AgentDebug bool
|
||||
AgentTrace bool
|
||||
EnablePprof bool
|
||||
@ -331,10 +329,6 @@ func MakeRuntimeConfigFileData(config RuntimeConfigOptions) string {
|
||||
enable_debug = ` + strconv.FormatBool(config.AgentDebug) + `
|
||||
enable_tracing = ` + strconv.FormatBool(config.AgentTrace) + `
|
||||
|
||||
[netmon]
|
||||
path = "` + config.NetmonPath + `"
|
||||
enable_debug = ` + strconv.FormatBool(config.NetmonDebug) + `
|
||||
|
||||
[runtime]
|
||||
enable_debug = ` + strconv.FormatBool(config.RuntimeDebug) + `
|
||||
enable_tracing = ` + strconv.FormatBool(config.RuntimeTrace) + `
|
||||
|
@ -97,5 +97,3 @@ const defaultVMCacheEndpoint string = "/var/run/kata-containers/cache.sock"
|
||||
|
||||
// Default config file used by stateless systems.
|
||||
var defaultRuntimeConfiguration = "@CONFIG_PATH@"
|
||||
|
||||
var defaultNetmonPath = "/usr/libexec/kata-containers/kata-netmon"
|
||||
|
@ -56,7 +56,6 @@ type tomlConfig struct {
|
||||
Agent map[string]agent
|
||||
Runtime runtime
|
||||
Image image
|
||||
Netmon netmon
|
||||
Factory factory
|
||||
}
|
||||
|
||||
@ -162,12 +161,6 @@ type agent struct {
|
||||
DialTimeout uint32 `toml:"dial_timeout"`
|
||||
}
|
||||
|
||||
type netmon struct {
|
||||
Path string `toml:"path"`
|
||||
Debug bool `toml:"enable_debug"`
|
||||
Enable bool `toml:"enable_netmon"`
|
||||
}
|
||||
|
||||
func (h hypervisor) path() (string, error) {
|
||||
p := h.Path
|
||||
|
||||
@ -506,22 +499,6 @@ func (a agent) kernelModules() []string {
|
||||
return a.KernelModules
|
||||
}
|
||||
|
||||
func (n netmon) enable() bool {
|
||||
return n.Enable
|
||||
}
|
||||
|
||||
func (n netmon) path() string {
|
||||
if n.Path == "" {
|
||||
return defaultNetmonPath
|
||||
}
|
||||
|
||||
return n.Path
|
||||
}
|
||||
|
||||
func (n netmon) debug() bool {
|
||||
return n.Debug
|
||||
}
|
||||
|
||||
func newFirecrackerHypervisorConfig(h hypervisor) (vc.HypervisorConfig, error) {
|
||||
hypervisor, err := h.path()
|
||||
if err != nil {
|
||||
@ -1014,12 +991,6 @@ func updateRuntimeConfig(configPath string, tomlConf tomlConfig, config *oci.Run
|
||||
}
|
||||
config.FactoryConfig = fConfig
|
||||
|
||||
config.NetmonConfig = vc.NetmonConfig{
|
||||
Path: tomlConf.Netmon.path(),
|
||||
Debug: tomlConf.Netmon.debug(),
|
||||
Enable: tomlConf.Netmon.enable(),
|
||||
}
|
||||
|
||||
err = SetKernelParams(config)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -1262,9 +1233,6 @@ func checkConfig(config oci.RuntimeConfig) error {
|
||||
// Because it is an expert option and conflicts with some other common configs.
|
||||
func checkNetNsConfig(config oci.RuntimeConfig) error {
|
||||
if config.DisableNewNetNs {
|
||||
if config.NetmonConfig.Enable {
|
||||
return fmt.Errorf("config disable_new_netns conflicts with enable_netmon")
|
||||
}
|
||||
if config.InterNetworkModel != vc.NetXConnectNoneModel {
|
||||
return fmt.Errorf("config disable_new_netns only works with 'none' internetworking_model")
|
||||
}
|
||||
|
@ -29,7 +29,6 @@ var (
|
||||
hypervisorDebug = false
|
||||
runtimeDebug = false
|
||||
runtimeTrace = false
|
||||
netmonDebug = false
|
||||
agentDebug = false
|
||||
agentTrace = false
|
||||
enablePprof = true
|
||||
@ -74,7 +73,6 @@ func createAllRuntimeConfigFiles(dir, hypervisor string) (config testRuntimeConf
|
||||
kernelPath := path.Join(dir, "kernel")
|
||||
kernelParams := "foo=bar xyz"
|
||||
imagePath := path.Join(dir, "image")
|
||||
netmonPath := path.Join(dir, "netmon")
|
||||
logDir := path.Join(dir, "logs")
|
||||
logPath := path.Join(logDir, "runtime.log")
|
||||
machineType := "machineType"
|
||||
@ -95,7 +93,6 @@ func createAllRuntimeConfigFiles(dir, hypervisor string) (config testRuntimeConf
|
||||
ImagePath: imagePath,
|
||||
KernelParams: kernelParams,
|
||||
MachineType: machineType,
|
||||
NetmonPath: netmonPath,
|
||||
LogPath: logPath,
|
||||
DefaultGuestHookPath: defaultGuestHookPath,
|
||||
DisableBlock: disableBlockDevice,
|
||||
@ -111,7 +108,6 @@ func createAllRuntimeConfigFiles(dir, hypervisor string) (config testRuntimeConf
|
||||
HypervisorDebug: hypervisorDebug,
|
||||
RuntimeDebug: runtimeDebug,
|
||||
RuntimeTrace: runtimeTrace,
|
||||
NetmonDebug: netmonDebug,
|
||||
AgentDebug: agentDebug,
|
||||
AgentTrace: agentTrace,
|
||||
SharedFS: sharedFS,
|
||||
@ -180,12 +176,6 @@ func createAllRuntimeConfigFiles(dir, hypervisor string) (config testRuntimeConf
|
||||
LongLiveConn: true,
|
||||
}
|
||||
|
||||
netmonConfig := vc.NetmonConfig{
|
||||
Path: netmonPath,
|
||||
Debug: false,
|
||||
Enable: false,
|
||||
}
|
||||
|
||||
factoryConfig := oci.FactoryConfig{
|
||||
TemplatePath: defaultTemplatePath,
|
||||
VMCacheEndpoint: defaultVMCacheEndpoint,
|
||||
@ -197,7 +187,6 @@ func createAllRuntimeConfigFiles(dir, hypervisor string) (config testRuntimeConf
|
||||
|
||||
AgentConfig: agentConfig,
|
||||
|
||||
NetmonConfig: netmonConfig,
|
||||
DisableNewNetNs: disableNewNetNs,
|
||||
EnablePprof: enablePprof,
|
||||
JaegerEndpoint: jaegerEndpoint,
|
||||
@ -493,7 +482,6 @@ func TestMinimalRuntimeConfig(t *testing.T) {
|
||||
defaultHypervisorPath = hypervisorPath
|
||||
jailerPath := path.Join(dir, "jailer")
|
||||
defaultJailerPath = jailerPath
|
||||
netmonPath := path.Join(dir, "netmon")
|
||||
|
||||
imagePath := path.Join(dir, "image.img")
|
||||
initrdPath := path.Join(dir, "initrd.img")
|
||||
@ -535,8 +523,6 @@ func TestMinimalRuntimeConfig(t *testing.T) {
|
||||
[agent.kata]
|
||||
debug_console_enabled=true
|
||||
kernel_modules=["a", "b", "c"]
|
||||
[netmon]
|
||||
path = "` + netmonPath + `"
|
||||
`
|
||||
|
||||
orgVHostVSockDevicePath := utils.VHostVSockDevicePath
|
||||
@ -561,11 +547,6 @@ func TestMinimalRuntimeConfig(t *testing.T) {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
err = createEmptyFile(netmonPath)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
_, config, err := LoadConfiguration(configPath, false)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@ -597,12 +578,6 @@ func TestMinimalRuntimeConfig(t *testing.T) {
|
||||
KernelModules: []string{"a", "b", "c"},
|
||||
}
|
||||
|
||||
expectedNetmonConfig := vc.NetmonConfig{
|
||||
Path: netmonPath,
|
||||
Debug: false,
|
||||
Enable: false,
|
||||
}
|
||||
|
||||
expectedFactoryConfig := oci.FactoryConfig{
|
||||
TemplatePath: defaultTemplatePath,
|
||||
VMCacheEndpoint: defaultVMCacheEndpoint,
|
||||
@ -614,8 +589,6 @@ func TestMinimalRuntimeConfig(t *testing.T) {
|
||||
|
||||
AgentConfig: expectedAgentConfig,
|
||||
|
||||
NetmonConfig: expectedNetmonConfig,
|
||||
|
||||
FactoryConfig: expectedFactoryConfig,
|
||||
}
|
||||
err = SetKernelParams(&expectedConfig)
|
||||
@ -1553,9 +1526,6 @@ func TestCheckNetNsConfig(t *testing.T) {
|
||||
|
||||
config := oci.RuntimeConfig{
|
||||
DisableNewNetNs: true,
|
||||
NetmonConfig: vc.NetmonConfig{
|
||||
Enable: true,
|
||||
},
|
||||
}
|
||||
err := checkNetNsConfig(config)
|
||||
assert.Error(err)
|
||||
|
@ -109,7 +109,6 @@ type RuntimeConfig struct {
|
||||
|
||||
FactoryConfig FactoryConfig
|
||||
HypervisorConfig vc.HypervisorConfig
|
||||
NetmonConfig vc.NetmonConfig
|
||||
AgentConfig vc.KataAgentConfig
|
||||
|
||||
//Determines how the VM should be connected to the
|
||||
@ -314,12 +313,6 @@ func networkConfig(ocispec specs.Spec, config RuntimeConfig) (vc.NetworkConfig,
|
||||
netConf.InterworkingModel = config.InterNetworkModel
|
||||
netConf.DisableNewNetNs = config.DisableNewNetNs
|
||||
|
||||
netConf.NetmonConfig = vc.NetmonConfig{
|
||||
Path: config.NetmonConfig.Path,
|
||||
Debug: config.NetmonConfig.Debug,
|
||||
Enable: config.NetmonConfig.Enable,
|
||||
}
|
||||
|
||||
return netConf, nil
|
||||
}
|
||||
|
||||
|
@ -366,7 +366,6 @@ type NetworkConfig struct {
|
||||
NetNSPath string
|
||||
NetNsCreated bool
|
||||
DisableNewNetNs bool
|
||||
NetmonConfig NetmonConfig
|
||||
InterworkingModel NetInterworkingModel
|
||||
}
|
||||
```
|
||||
|
@ -1,96 +0,0 @@
|
||||
// Copyright (c) 2018 Intel Corporation
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
package virtcontainers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"syscall"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// NetmonConfig is the structure providing specific configuration
|
||||
// for the network monitor.
|
||||
type NetmonConfig struct {
|
||||
Path string
|
||||
Debug bool
|
||||
Enable bool
|
||||
}
|
||||
|
||||
// netmonParams is the structure providing specific parameters needed
|
||||
// for the execution of the network monitor binary.
|
||||
type netmonParams struct {
|
||||
netmonPath string
|
||||
logLevel string
|
||||
runtime string
|
||||
sandboxID string
|
||||
debug bool
|
||||
}
|
||||
|
||||
func netmonLogger() *logrus.Entry {
|
||||
return virtLog.WithField("subsystem", "netmon")
|
||||
}
|
||||
|
||||
func prepareNetMonParams(params netmonParams) ([]string, error) {
|
||||
if params.netmonPath == "" {
|
||||
return []string{}, fmt.Errorf("Netmon path is empty")
|
||||
}
|
||||
if params.runtime == "" {
|
||||
return []string{}, fmt.Errorf("Netmon runtime path is empty")
|
||||
}
|
||||
if params.sandboxID == "" {
|
||||
return []string{}, fmt.Errorf("Netmon sandbox ID is empty")
|
||||
}
|
||||
|
||||
args := []string{params.netmonPath,
|
||||
"-r", params.runtime,
|
||||
"-s", params.sandboxID,
|
||||
}
|
||||
|
||||
if params.debug {
|
||||
args = append(args, "-d")
|
||||
}
|
||||
if params.logLevel != "" {
|
||||
args = append(args, []string{"-log", params.logLevel}...)
|
||||
}
|
||||
|
||||
return args, nil
|
||||
}
|
||||
|
||||
func startNetmon(params netmonParams) (int, error) {
|
||||
args, err := prepareNetMonParams(params)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
|
||||
cmd := exec.Command(args[0], args[1:]...)
|
||||
if err := cmd.Start(); err != nil {
|
||||
return -1, err
|
||||
}
|
||||
|
||||
return cmd.Process.Pid, nil
|
||||
}
|
||||
|
||||
func stopNetmon(pid int) error {
|
||||
if pid <= 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
sig := syscall.SIGKILL
|
||||
|
||||
netmonLogger().WithFields(
|
||||
logrus.Fields{
|
||||
"netmon-pid": pid,
|
||||
"netmon-signal": sig,
|
||||
}).Info("Stopping netmon")
|
||||
|
||||
if err := syscall.Kill(pid, sig); err != nil && err != syscall.ESRCH {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
// Copyright (c) 2018 Intel Corporation
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
package virtcontainers
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
const (
|
||||
testNetmonPath = "/foo/bar/netmon"
|
||||
testRuntimePath = "/foo/bar/runtime"
|
||||
)
|
||||
|
||||
func TestNetmonLogger(t *testing.T) {
|
||||
got := netmonLogger()
|
||||
expected := virtLog.WithField("subsystem", "netmon")
|
||||
assert.True(t, reflect.DeepEqual(expected, got),
|
||||
"Got %+v\nExpected %+v", got, expected)
|
||||
}
|
||||
|
||||
func TestPrepareNetMonParams(t *testing.T) {
|
||||
// Empty netmon path
|
||||
params := netmonParams{}
|
||||
got, err := prepareNetMonParams(params)
|
||||
assert.NotNil(t, err)
|
||||
assert.Equal(t, got, []string{})
|
||||
|
||||
// Empty runtime path
|
||||
params.netmonPath = testNetmonPath
|
||||
got, err = prepareNetMonParams(params)
|
||||
assert.NotNil(t, err)
|
||||
assert.Equal(t, got, []string{})
|
||||
|
||||
// Empty sandbox ID
|
||||
params.runtime = testRuntimePath
|
||||
got, err = prepareNetMonParams(params)
|
||||
assert.NotNil(t, err)
|
||||
assert.Equal(t, got, []string{})
|
||||
|
||||
// Successful case
|
||||
params.sandboxID = testSandboxID
|
||||
got, err = prepareNetMonParams(params)
|
||||
assert.Nil(t, err)
|
||||
expected := []string{testNetmonPath,
|
||||
"-r", testRuntimePath,
|
||||
"-s", testSandboxID}
|
||||
assert.True(t, reflect.DeepEqual(expected, got),
|
||||
"Got %+v\nExpected %+v", got, expected)
|
||||
}
|
||||
|
||||
func TestStopNetmon(t *testing.T) {
|
||||
pid := -1
|
||||
err := stopNetmon(pid)
|
||||
assert.Nil(t, err)
|
||||
}
|
@ -178,7 +178,6 @@ type NetworkInterfacePair struct {
|
||||
// NetworkConfig is the network configuration related to a network.
|
||||
type NetworkConfig struct {
|
||||
NetNSPath string
|
||||
NetmonConfig NetmonConfig
|
||||
InterworkingModel NetInterworkingModel
|
||||
NetNsCreated bool
|
||||
DisableNewNetNs bool
|
||||
@ -193,7 +192,6 @@ type NetworkNamespace struct {
|
||||
NetNsPath string
|
||||
Endpoints []Endpoint
|
||||
NetNsCreated bool
|
||||
NetmonPID int
|
||||
}
|
||||
|
||||
func createLink(netHandle *netlink.Handle, name string, expectedLink netlink.Link, queues int) (netlink.Link, []*os.File, error) {
|
||||
|
@ -164,7 +164,6 @@ func (s *Sandbox) dumpAgent(ss *persistapi.SandboxState) {
|
||||
func (s *Sandbox) dumpNetwork(ss *persistapi.SandboxState) {
|
||||
ss.Network = persistapi.NetworkInfo{
|
||||
NetNsPath: s.networkNS.NetNsPath,
|
||||
NetmonPID: s.networkNS.NetmonPID,
|
||||
NetNsCreated: s.networkNS.NetNsCreated,
|
||||
}
|
||||
for _, e := range s.networkNS.Endpoints {
|
||||
@ -367,7 +366,6 @@ func (c *Container) loadContProcess(cs persistapi.ContainerState) {
|
||||
func (s *Sandbox) loadNetwork(netInfo persistapi.NetworkInfo) {
|
||||
s.networkNS = NetworkNamespace{
|
||||
NetNsPath: netInfo.NetNsPath,
|
||||
NetmonPID: netInfo.NetmonPID,
|
||||
NetNsCreated: netInfo.NetNsCreated,
|
||||
}
|
||||
|
||||
|
@ -98,6 +98,5 @@ type NetworkEndpoint struct {
|
||||
type NetworkInfo struct {
|
||||
NetNsPath string
|
||||
Endpoints []NetworkEndpoint
|
||||
NetmonPID int
|
||||
NetNsCreated bool
|
||||
}
|
||||
|
@ -778,40 +778,6 @@ func (s *Sandbox) Delete(ctx context.Context) error {
|
||||
return s.store.Destroy(s.id)
|
||||
}
|
||||
|
||||
func (s *Sandbox) startNetworkMonitor(ctx context.Context) error {
|
||||
span, ctx := katatrace.Trace(ctx, s.Logger(), "startNetworkMonitor", sandboxTracingTags, map[string]string{"sandbox_id": s.id})
|
||||
defer span.End()
|
||||
|
||||
binPath, err := os.Executable()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logLevel := "info"
|
||||
if s.config.NetworkConfig.NetmonConfig.Debug {
|
||||
logLevel = "debug"
|
||||
}
|
||||
|
||||
params := netmonParams{
|
||||
netmonPath: s.config.NetworkConfig.NetmonConfig.Path,
|
||||
debug: s.config.NetworkConfig.NetmonConfig.Debug,
|
||||
logLevel: logLevel,
|
||||
runtime: binPath,
|
||||
sandboxID: s.id,
|
||||
}
|
||||
|
||||
return s.network.Run(ctx, s.networkNS.NetNsPath, func() error {
|
||||
pid, err := startNetmon(params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.networkNS.NetmonPID = pid
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (s *Sandbox) createNetwork(ctx context.Context) error {
|
||||
if s.config.NetworkConfig.DisableNewNetNs ||
|
||||
s.config.NetworkConfig.NetNSPath == "" {
|
||||
@ -838,18 +804,11 @@ func (s *Sandbox) createNetwork(ctx context.Context) error {
|
||||
}
|
||||
|
||||
s.networkNS.Endpoints = endpoints
|
||||
|
||||
if s.config.NetworkConfig.NetmonConfig.Enable {
|
||||
if err := s.startNetworkMonitor(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Sandbox) postCreatedNetwork(ctx context.Context) error {
|
||||
|
||||
return s.network.PostAdd(ctx, &s.networkNS, s.factory != nil)
|
||||
}
|
||||
|
||||
@ -857,12 +816,6 @@ func (s *Sandbox) removeNetwork(ctx context.Context) error {
|
||||
span, ctx := katatrace.Trace(ctx, s.Logger(), "removeNetwork", sandboxTracingTags, map[string]string{"sandbox_id": s.id})
|
||||
defer span.End()
|
||||
|
||||
if s.config.NetworkConfig.NetmonConfig.Enable {
|
||||
if err := stopNetmon(s.networkNS.NetmonPID); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return s.network.Remove(ctx, &s.networkNS, s.hypervisor)
|
||||
}
|
||||
|
||||
@ -1218,12 +1171,6 @@ func (s *Sandbox) startVM(ctx context.Context) (err error) {
|
||||
}
|
||||
|
||||
s.networkNS.Endpoints = endpoints
|
||||
|
||||
if s.config.NetworkConfig.NetmonConfig.Enable {
|
||||
if err := s.startNetworkMonitor(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
s.Logger().Info("VM started")
|
||||
|
@ -10,7 +10,6 @@ import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
@ -1300,33 +1299,6 @@ func TestGetNetNs(t *testing.T) {
|
||||
assert.Equal(t, netNs, expected)
|
||||
}
|
||||
|
||||
func TestStartNetworkMonitor(t *testing.T) {
|
||||
if os.Getuid() != 0 {
|
||||
t.Skip("Test disabled as requires root user")
|
||||
}
|
||||
trueBinPath, err := exec.LookPath("true")
|
||||
assert.Nil(t, err)
|
||||
assert.NotEmpty(t, trueBinPath)
|
||||
|
||||
s := &Sandbox{
|
||||
id: testSandboxID,
|
||||
config: &SandboxConfig{
|
||||
NetworkConfig: NetworkConfig{
|
||||
NetmonConfig: NetmonConfig{
|
||||
Path: trueBinPath,
|
||||
},
|
||||
},
|
||||
},
|
||||
networkNS: NetworkNamespace{
|
||||
NetNsPath: fmt.Sprintf("/proc/%d/task/%d/ns/net", os.Getpid(), unix.Gettid()),
|
||||
},
|
||||
ctx: context.Background(),
|
||||
}
|
||||
|
||||
err = s.startNetworkMonitor(context.Background())
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func TestSandboxStopStopped(t *testing.T) {
|
||||
s := &Sandbox{
|
||||
ctx: context.Background(),
|
||||
|
Loading…
Reference in New Issue
Block a user