Browse Source

SEND CAPABILITY IDS TO LXC

Sending capability ids instead of capability names ot LXC for --cap-add and --cap-drop.
Also fixed tests.

Docker-DCO-1.1-Signed-off-by: Abin Shahab <ashahab@altiscale.com> (github: ashahab-altiscale)
Abin Shahab 10 years ago
parent
commit
bff3509e43

+ 47 - 11
daemon/execdriver/lxc/lxc_template.go

@@ -1,12 +1,17 @@
 package lxc
 package lxc
 
 
 import (
 import (
-	"github.com/docker/docker/daemon/execdriver"
-	nativeTemplate "github.com/docker/docker/daemon/execdriver/native/template"
-	"github.com/docker/libcontainer/label"
+	"fmt"
 	"os"
 	"os"
 	"strings"
 	"strings"
 	"text/template"
 	"text/template"
+
+	log "github.com/Sirupsen/logrus"
+	"github.com/docker/docker/daemon/execdriver"
+	nativeTemplate "github.com/docker/docker/daemon/execdriver/native/template"
+	"github.com/docker/docker/utils"
+	"github.com/docker/libcontainer/label"
+	"github.com/docker/libcontainer/security/capabilities"
 )
 )
 
 
 const LxcTemplate = `
 const LxcTemplate = `
@@ -126,9 +131,17 @@ lxc.utsname = {{getHostname .ProcessConfig.Env}}
 {{if .ProcessConfig.Privileged}}
 {{if .ProcessConfig.Privileged}}
 # No cap values are needed, as lxc is starting in privileged mode
 # No cap values are needed, as lxc is starting in privileged mode
 {{else}}
 {{else}}
-{{range $value := keepCapabilities .CapAdd .CapDrop}}
-lxc.cap.keep = {{$value}}
-{{end}}
+	{{ with keepCapabilities .CapAdd .CapDrop }}
+		{{range .}}
+lxc.cap.keep = {{.}}
+		{{end}}
+	{{else}}
+		{{ with dropList .CapDrop }}
+		{{range .}}
+lxc.cap.drop = {{.}}
+		{{end}}
+		{{end}}
+	{{end}}
 {{end}}
 {{end}}
 {{end}}
 {{end}}
 `
 `
@@ -141,17 +154,39 @@ func escapeFstabSpaces(field string) string {
 	return strings.Replace(field, " ", "\\040", -1)
 	return strings.Replace(field, " ", "\\040", -1)
 }
 }
 
 
