Bladeren bron

Merge pull request #2844 from tianon/fix-mount-spaces

Add space-escaping to path parts of lxc.mount.entry lines in generated lxc.conf, allowing for spaces in mount point names
Victor Vieux 11 jaren geleden
bovenliggende
commit
39bec226c0
2 gewijzigde bestanden met toevoegingen van 41 en 15 verwijderingen
  1. 23 15
      lxc_template.go
  2. 18 0
      lxc_template_unit_test.go

+ 23 - 15
lxc_template.go

@@ -1,6 +1,7 @@
 package docker
 package docker
 
 
 import (
 import (
+	"strings"
 	"text/template"
 	"text/template"
 )
 )
 
 
@@ -31,8 +32,8 @@ lxc.rootfs = {{$ROOTFS}}
 
 
 {{if and .HostnamePath .HostsPath}}
 {{if and .HostnamePath .HostsPath}}
 # enable domain name support
 # enable domain name support
-lxc.mount.entry = {{.HostnamePath}} {{$ROOTFS}}/etc/hostname none bind,ro 0 0
-lxc.mount.entry = {{.HostsPath}} {{$ROOTFS}}/etc/hosts none bind,ro 0 0
+lxc.mount.entry = {{escapeFstabSpaces .HostnamePath}} {{escapeFstabSpaces $ROOTFS}}/etc/hostname none bind,ro 0 0
+lxc.mount.entry = {{escapeFstabSpaces .HostsPath}} {{escapeFstabSpaces $ROOTFS}}/etc/hosts none bind,ro 0 0
 {{end}}
 {{end}}
 
 
 # use a dedicated pts for the container (and limit the number of pseudo terminal
 # use a dedicated pts for the container (and limit the number of pseudo terminal
@@ -84,27 +85,27 @@ lxc.cgroup.devices.allow = c 10:200 rwm
 lxc.pivotdir = lxc_putold
 lxc.pivotdir = lxc_putold
 #  WARNING: procfs is a known attack vector and should probably be disabled
 #  WARNING: procfs is a known attack vector and should probably be disabled
 #           if your userspace allows it. eg. see http://blog.zx2c4.com/749
 #           if your userspace allows it. eg. see http://blog.zx2c4.com/749
-lxc.mount.entry = proc {{$ROOTFS}}/proc proc nosuid,nodev,noexec 0 0
+lxc.mount.entry = proc {{escapeFstabSpaces $ROOTFS}}/proc proc nosuid,nodev,noexec 0 0
 #  WARNING: sysfs is a known attack vector and should probably be disabled
 #  WARNING: sysfs is a known attack vector and should probably be disabled
 #           if your userspace allows it. eg. see http://bit.ly/T9CkqJ
 #           if your userspace allows it. eg. see http://bit.ly/T9CkqJ
-lxc.mount.entry = sysfs {{$ROOTFS}}/sys sysfs nosuid,nodev,noexec 0 0
-lxc.mount.entry = devpts {{$ROOTFS}}/dev/pts devpts newinstance,ptmxmode=0666,nosuid,noexec 0 0
-#lxc.mount.entry = varrun {{$ROOTFS}}/var/run tmpfs mode=755,size=4096k,nosuid,nodev,noexec 0 0
-#lxc.mount.entry = varlock {{$ROOTFS}}/var/lock tmpfs size=1024k,nosuid,nodev,noexec 0 0
-lxc.mount.entry = shm {{$ROOTFS}}/dev/shm tmpfs size=65536k,nosuid,nodev,noexec 0 0
+lxc.mount.entry = sysfs {{escapeFstabSpaces $ROOTFS}}/sys sysfs nosuid,nodev,noexec 0 0
+lxc.mount.entry = devpts {{escapeFstabSpaces $ROOTFS}}/dev/pts devpts newinstance,ptmxmode=0666,nosuid,noexec 0 0
+#lxc.mount.entry = varrun {{escapeFstabSpaces $ROOTFS}}/var/run tmpfs mode=755,size=4096k,nosuid,nodev,noexec 0 0
+#lxc.mount.entry = varlock {{escapeFstabSpaces $ROOTFS}}/var/lock tmpfs size=1024k,nosuid,nodev,noexec 0 0
+lxc.mount.entry = shm {{escapeFstabSpaces $ROOTFS}}/dev/shm tmpfs size=65536k,nosuid,nodev,noexec 0 0
 
 
 # Inject dockerinit
 # Inject dockerinit
