mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-06-26 23:38:31 +00:00
virtcontainers: Make all Network fields private
Prepare for making it a real interface. Signed-off-by: Samuel Ortiz <s.ortiz@apple.com>
This commit is contained in:
parent
49eee79f5f
commit
b858d0dedf
@ -217,7 +217,7 @@ func (fc *firecracker) CreateVM(ctx context.Context, id string, network *Network
|
|||||||
fc.setPaths(&fc.config)
|
fc.setPaths(&fc.config)
|
||||||
|
|
||||||
// So we need to repopulate this at StartVM where it is valid
|
// So we need to repopulate this at StartVM where it is valid
|
||||||
fc.netNSPath = network.NetNSPath
|
fc.netNSPath = network.NetNS()
|
||||||
|
|
||||||
// Till we create lower privileged kata user run as root
|
// Till we create lower privileged kata user run as root
|
||||||
// https://github.com/kata-containers/runtime/issues/1869
|
// https://github.com/kata-containers/runtime/issues/1869
|
||||||
|
@ -189,12 +189,12 @@ func networkLogger() *logrus.Entry {
|
|||||||
|
|
||||||
// Network represents a sandbox networking setup.
|
// Network represents a sandbox networking setup.
|
||||||
type Network struct {
|
type Network struct {
|
||||||
NetNSPath string
|
netNSPath string
|
||||||
InterworkingModel NetInterworkingModel
|
interworkingModel NetInterworkingModel
|
||||||
NetNSCreated bool
|
netNSCreated bool
|
||||||
|
|
||||||
Endpoints []Endpoint
|
eps []Endpoint
|
||||||
NetmonPID int
|
netmonPID int
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewNetwork(configs ...*NetworkConfig) (*Network, error) {
|
func NewNetwork(configs ...*NetworkConfig) (*Network, error) {
|
||||||
@ -223,8 +223,8 @@ func NewNetwork(configs ...*NetworkConfig) (*Network, error) {
|
|||||||
|
|
||||||
func LoadNetwork(netInfo persistapi.NetworkInfo) *Network {
|
func LoadNetwork(netInfo persistapi.NetworkInfo) *Network {
|
||||||
network := &Network{
|
network := &Network{
|
||||||
NetNSPath: netInfo.NetNsPath,
|
netNSPath: netInfo.NetNsPath,
|
||||||
NetNSCreated: netInfo.NetNsCreated,
|
netNSCreated: netInfo.NetNsCreated,
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, e := range netInfo.Endpoints {
|
for _, e := range netInfo.Endpoints {
|
||||||
@ -249,7 +249,7 @@ func LoadNetwork(netInfo persistapi.NetworkInfo) *Network {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
ep.load(e)
|
ep.load(e)
|
||||||
network.Endpoints = append(network.Endpoints, ep)
|
network.eps = append(network.eps, ep)
|
||||||
}
|
}
|
||||||
|
|
||||||
return network
|
return network
|
||||||
@ -300,7 +300,7 @@ func (n *Network) attachEndpoint(ctx context.Context, s *Sandbox, netInfo Networ
|
|||||||
endpoint, err = createPhysicalEndpoint(netInfo)
|
endpoint, err = createPhysicalEndpoint(netInfo)
|
||||||
} else {
|
} else {
|
||||||
var socketPath string
|
var socketPath string
|
||||||
idx := len(n.Endpoints)
|
idx := len(n.eps)
|
||||||
|
|
||||||
// Check if this is a dummy interface which has a vhost-user socket associated with it
|
// Check if this is a dummy interface which has a vhost-user socket associated with it
|
||||||
socketPath, err = vhostUserSocketPath(netInfo)
|
socketPath, err = vhostUserSocketPath(netInfo)
|
||||||
@ -313,7 +313,7 @@ func (n *Network) attachEndpoint(ctx context.Context, s *Sandbox, netInfo Networ
|
|||||||
endpoint, err = createVhostUserEndpoint(netInfo, socketPath)
|
endpoint, err = createVhostUserEndpoint(netInfo, socketPath)
|
||||||
} else if netInfo.Iface.Type == "macvlan" {
|
} else if netInfo.Iface.Type == "macvlan" {
|
||||||
networkLogger().Infof("macvlan interface found")
|
networkLogger().Infof("macvlan interface found")
|
||||||
endpoint, err = createMacvlanNetworkEndpoint(idx, netInfo.Iface.Name, n.InterworkingModel)
|
endpoint, err = createMacvlanNetworkEndpoint(idx, netInfo.Iface.Name, n.interworkingModel)
|
||||||
} else if netInfo.Iface.Type == "macvtap" {
|
} else if netInfo.Iface.Type == "macvtap" {
|
||||||
networkLogger().Infof("macvtap interface found")
|
networkLogger().Infof("macvtap interface found")
|
||||||
endpoint, err = createMacvtapNetworkEndpoint(netInfo)
|
endpoint, err = createMacvtapNetworkEndpoint(netInfo)
|
||||||
@ -330,14 +330,14 @@ func (n *Network) attachEndpoint(ctx context.Context, s *Sandbox, netInfo Networ
|
|||||||
return nil, fmt.Errorf("tun networking device not yet supported")
|
return nil, fmt.Errorf("tun networking device not yet supported")
|
||||||
case 2:
|
case 2:
|
||||||
networkLogger().Info("tuntap tap interface found")
|
networkLogger().Info("tuntap tap interface found")
|
||||||
endpoint, err = createTuntapNetworkEndpoint(idx, netInfo.Iface.Name, netInfo.Iface.HardwareAddr, n.InterworkingModel)
|
endpoint, err = createTuntapNetworkEndpoint(idx, netInfo.Iface.Name, netInfo.Iface.HardwareAddr, n.interworkingModel)
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("tuntap network %v mode unsupported", link.(*netlink.Tuntap).Mode)
|
return nil, fmt.Errorf("tuntap network %v mode unsupported", link.(*netlink.Tuntap).Mode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if netInfo.Iface.Type == "veth" {
|
} else if netInfo.Iface.Type == "veth" {
|
||||||
networkLogger().Info("veth interface found")
|
networkLogger().Info("veth interface found")
|
||||||
endpoint, err = createVethNetworkEndpoint(idx, netInfo.Iface.Name, n.InterworkingModel)
|
endpoint, err = createVethNetworkEndpoint(idx, netInfo.Iface.Name, n.interworkingModel)
|
||||||
} else if netInfo.Iface.Type == "ipvlan" {
|
} else if netInfo.Iface.Type == "ipvlan" {
|
||||||
networkLogger().Info("ipvlan interface found")
|
networkLogger().Info("ipvlan interface found")
|
||||||
endpoint, err = createIPVlanNetworkEndpoint(idx, netInfo.Iface.Name)
|
endpoint, err = createIPVlanNetworkEndpoint(idx, netInfo.Iface.Name)
|
||||||
@ -348,7 +348,7 @@ func (n *Network) attachEndpoint(ctx context.Context, s *Sandbox, netInfo Networ
|
|||||||
|
|
||||||
endpoint.SetProperties(netInfo)
|
endpoint.SetProperties(netInfo)
|
||||||
|
|
||||||
if err := doNetNS(n.NetNSPath, func(_ ns.NetNS) error {
|
if err := doNetNS(n.netNSPath, func(_ ns.NetNS) error {
|
||||||
networkLogger().WithField("endpoint-type", endpoint.Type()).WithField("hotplug", hotplug).Info("Attaching endpoint")
|
networkLogger().WithField("endpoint-type", endpoint.Type()).WithField("hotplug", hotplug).Info("Attaching endpoint")
|
||||||
if hotplug {
|
if hotplug {
|
||||||
if err := endpoint.HotAttach(ctx, s.hypervisor); err != nil {
|
if err := endpoint.HotAttach(ctx, s.hypervisor); err != nil {
|
||||||
@ -382,22 +382,22 @@ func (n *Network) attachEndpoint(ctx context.Context, s *Sandbox, netInfo Networ
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
n.Endpoints = append(n.Endpoints, endpoint)
|
n.eps = append(n.eps, endpoint)
|
||||||
|
|
||||||
return endpoint, nil
|
return endpoint, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Network) detachEndpoint(ctx context.Context, s *Sandbox, idx int, hotplug bool) error {
|
func (n *Network) detachEndpoint(ctx context.Context, s *Sandbox, idx int, hotplug bool) error {
|
||||||
if idx > len(n.Endpoints)-1 {
|
if idx > len(n.eps)-1 {
|
||||||
return fmt.Errorf("Enpoint index overflow")
|
return fmt.Errorf("Enpoint index overflow")
|
||||||
}
|
}
|
||||||
|
|
||||||
endpoint := n.Endpoints[idx]
|
endpoint := n.eps[idx]
|
||||||
|
|
||||||
if endpoint.GetRxRateLimiter() {
|
if endpoint.GetRxRateLimiter() {
|
||||||
networkLogger().WithField("endpoint-type", endpoint.Type()).Info("Deleting rx rate limiter")
|
networkLogger().WithField("endpoint-type", endpoint.Type()).Info("Deleting rx rate limiter")
|
||||||
// Deleting rx rate limiter should enter the network namespace.
|
// Deleting rx rate limiter should enter the network namespace.
|
||||||
if err := removeRxRateLimiter(endpoint, n.NetNSPath); err != nil {
|
if err := removeRxRateLimiter(endpoint, n.netNSPath); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -405,7 +405,7 @@ func (n *Network) detachEndpoint(ctx context.Context, s *Sandbox, idx int, hotpl
|
|||||||
if endpoint.GetTxRateLimiter() {
|
if endpoint.GetTxRateLimiter() {
|
||||||
networkLogger().WithField("endpoint-type", endpoint.Type()).Info("Deleting tx rate limiter")
|
networkLogger().WithField("endpoint-type", endpoint.Type()).Info("Deleting tx rate limiter")
|
||||||
// Deleting tx rate limiter should enter the network namespace.
|
// Deleting tx rate limiter should enter the network namespace.
|
||||||
if err := removeTxRateLimiter(endpoint, n.NetNSPath); err != nil {
|
if err := removeTxRateLimiter(endpoint, n.netNSPath); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -414,16 +414,16 @@ func (n *Network) detachEndpoint(ctx context.Context, s *Sandbox, idx int, hotpl
|
|||||||
// if required.
|
// if required.
|
||||||
networkLogger().WithField("endpoint-type", endpoint.Type()).Info("Detaching endpoint")
|
networkLogger().WithField("endpoint-type", endpoint.Type()).Info("Detaching endpoint")
|
||||||
if hotplug && s != nil {
|
if hotplug && s != nil {
|
||||||
if err := endpoint.HotDetach(ctx, s.hypervisor, n.NetNSCreated, n.NetNSPath); err != nil {
|
if err := endpoint.HotDetach(ctx, s.hypervisor, n.netNSCreated, n.netNSPath); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if err := endpoint.Detach(ctx, n.NetNSCreated, n.NetNSPath); err != nil {
|
if err := endpoint.Detach(ctx, n.netNSCreated, n.netNSPath); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
n.Endpoints = append(n.Endpoints[:idx], n.Endpoints[idx+1:]...)
|
n.eps = append(n.eps[:idx], n.eps[idx+1:]...)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -432,7 +432,7 @@ func (n *Network) detachEndpoint(ctx context.Context, s *Sandbox, idx int, hotpl
|
|||||||
// 1. Create the endpoints for the relevant interfaces found there.
|
// 1. Create the endpoints for the relevant interfaces found there.
|
||||||
// 2. Attach them to the VM.
|
// 2. Attach them to the VM.
|
||||||
func (n *Network) attachEndpoints(ctx context.Context, s *Sandbox, hotplug bool) error {
|
func (n *Network) attachEndpoints(ctx context.Context, s *Sandbox, hotplug bool) error {
|
||||||
netnsHandle, err := netns.GetFromPath(n.NetNSPath)
|
netnsHandle, err := netns.GetFromPath(n.netNSPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -474,11 +474,11 @@ func (n *Network) attachEndpoints(ctx context.Context, s *Sandbox, hotplug bool)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.Slice(n.Endpoints, func(i, j int) bool {
|
sort.Slice(n.eps, func(i, j int) bool {
|
||||||
return n.Endpoints[i].Name() < n.Endpoints[j].Name()
|
return n.eps[i].Name() < n.eps[j].Name()
|
||||||
})
|
})
|
||||||
|
|
||||||
networkLogger().WithField("endpoints", n.Endpoints).Info("Endpoints found after scan")
|
networkLogger().WithField("endpoints", n.eps).Info("endpoints found after scan")
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -488,7 +488,7 @@ func (n *Network) Run(ctx context.Context, cb func() error) error {
|
|||||||
span, _ := n.trace(ctx, "Run")
|
span, _ := n.trace(ctx, "Run")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
return doNetNS(n.NetNSPath, func(_ ns.NetNS) error {
|
return doNetNS(n.netNSPath, func(_ ns.NetNS) error {
|
||||||
return cb()
|
return cb()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -496,14 +496,14 @@ func (n *Network) Run(ctx context.Context, cb func() error) error {
|
|||||||
// Add adds all needed interfaces inside the network namespace.
|
// Add adds all needed interfaces inside the network namespace.
|
||||||
func (n *Network) Add(ctx context.Context, s *Sandbox, hotplug bool) error {
|
func (n *Network) Add(ctx context.Context, s *Sandbox, hotplug bool) error {
|
||||||
span, ctx := n.trace(ctx, "Add")
|
span, ctx := n.trace(ctx, "Add")
|
||||||
katatrace.AddTags(span, "type", n.InterworkingModel.GetModel())
|
katatrace.AddTags(span, "type", n.interworkingModel.GetModel())
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
if err := n.attachEndpoints(ctx, s, hotplug); err != nil {
|
if err := n.attachEndpoints(ctx, s, hotplug); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
katatrace.AddTags(span, "endpoints", n.Endpoints, "hotplug", hotplug)
|
katatrace.AddTags(span, "endpoints", n.eps, "hotplug", hotplug)
|
||||||
networkLogger().Debug("Network added")
|
networkLogger().Debug("Network added")
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -514,11 +514,11 @@ func (n *Network) PostAdd(ctx context.Context, hotplug bool) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Endpoints == nil {
|
if n.eps == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
endpoints := n.Endpoints
|
endpoints := n.eps
|
||||||
|
|
||||||
for _, endpoint := range endpoints {
|
for _, endpoint := range endpoints {
|
||||||
netPair := endpoint.NetworkPair()
|
netPair := endpoint.NetworkPair()
|
||||||
@ -541,7 +541,7 @@ func (n *Network) Remove(ctx context.Context) error {
|
|||||||
span, ctx := n.trace(ctx, "Remove")
|
span, ctx := n.trace(ctx, "Remove")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
for i, _ := range n.Endpoints {
|
for i, _ := range n.eps {
|
||||||
if err := n.detachEndpoint(ctx, nil, i, false); err != nil {
|
if err := n.detachEndpoint(ctx, nil, i, false); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -549,14 +549,27 @@ func (n *Network) Remove(ctx context.Context) error {
|
|||||||
|
|
||||||
networkLogger().Debug("Network removed")
|
networkLogger().Debug("Network removed")
|
||||||
|
|
||||||
if n.NetNSCreated {
|
if n.netNSCreated {
|
||||||
networkLogger().Infof("Network namespace %q deleted", n.NetNSPath)
|
networkLogger().Infof("Network namespace %q deleted", n.netNSPath)
|
||||||
return deleteNetNS(n.NetNSPath)
|
return deleteNetNS(n.netNSPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Network getters
|
||||||
|
func (n *Network) NetNS() string {
|
||||||
|
return n.netNSPath
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Network) NetNSCreated() bool {
|
||||||
|
return n.netNSCreated
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Network) Endpoints() []Endpoint {
|
||||||
|
return n.eps
|
||||||
|
}
|
||||||
|
|
||||||
func createLink(netHandle *netlink.Handle, name string, expectedLink netlink.Link, queues int) (netlink.Link, []*os.File, error) {
|
func createLink(netHandle *netlink.Handle, name string, expectedLink netlink.Link, queues int) (netlink.Link, []*os.File, error) {
|
||||||
var newLink netlink.Link
|
var newLink netlink.Link
|
||||||
var fds []*os.File
|
var fds []*os.File
|
||||||
@ -1212,7 +1225,7 @@ func deleteNetNS(netNSPath string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func generateVCNetworkStructures(ctx context.Context, network *Network) ([]*pbTypes.Interface, []*pbTypes.Route, []*pbTypes.ARPNeighbor, error) {
|
func generateVCNetworkStructures(ctx context.Context, network *Network) ([]*pbTypes.Interface, []*pbTypes.Route, []*pbTypes.ARPNeighbor, error) {
|
||||||
if network.NetNSPath == "" {
|
if network.netNSPath == "" {
|
||||||
return nil, nil, nil, nil
|
return nil, nil, nil, nil
|
||||||
}
|
}
|
||||||
span, _ := networkTrace(ctx, "generateVCNetworkStructures", nil)
|
span, _ := networkTrace(ctx, "generateVCNetworkStructures", nil)
|
||||||
@ -1222,7 +1235,7 @@ func generateVCNetworkStructures(ctx context.Context, network *Network) ([]*pbTy
|
|||||||
var ifaces []*pbTypes.Interface
|
var ifaces []*pbTypes.Interface
|
||||||
var neighs []*pbTypes.ARPNeighbor
|
var neighs []*pbTypes.ARPNeighbor
|
||||||
|
|
||||||
for _, endpoint := range network.Endpoints {
|
for _, endpoint := range network.eps {
|
||||||
var ipAddresses []*pbTypes.IPAddress
|
var ipAddresses []*pbTypes.IPAddress
|
||||||
for _, addr := range endpoint.Properties().Addrs {
|
for _, addr := range endpoint.Properties().Addrs {
|
||||||
// Skip localhost interface
|
// Skip localhost interface
|
||||||
|
@ -75,7 +75,7 @@ func TestGenerateInterfacesAndRoutes(t *testing.T) {
|
|||||||
|
|
||||||
nns, err := NewNetwork(&NetworkConfig{NetNSPath: "foobar", NetNsCreated: true})
|
nns, err := NewNetwork(&NetworkConfig{NetNSPath: "foobar", NetNsCreated: true})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
nns.Endpoints = endpoints
|
nns.eps = endpoints
|
||||||
|
|
||||||
resInterfaces, resRoutes, resNeighs, err := generateVCNetworkStructures(context.Background(), nns)
|
resInterfaces, resRoutes, resNeighs, err := generateVCNetworkStructures(context.Background(), nns)
|
||||||
|
|
||||||
|
@ -164,10 +164,10 @@ func (s *Sandbox) dumpAgent(ss *persistapi.SandboxState) {
|
|||||||
|
|
||||||
func (s *Sandbox) dumpNetwork(ss *persistapi.SandboxState) {
|
func (s *Sandbox) dumpNetwork(ss *persistapi.SandboxState) {
|
||||||
ss.Network = persistapi.NetworkInfo{
|
ss.Network = persistapi.NetworkInfo{
|
||||||
NetNsPath: s.network.NetNSPath,
|
NetNsPath: s.network.NetNS(),
|
||||||
NetNsCreated: s.network.NetNSCreated,
|
NetNsCreated: s.network.NetNSCreated(),
|
||||||
}
|
}
|
||||||
for _, e := range s.network.Endpoints {
|
for _, e := range s.network.Endpoints() {
|
||||||
ss.Network.Endpoints = append(ss.Network.Endpoints, e.save())
|
ss.Network.Endpoints = append(ss.Network.Endpoints, e.save())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -269,7 +269,7 @@ func (s *Sandbox) GetAnnotations() map[string]string {
|
|||||||
|
|
||||||
// GetNetNs returns the network namespace of the current sandbox.
|
// GetNetNs returns the network namespace of the current sandbox.
|
||||||
func (s *Sandbox) GetNetNs() string {
|
func (s *Sandbox) GetNetNs() string {
|
||||||
return s.network.NetNSPath
|
return s.network.NetNS()
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetHypervisorPid returns the hypervisor's pid.
|
// GetHypervisorPid returns the hypervisor's pid.
|
||||||
@ -880,7 +880,7 @@ func (s *Sandbox) AddInterface(ctx context.Context, inf *pbTypes.Interface) (*pb
|
|||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errDetach := s.network.detachEndpoint(ctx, s, len(s.network.Endpoints)-1, true); err != nil {
|
if errDetach := s.network.detachEndpoint(ctx, s, len(s.network.Endpoints())-1, true); err != nil {
|
||||||
s.Logger().WithField("endpoint-type", endpoint.Type()).WithError(errDetach).Error("rollback hot attaching endpoint failed")
|
s.Logger().WithField("endpoint-type", endpoint.Type()).WithError(errDetach).Error("rollback hot attaching endpoint failed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -903,7 +903,7 @@ func (s *Sandbox) AddInterface(ctx context.Context, inf *pbTypes.Interface) (*pb
|
|||||||
|
|
||||||
// RemoveInterface removes a nic of the sandbox.
|
// RemoveInterface removes a nic of the sandbox.
|
||||||
func (s *Sandbox) RemoveInterface(ctx context.Context, inf *pbTypes.Interface) (*pbTypes.Interface, error) {
|
func (s *Sandbox) RemoveInterface(ctx context.Context, inf *pbTypes.Interface) (*pbTypes.Interface, error) {
|
||||||
for i, endpoint := range s.network.Endpoints {
|
for i, endpoint := range s.network.Endpoints() {
|
||||||
if endpoint.HardwareAddr() == inf.HwAddr {
|
if endpoint.HardwareAddr() == inf.HwAddr {
|
||||||
s.Logger().WithField("endpoint-type", endpoint.Type()).Info("Hot detaching endpoint")
|
s.Logger().WithField("endpoint-type", endpoint.Type()).Info("Hot detaching endpoint")
|
||||||
if err := s.network.detachEndpoint(ctx, s, i, true); err != nil {
|
if err := s.network.detachEndpoint(ctx, s, i, true); err != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user