cni.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. package glue
  2. import (
  3. "fmt"
  4. "os"
  5. "sort"
  6. "strings"
  7. "github.com/containernetworking/cni/libcni"
  8. "github.com/containernetworking/cni/pkg/types"
  9. )
  10. var (
  11. cniDir = "/etc/docker/cni/%s.d"
  12. cniPath = []string{
  13. "/var/lib/cni/bin",
  14. "/usr/local/sbin",
  15. "/usr/sbin",
  16. "/sbin",
  17. "/usr/local/bin",
  18. "/usr/bin",
  19. "/bin",
  20. }
  21. )
  22. type CNIExec struct {
  23. confs []*libcni.NetworkConfig
  24. runtimeConf libcni.RuntimeConf
  25. cninet libcni.CNIConfig
  26. }
  27. func (c *CNIExec) Add(index int) (*types.Result, error) {
  28. return c.cninet.AddNetwork(c.confs[index], &c.runtimeConf)
  29. }
  30. func (c *CNIExec) Del(index int) error {
  31. rt := c.runtimeConf
  32. rt.NetNS = ""
  33. return c.cninet.DelNetwork(c.confs[index], &rt)
  34. }
  35. func NewCNIExec(state *DockerPluginState) (*CNIExec, error) {
  36. if state.HostConfig.NetworkMode.IsContainer() ||
  37. state.HostConfig.NetworkMode.IsHost() ||
  38. state.HostConfig.NetworkMode.IsNone() {
  39. return &CNIExec{}, nil
  40. }
  41. c := &CNIExec{
  42. runtimeConf: libcni.RuntimeConf{
  43. ContainerID: state.ContainerID,
  44. NetNS: fmt.Sprintf("/proc/%d/ns/net", state.State.Pid),
  45. IfName: "eth0",
  46. Args: [][2]string{
  47. {"IgnoreUnknown", "1"},
  48. {"DOCKER", "true"},
  49. },
  50. },
  51. cninet: libcni.CNIConfig{
  52. Path: cniPath,
  53. },
  54. }
  55. network := state.HostConfig.NetworkMode.NetworkName()
  56. if network == "" {
  57. network = "default"
  58. }
  59. dir := fmt.Sprintf(cniDir, network)
  60. files, err := libcni.ConfFiles(dir)
  61. if err != nil {
  62. return nil, err
  63. }
  64. sort.Strings(files)
  65. os.Setenv("PATH", strings.Join(cniPath, ":"))
  66. for _, file := range files {
  67. netConf, err := libcni.ConfFromFile(file)
  68. if err != nil {
  69. return nil, err
  70. }
  71. c.confs = append(c.confs, netConf)
  72. }
  73. return c, nil
  74. }
  75. func CNIAdd(state *DockerPluginState) (*types.Result, error) {
  76. c, err := NewCNIExec(state)
  77. if err != nil {
  78. return nil, err
  79. }
  80. var result *types.Result
  81. for i := range c.confs {
  82. pluginResult, err := c.Add(i)
  83. if err != nil {
  84. return nil, err
  85. }
  86. if pluginResult.IP4 != nil {
  87. result = pluginResult
  88. }
  89. }
  90. return result, nil
  91. }
  92. func CNIDel(state *DockerPluginState) error {
  93. c, err := NewCNIExec(state)
  94. if err != nil {
  95. return err
  96. }
  97. var lastErr error
  98. for i := len(c.confs) - 1; i >= 0; i-- {
  99. if err := c.Del(i); err != nil {
  100. lastErr = err
  101. }
  102. }
  103. return lastErr
  104. }