aboutsummaryrefslogtreecommitdiffhomepage
path: root/container/initoverlay_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'container/initoverlay_test.go')
-rw-r--r--container/initoverlay_test.go231
1 files changed, 230 insertions, 1 deletions
diff --git a/container/initoverlay_test.go b/container/initoverlay_test.go
index 68377dd4..f5f0aec5 100644
--- a/container/initoverlay_test.go
+++ b/container/initoverlay_test.go
@@ -1,8 +1,237 @@
package container
-import "testing"
+import (
+ "errors"
+ "io/fs"
+ "os"
+ "testing"
+)
func TestMountOverlayOp(t *testing.T) {
+ checkOpBehaviour(t, []opBehaviourTestCase{
+ {"mkdirTemp invalid ephemeral", &Params{ParentPerm: 0705}, &MountOverlayOp{
+ Target: MustAbs("/"),
+ Lower: []*Absolute{
+ MustAbs("/var/lib/planterette/base/debian:f92c9052"),
+ MustAbs("/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052"),
+ },
+ Upper: MustAbs("/proc/"),
+ }, nil, msg.WrapErr(fs.ErrInvalid, `upperdir has unexpected value "/proc/"`), nil, nil},
+
+ {"mkdirTemp upper ephemeral", &Params{ParentPerm: 0705}, &MountOverlayOp{
+ Target: MustAbs("/"),
+ Lower: []*Absolute{
+ MustAbs("/var/lib/planterette/base/debian:f92c9052"),
+ MustAbs("/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052"),
+ },
+ Upper: MustAbs("/"),
+ }, []kexpect{
+ {"evalSymlinks", expectArgs{"/var/lib/planterette/base/debian:f92c9052"}, "/var/lib/planterette/base/debian:f92c9052", nil},
+ {"evalSymlinks", expectArgs{"/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052"}, "/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052", nil},
+ }, nil, []kexpect{
+ {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0705)}, nil, nil},
+ {"mkdirTemp", expectArgs{"/", "overlay.upper.*"}, "overlay.upper.32768", errUnique},
+ }, wrapErrSelf(errUnique)},
+
+ {"mkdirTemp work ephemeral", &Params{ParentPerm: 0705}, &MountOverlayOp{
+ Target: MustAbs("/"),
+ Lower: []*Absolute{
+ MustAbs("/var/lib/planterette/base/debian:f92c9052"),
+ MustAbs("/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052"),
+ },
+ Upper: MustAbs("/"),
+ }, []kexpect{
+ {"evalSymlinks", expectArgs{"/var/lib/planterette/base/debian:f92c9052"}, "/var/lib/planterette/base/debian:f92c9052", nil},
+ {"evalSymlinks", expectArgs{"/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052"}, "/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052", nil},
+ }, nil, []kexpect{
+ {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0705)}, nil, nil},
+ {"mkdirTemp", expectArgs{"/", "overlay.upper.*"}, "overlay.upper.32768", nil},
+ {"mkdirTemp", expectArgs{"/", "overlay.work.*"}, "overlay.work.32768", errUnique},
+ }, wrapErrSelf(errUnique)},
+
+ {"success ephemeral", &Params{ParentPerm: 0705}, &MountOverlayOp{
+ Target: MustAbs("/"),
+ Lower: []*Absolute{
+ MustAbs("/var/lib/planterette/base/debian:f92c9052"),
+ MustAbs("/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052"),
+ },
+ Upper: MustAbs("/"),
+ }, []kexpect{
+ {"evalSymlinks", expectArgs{"/var/lib/planterette/base/debian:f92c9052"}, "/var/lib/planterette/base/debian:f92c9052", nil},
+ {"evalSymlinks", expectArgs{"/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052"}, "/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052", nil},
+ }, nil, []kexpect{
+ {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0705)}, nil, nil},
+ {"mkdirTemp", expectArgs{"/", "overlay.upper.*"}, "overlay.upper.32768", nil},
+ {"mkdirTemp", expectArgs{"/", "overlay.work.*"}, "overlay.work.32768", nil},
+ {"mount", expectArgs{"overlay", "/sysroot", "overlay", uintptr(0), "" +
+ "upperdir=overlay.upper.32768," +
+ "workdir=overlay.work.32768," +
+ "lowerdir=" +
+ `/host/var/lib/planterette/base/debian\:f92c9052:` +
+ `/host/var/lib/planterette/app/org.chromium.Chromium@debian\:f92c9052,` +
+ "userxattr"}, nil, nil},
+ }, nil},
+
+ {"short lower ro", &Params{ParentPerm: 0755}, &MountOverlayOp{
+ Target: MustAbs("/nix/store"),
+ Lower: []*Absolute{
+ MustAbs("/mnt-root/nix/.ro-store"),
+ },
+ }, []kexpect{
+ {"evalSymlinks", expectArgs{"/mnt-root/nix/.ro-store"}, "/mnt-root/nix/.ro-store", nil},
+ }, nil, []kexpect{
+ {"mkdirAll", expectArgs{"/sysroot/nix/store", os.FileMode(0755)}, nil, nil},
+ }, msg.WrapErr(fs.ErrInvalid, "readonly overlay requires at least two lowerdir")},
+
+ {"success ro", &Params{ParentPerm: 0755}, &MountOverlayOp{
+ Target: MustAbs("/nix/store"),
+ Lower: []*Absolute{
+ MustAbs("/mnt-root/nix/.ro-store"),
+ MustAbs("/mnt-root/nix/.ro-store0"),
+ },
+ }, []kexpect{
+ {"evalSymlinks", expectArgs{"/mnt-root/nix/.ro-store"}, "/mnt-root/nix/.ro-store", nil},
+ {"evalSymlinks", expectArgs{"/mnt-root/nix/.ro-store0"}, "/mnt-root/nix/.ro-store0", nil},
+ }, nil, []kexpect{
+ {"mkdirAll", expectArgs{"/sysroot/nix/store", os.FileMode(0755)}, nil, nil},
+ {"mount", expectArgs{"overlay", "/sysroot/nix/store", "overlay", uintptr(0), "" +
+ "lowerdir=" +
+ "/host/mnt-root/nix/.ro-store:" +
+ "/host/mnt-root/nix/.ro-store0," +
+ "userxattr"}, nil, nil},
+ }, nil},
+
+ {"nil lower", &Params{ParentPerm: 0700}, &MountOverlayOp{
+ Target: MustAbs("/nix/store"),
+ Upper: MustAbs("/mnt-root/nix/.rw-store/upper"),
+ Work: MustAbs("/mnt-root/nix/.rw-store/work"),
+ }, []kexpect{
+ {"evalSymlinks", expectArgs{"/mnt-root/nix/.rw-store/upper"}, "/mnt-root/nix/.rw-store/.upper", nil},
+ {"evalSymlinks", expectArgs{"/mnt-root/nix/.rw-store/work"}, "/mnt-root/nix/.rw-store/.work", nil},
+ }, nil, []kexpect{
+ {"mkdirAll", expectArgs{"/sysroot/nix/store", os.FileMode(0700)}, nil, nil},
+ }, msg.WrapErr(fs.ErrInvalid, "overlay requires at least one lowerdir")},
+
+ {"evalSymlinks upper", &Params{ParentPerm: 0700}, &MountOverlayOp{
+ Target: MustAbs("/nix/store"),
+ Lower: []*Absolute{MustAbs("/mnt-root/nix/.ro-store")},
+ Upper: MustAbs("/mnt-root/nix/.rw-store/upper"),
+ Work: MustAbs("/mnt-root/nix/.rw-store/work"),
+ }, []kexpect{
+ {"evalSymlinks", expectArgs{"/mnt-root/nix/.rw-store/upper"}, "/mnt-root/nix/.rw-store/.upper", errUnique},
+ }, wrapErrSelf(errUnique), nil, nil},
+
+ {"evalSymlinks work", &Params{ParentPerm: 0700}, &MountOverlayOp{
+ Target: MustAbs("/nix/store"),
+ Lower: []*Absolute{MustAbs("/mnt-root/nix/.ro-store")},
+ Upper: MustAbs("/mnt-root/nix/.rw-store/upper"),
+ Work: MustAbs("/mnt-root/nix/.rw-store/work"),
+ }, []kexpect{
+ {"evalSymlinks", expectArgs{"/mnt-root/nix/.rw-store/upper"}, "/mnt-root/nix/.rw-store/.upper", nil},
+ {"evalSymlinks", expectArgs{"/mnt-root/nix/.rw-store/work"}, "/mnt-root/nix/.rw-store/.work", errUnique},
+ }, wrapErrSelf(errUnique), nil, nil},
+
+ {"evalSymlinks lower", &Params{ParentPerm: 0700}, &MountOverlayOp{
+ Target: MustAbs("/nix/store"),
+ Lower: []*Absolute{MustAbs("/mnt-root/nix/.ro-store")},
+ Upper: MustAbs("/mnt-root/nix/.rw-store/upper"),
+ Work: MustAbs("/mnt-root/nix/.rw-store/work"),
+ }, []kexpect{
+ {"evalSymlinks", expectArgs{"/mnt-root/nix/.rw-store/upper"}, "/mnt-root/nix/.rw-store/.upper", nil},
+ {"evalSymlinks", expectArgs{"/mnt-root/nix/.rw-store/work"}, "/mnt-root/nix/.rw-store/.work", nil},
+ {"evalSymlinks", expectArgs{"/mnt-root/nix/.ro-store"}, "/mnt-root/nix/ro-store", errUnique},
+ }, wrapErrSelf(errUnique), nil, nil},
+
+ {"mkdirAll", &Params{ParentPerm: 0700}, &MountOverlayOp{
+ Target: MustAbs("/nix/store"),
+ Lower: []*Absolute{MustAbs("/mnt-root/nix/.ro-store")},
+ Upper: MustAbs("/mnt-root/nix/.rw-store/upper"),
+ Work: MustAbs("/mnt-root/nix/.rw-store/work"),
+ }, []kexpect{
+ {"evalSymlinks", expectArgs{"/mnt-root/nix/.rw-store/upper"}, "/mnt-root/nix/.rw-store/.upper", nil},
+ {"evalSymlinks", expectArgs{"/mnt-root/nix/.rw-store/work"}, "/mnt-root/nix/.rw-store/.work", nil},
+ {"evalSymlinks", expectArgs{"/mnt-root/nix/.ro-store"}, "/mnt-root/nix/ro-store", nil},
+ }, nil, []kexpect{
+ {"mkdirAll", expectArgs{"/sysroot/nix/store", os.FileMode(0700)}, nil, errUnique},
+ }, wrapErrSelf(errUnique)},
+
+ {"mount", &Params{ParentPerm: 0700}, &MountOverlayOp{
+ Target: MustAbs("/nix/store"),
+ Lower: []*Absolute{MustAbs("/mnt-root/nix/.ro-store")},
+ Upper: MustAbs("/mnt-root/nix/.rw-store/upper"),
+ Work: MustAbs("/mnt-root/nix/.rw-store/work"),
+ }, []kexpect{
+ {"evalSymlinks", expectArgs{"/mnt-root/nix/.rw-store/upper"}, "/mnt-root/nix/.rw-store/.upper", nil},
+ {"evalSymlinks", expectArgs{"/mnt-root/nix/.rw-store/work"}, "/mnt-root/nix/.rw-store/.work", nil},
+ {"evalSymlinks", expectArgs{"/mnt-root/nix/.ro-store"}, "/mnt-root/nix/ro-store", nil},
+ }, nil, []kexpect{
+ {"mkdirAll", expectArgs{"/sysroot/nix/store", os.FileMode(0700)}, nil, nil},
+ {"mount", expectArgs{"overlay", "/sysroot/nix/store", "overlay", uintptr(0), "upperdir=/host/mnt-root/nix/.rw-store/.upper,workdir=/host/mnt-root/nix/.rw-store/.work,lowerdir=/host/mnt-root/nix/ro-store,userxattr"}, nil, errUnique},
+ }, wrapErrSuffix(errUnique, `cannot mount overlay on "/nix/store":`)},
+
+ {"success single layer", &Params{ParentPerm: 0700}, &MountOverlayOp{
+ Target: MustAbs("/nix/store"),
+ Lower: []*Absolute{MustAbs("/mnt-root/nix/.ro-store")},
+ Upper: MustAbs("/mnt-root/nix/.rw-store/upper"),
+ Work: MustAbs("/mnt-root/nix/.rw-store/work"),
+ }, []kexpect{
+ {"evalSymlinks", expectArgs{"/mnt-root/nix/.rw-store/upper"}, "/mnt-root/nix/.rw-store/.upper", nil},
+ {"evalSymlinks", expectArgs{"/mnt-root/nix/.rw-store/work"}, "/mnt-root/nix/.rw-store/.work", nil},
+ {"evalSymlinks", expectArgs{"/mnt-root/nix/.ro-store"}, "/mnt-root/nix/ro-store", nil},
+ }, nil, []kexpect{
+ {"mkdirAll", expectArgs{"/sysroot/nix/store", os.FileMode(0700)}, nil, nil},
+ {"mount", expectArgs{"overlay", "/sysroot/nix/store", "overlay", uintptr(0), "" +
+ "upperdir=/host/mnt-root/nix/.rw-store/.upper," +
+ "workdir=/host/mnt-root/nix/.rw-store/.work," +
+ "lowerdir=/host/mnt-root/nix/ro-store," +
+ "userxattr"}, nil, nil},
+ }, nil},
+
+ {"success", &Params{ParentPerm: 0700}, &MountOverlayOp{
+ Target: MustAbs("/nix/store"),
+ Lower: []*Absolute{
+ MustAbs("/mnt-root/nix/.ro-store"),
+ MustAbs("/mnt-root/nix/.ro-store0"),
+ MustAbs("/mnt-root/nix/.ro-store1"),
+ MustAbs("/mnt-root/nix/.ro-store2"),
+ MustAbs("/mnt-root/nix/.ro-store3"),
+ },
+ Upper: MustAbs("/mnt-root/nix/.rw-store/upper"),
+ Work: MustAbs("/mnt-root/nix/.rw-store/work"),
+ }, []kexpect{
+ {"evalSymlinks", expectArgs{"/mnt-root/nix/.rw-store/upper"}, "/mnt-root/nix/.rw-store/.upper", nil},
+ {"evalSymlinks", expectArgs{"/mnt-root/nix/.rw-store/work"}, "/mnt-root/nix/.rw-store/.work", nil},
+ {"evalSymlinks", expectArgs{"/mnt-root/nix/.ro-store"}, "/mnt-root/nix/ro-store", nil},
+ {"evalSymlinks", expectArgs{"/mnt-root/nix/.ro-store0"}, "/mnt-root/nix/ro-store0", nil},
+ {"evalSymlinks", expectArgs{"/mnt-root/nix/.ro-store1"}, "/mnt-root/nix/ro-store1", nil},
+ {"evalSymlinks", expectArgs{"/mnt-root/nix/.ro-store2"}, "/mnt-root/nix/ro-store2", nil},
+ {"evalSymlinks", expectArgs{"/mnt-root/nix/.ro-store3"}, "/mnt-root/nix/ro-store3", nil},
+ }, nil, []kexpect{
+ {"mkdirAll", expectArgs{"/sysroot/nix/store", os.FileMode(0700)}, nil, nil},
+ {"mount", expectArgs{"overlay", "/sysroot/nix/store", "overlay", uintptr(0), "" +
+ "upperdir=/host/mnt-root/nix/.rw-store/.upper," +
+ "workdir=/host/mnt-root/nix/.rw-store/.work," +
+ "lowerdir=" +
+ "/host/mnt-root/nix/ro-store:" +
+ "/host/mnt-root/nix/ro-store0:" +
+ "/host/mnt-root/nix/ro-store1:" +
+ "/host/mnt-root/nix/ro-store2:" +
+ "/host/mnt-root/nix/ro-store3," +
+ "userxattr"}, nil, nil},
+ }, nil},
+ })
+
+ t.Run("unreachable", func(t *testing.T) {
+ t.Run("nil Upper non-nil Work not ephemeral", func(t *testing.T) {
+ wantErr := msg.WrapErr(fs.ErrClosed, "impossible overlay state reached")
+ if err := (&MountOverlayOp{
+ Work: MustAbs("/"),
+ }).early(nil, nil); !errors.Is(err, wantErr) {
+ t.Errorf("apply: error = %v, want %v", err, wantErr)
+ }
+ })
+ })
+
checkOpsValid(t, []opValidTestCase{
{"nil", (*MountOverlayOp)(nil), false},
{"zero", new(MountOverlayOp), false},