github.com/titanous/docker@v1.4.1/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 {{if .Network.Interface.IPAddress}} 20 lxc.network.ipv4 = {{.Network.Interface.IPAddress}}/{{.Network.Interface.IPPrefixLen}} 21 {{end}} 22 {{if .Network.Interface.Gateway}} 23 lxc.network.ipv4.gateway = {{.Network.Interface.Gateway}} 24 {{end}} 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.GetCgroupAllowString}} 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 66 # WARNING: mounting procfs and/or sysfs read-write is a known attack vector. 67 # See e.g. http://blog.zx2c4.com/749 and http://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 73 {{if .ProcessConfig.Tty}} 74 lxc.mount.entry = {{.ProcessConfig.Console}} {{escapeFstabSpaces $ROOTFS}}/dev/console none bind,rw 0 0 75 {{end}} 76 77 lxc.mount.entry = devpts {{escapeFstabSpaces $ROOTFS}}/dev/pts devpts {{formatMountLabel "newinstance,ptmxmode=0666,nosuid,noexec" ""}} 0 0 78 lxc.mount.entry = shm {{escapeFstabSpaces $ROOTFS}}/dev/shm tmpfs {{formatMountLabel "size=65536k,nosuid,nodev,noexec" ""}} 0 0 79 80 {{range $value := .Mounts}} 81 {{$createVal := isDirectory $value.Source}} 82 {{if $value.Writable}} 83 lxc.mount.entry = {{$value.Source}} {{escapeFstabSpaces $ROOTFS}}/{{escapeFstabSpaces $value.Destination}} none rbind,rw,create={{$createVal}} 0 0 84 {{else}} 85 lxc.mount.entry = {{$value.Source}} {{escapeFstabSpaces $ROOTFS}}/{{escapeFstabSpaces $value.Destination}} none rbind,ro,create={{$createVal}} 0 0 86 {{end}} 87 {{end}} 88 89 {{if .ProcessConfig.Env}} 90 lxc.utsname = {{getHostname .ProcessConfig.Env}} 91 {{end}} 92 93 {{if .ProcessConfig.Privileged}} 94 # No cap values are needed, as lxc is starting in privileged mode 95 {{else}} 96 {{range $value := keepCapabilities .CapAdd .CapDrop}} 97 lxc.cap.keep = {{$value}} 98 {{end}} 99 {{end}} 100 101 {{if .ProcessConfig.Privileged}} 102 {{if .AppArmor}} 103 lxc.aa_profile = unconfined 104 {{else}} 105 # Let AppArmor normal confinement take place (i.e., not unconfined) 106 {{end}} 107 {{end}} 108 109 # limits 110 {{if .Resources}} 111 {{if .Resources.Memory}} 112 lxc.cgroup.memory.limit_in_bytes = {{.Resources.Memory}} 113 lxc.cgroup.memory.soft_limit_in_bytes = {{.Resources.Memory}} 114 {{with $memSwap := getMemorySwap .Resources}} 115 lxc.cgroup.memory.memsw.limit_in_bytes = {{$memSwap}} 116 {{end}} 117 {{end}} 118 {{if .Resources.CpuShares}} 119 lxc.cgroup.cpu.shares = {{.Resources.CpuShares}} 120 {{end}} 121 {{if .Resources.Cpuset}} 122 lxc.cgroup.cpuset.cpus = {{.Resources.Cpuset}} 123 {{end}} 124 {{end}} 125 126 {{if .LxcConfig}} 127 {{range $value := .LxcConfig}} 128 lxc.{{$value}} 129 {{end}} 130 {{end}} 131 ` 132 133 var LxcTemplateCompiled *template.Template 134 135 // Escape spaces in strings according to the fstab documentation, which is the 136 // format for "lxc.mount.entry" lines in lxc.conf. See also "man 5 fstab". 137 func escapeFstabSpaces(field string) string { 138 return strings.Replace(field, " ", "\\040", -1) 139 } 140 141 func keepCapabilities(adds []string, drops []string) []string { 142 container := nativeTemplate.New() 143 caps, err := execdriver.TweakCapabilities(container.Capabilities, adds, drops) 144 var newCaps []string 145 for _, cap := range caps { 146 newCaps = append(newCaps, strings.ToLower(cap)) 147 } 148 if err != nil { 149 return []string{} 150 } 151 return newCaps 152 } 153 154 func isDirectory(source string) string { 155 f, err := os.Stat(source) 156 if err != nil { 157 if os.IsNotExist(err) { 158 return "dir" 159 } 160 return "" 161 } 162 if f.IsDir() { 163 return "dir" 164 } 165 return "file" 166 } 167 168 func getMemorySwap(v *execdriver.Resources) int64 { 169 // By default, MemorySwap is set to twice the size of RAM. 170 // If you want to omit MemorySwap, set it to `-1'. 171 if v.MemorySwap < 0 { 172 return 0 173 } 174 return v.Memory * 2 175 } 176 177 func getLabel(c map[string][]string, name string) string { 178 label := c["label"] 179 for _, l := range label { 180 parts := strings.SplitN(l, "=", 2) 181 if strings.TrimSpace(parts[0]) == name { 182 return strings.TrimSpace(parts[1]) 183 } 184 } 185 return "" 186 } 187 188 func getHostname(env []string) string { 189 for _, kv := range env { 190 parts := strings.SplitN(kv, "=", 2) 191 if parts[0] == "HOSTNAME" && len(parts) == 2 { 192 return parts[1] 193 } 194 } 195 return "" 196 } 197 198 func init() { 199 var err error 200 funcMap := template.FuncMap{ 201 "getMemorySwap": getMemorySwap, 202 "escapeFstabSpaces": escapeFstabSpaces, 203 "formatMountLabel": label.FormatMountLabel, 204 "isDirectory": isDirectory, 205 "keepCapabilities": keepCapabilities, 206 "getHostname": getHostname, 207 } 208 LxcTemplateCompiled, err = template.New("lxc").Funcs(funcMap).Parse(LxcTemplate) 209 if err != nil { 210 panic(err) 211 } 212 }