mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-07-04 11:06:21 +00:00
virtcontainers: Start network monitor from virtcontainers
This patch enables the code responsible for starting and stopping the network monitor. Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
parent
29e2fa0fed
commit
1406d99aba
96
virtcontainers/netmon.go
Normal file
96
virtcontainers/netmon.go
Normal file
@ -0,0 +1,96 @@
|
||||
// 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
|
||||
debug bool
|
||||
logLevel string
|
||||
runtime string
|
||||
sandboxID string
|
||||
}
|
||||
|
||||
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
|
||||
}
|
61
virtcontainers/netmon_test.go
Normal file
61
virtcontainers/netmon_test.go
Normal file
@ -0,0 +1,61 @@
|
||||
// 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)
|
||||
}
|
@ -142,6 +142,7 @@ type NetworkInterfacePair struct {
|
||||
type NetworkConfig struct {
|
||||
NetNSPath string
|
||||
NetNsCreated bool
|
||||
NetmonConfig NetmonConfig
|
||||
InterworkingModel NetInterworkingModel
|
||||
}
|
||||
|
||||
@ -474,6 +475,7 @@ type NetworkNamespace struct {
|
||||
NetNsPath string
|
||||
NetNsCreated bool
|
||||
Endpoints []Endpoint
|
||||
NetmonPID int
|
||||
}
|
||||
|
||||
// TypedJSONEndpoint is used as an intermediate representation for
|
||||
|
@ -961,6 +961,40 @@ func (s *Sandbox) Delete() error {
|
||||
return s.storage.deleteSandboxResources(s.id, nil)
|
||||
}
|
||||
|
||||
func (s *Sandbox) startNetworkMonitor() error {
|
||||
span, _ := s.trace("startNetworkMonitor")
|
||||
defer span.Finish()
|
||||
|
||||
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(s.networkNS.NetNsPath, func() error {
|
||||
pid, err := startNetmon(params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.networkNS.NetmonPID = pid
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (s *Sandbox) createNetwork() error {
|
||||
span, _ := s.trace("createNetwork")
|
||||
defer span.Finish()
|
||||
@ -983,6 +1017,12 @@ func (s *Sandbox) createNetwork() error {
|
||||
}
|
||||
}
|
||||
|
||||
if s.config.NetworkConfig.NetmonConfig.Enable {
|
||||
if err := s.startNetworkMonitor(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Store the network
|
||||
return s.storage.storeSandboxNetwork(s.id, s.networkNS)
|
||||
}
|
||||
@ -991,6 +1031,12 @@ func (s *Sandbox) removeNetwork() error {
|
||||
span, _ := s.trace("removeNetwork")
|
||||
defer span.Finish()
|
||||
|
||||
if s.config.NetworkConfig.NetmonConfig.Enable {
|
||||
if err := stopNetmon(s.networkNS.NetmonPID); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// In case there is a factory, the network has been handled through
|
||||
// some API calls to hotplug some interfaces and routes. This means
|
||||
// the removal of the network should follow the same logic.
|
||||
|
@ -11,6 +11,7 @@ import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"sync"
|
||||
@ -23,6 +24,7 @@ import (
|
||||
"github.com/kata-containers/runtime/virtcontainers/device/drivers"
|
||||
"github.com/kata-containers/runtime/virtcontainers/device/manager"
|
||||
"github.com/kata-containers/runtime/virtcontainers/pkg/annotations"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func newHypervisorConfig(kernelParams []Param, hParams []Param) HypervisorConfig {
|
||||
@ -1722,3 +1724,27 @@ func TestGetNetNs(t *testing.T) {
|
||||
netNs = s.GetNetNs()
|
||||
assert.Equal(t, netNs, expected)
|
||||
}
|
||||
|
||||
func TestStartNetworkMonitor(t *testing.T) {
|
||||
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,
|
||||
},
|
||||
},
|
||||
},
|
||||
network: &defNetwork{},
|
||||
networkNS: NetworkNamespace{
|
||||
NetNsPath: fmt.Sprintf("/proc/%d/task/%d/ns/net", os.Getpid(), unix.Gettid()),
|
||||
},
|
||||
}
|
||||
|
||||
err = s.startNetworkMonitor()
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user