-func keepCapabilities(adds []string, drops []string) []string {
+func keepCapabilities(adds []string, drops []string) ([]string, error) {
 	container := nativeTemplate.New()
 	container := nativeTemplate.New()
+	log.Debugf("adds %s drops %s\n", adds, drops)
 	caps, err := execdriver.TweakCapabilities(container.Capabilities, adds, drops)
 	caps, err := execdriver.TweakCapabilities(container.Capabilities, adds, drops)
+	if err != nil {
+		return nil, err
+	}
 	var newCaps []string
 	var newCaps []string
 	for _, cap := range caps {
 	for _, cap := range caps {
-		newCaps = append(newCaps, strings.ToLower(cap))
+		log.Debugf("cap %s\n", cap)
+		realCap := capabilities.GetCapability(cap)
+		numCap := fmt.Sprintf("%d", realCap.Value)
+		newCaps = append(newCaps, numCap)
 	}
 	}
-	if err != nil {
-		return []string{}
+
+	return newCaps, nil
+}
+
+func dropList(drops []string) ([]string, error) {
+	if utils.StringsContainsNoCase(drops, "all") {
+		var newCaps []string
+		for _, cap := range capabilities.GetAllCapabilities() {
+			log.Debugf("drop cap %s\n", cap)
+			realCap := capabilities.GetCapability(cap)
+			if realCap == nil {
+				return nil, fmt.Errorf("Invalid capability '%s'", cap)
+			}
+			numCap := fmt.Sprintf("%d", realCap.Value)
+			newCaps = append(newCaps, numCap)
+		}
+		return newCaps, nil
 	}
 	}
-	return newCaps
+	return []string{}, nil
 }
 }
 
 
 func isDirectory(source string) string {
 func isDirectory(source string) string {
@@ -206,6 +241,7 @@ func init() {
 		"formatMountLabel":  label.FormatMountLabel,
 		"formatMountLabel":  label.FormatMountLabel,
 		"isDirectory":       isDirectory,
 		"isDirectory":       isDirectory,
 		"keepCapabilities":  keepCapabilities,
 		"keepCapabilities":  keepCapabilities,
+		"dropList":          dropList,
 		"getHostname":       getHostname,
 		"getHostname":       getHostname,
 	}
 	}
 	LxcTemplateCompiled, err = template.New("lxc").Funcs(funcMap).Parse(LxcTemplate)
 	LxcTemplateCompiled, err = template.New("lxc").Funcs(funcMap).Parse(LxcTemplate)

+ 20 - 16
daemon/execdriver/lxc/lxc_template_unit_test.go

@@ -5,6 +5,11 @@ package lxc
 import (
 import (
 	"bufio"
 	"bufio"
 	"fmt"
 	"fmt"
+	"github.com/docker/docker/daemon/execdriver"
+	nativeTemplate "github.com/docker/docker/daemon/execdriver/native/template"
+	"github.com/docker/libcontainer/devices"
+	"github.com/docker/libcontainer/security/capabilities"
+	"github.com/syndtr/gocapability/capability"
 	"io/ioutil"
 	"io/ioutil"
 	"math/rand"
 	"math/rand"
 	"os"
 	"os"
@@ -12,10 +17,6 @@ import (
 	"strings"
 	"strings"
 	"testing"
 	"testing"
 	"time"
 	"time"
-
-	"github.com/docker/docker/daemon/execdriver"
-	nativeTemplate "github.com/docker/docker/daemon/execdriver/native/template"
-	"github.com/docker/libcontainer/devices"
 )
 )
 
 
 func TestLXCConfig(t *testing.T) {
 func TestLXCConfig(t *testing.T) {
@@ -292,13 +293,15 @@ func TestCustomLxcConfigMisc(t *testing.T) {
 	grepFile(t, p, "lxc.cgroup.cpuset.cpus = 0,1")
 	grepFile(t, p, "lxc.cgroup.cpuset.cpus = 0,1")
 	container := nativeTemplate.New()
 	container := nativeTemplate.New()
 	for _, cap := range container.Capabilities {
 	for _, cap := range container.Capabilities {
-		cap = strings.ToLower(cap)
-		if cap != "mknod" && cap != "kill" {
-			grepFile(t, p, fmt.Sprintf("lxc.cap.keep = %s", cap))
+		realCap := capabilities.GetCapability(cap)
+		numCap := fmt.Sprintf("%d", realCap.Value)
+		if cap != "MKNOD" && cap != "KILL" {
+			grepFile(t, p, fmt.Sprintf("lxc.cap.keep = %s", numCap))
 		}
 		}
 	}
 	}
-	grepFileWithReverse(t, p, fmt.Sprintf("lxc.cap.keep = kill"), true)
-	grepFileWithReverse(t, p, fmt.Sprintf("lxc.cap.keep = mknod"), true)
+
+	grepFileWithReverse(t, p, fmt.Sprintf("lxc.cap.keep = %d", capability.CAP_KILL), true)
+	grepFileWithReverse(t, p, fmt.Sprintf("lxc.cap.keep = %d", capability.CAP_MKNOD), true)
 }
 }
 
 
 func TestCustomLxcConfigMiscOverride(t *testing.T) {
 func TestCustomLxcConfigMiscOverride(t *testing.T) {
@@ -333,8 +336,8 @@ func TestCustomLxcConfigMiscOverride(t *testing.T) {
 			},
 			},
 		},
 		},
 		ProcessConfig: processConfig,
 		ProcessConfig: processConfig,
-		CapAdd:        []string{"net_admin", "syslog"},
-		CapDrop:       []string{"kill", "mknod"},
+		CapAdd:        []string{"NET_ADMIN", "SYSLOG"},
+		CapDrop:       []string{"KILL", "MKNOD"},
 	}
 	}
 
 
 	p, err := driver.generateLXCConfig(command)
 	p, err := driver.generateLXCConfig(command)
