github.com/sbward/docker@v1.4.2-0.20150114010528-c9dab702bed3/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.createPid(container, c); err != nil { 44 return nil, err 45 } 46 47 if err := d.createNetwork(container, c); err != nil { 48 return nil, err 49 } 50 51 if c.ProcessConfig.Privileged { 52 if err := d.setPrivileged(container); err != nil { 53 return nil, err 54 } 55 } else { 56 if err := d.setCapabilities(container, c); err != nil { 57 return nil, err 58 } 59 } 60 61 if c.AppArmorProfile != "" { 62 container.AppArmorProfile = c.AppArmorProfile 63 } 64 65 if err := d.setupCgroups(container, c); err != nil { 66 return nil, err 67 } 68 69 if err := d.setupMounts(container, c); err != nil { 70 return nil, err 71 } 72 73 if err := d.setupLabels(container, c); err != nil { 74 return nil, err 75 } 76 77 cmds := make(map[string]*exec.Cmd) 78 d.Lock() 79 for k, v := range d.activeContainers { 80 cmds[k] = v.cmd 81 } 82 d.Unlock() 83 84 return container, nil 85 } 86 87 func (d *driver) createNetwork(container *libcontainer.Config, c *execdriver.Command) error { 88 if c.Network.HostNetworking { 89 container.Namespaces.Remove(libcontainer.NEWNET) 90 return nil 91 } 92 93 container.Networks = []*libcontainer.Network{ 94 { 95 Mtu: c.Network.Mtu, 96 Address: fmt.Sprintf("%s/%d", "127.0.0.1", 0), 97 Gateway: "localhost", 98 Type: "loopback", 99 }, 100 } 101 102 if c.Network.Interface != nil { 103 vethNetwork := libcontainer.Network{ 104 Mtu: c.Network.Mtu, 105 Address: fmt.Sprintf("%s/%d", c.Network.Interface.IPAddress, c.Network.Interface.IPPrefixLen), 106 MacAddress: c.Network.Interface.MacAddress, 107 Gateway: c.Network.Interface.Gateway, 108 Type: "veth", 109 Bridge: c.Network.Interface.Bridge, 110 VethPrefix: "veth", 111 } 112 if c.Network.Interface.GlobalIPv6Address != "" { 113 vethNetwork.IPv6Address = fmt.Sprintf("%s/%d", c.Network.Interface.GlobalIPv6Address, c.Network.Interface.GlobalIPv6PrefixLen) 114 vethNetwork.IPv6Gateway = c.Network.Interface.IPv6Gateway 115 } 116 container.Networks = append(container.Networks, &vethNetwork) 117 } 118 119 if c.Network.ContainerID != "" { 120 d.Lock() 121 active := d.activeContainers[c.Network.ContainerID] 122 d.Unlock() 123 124 if active == nil || active.cmd.Process == nil { 125 return fmt.Errorf("%s is not a valid running container to join", c.Network.ContainerID) 126 } 127 cmd := active.cmd 128 129 nspath := filepath.Join("/proc", fmt.Sprint(cmd.Process.Pid), "ns", "net") 130 container.Namespaces.Add(libcontainer.NEWNET, nspath) 131 } 132 133 return nil 134 } 135 136 func (d *driver) createIpc(container *libcontainer.Config, c *execdriver.Command) error { 137 if c.Ipc.HostIpc { 138 container.Namespaces.Remove(libcontainer.NEWIPC) 139 return nil 140 } 141 142 if c.Ipc.ContainerID != "" { 143 d.Lock() 144 active := d.activeContainers[c.Ipc.ContainerID] 145 d.Unlock() 146 147 if active == nil || active.cmd.Process == nil { 148 return fmt.Errorf("%s is not a valid running container to join", c.Ipc.ContainerID) 149 } 150 cmd := active.cmd 151 152 container.Namespaces.Add(libcontainer.NEWIPC, filepath.Join("/proc", fmt.Sprint(cmd.Process.Pid), "ns", "ipc")) 153 } 154 155 return nil 156 } 157 158 func (d *driver) createPid(container *libcontainer.Config, c *execdriver.Command) error { 159 if c.Pid.HostPid { 160 container.Namespaces.Remove(libcontainer.NEWPID) 161 return nil 162 } 163 164 return nil 165 } 166 167 func (d *driver) setPrivileged(container *libcontainer.Config) (err error) { 168 container.Capabilities = capabilities.GetAllCapabilities() 169 container.Cgroups.AllowAllDevices = true 170 171 hostDeviceNodes, err := devices.GetHostDeviceNodes() 172 if err != nil { 173 return err 174 } 175 container.MountConfig.DeviceNodes = hostDeviceNodes 176 177 container.RestrictSys = false 178 179 if apparmor.IsEnabled() { 180 container.AppArmorProfile = "unconfined" 181 } 182 183 return nil 184 } 185 186 func (d *driver) setCapabilities(container *libcontainer.Config, c *execdriver.Command) (err error) { 187 container.Capabilities, err = execdriver.TweakCapabilities(container.Capabilities, c.CapAdd, c.CapDrop) 188 return err 189 } 190 191 func (d *driver) setupCgroups(container *libcontainer.Config, c *execdriver.Command) error { 192 if c.Resources != nil { 193 container.Cgroups.CpuShares = c.Resources.CpuShares 194 container.Cgroups.Memory = c.Resources.Memory 195 container.Cgroups.MemoryReservation = c.Resources.Memory 196 container.Cgroups.MemorySwap = c.Resources.MemorySwap 197 container.Cgroups.CpusetCpus = c.Resources.Cpuset 198 } 199 200 return nil 201 } 202 203 func (d *driver) setupMounts(container *libcontainer.Config, c *execdriver.Command) error { 204 for _, m := range c.Mounts { 205 container.MountConfig.Mounts = append(container.MountConfig.Mounts, &mount.Mount{ 206 Type: "bind", 207 Source: m.Source, 208 Destination: m.Destination, 209 Writable: m.Writable, 210 Private: m.Private, 211 Slave: m.Slave, 212 }) 213 } 214 215 return nil 216 } 217 218 func (d *driver) setupLabels(container *libcontainer.Config, c *execdriver.Command) error { 219 container.ProcessLabel = c.ProcessLabel 220 container.MountConfig.MountLabel = c.MountLabel 221 222 return nil 223 }