Fix #I4KI81 reason: modify kata-containers version and update it to 1.11.1 Signed-off-by: holyfei <yangfeiyu20092010@163.com>
359 lines
13 KiB
Diff
359 lines
13 KiB
Diff
From f943e5d91f6922c599b46727e2dfd5e8e7e5bea8 Mon Sep 17 00:00:00 2001
|
|
From: jiangpengfei <jiangpengfei9@huawei.com>
|
|
Date: Wed, 19 Aug 2020 22:43:54 +0800
|
|
Subject: [PATCH 50/50] runtime: add kata-network upate-iface subcommand
|
|
|
|
reason: add kata-network update-iface subcommand to
|
|
update the exist interface in the Kata VM.
|
|
|
|
Signed-off-by: jiangpengfei <jiangpengfei9@huawei.com>
|
|
---
|
|
cli/network.go | 37 +++++++++-
|
|
virtcontainers/api.go | 25 +++++--
|
|
virtcontainers/implementation.go | 5 ++
|
|
virtcontainers/interfaces.go | 1 +
|
|
virtcontainers/pkg/vcmock/mock.go | 8 +++
|
|
virtcontainers/pkg/vcmock/types.go | 1 +
|
|
virtcontainers/sandbox.go | 137 +++++++++++++++++++++++++++++++++++++
|
|
7 files changed, 207 insertions(+), 7 deletions(-)
|
|
|
|
diff --git a/cli/network.go b/cli/network.go
|
|
index 3dd0971e..7dce0528 100644
|
|
--- a/cli/network.go
|
|
+++ b/cli/network.go
|
|
@@ -65,8 +65,9 @@ var addIfaceCommand = cli.Command{
|
|
"hwAddr":"<mac>",
|
|
"linkType":"tap",
|
|
"vhostUserSocket":"<path>"
|
|
+ "queues":<queues>
|
|
}
|
|
- device,name,mtu,hwAddr are required, IPAddresses and vhostUserSocket are optional.
|
|
+ device,name,mtu,hwAddr are required, IPAddresses, queues and vhostUserSocket are optional.
|
|
`,
|
|
Flags: []cli.Flag{},
|
|
Action: func(context *cli.Context) error {
|
|
@@ -104,6 +105,34 @@ var delIfaceCommand = cli.Command{
|
|
},
|
|
}
|
|
|
|
+var updateIfaceCommand = cli.Command{
|
|
+ Name: "update-iface",
|
|
+ Usage: "update the interface in container",
|
|
+ ArgsUsage: `update-iface <container-id> file or - for stdin
|
|
+ file or stdin for example:
|
|
+ {
|
|
+ "device":"",
|
|
+ "name":"<interface-name>",
|
|
+ "IPAddresses":[{"address":"<ip>","mask":"<mask>"}],
|
|
+ "mtu":0,
|
|
+ "hwAddr":"",
|
|
+ "linkType":"",
|
|
+ "vhostUserSocket":"",
|
|
+ "queues":0
|
|
+ }
|
|
+ name is required,IPAddresses is optional,device,mtu,hwAddr,linkType,queues and vhostUserSocket should be 0 or empty.
|
|
+ `,
|
|
+ Flags: []cli.Flag{},
|
|
+ Action: func(context *cli.Context) error {
|
|
+ ctx, err := cliContextToContext(context)
|
|
+ if err != nil {
|
|
+ return err
|
|
+ }
|
|
+
|
|
+ return networkModifyCommand(ctx, context.Args().First(), context.Args().Get(1), interfaceType, vcTypes.NetworkOpUpdate)
|
|
+ },
|
|
+}
|
|
+
|
|
var listIfacesCommand = cli.Command{
|
|
Name: "list-ifaces",
|
|
Usage: "list network interfaces in a container",
|
|
@@ -262,6 +291,12 @@ func networkModifyCommand(ctx context.Context, containerID, input string, opType
|
|
kataLog.WithField("resulting-interface", fmt.Sprintf("%+v", resultingInf)).
|
|
WithError(err).Error("delete interface failed")
|
|
}
|
|
+ case vcTypes.NetworkOpUpdate:
|
|
+ resultingInf, err = vci.UpdateInterface(ctx, sandboxID, inf)
|
|
+ if err != nil {
|
|
+ kataLog.WithField("resulting-interface", fmt.Sprintf("%+v", resultingInf)).
|
|
+ WithError(err).Error("update interface failed")
|
|
+ }
|
|
}
|
|
|
|
json.NewEncoder(output).Encode(resultingInf)
|
|
diff --git a/virtcontainers/api.go b/virtcontainers/api.go
|
|
index 7036df8c..ca5412a9 100644
|
|
--- a/virtcontainers/api.go
|
|
+++ b/virtcontainers/api.go
|
|
@@ -889,7 +889,7 @@ func AddDevice(ctx context.Context, sandboxID string, info deviceConfig.DeviceIn
|
|
return s.AddDevice(info)
|
|
}
|
|
|
|
-func toggleInterface(ctx context.Context, sandboxID string, inf *vcTypes.Interface, add bool) (*vcTypes.Interface, error) {
|
|
+func toggleInterface(ctx context.Context, sandboxID string, inf *vcTypes.Interface, op vcTypes.NetworkOp) (*vcTypes.Interface, error) {
|
|
if sandboxID == "" {
|
|
return nil, vcTypes.ErrNeedSandboxID
|
|
}
|
|
@@ -906,11 +906,16 @@ func toggleInterface(ctx context.Context, sandboxID string, inf *vcTypes.Interfa
|
|
}
|
|
defer s.releaseStatelessSandbox()
|
|
|
|
- if add {
|
|
+ switch op {
|
|
+ case vcTypes.NetworkOpAdd:
|
|
return s.AddInterface(inf)
|
|
+ case vcTypes.NetworkOpRemove:
|
|
+ return s.RemoveInterface(inf)
|
|
+ case vcTypes.NetworkOpUpdate:
|
|
+ return s.UpdateInterface(inf)
|
|
+ default:
|
|
+ return nil, fmt.Errorf("operation is not found")
|
|
}
|
|
-
|
|
- return s.RemoveInterface(inf)
|
|
}
|
|
|
|
// AddInterface is the virtcontainers add interface entry point.
|
|
@@ -918,7 +923,7 @@ func AddInterface(ctx context.Context, sandboxID string, inf *vcTypes.Interface)
|
|
span, ctx := trace(ctx, "AddInterface")
|
|
defer span.Finish()
|
|
|
|
- return toggleInterface(ctx, sandboxID, inf, true)
|
|
+ return toggleInterface(ctx, sandboxID, inf, vcTypes.NetworkOpAdd)
|
|
}
|
|
|
|
// RemoveInterface is the virtcontainers remove interface entry point.
|
|
@@ -926,7 +931,15 @@ func RemoveInterface(ctx context.Context, sandboxID string, inf *vcTypes.Interfa
|
|
span, ctx := trace(ctx, "RemoveInterface")
|
|
defer span.Finish()
|
|
|
|
- return toggleInterface(ctx, sandboxID, inf, false)
|
|
+ return toggleInterface(ctx, sandboxID, inf, vcTypes.NetworkOpRemove)
|
|
+}
|
|
+
|
|
+// UpdateInterface updates interface entry point in the virtcontainers.
|
|
+func UpdateInterface(ctx context.Context, sandboxID string, inf *vcTypes.Interface) (*vcTypes.Interface, error) {
|
|
+ span, ctx := trace(ctx, "UpdateInterface")
|
|
+ defer span.Finish()
|
|
+
|
|
+ return toggleInterface(ctx, sandboxID, inf, vcTypes.NetworkOpUpdate)
|
|
}
|
|
|
|
// ListInterfaces is the virtcontainers list interfaces entry point.
|
|
diff --git a/virtcontainers/implementation.go b/virtcontainers/implementation.go
|
|
index 0265d1ed..e4bc4ae6 100644
|
|
--- a/virtcontainers/implementation.go
|
|
+++ b/virtcontainers/implementation.go
|
|
@@ -163,6 +163,11 @@ func (impl *VCImpl) ListInterfaces(ctx context.Context, sandboxID string) ([]*vc
|
|
return ListInterfaces(ctx, sandboxID)
|
|
}
|
|
|
|
+// ListInterfaces implements the VC function of the same name.
|
|
+func (impl *VCImpl) UpdateInterface(ctx context.Context, sandboxID string, inf *vcTypes.Interface) (*vcTypes.Interface, error) {
|
|
+ return UpdateInterface(ctx, sandboxID, inf)
|
|
+}
|
|
+
|
|
// UpdateRoutes implements the VC function of the same name.
|
|
func (impl *VCImpl) UpdateRoutes(ctx context.Context, sandboxID string, routes []*vcTypes.Route, op vcTypes.NetworkOp) ([]*vcTypes.Route, error) {
|
|
return UpdateRoutes(ctx, sandboxID, routes, op)
|
|
diff --git a/virtcontainers/interfaces.go b/virtcontainers/interfaces.go
|
|
index d8f0be69..0fd12d84 100644
|
|
--- a/virtcontainers/interfaces.go
|
|
+++ b/virtcontainers/interfaces.go
|
|
@@ -51,6 +51,7 @@ type VC interface {
|
|
|
|
AddInterface(ctx context.Context, sandboxID string, inf *vcTypes.Interface) (*vcTypes.Interface, error)
|
|
RemoveInterface(ctx context.Context, sandboxID string, inf *vcTypes.Interface) (*vcTypes.Interface, error)
|
|
+ UpdateInterface(ctx context.Context, sandboxID string, inf *vcTypes.Interface) (*vcTypes.Interface, error)
|
|
ListInterfaces(ctx context.Context, sandboxID string) ([]*vcTypes.Interface, error)
|
|
UpdateRoutes(ctx context.Context, sandboxID string, routes []*vcTypes.Route, op vcTypes.NetworkOp) ([]*vcTypes.Route, error)
|
|
ListRoutes(ctx context.Context, sandboxID string) ([]*vcTypes.Route, error)
|
|
diff --git a/virtcontainers/pkg/vcmock/mock.go b/virtcontainers/pkg/vcmock/mock.go
|
|
index aa9bae9a..d3bf201f 100644
|
|
--- a/virtcontainers/pkg/vcmock/mock.go
|
|
+++ b/virtcontainers/pkg/vcmock/mock.go
|
|
@@ -273,6 +273,14 @@ func (m *VCMock) ListInterfaces(ctx context.Context, sandboxID string) ([]*vcTyp
|
|
return nil, fmt.Errorf("%s: %s (%+v): sandboxID: %v", mockErrorPrefix, getSelf(), m, sandboxID)
|
|
}
|
|
|
|
+// UpdateInterface implements the VC function of the same name
|
|
+func (m *VCMock) UpdateInterface(ctx context.Context, sandboxID string, inf *vcTypes.Interface) (*vcTypes.Interface, error) {
|
|
+ if m.UpdateRoutesFunc != nil {
|
|
+ return m.UpdateInterfaceFunc(ctx, sandboxID, inf)
|
|
+ }
|
|
+ return nil, fmt.Errorf("%s: %s (%+v): sandboxID: %v", mockErrorPrefix, getSelf(), m, sandboxID)
|
|
+}
|
|
+
|
|
// UpdateRoutes implements the VC function of the same name.
|
|
func (m *VCMock) UpdateRoutes(ctx context.Context, sandboxID string, routes []*vcTypes.Route, op vcTypes.NetworkOp) ([]*vcTypes.Route, error) {
|
|
if m.UpdateRoutesFunc != nil {
|
|
diff --git a/virtcontainers/pkg/vcmock/types.go b/virtcontainers/pkg/vcmock/types.go
|
|
index 610b4602..152e66b7 100644
|
|
--- a/virtcontainers/pkg/vcmock/types.go
|
|
+++ b/virtcontainers/pkg/vcmock/types.go
|
|
@@ -73,6 +73,7 @@ type VCMock struct {
|
|
AddInterfaceFunc func(ctx context.Context, sandboxID string, inf *vcTypes.Interface) (*vcTypes.Interface, error)
|
|
RemoveInterfaceFunc func(ctx context.Context, sandboxID string, inf *vcTypes.Interface) (*vcTypes.Interface, error)
|
|
ListInterfacesFunc func(ctx context.Context, sandboxID string) ([]*vcTypes.Interface, error)
|
|
+ UpdateInterfaceFunc func(ctx context.Context, sandboxID string, inf *vcTypes.Interface) (*vcTypes.Interface, error)
|
|
UpdateRoutesFunc func(ctx context.Context, sandboxID string, routes []*vcTypes.Route) ([]*vcTypes.Route, error)
|
|
ListRoutesFunc func(ctx context.Context, sandboxID string) ([]*vcTypes.Route, error)
|
|
CleanupContainerFunc func(ctx context.Context, sandboxID, containerID string, force bool) error
|
|
diff --git a/virtcontainers/sandbox.go b/virtcontainers/sandbox.go
|
|
index d8ab6c1a..174e6cb6 100644
|
|
--- a/virtcontainers/sandbox.go
|
|
+++ b/virtcontainers/sandbox.go
|
|
@@ -1031,6 +1031,54 @@ func (s *Sandbox) RemoveInterface(inf *vcTypes.Interface) (*vcTypes.Interface, e
|
|
return nil, nil
|
|
}
|
|
|
|
+// UpdateInterface updates the nic.
|
|
+func (s *Sandbox) UpdateInterface(inf *vcTypes.Interface) (*vcTypes.Interface, error) {
|
|
+ err := checkUpdateInterfaceInfo(inf)
|
|
+ if err != nil {
|
|
+ return nil, err
|
|
+ }
|
|
+
|
|
+ nicInGuest := false
|
|
+
|
|
+ endpoint := s.getEndpointByName(inf.Name)
|
|
+ // nic is not in local endpoints
|
|
+ if endpoint == nil {
|
|
+ interfaceInGuestInf := s.getInterfaceInfByName(inf.Name)
|
|
+ if interfaceInGuestInf == nil {
|
|
+ return nil, fmt.Errorf("can not find the network interface")
|
|
+ }
|
|
+
|
|
+ nicInGuest = true
|
|
+ endpoint, err = s.generateEndpointForStore(interfaceInGuestInf)
|
|
+ if err != nil {
|
|
+ return nil, err
|
|
+ }
|
|
+ }
|
|
+
|
|
+ // update endpoint ip
|
|
+ err = s.updateEndpointIP(endpoint, inf)
|
|
+ if err != nil {
|
|
+ return nil, err
|
|
+ }
|
|
+
|
|
+ s.Logger().WithField("endpoint-type", endpoint.Type()).Info("Update endpoint")
|
|
+ grpcIf, err := s.agent.updateInterface(inf)
|
|
+ if err != nil {
|
|
+ return nil, err
|
|
+ }
|
|
+
|
|
+ if nicInGuest {
|
|
+ s.networkNS.Endpoints = append(s.networkNS.Endpoints, endpoint)
|
|
+ }
|
|
+
|
|
+ if err = s.Save(); err != nil {
|
|
+ s.Logger().WithError(err).Error("failed to store the network information")
|
|
+ return nil, err
|
|
+ }
|
|
+
|
|
+ return grpcIf, nil
|
|
+}
|
|
+
|
|
// ListInterfaces lists all nics and their configurations in the sandbox.
|
|
func (s *Sandbox) ListInterfaces() ([]*vcTypes.Interface, error) {
|
|
return s.agent.listInterfaces()
|
|
@@ -2431,6 +2479,95 @@ func (s *Sandbox) IsCompatOldCNI() bool {
|
|
return s.config.NetworkConfig.EnableCompatOldCNI
|
|
}
|
|
|
|
+func checkUpdateInterfaceInfo(inf *vcTypes.Interface) error {
|
|
+ if inf.Mtu > 0 || inf.Queues > 0 || inf.Device != "" || inf.VhostUserSocket != "" || inf.LinkType != "" || inf.HwAddr != "" {
|
|
+ return fmt.Errorf("device,mtu,hwAddr,linkType,queues and vhostUserSocket should be 0 or empty")
|
|
+ }
|
|
+
|
|
+ return nil
|
|
+}
|
|
+
|
|
+// getEndpointByName returns the endpoint by name.
|
|
+func (s *Sandbox) getEndpointByName(name string) Endpoint {
|
|
+ if name == "" {
|
|
+ return nil
|
|
+ }
|
|
+
|
|
+ for i, endpoint := range s.networkNS.Endpoints {
|
|
+ if endpoint.Name() == name {
|
|
+ return s.networkNS.Endpoints[i]
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return nil
|
|
+}
|
|
+
|
|
+// getInterfaceInfByName returns the interface information.
|
|
+func (s *Sandbox) getInterfaceInfByName(name string) *vcTypes.Interface {
|
|
+ if name == "" {
|
|
+ return nil
|
|
+ }
|
|
+
|
|
+ nics, err := s.agent.listInterfaces()
|
|
+ if err != nil {
|
|
+ return nil
|
|
+ }
|
|
+
|
|
+ for _, i := range nics {
|
|
+ if i.Name == name {
|
|
+ return i
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return nil
|
|
+}
|
|
+
|
|
+// generateEndpointForStore only generates endpoint information for store,it does not create a endpoint
|
|
+func (s *Sandbox) generateEndpointForStore(inf *vcTypes.Interface) (*TapEndpoint, error) {
|
|
+ netInfo, err := s.generateNetInfo(inf)
|
|
+ if err != nil {
|
|
+ return nil, err
|
|
+ }
|
|
+
|
|
+ endpoint := &TapEndpoint{
|
|
+ TapInterface: TapInterface{
|
|
+ Name: inf.Name,
|
|
+ TAPIface: NetworkInterface{
|
|
+ HardAddr: inf.HwAddr,
|
|
+ },
|
|
+ },
|
|
+ EndpointType: TapEndpointType,
|
|
+ }
|
|
+
|
|
+ endpoint.SetProperties(netInfo)
|
|
+
|
|
+ return endpoint, nil
|
|
+}
|
|
+
|
|
+func (s *Sandbox) updateEndpointIP(endpoint Endpoint, inf *vcTypes.Interface) error {
|
|
+ if endpoint == nil {
|
|
+ return fmt.Errorf("endpoint is nil")
|
|
+ }
|
|
+
|
|
+ netInfo := endpoint.Properties()
|
|
+
|
|
+ var addrs []netlink.Addr
|
|
+ for _, addr := range inf.IPAddresses {
|
|
+ netlinkAddrStr := fmt.Sprintf("%s/%s", addr.Address, addr.Mask)
|
|
+ netlinkAddr, err := netlink.ParseAddr(netlinkAddrStr)
|
|
+ if err != nil {
|
|
+ return fmt.Errorf("could not parse %q: %v", netlinkAddrStr, err)
|
|
+ }
|
|
+
|
|
+ addrs = append(addrs, *netlinkAddr)
|
|
+ }
|
|
+
|
|
+ netInfo.Addrs = addrs
|
|
+ endpoint.SetProperties(netInfo)
|
|
+
|
|
+ return nil
|
|
+}
|
|
+
|
|
// updateStaticSandboxResources update sandbox's cpu and memory resource passed by
|
|
// sandbox_cpu and sandbox_mem annotations
|
|
func updateStaticSandboxResources(sandboxConfig *SandboxConfig) error {
|
|
--
|
|
2.14.3 (Apple Git-98)
|
|
|