@@ -354,11 +357,12 @@ func TestCustomLxcConfigMiscOverride(t *testing.T) {
 	grepFile(t, p, "lxc.cgroup.cpuset.cpus = 0,1")
 	grepFile(t, p, "lxc.cgroup.cpuset.cpus = 0,1")
 	container := nativeTemplate.New()
 	container := nativeTemplate.New()
 	for _, cap := range container.Capabilities {
 	for _, cap := range container.Capabilities {
-		cap = strings.ToLower(cap)
-		if cap != "mknod" && cap != "kill" {
-			grepFile(t, p, fmt.Sprintf("lxc.cap.keep = %s", cap))
+		realCap := capabilities.GetCapability(cap)
+		numCap := fmt.Sprintf("%d", realCap.Value)
+		if cap != "MKNOD" && cap != "KILL" {
+			grepFile(t, p, fmt.Sprintf("lxc.cap.keep = %s", numCap))
 		}
 		}
 	}
 	}
-	grepFileWithReverse(t, p, fmt.Sprintf("lxc.cap.keep = kill"), true)
-	grepFileWithReverse(t, p, fmt.Sprintf("lxc.cap.keep = mknod"), true)
+	grepFileWithReverse(t, p, fmt.Sprintf("lxc.cap.keep = %d", capability.CAP_KILL), true)
+	grepFileWithReverse(t, p, fmt.Sprintf("lxc.cap.keep = %d", capability.CAP_MKNOD), true)
 }
 }

+ 3 - 3
integration-cli/docker_cli_run_test.go

@@ -986,7 +986,7 @@ func TestRunCapDropCannotMknodLowerCase(t *testing.T) {
 }
 }
 
 
 func TestRunCapDropALLCannotMknod(t *testing.T) {
 func TestRunCapDropALLCannotMknod(t *testing.T) {
-	cmd := exec.Command(dockerBinary, "run", "--cap-drop=ALL", "busybox", "sh", "-c", "mknod /tmp/sda b 8 0 && echo ok")
+	cmd := exec.Command(dockerBinary, "run", "--cap-drop=ALL", "--cap-add=SETGID", "busybox", "sh", "-c", "mknod /tmp/sda b 8 0 && echo ok")
 	out, _, err := runCommandWithOutput(cmd)
 	out, _, err := runCommandWithOutput(cmd)
 	if err == nil {
 	if err == nil {
 		t.Fatal(err, out)
 		t.Fatal(err, out)
@@ -1000,8 +1000,8 @@ func TestRunCapDropALLCannotMknod(t *testing.T) {
 	logDone("run - test --cap-drop=ALL cannot mknod")
 	logDone("run - test --cap-drop=ALL cannot mknod")
 }
 }
 
 
-func TestRunCapDropALLAddMknodCannotMknod(t *testing.T) {
-	cmd := exec.Command(dockerBinary, "run", "--cap-drop=ALL", "--cap-add=MKNOD", "busybox", "sh", "-c", "mknod /tmp/sda b 8 0 && echo ok")
+func TestRunCapDropALLAddMknodCanMknod(t *testing.T) {
+	cmd := exec.Command(dockerBinary, "run", "--cap-drop=ALL", "--cap-add=MKNOD", "--cap-add=SETGID", "busybox", "sh", "-c", "mknod /tmp/sda b 8 0 && echo ok")
 	out, _, err := runCommandWithOutput(cmd)
 	out, _, err := runCommandWithOutput(cmd)
 	if err != nil {
 	if err != nil {
 		t.Fatal(err, out)
 		t.Fatal(err, out)