2014-01-15 17:26:04 -08:00
|
|
|
package lxc
|
2013-01-18 16:13:39 -08:00
|
|
|
|
|
|
|
import (
|
2013-11-24 20:00:39 -07:00
|
|
|
"strings"
|
2013-01-18 16:13:39 -08:00
|
|
|
"text/template"
|
2014-05-01 10:08:18 -07:00
|
|
|
|
|
|
|
"github.com/dotcloud/docker/daemon/execdriver"
|
|
|
|
"github.com/dotcloud/docker/pkg/label"
|
2013-01-18 16:13:39 -08:00
|
|
|
)
|
|
|
|
|
|
|
|
const LxcTemplate = `
|
2014-03-16 20:52:27 +01:00
|
|
|
{{if .Network.Interface}}
|
2013-01-18 16:13:39 -08:00
|
|
|
# network configuration
|
2013-02-20 17:47:09 -08:00
|
|
|
lxc.network.type = veth
|
2014-03-16 20:52:27 +01:00
|
|
|
lxc.network.link = {{.Network.Interface.Bridge}}
|
2013-02-20 17:47:09 -08:00
|
|
|
lxc.network.name = eth0
|
2014-05-02 14:17:31 -07:00
|
|
|
lxc.network.mtu = {{.Network.Mtu}}
|
2014-05-20 19:10:23 +00:00
|
|
|
{{else if .Network.HostNetworking}}
|
|
|
|
lxc.network.type = none
|
|
|
|
{{else}}
|
2014-01-15 17:26:04 -08:00
|
|
|
# network is disabled (-n=false)
|
|
|
|
lxc.network.type = empty
|
2014-01-31 12:44:20 -05:00
|
|
|
lxc.network.flags = up
|
2014-03-16 20:52:27 +01:00
|
|
|
lxc.network.mtu = {{.Network.Mtu}}
|
2014-05-02 14:17:31 -07:00
|
|
|
{{end}}
|
2013-01-18 16:13:39 -08:00
|
|
|
|
|
|
|
# root filesystem
|
2014-01-15 17:26:04 -08:00
|
|
|
{{$ROOTFS := .Rootfs}}
|
2013-02-13 13:56:19 -08:00
|
|
|
lxc.rootfs = {{$ROOTFS}}
|
2013-01-18 16:13:39 -08:00
|
|
|
|
|
|
|
# use a dedicated pts for the container (and limit the number of pseudo terminal
|
|
|
|
# available)
|
|
|
|
lxc.pts = 1024
|
|
|
|
|
|
|
|
# disable the main console
|
|
|
|
lxc.console = none
|
2014-03-27 08:57:01 +00:00
|
|
|
{{if .ProcessLabel}}
|
|
|
|
lxc.se_context = {{ .ProcessLabel}}
|
2014-03-18 16:49:16 -04:00
|
|
|
{{end}}
|
2014-04-02 16:52:49 +00:00
|
|
|
{{$MOUNTLABEL := .MountLabel}}
|
2013-01-18 16:13:39 -08:00
|
|
|
|
|
|
|
# no controlling tty at all
|
|
|
|
lxc.tty = 1
|
|
|
|
|
2014-01-15 17:26:04 -08:00
|
|
|
{{if .Privileged}}
|
2014-01-15 14:36:13 -08:00
|
|
|
lxc.cgroup.devices.allow = a
|
2013-08-09 15:53:02 -07:00
|
|
|
{{else}}
|
2013-01-18 16:13:39 -08:00
|
|
|
# no implicit access to devices
|
|
|
|
lxc.cgroup.devices.deny = a
|
|
|
|
|
2013-12-01 15:27:24 -08:00
|
|
|
# but allow mknod for any device
|
|
|
|
lxc.cgroup.devices.allow = c *:* m
|
|
|
|
lxc.cgroup.devices.allow = b *:* m
|
|
|
|
|
2013-01-18 16:13:39 -08:00
|
|
|
# /dev/null and zero
|
|
|
|
lxc.cgroup.devices.allow = c 1:3 rwm
|
|
|
|
lxc.cgroup.devices.allow = c 1:5 rwm
|
|
|
|
|
|
|
|
# consoles
|
|
|
|
lxc.cgroup.devices.allow = c 5:1 rwm
|
|
|
|
lxc.cgroup.devices.allow = c 5:0 rwm
|
|
|
|
lxc.cgroup.devices.allow = c 4:0 rwm
|
|
|
|
lxc.cgroup.devices.allow = c 4:1 rwm
|
|
|
|
|
|
|
|
# /dev/urandom,/dev/random
|
|
|
|
lxc.cgroup.devices.allow = c 1:9 rwm
|
|
|
|
lxc.cgroup.devices.allow = c 1:8 rwm
|
|
|
|
|
2013-10-31 14:58:43 -07:00
|
|
|
# /dev/pts/ - pts namespaces are "coming soon"
|
2013-01-18 16:13:39 -08:00
|
|
|
lxc.cgroup.devices.allow = c 136:* rwm
|
|
|
|
lxc.cgroup.devices.allow = c 5:2 rwm
|
|
|
|
|
|
|
|
# tuntap
|
|
|
|
lxc.cgroup.devices.allow = c 10:200 rwm
|
|
|
|
|
|
|
|
# fuse
|
|
|
|
#lxc.cgroup.devices.allow = c 10:229 rwm
|
|
|
|
|
|
|
|
# rtc
|
|
|
|
#lxc.cgroup.devices.allow = c 254:0 rwm
|
2013-08-09 15:53:02 -07:00
|
|
|
{{end}}
|
2013-01-18 16:13:39 -08:00
|
|
|
|
|
|
|
# standard mount point
|
2013-10-09 16:40:46 -04:00
|
|
|
# Use mnt.putold as per https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/986385
|
|
|
|
lxc.pivotdir = lxc_putold
|
2013-12-17 14:04:37 -08:00
|
|
|
|
|
|
|
# NOTICE: These mounts must be applied within the namespace
|
|
|
|
|
2014-04-30 18:00:42 -07:00
|
|
|
# WARNING: mounting procfs and/or sysfs read-write is a known attack vector.
|
|
|
|
# See e.g. http://blog.zx2c4.com/749 and http://bit.ly/T9CkqJ
|
|
|
|
# We mount them read-write here, but later, dockerinit will call the Restrict() function to remount them read-only.
|
|
|
|
# We cannot mount them directly read-only, because that would prevent loading AppArmor profiles.
|
2013-11-24 20:00:39 -07:00
|
|
|
lxc.mount.entry = proc {{escapeFstabSpaces $ROOTFS}}/proc proc nosuid,nodev,noexec 0 0
|
|
|
|
lxc.mount.entry = sysfs {{escapeFstabSpaces $ROOTFS}}/sys sysfs nosuid,nodev,noexec 0 0
|
2014-05-07 15:08:52 +02:00
|
|
|
lxc.mount.entry = tmpfs {{escapeFstabSpaces $ROOTFS}}/run tmpfs nosuid,nodev,noexec 0 0
|
2013-12-17 14:04:37 -08:00
|
|
|
|
2014-02-13 17:23:09 -08:00
|
|
|
{{if .Tty}}
|
|
|
|
lxc.mount.entry = {{.Console}} {{escapeFstabSpaces $ROOTFS}}/dev/console none bind,rw 0 0
|
|
|
|
{{end}}
|
|
|
|
|
2014-04-02 13:56:30 -04:00
|
|
|
lxc.mount.entry = devpts {{escapeFstabSpaces $ROOTFS}}/dev/pts devpts {{formatMountLabel "newinstance,ptmxmode=0666,nosuid,noexec" $MOUNTLABEL}} 0 0
|
|
|
|
lxc.mount.entry = shm {{escapeFstabSpaces $ROOTFS}}/dev/shm tmpfs {{formatMountLabel "size=65536k,nosuid,nodev,noexec" $MOUNTLABEL}} 0 0
|
2013-01-18 16:13:39 -08:00
|
|
|
|
2014-03-03 16:15:29 +01:00
|
|
|
{{range $value := .Mounts}}
|
|
|
|
{{if $value.Writable}}
|
|
|
|
lxc.mount.entry = {{$value.Source}} {{escapeFstabSpaces $ROOTFS}}/{{escapeFstabSpaces $value.Destination}} none bind,rw 0 0
|
|
|
|
{{else}}
|
|
|
|
lxc.mount.entry = {{$value.Source}} {{escapeFstabSpaces $ROOTFS}}/{{escapeFstabSpaces $value.Destination}} none bind,ro 0 0
|
|
|
|
{{end}}
|
|
|
|
{{end}}
|
|
|
|
|
2014-01-15 17:26:04 -08:00
|
|
|
{{if .Privileged}}
|
|
|
|
{{if .AppArmor}}
|
2013-10-31 14:58:43 -07:00
|
|
|
lxc.aa_profile = unconfined
|
|
|
|
{{else}}
|
2014-04-30 18:00:42 -07:00
|
|
|
# Let AppArmor normal confinement take place (i.e., not unconfined)
|
2013-10-31 14:58:43 -07:00
|
|
|
{{end}}
|
2013-08-09 15:53:02 -07:00
|
|
|
{{end}}
|
2013-01-18 16:13:39 -08:00
|
|
|
|
|
|
|
# limits
|
2014-01-20 16:23:02 -05:00
|
|
|
{{if .Resources}}
|
|
|
|
{{if .Resources.Memory}}
|
|
|
|
lxc.cgroup.memory.limit_in_bytes = {{.Resources.Memory}}
|
|
|
|
lxc.cgroup.memory.soft_limit_in_bytes = {{.Resources.Memory}}
|
|
|
|
{{with $memSwap := getMemorySwap .Resources}}
|
2013-03-11 19:55:14 -07:00
|
|
|
lxc.cgroup.memory.memsw.limit_in_bytes = {{$memSwap}}
|
2013-03-11 17:40:54 -07:00
|
|
|
{{end}}
|
2013-01-18 16:13:39 -08:00
|
|
|
{{end}}
|
2014-01-20 16:23:02 -05:00
|
|
|
{{if .Resources.CpuShares}}
|
|
|
|
lxc.cgroup.cpu.shares = {{.Resources.CpuShares}}
|
2014-01-15 17:26:04 -08:00
|
|
|
{{end}}
|
2014-05-12 17:44:57 -07:00
|
|
|
{{if .Resources.Cpuset}}
|
|
|
|
lxc.cgroup.cpuset.cpus = {{.Resources.Cpuset}}
|
|
|
|
{{end}}
|
2013-05-07 11:16:30 -07:00
|
|
|
{{end}}
|
2013-01-18 16:13:39 -08:00
|
|
|
|
2014-03-20 22:58:02 +00:00
|
|
|
{{if .Config.lxc}}
|
|
|
|
{{range $value := .Config.lxc}}
|
2014-03-24 07:16:40 +00:00
|
|
|
lxc.{{$value}}
|
2013-08-15 23:35:03 +00:00
|
|
|
{{end}}
|
|
|
|
{{end}}
|
|
|
|
`
|
|
|
|
|
2013-01-18 16:13:39 -08:00
|
|
|
var LxcTemplateCompiled *template.Template
|
|
|
|
|
2013-11-24 20:00:39 -07:00
|
|
|
// Escape spaces in strings according to the fstab documentation, which is the
|
|
|
|
// format for "lxc.mount.entry" lines in lxc.conf. See also "man 5 fstab".
|
|
|
|
func escapeFstabSpaces(field string) string {
|
|
|
|
return strings.Replace(field, " ", "\\040", -1)
|
|
|
|
}
|
|
|
|
|
2014-01-20 16:23:02 -05:00
|
|
|
func getMemorySwap(v *execdriver.Resources) int64 {
|
2013-03-11 19:25:02 -07:00
|
|
|
// By default, MemorySwap is set to twice the size of RAM.
|
|
|
|
// If you want to omit MemorySwap, set it to `-1'.
|
2014-01-15 17:26:04 -08:00
|
|
|
if v.MemorySwap < 0 {
|
2013-03-11 17:40:54 -07:00
|
|
|
return 0
|
|
|
|
}
|
2014-01-15 17:26:04 -08:00
|
|
|
return v.Memory * 2
|
2013-10-31 14:58:43 -07:00
|
|
|
}
|
|
|
|
|
2014-03-27 08:25:01 +00:00
|
|
|
func getLabel(c map[string][]string, name string) string {
|
|
|
|
label := c["label"]
|
|
|
|
for _, l := range label {
|
|
|
|
parts := strings.SplitN(l, "=", 2)
|
2014-03-27 08:57:01 +00:00
|
|
|
if strings.TrimSpace(parts[0]) == name {
|
|
|
|
return strings.TrimSpace(parts[1])
|
2014-03-27 08:25:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return ""
|
2014-03-18 16:49:16 -04:00
|
|
|
}
|
|
|
|
|
2013-01-18 16:13:39 -08:00
|
|
|
func init() {
|
|
|
|
var err error
|
2013-03-11 17:40:54 -07:00
|
|
|
funcMap := template.FuncMap{
|
2013-11-24 20:02:06 -07:00
|
|
|
"getMemorySwap": getMemorySwap,
|
2013-11-24 20:00:39 -07:00
|
|
|
"escapeFstabSpaces": escapeFstabSpaces,
|
2014-03-18 16:49:16 -04:00
|
|
|
"formatMountLabel": label.FormatMountLabel,
|
2013-03-11 17:40:54 -07:00
|
|
|
}
|
|
|
|
LxcTemplateCompiled, err = template.New("lxc").Funcs(funcMap).Parse(LxcTemplate)
|
2013-01-18 16:13:39 -08:00
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
}
|