lxc_template.go 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. package lxc
  2. import (
  3. "strings"
  4. "text/template"
  5. "github.com/dotcloud/docker/daemon/execdriver"
  6. "github.com/dotcloud/docker/pkg/label"
  7. )
  8. const LxcTemplate = `
  9. {{if .Network.Interface}}
  10. # network configuration
  11. lxc.network.type = veth
  12. lxc.network.link = {{.Network.Interface.Bridge}}
  13. lxc.network.name = eth0
  14. lxc.network.mtu = {{.Network.Mtu}}
  15. {{else if not .Network.HostNetworking}}
  16. # network is disabled (-n=false)
  17. lxc.network.type = empty
  18. lxc.network.flags = up
  19. lxc.network.mtu = {{.Network.Mtu}}
  20. {{end}}
  21. # root filesystem
  22. {{$ROOTFS := .Rootfs}}
  23. lxc.rootfs = {{$ROOTFS}}
  24. # use a dedicated pts for the container (and limit the number of pseudo terminal
  25. # available)
  26. lxc.pts = 1024
  27. # disable the main console
  28. lxc.console = none
  29. {{if .ProcessLabel}}
  30. lxc.se_context = {{ .ProcessLabel}}
  31. {{end}}
  32. {{$MOUNTLABEL := .MountLabel}}
  33. # no controlling tty at all
  34. lxc.tty = 1
  35. {{if .Privileged}}
  36. lxc.cgroup.devices.allow = a
  37. {{else}}
  38. # no implicit access to devices
  39. lxc.cgroup.devices.deny = a
  40. # but allow mknod for any device
  41. lxc.cgroup.devices.allow = c *:* m
  42. lxc.cgroup.devices.allow = b *:* m
  43. # /dev/null and zero
  44. lxc.cgroup.devices.allow = c 1:3 rwm
  45. lxc.cgroup.devices.allow = c 1:5 rwm
  46. # consoles
  47. lxc.cgroup.devices.allow = c 5:1 rwm
  48. lxc.cgroup.devices.allow = c 5:0 rwm
  49. lxc.cgroup.devices.allow = c 4:0 rwm
  50. lxc.cgroup.devices.allow = c 4:1 rwm
  51. # /dev/urandom,/dev/random
  52. lxc.cgroup.devices.allow = c 1:9 rwm
  53. lxc.cgroup.devices.allow = c 1:8 rwm
  54. # /dev/pts/ - pts namespaces are "coming soon"
  55. lxc.cgroup.devices.allow = c 136:* rwm
  56. lxc.cgroup.devices.allow = c 5:2 rwm
  57. # tuntap
  58. lxc.cgroup.devices.allow = c 10:200 rwm
  59. # fuse
  60. #lxc.cgroup.devices.allow = c 10:229 rwm
  61. # rtc
  62. #lxc.cgroup.devices.allow = c 254:0 rwm
  63. {{end}}
  64. # standard mount point
  65. # Use mnt.putold as per https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/986385
  66. lxc.pivotdir = lxc_putold
  67. # NOTICE: These mounts must be applied within the namespace
  68. # WARNING: mounting procfs and/or sysfs read-write is a known attack vector.
  69. # See e.g. http://blog.zx2c4.com/749 and http://bit.ly/T9CkqJ
  70. # We mount them read-write here, but later, dockerinit will call the Restrict() function to remount them read-only.
  71. # We cannot mount them directly read-only, because that would prevent loading AppArmor profiles.
  72. lxc.mount.entry = proc {{escapeFstabSpaces $ROOTFS}}/proc proc nosuid,nodev,noexec 0 0
  73. lxc.mount.entry = sysfs {{escapeFstabSpaces $ROOTFS}}/sys sysfs nosuid,nodev,noexec 0 0
  74. lxc.mount.entry = tmpfs {{escapeFstabSpaces $ROOTFS}}/run tmpfs nosuid,nodev,noexec 0 0
  75. {{if .Tty}}
  76. lxc.mount.entry = {{.Console}} {{escapeFstabSpaces $ROOTFS}}/dev/console none bind,rw 0 0
  77. {{end}}
  78. lxc.mount.entry = devpts {{escapeFstabSpaces $ROOTFS}}/dev/pts devpts {{formatMountLabel "newinstance,ptmxmode=0666,nosuid,noexec" $MOUNTLABEL}} 0 0
  79. lxc.mount.entry = shm {{escapeFstabSpaces $ROOTFS}}/dev/shm tmpfs {{formatMountLabel "size=65536k,nosuid,nodev,noexec" $MOUNTLABEL}} 0 0
  80. {{range $value := .Mounts}}
  81. {{if $value.Writable}}
  82. lxc.mount.entry = {{$value.Source}} {{escapeFstabSpaces $ROOTFS}}/{{escapeFstabSpaces $value.Destination}} none bind,rw 0 0
  83. {{else}}
  84. lxc.mount.entry = {{$value.Source}} {{escapeFstabSpaces $ROOTFS}}/{{escapeFstabSpaces $value.Destination}} none bind,ro 0 0
  85. {{end}}
  86. {{end}}
  87. {{if .Privileged}}
  88. {{if .AppArmor}}
  89. lxc.aa_profile = unconfined
  90. {{else}}
  91. # Let AppArmor normal confinement take place (i.e., not unconfined)
  92. {{end}}
  93. {{end}}
  94. # limits
  95. {{if .Resources}}
  96. {{if .Resources.Memory}}
  97. lxc.cgroup.memory.limit_in_bytes = {{.Resources.Memory}}
  98. lxc.cgroup.memory.soft_limit_in_bytes = {{.Resources.Memory}}
  99. {{with $memSwap := getMemorySwap .Resources}}
  100. lxc.cgroup.memory.memsw.limit_in_bytes = {{$memSwap}}
  101. {{end}}
  102. {{end}}
  103. {{if .Resources.CpuShares}}
  104. lxc.cgroup.cpu.shares = {{.Resources.CpuShares}}
  105. {{end}}
  106. {{if .Resources.Cpuset}}
  107. lxc.cgroup.cpuset.cpus = {{.Resources.Cpuset}}
  108. {{end}}
  109. {{end}}
  110. {{if .Config.lxc}}
  111. {{range $value := .Config.lxc}}
  112. lxc.{{$value}}
  113. {{end}}
  114. {{end}}
  115. `
  116. var LxcTemplateCompiled *template.Template
  117. // Escape spaces in strings according to the fstab documentation, which is the
  118. // format for "lxc.mount.entry" lines in lxc.conf. See also "man 5 fstab".
  119. func escapeFstabSpaces(field string) string {
  120. return strings.Replace(field, " ", "\\040", -1)
  121. }
  122. func getMemorySwap(v *execdriver.Resources) int64 {
  123. // By default, MemorySwap is set to twice the size of RAM.
  124. // If you want to omit MemorySwap, set it to `-1'.
  125. if v.MemorySwap < 0 {
  126. return 0
  127. }
  128. return v.Memory * 2
  129. }
  130. func getLabel(c map[string][]string, name string) string {
  131. label := c["label"]
  132. for _, l := range label {
  133. parts := strings.SplitN(l, "=", 2)
  134. if strings.TrimSpace(parts[0]) == name {
  135. return strings.TrimSpace(parts[1])
  136. }
  137. }
  138. return ""
  139. }
  140. func init() {
  141. var err error
  142. funcMap := template.FuncMap{
  143. "getMemorySwap": getMemorySwap,
  144. "escapeFstabSpaces": escapeFstabSpaces,
  145. "formatMountLabel": label.FormatMountLabel,
  146. }
  147. LxcTemplateCompiled, err = template.New("lxc").Funcs(funcMap).Parse(LxcTemplate)
  148. if err != nil {
  149. panic(err)
  150. }
  151. }