-lxc.mount.entry = {{.SysInitPath}} {{$ROOTFS}}/.dockerinit none bind,ro 0 0
+lxc.mount.entry = {{escapeFstabSpaces .SysInitPath}} {{escapeFstabSpaces $ROOTFS}}/.dockerinit none bind,ro 0 0
 
 
 # Inject env
 # Inject env
-lxc.mount.entry = {{.EnvConfigPath}} {{$ROOTFS}}/.dockerenv none bind,ro 0 0
+lxc.mount.entry = {{escapeFstabSpaces .EnvConfigPath}} {{escapeFstabSpaces $ROOTFS}}/.dockerenv none bind,ro 0 0
 
 
 # In order to get a working DNS environment, mount bind (ro) the host's /etc/resolv.conf into the container
 # In order to get a working DNS environment, mount bind (ro) the host's /etc/resolv.conf into the container
-lxc.mount.entry = {{.ResolvConfPath}} {{$ROOTFS}}/etc/resolv.conf none bind,ro 0 0
+lxc.mount.entry = {{escapeFstabSpaces .ResolvConfPath}} {{escapeFstabSpaces $ROOTFS}}/etc/resolv.conf none bind,ro 0 0
 {{if .Volumes}}
 {{if .Volumes}}
 {{ $rw := .VolumesRW }}
 {{ $rw := .VolumesRW }}
 {{range $virtualPath, $realPath := .Volumes}}
 {{range $virtualPath, $realPath := .Volumes}}
-lxc.mount.entry = {{$realPath}} {{$ROOTFS}}/{{$virtualPath}} none bind,{{ if index $rw $virtualPath }}rw{{else}}ro{{end}} 0 0
+lxc.mount.entry = {{escapeFstabSpaces $realPath}} {{escapeFstabSpaces $ROOTFS}}/{{escapeFstabSpaces $virtualPath}} none bind,{{ if index $rw $virtualPath }}rw{{else}}ro{{end}} 0 0
 {{end}}
 {{end}}
 {{end}}
 {{end}}
 
 
@@ -144,6 +145,12 @@ lxc.cgroup.cpu.shares = {{.Config.CpuShares}}
 
 
 var LxcTemplateCompiled *template.Template
 var LxcTemplateCompiled *template.Template
 
 
+// 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)
+}
+
 func getMemorySwap(config *Config) int64 {
 func getMemorySwap(config *Config) int64 {
 	// By default, MemorySwap is set to twice the size of RAM.
 	// By default, MemorySwap is set to twice the size of RAM.
 	// If you want to omit MemorySwap, set it to `-1'.
 	// If you want to omit MemorySwap, set it to `-1'.
@@ -164,9 +171,10 @@ func getCapabilities(container *Container) *Capabilities {
 func init() {
 func init() {
 	var err error
 	var err error
 	funcMap := template.FuncMap{
 	funcMap := template.FuncMap{
-		"getMemorySwap":   getMemorySwap,
-		"getHostConfig":   getHostConfig,
-		"getCapabilities": getCapabilities,
+		"getMemorySwap":     getMemorySwap,
+		"getHostConfig":     getHostConfig,
+		"getCapabilities":   getCapabilities,
+		"escapeFstabSpaces": escapeFstabSpaces,
 	}
 	}
 	LxcTemplateCompiled, err = template.New("lxc").Funcs(funcMap).Parse(LxcTemplate)
 	LxcTemplateCompiled, err = template.New("lxc").Funcs(funcMap).Parse(LxcTemplate)
 	if err != nil {
 	if err != nil {

+ 18 - 0
lxc_template_unit_test.go

@@ -100,3 +100,21 @@ func grepFile(t *testing.T, path string, pattern string) {
 	}
 	}
 	t.Fatalf("grepFile: pattern \"%s\" not found in \"%s\"", pattern, path)
 	t.Fatalf("grepFile: pattern \"%s\" not found in \"%s\"", pattern, path)
 }
 }
+
+func TestEscapeFstabSpaces(t *testing.T) {
+	var testInputs = map[string]string{
+		" ":                      "\\040",
+		"":                       "",
+		"/double  space":         "/double\\040\\040space",
+		"/some long test string": "/some\\040long\\040test\\040string",
+		"/var/lib/docker":        "/var/lib/docker",
+		" leading":               "\\040leading",
+		"trailing ":              "trailing\\040",
+	}
+	for in, exp := range testInputs {
+		if out := escapeFstabSpaces(in); exp != out {
+			t.Logf("Expected %s got %s", exp, out)
+			t.Fail()
+		}
+	}
+}