plugin_linux.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. // +build linux
  2. package v2
  3. import (
  4. "os"
  5. "path/filepath"
  6. "strings"
  7. "github.com/docker/docker/api/types"
  8. "github.com/docker/docker/oci"
  9. "github.com/docker/docker/pkg/system"
  10. specs "github.com/opencontainers/runtime-spec/specs-go"
  11. "github.com/pkg/errors"
  12. )
  13. // InitSpec creates an OCI spec from the plugin's config.
  14. func (p *Plugin) InitSpec(execRoot string) (*specs.Spec, error) {
  15. s := oci.DefaultSpec()
  16. s.Root = specs.Root{
  17. Path: p.Rootfs,
  18. Readonly: false, // TODO: all plugins should be readonly? settable in config?
  19. }
  20. userMounts := make(map[string]struct{}, len(p.PluginObj.Settings.Mounts))
  21. for _, m := range p.PluginObj.Settings.Mounts {
  22. userMounts[m.Destination] = struct{}{}
  23. }
  24. execRoot = filepath.Join(execRoot, p.PluginObj.ID)
  25. if err := os.MkdirAll(execRoot, 0700); err != nil {
  26. return nil, errors.WithStack(err)
  27. }
  28. mounts := append(p.PluginObj.Config.Mounts, types.PluginMount{
  29. Source: &execRoot,
  30. Destination: defaultPluginRuntimeDestination,
  31. Type: "bind",
  32. Options: []string{"rbind", "rshared"},
  33. })
  34. if p.PluginObj.Config.Network.Type != "" {
  35. // TODO: if net == bridge, use libnetwork controller to create a new plugin-specific bridge, bind mount /etc/hosts and /etc/resolv.conf look at the docker code (allocateNetwork, initialize)
  36. if p.PluginObj.Config.Network.Type == "host" {
  37. oci.RemoveNamespace(&s, specs.NamespaceType("network"))
  38. }
  39. etcHosts := "/etc/hosts"
  40. resolvConf := "/etc/resolv.conf"
  41. mounts = append(mounts,
  42. types.PluginMount{
  43. Source: &etcHosts,
  44. Destination: etcHosts,
  45. Type: "bind",
  46. Options: []string{"rbind", "ro"},
  47. },
  48. types.PluginMount{
  49. Source: &resolvConf,
  50. Destination: resolvConf,
  51. Type: "bind",
  52. Options: []string{"rbind", "ro"},
  53. })
  54. }
  55. for _, mnt := range mounts {
  56. m := specs.Mount{
  57. Destination: mnt.Destination,
  58. Type: mnt.Type,
  59. Options: mnt.Options,
  60. }
  61. if mnt.Source == nil {
  62. return nil, errors.New("mount source is not specified")
  63. }
  64. m.Source = *mnt.Source
  65. s.Mounts = append(s.Mounts, m)
  66. }
  67. for i, m := range s.Mounts {
  68. if strings.HasPrefix(m.Destination, "/dev/") {
  69. if _, ok := userMounts[m.Destination]; ok {
  70. s.Mounts = append(s.Mounts[:i], s.Mounts[i+1:]...)
  71. }
  72. }
  73. }
  74. if p.PluginObj.Config.PropagatedMount != "" {
  75. p.PropagatedMount = filepath.Join(p.Rootfs, p.PluginObj.Config.PropagatedMount)
  76. s.Linux.RootfsPropagation = "rshared"
  77. }
  78. if p.PluginObj.Config.Linux.AllowAllDevices {
  79. rwm := "rwm"
  80. s.Linux.Resources.Devices = []specs.DeviceCgroup{{Allow: true, Access: &rwm}}
  81. }
  82. for _, dev := range p.PluginObj.Settings.Devices {
  83. path := *dev.Path
  84. d, dPermissions, err := oci.DevicesFromPath(path, path, "rwm")
  85. if err != nil {
  86. return nil, errors.WithStack(err)
  87. }
  88. s.Linux.Devices = append(s.Linux.Devices, d...)
  89. s.Linux.Resources.Devices = append(s.Linux.Resources.Devices, dPermissions...)
  90. }
  91. envs := make([]string, 1, len(p.PluginObj.Settings.Env)+1)
  92. envs[0] = "PATH=" + system.DefaultPathEnv
  93. envs = append(envs, p.PluginObj.Settings.Env...)
  94. args := append(p.PluginObj.Config.Entrypoint, p.PluginObj.Settings.Args...)
  95. cwd := p.PluginObj.Config.WorkDir
  96. if len(cwd) == 0 {
  97. cwd = "/"
  98. }
  99. s.Process.Terminal = false
  100. s.Process.Args = args
  101. s.Process.Cwd = cwd
  102. s.Process.Env = envs
  103. s.Process.Capabilities = append(s.Process.Capabilities, p.PluginObj.Config.Linux.Capabilities...)
  104. return &s, nil
  105. }