github.com/codemac/docker@v1.2.1-0.20150518222241-6a18412d5b9c/daemon/execdriver/lxc/lxc_template.go (about) 1 // +build linux 2 3 package lxc 4 5 import ( 6 "fmt" 7 "os" 8 "strings" 9 "text/template" 10 11 "github.com/Sirupsen/logrus" 12 "github.com/docker/docker/daemon/execdriver" 13 nativeTemplate "github.com/docker/docker/daemon/execdriver/native/template" 14 "github.com/docker/docker/pkg/stringutils" 15 "github.com/docker/libcontainer/label" 16 ) 17 18 const LxcTemplate = ` 19 {{if .Network.Interface}} 20 # network configuration 21 lxc.network.type = veth 22 lxc.network.link = {{.Network.Interface.Bridge}} 23 lxc.network.name = eth0 24 lxc.network.mtu = {{.Network.Mtu}} 25 lxc.network.flags = up 26 {{else if .Network.HostNetworking}} 27 lxc.network.type = none 28 {{else}} 29 # network is disabled (-n=false) 30 lxc.network.type = empty 31 lxc.network.flags = up 32 lxc.network.mtu = {{.Network.Mtu}} 33 {{end}} 34 35 # root filesystem 36 {{$ROOTFS := .Rootfs}} 37 lxc.rootfs = {{$ROOTFS}} 38 39 # use a dedicated pts for the container (and limit the number of pseudo terminal 40 # available) 41 lxc.pts = 1024 42 43 # disable the main console 44 lxc.console = none 45 46 # no controlling tty at all 47 lxc.tty = 1 48 49 {{if .ProcessConfig.Privileged}} 50 lxc.cgroup.devices.allow = a 51 {{else}} 52 # no implicit access to devices 53 lxc.cgroup.devices.deny = a 54 #Allow the devices passed to us in the AllowedDevices list. 55 {{range $allowedDevice := .AllowedDevices}} 56 lxc.cgroup.devices.allow = {{$allowedDevice.CgroupString}} 57 {{end}} 58 {{end}} 59 60 # standard mount point 61 # Use mnt.putold as per https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/986385 62 lxc.pivotdir = lxc_putold 63 64 # NOTICE: These mounts must be applied within the namespace 65 {{if .ProcessConfig.Privileged}} 66 # WARNING: mounting procfs and/or sysfs read-write is a known attack vector. 67 # See e.g. http://blog.zx2c4.com/749 and https://bit.ly/T9CkqJ 68 # We mount them read-write here, but later, dockerinit will call the Restrict() function to remount them read-only. 69 # We cannot mount them directly read-only, because that would prevent loading AppArmor profiles. 70 lxc.mount.entry = proc {{escapeFstabSpaces $ROOTFS}}/proc proc nosuid,nodev,noexec 0 0 71 lxc.mount.entry = sysfs {{escapeFstabSpaces $ROOTFS}}/sys sysfs nosuid,nodev,noexec 0 0 72 {{if .AppArmor}} 73 lxc.aa_profile = unconfined 74 {{end}} 75 {{else}} 76 # In non-privileged mode, lxc will automatically mount /proc and /sys in readonly mode 77 # for security. See: http://man7.org/linux/man-pages/man5/lxc.container.conf.5.html 78 lxc.mount.auto = proc sys 79 {{if .AppArmorProfile}} 80 lxc.aa_profile = {{.AppArmorProfile}} 81 {{end}} 82 {{end}} 83 84 {{if .ProcessConfig.Tty}} 85 lxc.mount.entry = {{.ProcessConfig.Console}} {{escapeFstabSpaces $ROOTFS}}/dev/console none bind,rw 0 0 86 {{end}} 87 88 lxc.mount.entry = devpts {{escapeFstabSpaces $ROOTFS}}/dev/pts devpts {{formatMountLabel "newinstance,ptmxmode=0666,nosuid,noexec" ""}} 0 0 89 lxc.mount.entry = shm {{escapeFstabSpaces $ROOTFS}}/dev/shm tmpfs {{formatMountLabel "size=65536k,nosuid,nodev,noexec" ""}} 0 0 90 91 {{range $value := .Mounts}} 92 {{$createVal := isDirectory $value.Source}} 93 {{if $value.Writable}} 94 lxc.mount.entry = {{$value.Source}} {{escapeFstabSpaces $ROOTFS}}/{{escapeFstabSpaces $value.Destination}} none rbind,rw,create={{$createVal}} 0 0 95 {{else}} 96 lxc.mount.entry = {{$value.Source}} {{escapeFstabSpaces $ROOTFS}}/{{escapeFstabSpaces $value.Destination}} none rbind,ro,create={{$createVal}} 0 0 97 {{end}} 98 {{end}} 99 100 # limits 101 {{if .Resources}} 102 {{if .Resources.Memory}} 103 lxc.cgroup.memory.limit_in_bytes = {{.Resources.Memory}} 104 lxc.cgroup.memory.soft_limit_in_bytes = {{.Resources.Memory}} 105 {{with $memSwap := getMemorySwap .Resources}} 106 lxc.cgroup.memory.memsw.limit_in_bytes = {{$memSwap}} 107 {{end}} 108 {{end}} 109 {{if .Resources.CpuShares}} 110 lxc.cgroup.cpu.shares = {{.Resources.CpuShares}} 111 {{end}} 112 {{if .Resources.CpuPeriod}} 113 lxc.cgroup.cpu.cfs_period_us = {{.Resources.CpuPeriod}} 114 {{end}} 115 {{if .Resources.CpusetCpus}} 116 lxc.cgroup.cpuset.cpus = {{.Resources.CpusetCpus}} 117 {{end}} 118 {{if .Resources.CpusetMems}} 119 lxc.cgroup.cpuset.mems = {{.Resources.CpusetMems}} 120 {{end}} 121 {{if .Resources.CpuQuota}} 122 lxc.cgroup.cpu.cfs_quota_us = {{.Resources.CpuQuota}} 123 {{end}} 124 {{if .Resources.BlkioWeight}} 125 lxc.cgroup.blkio.weight = {{.Resources.BlkioWeight}} 126 {{end}} 127 {{if .Resources.OomKillDisable}} 128 lxc.cgroup.memory.oom_control = {{.Resources.OomKillDisable}} 129 {{end}} 130 {{end}} 131 132 {{if .LxcConfig}} 133 {{range $value := .LxcConfig}} 134 lxc.{{$value}} 135 {{end}} 136 {{end}} 137 138 {{if .Network.Interface}} 139 {{if .Network.Interface.IPAddress}} 140 lxc.network.ipv4 = {{.Network.Interface.IPAddress}}/{{.Network.Interface.IPPrefixLen}} 141 {{end}} 142 {{if .Network.Interface.Gateway}} 143 lxc.network.ipv4.gateway = {{.Network.Interface.Gateway}} 144 {{end}} 145 {{if .Network.Interface.MacAddress}} 146 lxc.network.hwaddr = {{.Network.Interface.MacAddress}} 147 {{end}} 148 {{if .ProcessConfig.Env}} 149 lxc.utsname = {{getHostname .ProcessConfig.Env}} 150 {{end}} 151 152 {{if .ProcessConfig.Privileged}} 153 # No cap values are needed, as lxc is starting in privileged mode 154 {{else}} 155 {{ with keepCapabilities .CapAdd .CapDrop }} 156 {{range .}} 157 lxc.cap.keep = {{.}} 158 {{end}} 159 {{else}} 160 {{ with dropList .CapDrop }} 161 {{range .}} 162 lxc.cap.drop = {{.}} 163 {{end}} 164 {{end}} 165 {{end}} 166 {{end}} 167 {{end}} 168 ` 169 170 var LxcTemplateCompiled *template.Template 171 172 // Escape spaces in strings according to the fstab documentation, which is the 173 // format for "lxc.mount.entry" lines in lxc.conf. See also "man 5 fstab". 174 func escapeFstabSpaces(field string) string { 175 return strings.Replace(field, " ", "\\040", -1) 176 } 177 178 func keepCapabilities(adds []string, drops []string) ([]string, error) { 179 container := nativeTemplate.New() 180 logrus.Debugf("adds %s drops %s\n", adds, drops) 181 caps, err := execdriver.TweakCapabilities(container.Capabilities, adds, drops) 182 if err != nil { 183 return nil, err 184 } 185 var newCaps []string 186 for _, cap := range caps { 187 logrus.Debugf("cap %s\n", cap) 188 realCap := execdriver.GetCapability(cap) 189 numCap := fmt.Sprintf("%d", realCap.Value) 190 newCaps = append(newCaps, numCap) 191 } 192 193 return newCaps, nil 194 } 195 196 func dropList(drops []string) ([]string, error) { 197 if stringutils.InSlice(drops, "all") { 198 var newCaps []string 199 for _, capName := range execdriver.GetAllCapabilities() { 200 cap := execdriver.GetCapability(capName) 201 logrus.Debugf("drop cap %s\n", cap.Key) 202 numCap := fmt.Sprintf("%d", cap.Value) 203 newCaps = append(newCaps, numCap) 204 } 205 return newCaps, nil 206 } 207 return []string{}, nil 208 } 209 210 func isDirectory(source string) string { 211 f, err := os.Stat(source) 212 logrus.Debugf("dir: %s\n", source) 213 if err != nil { 214 if os.IsNotExist(err) { 215 return "dir" 216 } 217 return "" 218 } 219 if f.IsDir() { 220 return "dir" 221 } 222 return "file" 223 } 224 225 func getMemorySwap(v *execdriver.Resources) int64 { 226 // By default, MemorySwap is set to twice the size of RAM. 227 // If you want to omit MemorySwap, set it to `-1'. 228 if v.MemorySwap < 0 { 229 return 0 230 } 231 return v.Memory * 2 232 } 233 234 func getLabel(c map[string][]string, name string) string { 235 label := c["label"] 236 for _, l := range label { 237 parts := strings.SplitN(l, "=", 2) 238 if strings.TrimSpace(parts[0]) == name { 239 return strings.TrimSpace(parts[1]) 240 } 241 } 242 return "" 243 } 244 245 func getHostname(env []string) string { 246 for _, kv := range env { 247 parts := strings.SplitN(kv, "=", 2) 248 if parts[0] == "HOSTNAME" && len(parts) == 2 { 249 return parts[1] 250 } 251 } 252 return "" 253 } 254 255 func init() { 256 var err error 257 funcMap := template.FuncMap{ 258 "getMemorySwap": getMemorySwap, 259 "escapeFstabSpaces": escapeFstabSpaces, 260 "formatMountLabel": label.FormatMountLabel, 261 "isDirectory": isDirectory, 262 "keepCapabilities": keepCapabilities, 263 "dropList": dropList, 264 "getHostname": getHostname, 265 } 266 LxcTemplateCompiled, err = template.New("lxc").Funcs(funcMap).Parse(LxcTemplate) 267 if err != nil { 268 panic(err) 269 } 270 }