Files
Memoh/internal/containerd/network.go
T

114 lines
2.7 KiB
Go

package containerd
import (
"context"
"fmt"
"os"
"path/filepath"
"strings"
"github.com/containerd/containerd/v2/client"
gocni "github.com/containerd/go-cni"
)
func setupCNINetwork(ctx context.Context, task client.Task, containerID string, CNIBinDir string, CNIConfDir string) error {
if task == nil {
return ErrInvalidArgument
}
if containerID == "" {
containerID = task.ID()
}
if containerID == "" {
return ErrInvalidArgument
}
pid := task.Pid()
if pid == 0 {
return fmt.Errorf("task pid not available for %s", containerID)
}
if _, err := os.Stat(CNIConfDir); err != nil {
return fmt.Errorf("cni config dir missing: %s: %w", CNIConfDir, err)
}
if _, err := os.Stat(CNIBinDir); err != nil {
return fmt.Errorf("cni bin dir missing: %s: %w", CNIBinDir, err)
}
netnsPath := filepath.Join("/proc", fmt.Sprint(pid), "ns", "net")
if _, err := os.Stat(netnsPath); err != nil {
return fmt.Errorf("netns not found: %s: %w", netnsPath, err)
}
cni, err := gocni.New(
gocni.WithPluginDir([]string{CNIBinDir}),
gocni.WithPluginConfDir(CNIConfDir),
)
if err != nil {
return err
}
if err := cni.Load(gocni.WithLoNetwork, gocni.WithDefaultConf); err != nil {
return err
}
_, err = cni.Setup(ctx, containerID, netnsPath)
if err != nil {
if !isDuplicateAllocationError(err) {
return err
}
if rmErr := cni.Remove(ctx, containerID, netnsPath); rmErr != nil {
return rmErr
}
_, err = cni.Setup(ctx, containerID, netnsPath)
if err != nil {
return err
}
}
return nil
}
func removeCNINetwork(ctx context.Context, task client.Task, containerID string, CNIBinDir string, CNIConfDir string) error {
if task == nil {
return ErrInvalidArgument
}
if containerID == "" {
containerID = task.ID()
}
if containerID == "" {
return ErrInvalidArgument
}
pid := task.Pid()
if pid == 0 {
return fmt.Errorf("task pid not available for %s", containerID)
}
if _, err := os.Stat(CNIConfDir); err != nil {
return fmt.Errorf("cni config dir missing: %s: %w", CNIConfDir, err)
}
if _, err := os.Stat(CNIBinDir); err != nil {
return fmt.Errorf("cni bin dir missing: %s: %w", CNIBinDir, err)
}
netnsPath := filepath.Join("/proc", fmt.Sprint(pid), "ns", "net")
if _, err := os.Stat(netnsPath); err != nil {
return fmt.Errorf("netns not found: %s: %w", netnsPath, err)
}
cni, err := gocni.New(
gocni.WithPluginDir([]string{CNIBinDir}),
gocni.WithPluginConfDir(CNIConfDir),
)
if err != nil {
return err
}
if err := cni.Load(gocni.WithLoNetwork, gocni.WithDefaultConf); err != nil {
return err
}
return cni.Remove(ctx, containerID, netnsPath)
}
func isDuplicateAllocationError(err error) bool {
if err == nil {
return false
}
return strings.Contains(err.Error(), "duplicate allocation")
}