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