github.com/titanous/docker@v1.4.1/daemon/execdriver/native/create.go (about) 1 // +build linux,cgo 2 3 package native 4 5 import ( 6 "fmt" 7 "os" 8 "os/exec" 9 "path/filepath" 10 11 "github.com/docker/docker/daemon/execdriver" 12 "github.com/docker/docker/daemon/execdriver/native/template" 13 "github.com/docker/libcontainer" 14 "github.com/docker/libcontainer/apparmor" 15 "github.com/docker/libcontainer/devices" 16 "github.com/docker/libcontainer/mount" 17 "github.com/docker/libcontainer/security/capabilities" 18 ) 19 20 // createContainer populates and configures the container type with the 21 // data provided by the execdriver.Command 22 func (d *driver) createContainer(c *execdriver.Command) (*libcontainer.Config, error) { 23 container := template.New() 24 25 container.Hostname = getEnv("HOSTNAME", c.ProcessConfig.Env) 26 container.Tty = c.ProcessConfig.Tty 27 container.User = c.ProcessConfig.User 28 container.WorkingDir = c.WorkingDir 29 container.Env = c.ProcessConfig.Env 30 container.Cgroups.Name = c.ID 31 container.Cgroups.AllowedDevices = c.AllowedDevices 32 container.MountConfig.DeviceNodes = c.AutoCreatedDevices 33 container.RootFs = c.Rootfs 34 35 // check to see if we are running in ramdisk to disable pivot root 36 container.MountConfig.NoPivotRoot = os.Getenv("DOCKER_RAMDISK") != "" 37 container.RestrictSys = true 38 39 if err := d.createIpc(container, c); err != nil { 40 return nil, err 41 } 42 43 if err := d.createNetwork(container, c); err != nil { 44 return nil, err 45 } 46 47 if c.ProcessConfig.Privileged { 48 if err := d.setPrivileged(container); err != nil { 49 return nil, err 50 } 51 } else { 52 if err := d.setCapabilities(container, c); err != nil { 53 return nil, err 54 } 55 } 56 57 if c.AppArmorProfile != "" { 58 container.AppArmorProfile = c.AppArmorProfile 59 } 60 61 if err := d.setupCgroups(container, c); err != nil { 62 return nil, err 63 } 64 65 if err := d.setupMounts(container, c); err != nil { 66 return nil, err 67 } 68 69 if err := d.setupLabels(container, c); err != nil { 70 return nil, err 71 } 72 73 cmds := make(map[string]*exec.Cmd) 74 d.Lock() 75 for k, v := range d.activeContainers { 76 cmds[k] = v.cmd 77 } 78 d.Unlock() 79 80 return container, nil 81 } 82 83 func (d *driver) createNetwork(container *libcontainer.Config, c *execdriver.Command) error { 84 if c.Network.HostNetworking { 85 container.Namespaces["NEWNET"] = false 86 return nil 87 } 88 89 container.Networks = []*libcontainer.Network{ 90 { 91 Mtu: c.Network.Mtu, 92 Address: fmt.Sprintf("%s/%d", "127.0.0.1", 0), 93 Gateway: "localhost", 94 Type: "loopback", 95 }, 96 } 97 98 if c.Network.Interface != nil { 99 vethNetwork := libcontainer.Network{ 100 Mtu: c.Network.Mtu, 101 Address: fmt.Sprintf("%s/%d", c.Network.Interface.IPAddress, c.Network.Interface.IPPrefixLen), 102 MacAddress: c.Network.Interface.MacAddress, 103 Gateway: c.Network.Interface.Gateway, 104 Type: "veth", 105 Bridge: c.Network.Interface.Bridge, 106 VethPrefix: "veth", 107 } 108 container.Networks = append(container.Networks, &vethNetwork) 109 } 110 111 if c.Network.ContainerID != "" { 112 d.Lock() 113 active := d.activeContainers[c.Network.ContainerID] 114 d.Unlock() 115 116 if active == nil || active.cmd.Process == nil { 117 return fmt.Errorf("%s is not a valid running container to join", c.Network.ContainerID) 118 } 119 cmd := active.cmd 120 121 nspath := filepath.Join("/proc", fmt.Sprint(cmd.Process.Pid), "ns", "net") 122 container.Networks = append(container.Networks, &libcontainer.Network{ 123 Type: "netns", 124 NsPath: nspath, 125 }) 126 } 127 128 return nil 129 } 130 131 func (d *driver) createIpc(container *libcontainer.Config, c *execdriver.Command) error { 132 if c.Ipc.HostIpc { 133 container.Namespaces["NEWIPC"] = false 134 return nil 135 } 136 137 if c.Ipc.ContainerID != "" { 138 d.Lock() 139 active := d.activeContainers[c.Ipc.ContainerID] 140 d.Unlock() 141 142 if active == nil || active.cmd.Process == nil { 143 return fmt.Errorf("%s is not a valid running container to join", c.Ipc.ContainerID) 144 } 145 cmd := active.cmd 146 147 container.IpcNsPath = filepath.Join("/proc", fmt.Sprint(cmd.Process.Pid), "ns", "ipc") 148 } 149 150 return nil 151 } 152 153 func (d *driver) setPrivileged(container *libcontainer.Config) (err error) { 154 container.Capabilities = capabilities.GetAllCapabilities() 155 container.Cgroups.AllowAllDevices = true 156 157 hostDeviceNodes, err := devices.GetHostDeviceNodes() 158 if err != nil { 159 return err 160 } 161 container.MountConfig.DeviceNodes = hostDeviceNodes 162 163 container.RestrictSys = false 164 165 if apparmor.IsEnabled() { 166 container.AppArmorProfile = "unconfined" 167 } 168 169 return nil 170 } 171 172 func (d *driver) setCapabilities(container *libcontainer.Config, c *execdriver.Command) (err error) { 173 container.Capabilities, err = execdriver.TweakCapabilities(container.Capabilities, c.CapAdd, c.CapDrop) 174 return err 175 } 176 177 func (d *driver) setupCgroups(container *libcontainer.Config, c *execdriver.Command) error { 178 if c.Resources != nil { 179 container.Cgroups.CpuShares = c.Resources.CpuShares 180 container.Cgroups.Memory = c.Resources.Memory 181 container.Cgroups.MemoryReservation = c.Resources.Memory 182 container.Cgroups.MemorySwap = c.Resources.MemorySwap 183 container.Cgroups.CpusetCpus = c.Resources.Cpuset 184 } 185 186 return nil 187 } 188 189 func (d *driver) setupMounts(container *libcontainer.Config, c *execdriver.Command) error { 190 for _, m := range c.Mounts { 191 container.MountConfig.Mounts = append(container.MountConfig.Mounts, &mount.Mount{ 192 Type: "bind", 193 Source: m.Source, 194 Destination: m.Destination, 195 Writable: m.Writable, 196 Private: m.Private, 197 Slave: m.Slave, 198 }) 199 } 200 201 return nil 202 } 203 204 func (d *driver) setupLabels(container *libcontainer.Config, c *execdriver.Command) error { 205 container.ProcessLabel = c.ProcessLabel 206 container.MountConfig.MountLabel = c.MountLabel 207 208 return nil 209 }