mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
![Dan Walsh](/assets/img/avatar_default.png)
docker will run the process(es) within the container with an SELinux label and will label all of the content within the container with mount label. Any temporary file systems created within the container need to be mounted with the same mount label. The user can override the process label by specifying -Z With a string of space separated options. -Z "user=unconfined_u role=unconfined_r type=unconfined_t level=s0" Would cause the process label to run with unconfined_u:unconfined_r:unconfined_t:s0" By default the processes will run execute within the container as svirt_lxc_net_t. All of the content in the container as svirt_sandbox_file_t. The process mcs level is based of the PID of the docker process that is creating the container. If you run the container in --priv mode, the labeling will be disabled. Docker-DCO-1.1-Signed-off-by: Dan Walsh <dwalsh@redhat.com> (github: rhatdan)
697 lines
12 KiB
Go
697 lines
12 KiB
Go
package aufs
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"github.com/dotcloud/docker/archive"
|
|
"github.com/dotcloud/docker/runtime/graphdriver"
|
|
"io/ioutil"
|
|
"os"
|
|
"path"
|
|
"testing"
|
|
)
|
|
|
|
var (
|
|
tmp = path.Join(os.TempDir(), "aufs-tests", "aufs")
|
|
)
|
|
|
|
func testInit(dir string, t *testing.T) graphdriver.Driver {
|
|
d, err := Init(dir)
|
|
if err != nil {
|
|
if err == ErrAufsNotSupported {
|
|
t.Skip(err)
|
|
} else {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
return d
|
|
}
|
|
|
|
func newDriver(t *testing.T) *Driver {
|
|
if err := os.MkdirAll(tmp, 0755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
d := testInit(tmp, t)
|
|
return d.(*Driver)
|
|
}
|
|
|
|
func TestNewDriver(t *testing.T) {
|
|
if err := os.MkdirAll(tmp, 0755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
d := testInit(tmp, t)
|
|
defer os.RemoveAll(tmp)
|
|
if d == nil {
|
|
t.Fatalf("Driver should not be nil")
|
|
}
|
|
}
|
|
|
|
func TestAufsString(t *testing.T) {
|
|
d := newDriver(t)
|
|
defer os.RemoveAll(tmp)
|
|
|
|
if d.String() != "aufs" {
|
|
t.Fatalf("Expected aufs got %s", d.String())
|
|
}
|
|
}
|
|
|
|
func TestCreateDirStructure(t *testing.T) {
|
|
newDriver(t)
|
|
defer os.RemoveAll(tmp)
|
|
|
|
paths := []string{
|
|
"mnt",
|
|
"layers",
|
|
"diff",
|
|
}
|
|
|
|
for _, p := range paths {
|
|
if _, err := os.Stat(path.Join(tmp, p)); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
// We should be able to create two drivers with the same dir structure
|
|
func TestNewDriverFromExistingDir(t *testing.T) {
|
|
if err := os.MkdirAll(tmp, 0755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
testInit(tmp, t)
|
|
testInit(tmp, t)
|
|
os.RemoveAll(tmp)
|
|
}
|
|
|
|
func TestCreateNewDir(t *testing.T) {
|
|
d := newDriver(t)
|
|
defer os.RemoveAll(tmp)
|
|
|
|
if err := d.Create("1", "", ""); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestCreateNewDirStructure(t *testing.T) {
|
|
d := newDriver(t)
|
|
defer os.RemoveAll(tmp)
|
|
|
|
if err := d.Create("1", "", ""); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
paths := []string{
|
|
"mnt",
|
|
"diff",
|
|
"layers",
|
|
}
|
|
|
|
for _, p := range paths {
|
|
if _, err := os.Stat(path.Join(tmp, p, "1")); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestRemoveImage(t *testing.T) {
|
|
d := newDriver(t)
|
|
defer os.RemoveAll(tmp)
|
|
|
|
if err := d.Create("1", "", ""); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if err := d.Remove("1"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
paths := []string{
|
|
"mnt",
|
|
"diff",
|
|
"layers",
|
|
}
|
|
|
|
for _, p := range paths {
|
|
if _, err := os.Stat(path.Join(tmp, p, "1")); err == nil {
|
|
t.Fatalf("Error should not be nil because dirs with id 1 should be delted: %s", p)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestGetWithoutParent(t *testing.T) {
|
|
d := newDriver(t)
|
|
defer os.RemoveAll(tmp)
|
|
|
|
if err := d.Create("1", "", ""); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
diffPath, err := d.Get("1")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
expected := path.Join(tmp, "diff", "1")
|
|
if diffPath != expected {
|
|
t.Fatalf("Expected path %s got %s", expected, diffPath)
|
|
}
|
|
}
|
|
|
|
func TestCleanupWithNoDirs(t *testing.T) {
|
|
d := newDriver(t)
|
|
defer os.RemoveAll(tmp)
|
|
|
|
if err := d.Cleanup(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestCleanupWithDir(t *testing.T) {
|
|
d := newDriver(t)
|
|
defer os.RemoveAll(tmp)
|
|
|
|
if err := d.Create("1", "", ""); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if err := d.Cleanup(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestMountedFalseResponse(t *testing.T) {
|
|
d := newDriver(t)
|
|
defer os.RemoveAll(tmp)
|
|
|
|
if err := d.Create("1", "", ""); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
response, err := d.mounted("1")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if response != false {
|
|
t.Fatalf("Response if dir id 1 is mounted should be false")
|
|
}
|
|
}
|
|
|
|
func TestMountedTrueReponse(t *testing.T) {
|
|
d := newDriver(t)
|
|
defer os.RemoveAll(tmp)
|
|
defer d.Cleanup()
|
|
|
|
if err := d.Create("1", "", ""); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := d.Create("2", "1", ""); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
_, err := d.Get("2")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
response, err := d.mounted("2")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if response != true {
|
|
t.Fatalf("Response if dir id 2 is mounted should be true")
|
|
}
|
|
}
|
|
|
|
func TestMountWithParent(t *testing.T) {
|
|
d := newDriver(t)
|
|
defer os.RemoveAll(tmp)
|
|
|
|
if err := d.Create("1", "", ""); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := d.Create("2", "1", ""); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
defer func() {
|
|
if err := d.Cleanup(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}()
|
|
|
|
mntPath, err := d.Get("2")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if mntPath == "" {
|
|
t.Fatal("mntPath should not be empty string")
|
|
}
|
|
|
|
expected := path.Join(tmp, "mnt", "2")
|
|
if mntPath != expected {
|
|
t.Fatalf("Expected %s got %s", expected, mntPath)
|
|
}
|
|
}
|
|
|
|
func TestRemoveMountedDir(t *testing.T) {
|
|
d := newDriver(t)
|
|
defer os.RemoveAll(tmp)
|
|
|
|
if err := d.Create("1", "", ""); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := d.Create("2", "1", ""); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
defer func() {
|
|
if err := d.Cleanup(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}()
|
|
|
|
mntPath, err := d.Get("2")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if mntPath == "" {
|
|
t.Fatal("mntPath should not be empty string")
|
|
}
|
|
|
|
mounted, err := d.mounted("2")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if !mounted {
|
|
t.Fatalf("Dir id 2 should be mounted")
|
|
}
|
|
|
|
if err := d.Remove("2"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestCreateWithInvalidParent(t *testing.T) {
|
|
d := newDriver(t)
|
|
defer os.RemoveAll(tmp)
|
|
|
|
if err := d.Create("1", "docker", ""); err == nil {
|
|
t.Fatalf("Error should not be nil with parent does not exist")
|
|
}
|
|
}
|
|
|
|
func TestGetDiff(t *testing.T) {
|
|
d := newDriver(t)
|
|
defer os.RemoveAll(tmp)
|
|
|
|
if err := d.Create("1", "", ""); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
diffPath, err := d.Get("1")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Add a file to the diff path with a fixed size
|
|
size := int64(1024)
|
|
|
|
f, err := os.Create(path.Join(diffPath, "test_file"))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := f.Truncate(size); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
f.Close()
|
|
|
|
a, err := d.Diff("1")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if a == nil {
|
|
t.Fatalf("Archive should not be nil")
|
|
}
|
|
}
|
|
|
|
func TestChanges(t *testing.T) {
|
|
d := newDriver(t)
|
|
defer os.RemoveAll(tmp)
|
|
|
|
if err := d.Create("1", "", ""); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := d.Create("2", "1", ""); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
defer func() {
|
|
if err := d.Cleanup(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}()
|
|
|
|
mntPoint, err := d.Get("2")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Create a file to save in the mountpoint
|
|
f, err := os.Create(path.Join(mntPoint, "test.txt"))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if _, err := f.WriteString("testline"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := f.Close(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
changes, err := d.Changes("2")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(changes) != 1 {
|
|
t.Fatalf("Dir 2 should have one change from parent got %d", len(changes))
|
|
}
|
|
change := changes[0]
|
|
|
|
expectedPath := "/test.txt"
|
|
if change.Path != expectedPath {
|
|
t.Fatalf("Expected path %s got %s", expectedPath, change.Path)
|
|
}
|
|
|
|
if change.Kind != archive.ChangeAdd {
|
|
t.Fatalf("Change kind should be ChangeAdd got %s", change.Kind)
|
|
}
|
|
|
|
if err := d.Create("3", "2", ""); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
mntPoint, err = d.Get("3")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Create a file to save in the mountpoint
|
|
f, err = os.Create(path.Join(mntPoint, "test2.txt"))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if _, err := f.WriteString("testline"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := f.Close(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
changes, err = d.Changes("3")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if len(changes) != 1 {
|
|
t.Fatalf("Dir 2 should have one change from parent got %d", len(changes))
|
|
}
|
|
change = changes[0]
|
|
|
|
expectedPath = "/test2.txt"
|
|
if change.Path != expectedPath {
|
|
t.Fatalf("Expected path %s got %s", expectedPath, change.Path)
|
|
}
|
|
|
|
if change.Kind != archive.ChangeAdd {
|
|
t.Fatalf("Change kind should be ChangeAdd got %s", change.Kind)
|
|
}
|
|
}
|
|
|
|
func TestDiffSize(t *testing.T) {
|
|
d := newDriver(t)
|
|
defer os.RemoveAll(tmp)
|
|
|
|
if err := d.Create("1", "", ""); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
diffPath, err := d.Get("1")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Add a file to the diff path with a fixed size
|
|
size := int64(1024)
|
|
|
|
f, err := os.Create(path.Join(diffPath, "test_file"))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := f.Truncate(size); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
s, err := f.Stat()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
size = s.Size()
|
|
if err := f.Close(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
diffSize, err := d.DiffSize("1")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if diffSize != size {
|
|
t.Fatalf("Expected size to be %d got %d", size, diffSize)
|
|
}
|
|
}
|
|
|
|
func TestChildDiffSize(t *testing.T) {
|
|
d := newDriver(t)
|
|
defer os.RemoveAll(tmp)
|
|
defer d.Cleanup()
|
|
|
|
if err := d.Create("1", "", ""); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
diffPath, err := d.Get("1")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Add a file to the diff path with a fixed size
|
|
size := int64(1024)
|
|
|
|
f, err := os.Create(path.Join(diffPath, "test_file"))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := f.Truncate(size); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
s, err := f.Stat()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
size = s.Size()
|
|
if err := f.Close(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
diffSize, err := d.DiffSize("1")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if diffSize != size {
|
|
t.Fatalf("Expected size to be %d got %d", size, diffSize)
|
|
}
|
|
|
|
if err := d.Create("2", "1", ""); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
diffSize, err = d.DiffSize("2")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
// The diff size for the child should be zero
|
|
if diffSize != 0 {
|
|
t.Fatalf("Expected size to be %d got %d", 0, diffSize)
|
|
}
|
|
}
|
|
|
|
func TestExists(t *testing.T) {
|
|
d := newDriver(t)
|
|
defer os.RemoveAll(tmp)
|
|
defer d.Cleanup()
|
|
|
|
if err := d.Create("1", "", ""); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if d.Exists("none") {
|
|
t.Fatal("id name should not exist in the driver")
|
|
}
|
|
|
|
if !d.Exists("1") {
|
|
t.Fatal("id 1 should exist in the driver")
|
|
}
|
|
}
|
|
|
|
func TestStatus(t *testing.T) {
|
|
d := newDriver(t)
|
|
defer os.RemoveAll(tmp)
|
|
defer d.Cleanup()
|
|
|
|
if err := d.Create("1", "", ""); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
status := d.Status()
|
|
if status == nil || len(status) == 0 {
|
|
t.Fatal("Status should not be nil or empty")
|
|
}
|
|
rootDir := status[0]
|
|
dirs := status[1]
|
|
if rootDir[0] != "Root Dir" {
|
|
t.Fatalf("Expected Root Dir got %s", rootDir[0])
|
|
}
|
|
if rootDir[1] != d.rootPath() {
|
|
t.Fatalf("Expected %s got %s", d.rootPath(), rootDir[1])
|
|
}
|
|
if dirs[0] != "Dirs" {
|
|
t.Fatalf("Expected Dirs got %s", dirs[0])
|
|
}
|
|
if dirs[1] != "1" {
|
|
t.Fatalf("Expected 1 got %s", dirs[1])
|
|
}
|
|
}
|
|
|
|
func TestApplyDiff(t *testing.T) {
|
|
d := newDriver(t)
|
|
defer os.RemoveAll(tmp)
|
|
defer d.Cleanup()
|
|
|
|
if err := d.Create("1", "", ""); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
diffPath, err := d.Get("1")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Add a file to the diff path with a fixed size
|
|
size := int64(1024)
|
|
|
|
f, err := os.Create(path.Join(diffPath, "test_file"))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := f.Truncate(size); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
f.Close()
|
|
|
|
diff, err := d.Diff("1")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if err := d.Create("2", "", ""); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := d.Create("3", "2", ""); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if err := d.ApplyDiff("3", diff); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Ensure that the file is in the mount point for id 3
|
|
|
|
mountPoint, err := d.Get("3")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := os.Stat(path.Join(mountPoint, "test_file")); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func hash(c string) string {
|
|
h := sha256.New()
|
|
fmt.Fprint(h, c)
|
|
return hex.EncodeToString(h.Sum(nil))
|
|
}
|
|
|
|
func TestMountMoreThan42Layers(t *testing.T) {
|
|
d := newDriver(t)
|
|
defer os.RemoveAll(tmp)
|
|
defer d.Cleanup()
|
|
var last string
|
|
var expected int
|
|
|
|
for i := 1; i < 127; i++ {
|
|
expected++
|
|
var (
|
|
parent = fmt.Sprintf("%d", i-1)
|
|
current = fmt.Sprintf("%d", i)
|
|
)
|
|
|
|
if parent == "0" {
|
|
parent = ""
|
|
} else {
|
|
parent = hash(parent)
|
|
}
|
|
current = hash(current)
|
|
|
|
if err := d.Create(current, parent, ""); err != nil {
|
|
t.Logf("Current layer %d", i)
|
|
t.Fatal(err)
|
|
}
|
|
point, err := d.Get(current)
|
|
if err != nil {
|
|
t.Logf("Current layer %d", i)
|
|
t.Fatal(err)
|
|
}
|
|
f, err := os.Create(path.Join(point, current))
|
|
if err != nil {
|
|
t.Logf("Current layer %d", i)
|
|
t.Fatal(err)
|
|
}
|
|
f.Close()
|
|
|
|
if i%10 == 0 {
|
|
if err := os.Remove(path.Join(point, parent)); err != nil {
|
|
t.Logf("Current layer %d", i)
|
|
t.Fatal(err)
|
|
}
|
|
expected--
|
|
}
|
|
last = current
|
|
}
|
|
|
|
// Perform the actual mount for the top most image
|
|
point, err := d.Get(last)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
files, err := ioutil.ReadDir(point)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(files) != expected {
|
|
t.Fatalf("Expected %d got %d", expected, len(files))
|
|
}
|
|
}
|