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 {
|
type NetworkConfig struct {
|
||||||
NetNSPath string
|
NetNSPath string
|
||||||
NetNsCreated bool
|
NetNsCreated bool
|
||||||
|
NetmonConfig NetmonConfig
|
||||||
InterworkingModel NetInterworkingModel
|
InterworkingModel NetInterworkingModel
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -474,6 +475,7 @@ type NetworkNamespace struct {
|
|||||||
NetNsPath string
|
NetNsPath string
|
||||||
NetNsCreated bool
|
NetNsCreated bool
|
||||||
Endpoints []Endpoint
|
Endpoints []Endpoint
|
||||||
|
NetmonPID int
|
||||||
}
|
}
|
||||||
|
|
||||||
// TypedJSONEndpoint is used as an intermediate representation for
|
// TypedJSONEndpoint is used as an intermediate representation for
|
||||||
|
@ -961,6 +961,40 @@ func (s *Sandbox) Delete() error {
|
|||||||
return s.storage.deleteSandboxResources(s.id, nil)
|
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 {
|
func (s *Sandbox) createNetwork() error {
|
||||||
span, _ := s.trace("createNetwork")
|
span, _ := s.trace("createNetwork")
|
||||||
defer span.Finish()
|
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
|
// Store the network
|
||||||
return s.storage.storeSandboxNetwork(s.id, s.networkNS)
|
return s.storage.storeSandboxNetwork(s.id, s.networkNS)
|
||||||
}
|
}
|
||||||
@ -991,6 +1031,12 @@ func (s *Sandbox) removeNetwork() error {
|
|||||||
span, _ := s.trace("removeNetwork")
|
span, _ := s.trace("removeNetwork")
|
||||||
defer span.Finish()
|
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
|
// In case there is a factory, the network has been handled through
|
||||||
// some API calls to hotplug some interfaces and routes. This means
|
// some API calls to hotplug some interfaces and routes. This means
|
||||||
// the removal of the network should follow the same logic.
|
// the removal of the network should follow the same logic.
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"reflect"
|
"reflect"
|
||||||
"sync"
|
"sync"
|
||||||
@ -23,6 +24,7 @@ import (
|
|||||||
"github.com/kata-containers/runtime/virtcontainers/device/drivers"
|
"github.com/kata-containers/runtime/virtcontainers/device/drivers"
|
||||||
"github.com/kata-containers/runtime/virtcontainers/device/manager"
|
"github.com/kata-containers/runtime/virtcontainers/device/manager"
|
||||||
"github.com/kata-containers/runtime/virtcontainers/pkg/annotations"
|
"github.com/kata-containers/runtime/virtcontainers/pkg/annotations"
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newHypervisorConfig(kernelParams []Param, hParams []Param) HypervisorConfig {
|
func newHypervisorConfig(kernelParams []Param, hParams []Param) HypervisorConfig {
|
||||||
@ -1722,3 +1724,27 @@ func TestGetNetNs(t *testing.T) {
|
|||||||
netNs = s.GetNetNs()
|
netNs = s.GetNetNs()
|
||||||
assert.Equal(t, netNs, expected)
|
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