github.com/gondor/docker@v1.9.0-rc1/daemon/execdriver/lxc/lxc_template_unit_test.go (about)

     1  // +build linux
     2  
     3  package lxc
     4  
     5  import (
     6  	"bufio"
     7  	"fmt"
     8  	"io/ioutil"
     9  	"math/rand"
    10  	"os"
    11  	"path"
    12  	"strings"
    13  	"testing"
    14  	"time"
    15  
    16  	"github.com/docker/docker/daemon/execdriver"
    17  	nativeTemplate "github.com/docker/docker/daemon/execdriver/native/template"
    18  	"github.com/opencontainers/runc/libcontainer/configs"
    19  	"github.com/syndtr/gocapability/capability"
    20  )
    21  
    22  func TestLXCConfig(t *testing.T) {
    23  	root, err := ioutil.TempDir("", "TestLXCConfig")
    24  	if err != nil {
    25  		t.Fatal(err)
    26  	}
    27  	defer os.RemoveAll(root)
    28  
    29  	os.MkdirAll(path.Join(root, "containers", "1"), 0777)
    30  
    31  	// Memory is allocated randomly for testing
    32  	r := rand.New(rand.NewSource(time.Now().UTC().UnixNano()))
    33  	var (
    34  		memMin = 33554432
    35  		memMax = 536870912
    36  		mem    = memMin + r.Intn(memMax-memMin)
    37  		cpuMin = 100
    38  		cpuMax = 10000
    39  		cpu    = cpuMin + r.Intn(cpuMax-cpuMin)
    40  	)
    41  
    42  	driver, err := NewDriver(root, root, "", false)
    43  	if err != nil {
    44  		t.Fatal(err)
    45  	}
    46  	command := &execdriver.Command{
    47  		ID: "1",
    48  		Resources: &execdriver.Resources{
    49  			Memory:    int64(mem),
    50  			CPUShares: int64(cpu),
    51  		},
    52  		Network: &execdriver.Network{
    53  			Mtu: 1500,
    54  		},
    55  		AllowedDevices: make([]*configs.Device, 0),
    56  		ProcessConfig:  execdriver.ProcessConfig{},
    57  	}
    58  	p, err := driver.generateLXCConfig(command)
    59  	if err != nil {
    60  		t.Fatal(err)
    61  	}
    62  	grepFile(t, p,
    63  		fmt.Sprintf("lxc.cgroup.memory.limit_in_bytes = %d", mem))
    64  
    65  	grepFile(t, p,
    66  		fmt.Sprintf("lxc.cgroup.memory.memsw.limit_in_bytes = %d", mem*2))
    67  }
    68  
    69  func TestCustomLxcConfig(t *testing.T) {
    70  	root, err := ioutil.TempDir("", "TestCustomLxcConfig")
    71  	if err != nil {
    72  		t.Fatal(err)
    73  	}
    74  	defer os.RemoveAll(root)
    75  
    76  	os.MkdirAll(path.Join(root, "containers", "1"), 0777)
    77  
    78  	driver, err := NewDriver(root, root, "", false)
    79  	if err != nil {
    80  		t.Fatal(err)
    81  	}
    82  	processConfig := execdriver.ProcessConfig{
    83  		Privileged: false,
    84  	}
    85  	command := &execdriver.Command{
    86  		ID: "1",
    87  		LxcConfig: []string{
    88  			"lxc.utsname = docker",
    89  			"lxc.cgroup.cpuset.cpus = 0,1",
    90  		},
    91  		Network: &execdriver.Network{
    92  			Mtu: 1500,
    93  		},
    94  		ProcessConfig: processConfig,
    95  	}
    96  
    97  	p, err := driver.generateLXCConfig(command)
    98  	if err != nil {
    99  		t.Fatal(err)
   100  	}
   101  
   102  	grepFile(t, p, "lxc.utsname = docker")
   103  	grepFile(t, p, "lxc.cgroup.cpuset.cpus = 0,1")
   104  }
   105  
   106  func grepFile(t *testing.T, path string, pattern string) {
   107  	grepFileWithReverse(t, path, pattern, false)
   108  }
   109  
   110  func grepFileWithReverse(t *testing.T, path string, pattern string, inverseGrep bool) {
   111  	f, err := os.Open(path)
   112  	if err != nil {
   113  		t.Fatal(err)
   114  	}
   115  	defer f.Close()
   116  	r := bufio.NewReader(f)
   117  	var (
   118  		line string
   119  	)
   120  	err = nil
   121  	for err == nil {
   122  		line, err = r.ReadString('\n')
   123  		if strings.Contains(line, pattern) == true {
   124  			if inverseGrep {
   125  				t.Fatalf("grepFile: pattern \"%s\" found in \"%s\"", pattern, path)
   126  			}
   127  			return
   128  		}
   129  	}
   130  	if inverseGrep {
   131  		return
   132  	}
   133  	t.Fatalf("grepFile: pattern \"%s\" not found in \"%s\"", pattern, path)
   134  }
   135  
   136  func TestEscapeFstabSpaces(t *testing.T) {
   137  	var testInputs = map[string]string{
   138  		" ":                      "\\040",
   139  		"":                       "",
   140  		"/double  space":         "/double\\040\\040space",
   141  		"/some long test string": "/some\\040long\\040test\\040string",
   142  		"/var/lib/docker":        "/var/lib/docker",
   143  		" leading":               "\\040leading",
   144  		"trailing ":              "trailing\\040",
   145  	}
   146  	for in, exp := range testInputs {
   147  		if out := escapeFstabSpaces(in); exp != out {
   148  			t.Logf("Expected %s got %s", exp, out)
   149  			t.Fail()
   150  		}
   151  	}
   152  }
   153  
   154  func TestIsDirectory(t *testing.T) {
   155  	tempDir, err := ioutil.TempDir("", "TestIsDir")
   156  	if err != nil {
   157  		t.Fatal(err)
   158  	}
   159  	defer os.RemoveAll(tempDir)
   160  
   161  	tempFile, err := ioutil.TempFile(tempDir, "TestIsDirFile")
   162  	if err != nil {
   163  		t.Fatal(err)
   164  	}
   165  
   166  	if isDirectory(tempDir) != "dir" {
   167  		t.Logf("Could not identify %s as a directory", tempDir)
   168  		t.Fail()
   169  	}
   170  
   171  	if isDirectory(tempFile.Name()) != "file" {
   172  		t.Logf("Could not identify %s as a file", tempFile.Name())
   173  		t.Fail()
   174  	}
   175  }
   176  
   177  func TestCustomLxcConfigMounts(t *testing.T) {
   178  	root, err := ioutil.TempDir("", "TestCustomLxcConfig")
   179  	if err != nil {
   180  		t.Fatal(err)
   181  	}
   182  	defer os.RemoveAll(root)
   183  	tempDir, err := ioutil.TempDir("", "TestIsDir")
   184  	if err != nil {
   185  		t.Fatal(err)
   186  	}
   187  	defer os.RemoveAll(tempDir)
   188  
   189  	tempFile, err := ioutil.TempFile(tempDir, "TestIsDirFile")
   190  	if err != nil {
   191  		t.Fatal(err)
   192  	}
   193  	os.MkdirAll(path.Join(root, "containers", "1"), 0777)
   194  
   195  	driver, err := NewDriver(root, root, "", false)
   196  	if err != nil {
   197  		t.Fatal(err)
   198  	}
   199  	processConfig := execdriver.ProcessConfig{
   200  		Privileged: false,
   201  	}
   202  	mounts := []execdriver.Mount{
   203  		{
   204  			Source:      tempDir,
   205  			Destination: tempDir,
   206  			Writable:    false,
   207  			Private:     true,
   208  		},
   209  		{
   210  			Source:      tempFile.Name(),
   211  			Destination: tempFile.Name(),
   212  			Writable:    true,
   213  			Private:     true,
   214  		},
   215  	}
   216  	command := &execdriver.Command{
   217  		ID: "1",
   218  		LxcConfig: []string{
   219  			"lxc.utsname = docker",
   220  			"lxc.cgroup.cpuset.cpus = 0,1",
   221  		},
   222  		Network: &execdriver.Network{
   223  			Mtu: 1500,
   224  		},
   225  		Mounts:        mounts,
   226  		ProcessConfig: processConfig,
   227  	}
   228  
   229  	p, err := driver.generateLXCConfig(command)
   230  	if err != nil {
   231  		t.Fatal(err)
   232  	}
   233  
   234  	grepFile(t, p, "lxc.utsname = docker")
   235  	grepFile(t, p, "lxc.cgroup.cpuset.cpus = 0,1")
   236  
   237  	grepFile(t, p, fmt.Sprintf("lxc.mount.entry = %s %s none rbind,ro,create=%s 0 0", tempDir, "/"+tempDir, "dir"))
   238  	grepFile(t, p, fmt.Sprintf("lxc.mount.entry = %s %s none rbind,rw,create=%s 0 0", tempFile.Name(), "/"+tempFile.Name(), "file"))
   239  }
   240  
   241  func TestCustomLxcConfigMisc(t *testing.T) {
   242  	root, err := ioutil.TempDir("", "TestCustomLxcConfig")
   243  	if err != nil {
   244  		t.Fatal(err)
   245  	}
   246  	defer os.RemoveAll(root)
   247  	os.MkdirAll(path.Join(root, "containers", "1"), 0777)
   248  	driver, err := NewDriver(root, root, "", true)
   249  
   250  	if err != nil {
   251  		t.Fatal(err)
   252  	}
   253  	processConfig := execdriver.ProcessConfig{
   254  		Privileged: false,
   255  	}
   256  
   257  	processConfig.Env = []string{"HOSTNAME=testhost"}
   258  	command := &execdriver.Command{
   259  		ID: "1",
   260  		LxcConfig: []string{
   261  			"lxc.cgroup.cpuset.cpus = 0,1",
   262  		},
   263  		Network: &execdriver.Network{
   264  			Mtu: 1500,
   265  		},
   266  		ProcessConfig:   processConfig,
   267  		CapAdd:          []string{"net_admin", "syslog"},
   268  		CapDrop:         []string{"kill", "mknod"},
   269  		AppArmorProfile: "lxc-container-default-with-nesting",
   270  	}
   271  
   272  	p, err := driver.generateLXCConfig(command)
   273  	if err != nil {
   274  		t.Fatal(err)
   275  	}
   276  	grepFile(t, p, "lxc.aa_profile = lxc-container-default-with-nesting")
   277  	// hostname
   278  	grepFile(t, p, "lxc.utsname = testhost")
   279  	grepFile(t, p, "lxc.cgroup.cpuset.cpus = 0,1")
   280  	container := nativeTemplate.New()
   281  	for _, cap := range container.Capabilities {
   282  		realCap := execdriver.GetCapability(cap)
   283  		numCap := fmt.Sprintf("%d", realCap.Value)
   284  		if cap != "MKNOD" && cap != "KILL" {
   285  			grepFile(t, p, fmt.Sprintf("lxc.cap.keep = %s", numCap))
   286  		}
   287  	}
   288  
   289  	grepFileWithReverse(t, p, fmt.Sprintf("lxc.cap.keep = %d", capability.CAP_KILL), true)
   290  	grepFileWithReverse(t, p, fmt.Sprintf("lxc.cap.keep = %d", capability.CAP_MKNOD), true)
   291  }
   292  
   293  func TestCustomLxcConfigMiscOverride(t *testing.T) {
   294  	root, err := ioutil.TempDir("", "TestCustomLxcConfig")
   295  	if err != nil {
   296  		t.Fatal(err)
   297  	}
   298  	defer os.RemoveAll(root)
   299  	os.MkdirAll(path.Join(root, "containers", "1"), 0777)
   300  	driver, err := NewDriver(root, root, "", false)
   301  	if err != nil {
   302  		t.Fatal(err)
   303  	}
   304  	processConfig := execdriver.ProcessConfig{
   305  		Privileged: false,
   306  	}
   307  
   308  	processConfig.Env = []string{"HOSTNAME=testhost"}
   309  	command := &execdriver.Command{
   310  		ID: "1",
   311  		LxcConfig: []string{
   312  			"lxc.cgroup.cpuset.cpus = 0,1",
   313  			"lxc.network.ipv4 = 172.0.0.1",
   314  		},
   315  		Network: &execdriver.Network{
   316  			Mtu: 1500,
   317  		},
   318  		ProcessConfig: processConfig,
   319  		CapAdd:        []string{"NET_ADMIN", "SYSLOG"},
   320  		CapDrop:       []string{"KILL", "MKNOD"},
   321  	}
   322  
   323  	p, err := driver.generateLXCConfig(command)
   324  	if err != nil {
   325  		t.Fatal(err)
   326  	}
   327  
   328  	// hostname
   329  	grepFile(t, p, "lxc.utsname = testhost")
   330  	grepFile(t, p, "lxc.cgroup.cpuset.cpus = 0,1")
   331  	container := nativeTemplate.New()
   332  	for _, cap := range container.Capabilities {
   333  		realCap := execdriver.GetCapability(cap)
   334  		numCap := fmt.Sprintf("%d", realCap.Value)
   335  		if cap != "MKNOD" && cap != "KILL" {
   336  			grepFile(t, p, fmt.Sprintf("lxc.cap.keep = %s", numCap))
   337  		}
   338  	}
   339  	grepFileWithReverse(t, p, fmt.Sprintf("lxc.cap.keep = %d", capability.CAP_KILL), true)
   340  	grepFileWithReverse(t, p, fmt.Sprintf("lxc.cap.keep = %d", capability.CAP_MKNOD), true)
   341  }