github.com/fcwu/docker@v1.4.2-0.20150115145920-2a69ca89f0df/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.Remove(libcontainer.NEWNET) 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.Namespaces.Add(libcontainer.NEWNET, nspath) 123 } 124 125 return nil 126 } 127 128 func (d *driver) createIpc(container *libcontainer.Config, c *execdriver.Command) error { 129 if c.Ipc.HostIpc { 130 container.Namespaces.Remove(libcontainer.NEWIPC) 131 return nil 132 } 133 134 if c.Ipc.ContainerID != "" { 135 d.Lock() 136 active := d.activeContainers[c.Ipc.ContainerID] 137 d.Unlock() 138 139 if active == nil || active.cmd.Process == nil { 140 return fmt.Errorf("%s is not a valid running container to join", c.Ipc.ContainerID) 141 } 142 cmd := active.cmd 143 144 container.Namespaces.Add(libcontainer.NEWIPC, filepath.Join("/proc", fmt.Sprint(cmd.Process.Pid), "ns", "ipc")) 145 } 146 147 return nil 148 } 149 150 func (d *driver) setPrivileged(container *libcontainer.Config) (err error) { 151 container.Capabilities = capabilities.GetAllCapabilities() 152 container.Cgroups.AllowAllDevices = true 153 154 hostDeviceNodes, err := devices.GetHostDeviceNodes() 155 if err != nil { 156 return err 157 } 158 container.MountConfig.DeviceNodes = hostDeviceNodes 159 160 container.RestrictSys = false 161 162 if apparmor.IsEnabled() { 163 container.AppArmorProfile = "unconfined" 164 } 165 166 return nil 167 } 168 169 func (d *driver) setCapabilities(container *libcontainer.Config, c *execdriver.Command) (err error) { 170 container.Capabilities, err = execdriver.TweakCapabilities(container.Capabilities, c.CapAdd, c.CapDrop) 171 return err 172 } 173 174 func (d *driver) setupCgroups(container *libcontainer.Config, c *execdriver.Command) error { 175 if c.Resources != nil { 176 container.Cgroups.CpuShares = c.Resources.CpuShares 177 container.Cgroups.Memory = c.Resources.Memory 178 container.Cgroups.MemoryReservation = c.Resources.Memory 179 container.Cgroups.MemorySwap = c.Resources.MemorySwap 180 container.Cgroups.CpusetCpus = c.Resources.Cpuset 181 } 182 183 return nil 184 } 185 186 func (d *driver) setupMounts(container *libcontainer.Config, c *execdriver.Command) error { 187 for _, m := range c.Mounts { 188 container.MountConfig.Mounts = append(container.MountConfig.Mounts, &mount.Mount{ 189 Type: "bind", 190 Source: m.Source, 191 Destination: m.Destination, 192 Writable: m.Writable, 193 Private: m.Private, 194 Slave: m.Slave, 195 }) 196 } 197 198 return nil 199 } 200 201 func (d *driver) setupLabels(container *libcontainer.Config, c *execdriver.Command) error { 202 container.ProcessLabel = c.ProcessLabel 203 container.MountConfig.MountLabel = c.MountLabel 204 205 return nil 206 }