Skip to content
This repository has been archived by the owner on May 12, 2021. It is now read-only.

Commit

Permalink
virtcontainers: Start network monitor from virtcontainers
Browse files Browse the repository at this point in the history
This patch enables the code responsible for starting and stopping
the network monitor.

Signed-off-by: Sebastien Boeuf <[email protected]>
  • Loading branch information
Sebastien Boeuf committed Sep 14, 2018
1 parent 29e2fa0 commit 1406d99
Show file tree
Hide file tree
Showing 5 changed files with 231 additions and 0 deletions.
96 changes: 96 additions & 0 deletions virtcontainers/netmon.go
Original file line number Diff line number Diff line change
@@ -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 changes: 61 additions & 0 deletions virtcontainers/netmon_test.go
Original file line number Diff line number Diff line change
@@ -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)
}
2 changes: 2 additions & 0 deletions virtcontainers/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ type NetworkInterfacePair struct {
type NetworkConfig struct {
NetNSPath string
NetNsCreated bool
NetmonConfig NetmonConfig
InterworkingModel NetInterworkingModel
}

Expand Down Expand Up @@ -474,6 +475,7 @@ type NetworkNamespace struct {
NetNsPath string
NetNsCreated bool
Endpoints []Endpoint
NetmonPID int
}

// TypedJSONEndpoint is used as an intermediate representation for
Expand Down
46 changes: 46 additions & 0 deletions virtcontainers/sandbox.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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)
}
Expand All @@ -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.
Expand Down
26 changes: 26 additions & 0 deletions virtcontainers/sandbox_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"reflect"
"sync"
Expand All @@ -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 {
Expand Down Expand Up @@ -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)
}

0 comments on commit 1406d99

Please sign in to comment.