github.com/shishir-a412ed/docker@v1.3.2-0.20180103180333-fda904911d87/plugin/v2/plugin_linux.go (about) 1 package v2 2 3 import ( 4 "os" 5 "path/filepath" 6 "runtime" 7 "strings" 8 9 "github.com/docker/docker/api/types" 10 "github.com/docker/docker/oci" 11 "github.com/docker/docker/pkg/system" 12 specs "github.com/opencontainers/runtime-spec/specs-go" 13 "github.com/pkg/errors" 14 ) 15 16 // InitSpec creates an OCI spec from the plugin's config. 17 func (p *Plugin) InitSpec(execRoot string) (*specs.Spec, error) { 18 s := oci.DefaultSpec() 19 s.Root = &specs.Root{ 20 Path: p.Rootfs, 21 Readonly: false, // TODO: all plugins should be readonly? settable in config? 22 } 23 24 userMounts := make(map[string]struct{}, len(p.PluginObj.Settings.Mounts)) 25 for _, m := range p.PluginObj.Settings.Mounts { 26 userMounts[m.Destination] = struct{}{} 27 } 28 29 execRoot = filepath.Join(execRoot, p.PluginObj.ID) 30 if err := os.MkdirAll(execRoot, 0700); err != nil { 31 return nil, errors.WithStack(err) 32 } 33 34 mounts := append(p.PluginObj.Config.Mounts, types.PluginMount{ 35 Source: &execRoot, 36 Destination: defaultPluginRuntimeDestination, 37 Type: "bind", 38 Options: []string{"rbind", "rshared"}, 39 }) 40 41 if p.PluginObj.Config.Network.Type != "" { 42 // 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) 43 if p.PluginObj.Config.Network.Type == "host" { 44 oci.RemoveNamespace(&s, specs.LinuxNamespaceType("network")) 45 } 46 etcHosts := "/etc/hosts" 47 resolvConf := "/etc/resolv.conf" 48 mounts = append(mounts, 49 types.PluginMount{ 50 Source: &etcHosts, 51 Destination: etcHosts, 52 Type: "bind", 53 Options: []string{"rbind", "ro"}, 54 }, 55 types.PluginMount{ 56 Source: &resolvConf, 57 Destination: resolvConf, 58 Type: "bind", 59 Options: []string{"rbind", "ro"}, 60 }) 61 } 62 if p.PluginObj.Config.PidHost { 63 oci.RemoveNamespace(&s, specs.LinuxNamespaceType("pid")) 64 } 65 66 if p.PluginObj.Config.IpcHost { 67 oci.RemoveNamespace(&s, specs.LinuxNamespaceType("ipc")) 68 } 69 70 for _, mnt := range mounts { 71 m := specs.Mount{ 72 Destination: mnt.Destination, 73 Type: mnt.Type, 74 Options: mnt.Options, 75 } 76 if mnt.Source == nil { 77 return nil, errors.New("mount source is not specified") 78 } 79 m.Source = *mnt.Source 80 s.Mounts = append(s.Mounts, m) 81 } 82 83 for i, m := range s.Mounts { 84 if strings.HasPrefix(m.Destination, "/dev/") { 85 if _, ok := userMounts[m.Destination]; ok { 86 s.Mounts = append(s.Mounts[:i], s.Mounts[i+1:]...) 87 } 88 } 89 } 90 91 if p.PluginObj.Config.PropagatedMount != "" { 92 p.PropagatedMount = filepath.Join(p.Rootfs, p.PluginObj.Config.PropagatedMount) 93 s.Linux.RootfsPropagation = "rshared" 94 } 95 96 if p.PluginObj.Config.Linux.AllowAllDevices { 97 s.Linux.Resources.Devices = []specs.LinuxDeviceCgroup{{Allow: true, Access: "rwm"}} 98 } 99 for _, dev := range p.PluginObj.Settings.Devices { 100 path := *dev.Path 101 d, dPermissions, err := oci.DevicesFromPath(path, path, "rwm") 102 if err != nil { 103 return nil, errors.WithStack(err) 104 } 105 s.Linux.Devices = append(s.Linux.Devices, d...) 106 s.Linux.Resources.Devices = append(s.Linux.Resources.Devices, dPermissions...) 107 } 108 109 envs := make([]string, 1, len(p.PluginObj.Settings.Env)+1) 110 envs[0] = "PATH=" + system.DefaultPathEnv(runtime.GOOS) 111 envs = append(envs, p.PluginObj.Settings.Env...) 112 113 args := append(p.PluginObj.Config.Entrypoint, p.PluginObj.Settings.Args...) 114 cwd := p.PluginObj.Config.WorkDir 115 if len(cwd) == 0 { 116 cwd = "/" 117 } 118 s.Process.Terminal = false 119 s.Process.Args = args 120 s.Process.Cwd = cwd 121 s.Process.Env = envs 122 123 caps := s.Process.Capabilities 124 caps.Bounding = append(caps.Bounding, p.PluginObj.Config.Linux.Capabilities...) 125 caps.Permitted = append(caps.Permitted, p.PluginObj.Config.Linux.Capabilities...) 126 caps.Inheritable = append(caps.Inheritable, p.PluginObj.Config.Linux.Capabilities...) 127 caps.Effective = append(caps.Effective, p.PluginObj.Config.Linux.Capabilities...) 128 129 return &s, nil 130 }