container/check: move absolute pathname
All checks were successful
Test / Create distribution (push) Successful in 34s
Test / Hpkg (push) Successful in 4m3s
Test / Sandbox (race detector) (push) Successful in 4m26s
Test / Hakurei (race detector) (push) Successful in 5m19s
Test / Sandbox (push) Successful in 1m28s
Test / Hakurei (push) Successful in 2m16s
Test / Flake checks (push) Successful in 1m37s
All checks were successful
Test / Create distribution (push) Successful in 34s
Test / Hpkg (push) Successful in 4m3s
Test / Sandbox (race detector) (push) Successful in 4m26s
Test / Hakurei (race detector) (push) Successful in 5m19s
Test / Sandbox (push) Successful in 1m28s
Test / Hakurei (push) Successful in 2m16s
Test / Flake checks (push) Successful in 1m37s
This allows use of absolute pathname values without importing container. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
@@ -3,13 +3,15 @@ package container
|
||||
import (
|
||||
"encoding/gob"
|
||||
"fmt"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
)
|
||||
|
||||
func init() { gob.Register(new(AutoEtcOp)) }
|
||||
|
||||
// Etc appends an [Op] that expands host /etc into a toplevel symlink mirror with /etc semantics.
|
||||
// This is not a generic setup op. It is implemented here to reduce ipc overhead.
|
||||
func (f *Ops) Etc(host *Absolute, prefix string) *Ops {
|
||||
func (f *Ops) Etc(host *check.Absolute, prefix string) *Ops {
|
||||
e := &AutoEtcOp{prefix}
|
||||
f.Mkdir(AbsFHSEtc, 0755)
|
||||
f.Bind(host, e.hostPath(), 0)
|
||||
@@ -57,8 +59,8 @@ func (e *AutoEtcOp) apply(state *setupState, k syscallDispatcher) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *AutoEtcOp) hostPath() *Absolute { return AbsFHSEtc.Append(e.hostRel()) }
|
||||
func (e *AutoEtcOp) hostRel() string { return ".host/" + e.Prefix }
|
||||
func (e *AutoEtcOp) hostPath() *check.Absolute { return AbsFHSEtc.Append(e.hostRel()) }
|
||||
func (e *AutoEtcOp) hostRel() string { return ".host/" + e.Prefix }
|
||||
|
||||
func (e *AutoEtcOp) Is(op Op) bool {
|
||||
ve, ok := op.(*AutoEtcOp)
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/stub"
|
||||
)
|
||||
|
||||
@@ -256,11 +257,11 @@ func TestAutoEtcOp(t *testing.T) {
|
||||
})
|
||||
|
||||
checkOpsBuilder(t, []opsBuilderTestCase{
|
||||
{"pd", new(Ops).Etc(MustAbs("/etc/"), "048090b6ed8f9ebb10e275ff5d8c0659"), Ops{
|
||||
&MkdirOp{Path: MustAbs("/etc/"), Perm: 0755},
|
||||
{"pd", new(Ops).Etc(check.MustAbs("/etc/"), "048090b6ed8f9ebb10e275ff5d8c0659"), Ops{
|
||||
&MkdirOp{Path: check.MustAbs("/etc/"), Perm: 0755},
|
||||
&BindMountOp{
|
||||
Source: MustAbs("/etc/"),
|
||||
Target: MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
Source: check.MustAbs("/etc/"),
|
||||
Target: check.MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
},
|
||||
&AutoEtcOp{Prefix: "048090b6ed8f9ebb10e275ff5d8c0659"},
|
||||
}},
|
||||
|
||||
@@ -3,19 +3,21 @@ package container
|
||||
import (
|
||||
"encoding/gob"
|
||||
"fmt"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
)
|
||||
|
||||
func init() { gob.Register(new(AutoRootOp)) }
|
||||
|
||||
// Root appends an [Op] that expands a directory into a toplevel bind mount mirror on container root.
|
||||
// This is not a generic setup op. It is implemented here to reduce ipc overhead.
|
||||
func (f *Ops) Root(host *Absolute, flags int) *Ops {
|
||||
func (f *Ops) Root(host *check.Absolute, flags int) *Ops {
|
||||
*f = append(*f, &AutoRootOp{host, flags, nil})
|
||||
return f
|
||||
}
|
||||
|
||||
type AutoRootOp struct {
|
||||
Host *Absolute
|
||||
Host *check.Absolute
|
||||
// passed through to bindMount
|
||||
Flags int
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/stub"
|
||||
)
|
||||
|
||||
@@ -18,14 +19,14 @@ func TestAutoRootOp(t *testing.T) {
|
||||
|
||||
checkOpBehaviour(t, []opBehaviourTestCase{
|
||||
{"readdir", &Params{ParentPerm: 0750}, &AutoRootOp{
|
||||
Host: MustAbs("/"),
|
||||
Host: check.MustAbs("/"),
|
||||
Flags: BindWritable,
|
||||
}, []stub.Call{
|
||||
call("readdir", stub.ExpectArgs{"/"}, stubDir(), stub.UniqueError(2)),
|
||||
}, stub.UniqueError(2), nil, nil},
|
||||
|
||||
{"early", &Params{ParentPerm: 0750}, &AutoRootOp{
|
||||
Host: MustAbs("/"),
|
||||
Host: check.MustAbs("/"),
|
||||
Flags: BindWritable,
|
||||
}, []stub.Call{
|
||||
call("readdir", stub.ExpectArgs{"/"}, stubDir("bin", "dev", "etc", "home", "lib64",
|
||||
@@ -34,7 +35,7 @@ func TestAutoRootOp(t *testing.T) {
|
||||
}, stub.UniqueError(1), nil, nil},
|
||||
|
||||
{"apply", &Params{ParentPerm: 0750}, &AutoRootOp{
|
||||
Host: MustAbs("/"),
|
||||
Host: check.MustAbs("/"),
|
||||
Flags: BindWritable,
|
||||
}, []stub.Call{
|
||||
call("readdir", stub.ExpectArgs{"/"}, stubDir("bin", "dev", "etc", "home", "lib64",
|
||||
@@ -55,7 +56,7 @@ func TestAutoRootOp(t *testing.T) {
|
||||
}, stub.UniqueError(0)},
|
||||
|
||||
{"success pd", &Params{ParentPerm: 0750}, &AutoRootOp{
|
||||
Host: MustAbs("/"),
|
||||
Host: check.MustAbs("/"),
|
||||
Flags: BindWritable,
|
||||
}, []stub.Call{
|
||||
call("readdir", stub.ExpectArgs{"/"}, stubDir("bin", "dev", "etc", "home", "lib64",
|
||||
@@ -86,7 +87,7 @@ func TestAutoRootOp(t *testing.T) {
|
||||
}, nil},
|
||||
|
||||
{"success", &Params{ParentPerm: 0750}, &AutoRootOp{
|
||||
Host: MustAbs("/var/lib/planterette/base/debian:f92c9052"),
|
||||
Host: check.MustAbs("/var/lib/planterette/base/debian:f92c9052"),
|
||||
}, []stub.Call{
|
||||
call("readdir", stub.ExpectArgs{"/var/lib/planterette/base/debian:f92c9052"}, stubDir("bin", "dev", "etc", "home", "lib64",
|
||||
"lost+found", "mnt", "nix", "proc", "root", "run", "srv", "sys", "tmp", "usr", "var"), nil),
|
||||
@@ -119,13 +120,13 @@ func TestAutoRootOp(t *testing.T) {
|
||||
checkOpsValid(t, []opValidTestCase{
|
||||
{"nil", (*AutoRootOp)(nil), false},
|
||||
{"zero", new(AutoRootOp), false},
|
||||
{"valid", &AutoRootOp{Host: MustAbs("/")}, true},
|
||||
{"valid", &AutoRootOp{Host: check.MustAbs("/")}, true},
|
||||
})
|
||||
|
||||
checkOpsBuilder(t, []opsBuilderTestCase{
|
||||
{"pd", new(Ops).Root(MustAbs("/"), BindWritable), Ops{
|
||||
{"pd", new(Ops).Root(check.MustAbs("/"), BindWritable), Ops{
|
||||
&AutoRootOp{
|
||||
Host: MustAbs("/"),
|
||||
Host: check.MustAbs("/"),
|
||||
Flags: BindWritable,
|
||||
},
|
||||
}},
|
||||
@@ -135,42 +136,42 @@ func TestAutoRootOp(t *testing.T) {
|
||||
{"zero", new(AutoRootOp), new(AutoRootOp), false},
|
||||
|
||||
{"internal ne", &AutoRootOp{
|
||||
Host: MustAbs("/"),
|
||||
Host: check.MustAbs("/"),
|
||||
Flags: BindWritable,
|
||||
}, &AutoRootOp{
|
||||
Host: MustAbs("/"),
|
||||
Host: check.MustAbs("/"),
|
||||
Flags: BindWritable,
|
||||
resolved: []*BindMountOp{new(BindMountOp)},
|
||||
}, true},
|
||||
|
||||
{"flags differs", &AutoRootOp{
|
||||
Host: MustAbs("/"),
|
||||
Host: check.MustAbs("/"),
|
||||
Flags: BindWritable | BindDevice,
|
||||
}, &AutoRootOp{
|
||||
Host: MustAbs("/"),
|
||||
Host: check.MustAbs("/"),
|
||||
Flags: BindWritable,
|
||||
}, false},
|
||||
|
||||
{"host differs", &AutoRootOp{
|
||||
Host: MustAbs("/tmp/"),
|
||||
Host: check.MustAbs("/tmp/"),
|
||||
Flags: BindWritable,
|
||||
}, &AutoRootOp{
|
||||
Host: MustAbs("/"),
|
||||
Host: check.MustAbs("/"),
|
||||
Flags: BindWritable,
|
||||
}, false},
|
||||
|
||||
{"equals", &AutoRootOp{
|
||||
Host: MustAbs("/"),
|
||||
Host: check.MustAbs("/"),
|
||||
Flags: BindWritable,
|
||||
}, &AutoRootOp{
|
||||
Host: MustAbs("/"),
|
||||
Host: check.MustAbs("/"),
|
||||
Flags: BindWritable,
|
||||
}, true},
|
||||
})
|
||||
|
||||
checkOpMeta(t, []opMetaTestCase{
|
||||
{"root", &AutoRootOp{
|
||||
Host: MustAbs("/"),
|
||||
Host: check.MustAbs("/"),
|
||||
Flags: BindWritable,
|
||||
}, "setting up", `auto root "/" flags 0x2`},
|
||||
})
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
package container
|
||||
// Package check provides types yielding values checked to meet a condition.
|
||||
package check
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
@@ -11,9 +12,7 @@ import (
|
||||
)
|
||||
|
||||
// AbsoluteError is returned by [NewAbs] and holds the invalid pathname.
|
||||
type AbsoluteError struct {
|
||||
Pathname string
|
||||
}
|
||||
type AbsoluteError struct{ Pathname string }
|
||||
|
||||
func (e *AbsoluteError) Error() string { return fmt.Sprintf("path %q is not absolute", e.Pathname) }
|
||||
func (e *AbsoluteError) Is(target error) bool {
|
||||
@@ -25,15 +24,13 @@ func (e *AbsoluteError) Is(target error) bool {
|
||||
}
|
||||
|
||||
// Absolute holds a pathname checked to be absolute.
|
||||
type Absolute struct {
|
||||
pathname string
|
||||
}
|
||||
type Absolute struct{ pathname string }
|
||||
|
||||
// isAbs wraps [path.IsAbs] in case additional checks are added in the future.
|
||||
func isAbs(pathname string) bool { return path.IsAbs(pathname) }
|
||||
// unsafeAbs returns [check.Absolute] on any string value.
|
||||
func unsafeAbs(pathname string) *Absolute { return &Absolute{pathname} }
|
||||
|
||||
func (a *Absolute) String() string {
|
||||
if a.pathname == zeroString {
|
||||
if a.pathname == "" {
|
||||
panic("attempted use of zero Absolute")
|
||||
}
|
||||
return a.pathname
|
||||
@@ -44,16 +41,16 @@ func (a *Absolute) Is(v *Absolute) bool {
|
||||
return true
|
||||
}
|
||||
return a != nil && v != nil &&
|
||||
a.pathname != zeroString && v.pathname != zeroString &&
|
||||
a.pathname != "" && v.pathname != "" &&
|
||||
a.pathname == v.pathname
|
||||
}
|
||||
|
||||
// NewAbs checks pathname and returns a new [Absolute] if pathname is absolute.
|
||||
func NewAbs(pathname string) (*Absolute, error) {
|
||||
if !isAbs(pathname) {
|
||||
if !path.IsAbs(pathname) {
|
||||
return nil, &AbsoluteError{pathname}
|
||||
}
|
||||
return &Absolute{pathname}, nil
|
||||
return unsafeAbs(pathname), nil
|
||||
}
|
||||
|
||||
// MustAbs calls [NewAbs] and panics on error.
|
||||
@@ -67,16 +64,16 @@ func MustAbs(pathname string) *Absolute {
|
||||
|
||||
// Append calls [path.Join] with [Absolute] as the first element.
|
||||
func (a *Absolute) Append(elem ...string) *Absolute {
|
||||
return &Absolute{path.Join(append([]string{a.String()}, elem...)...)}
|
||||
return unsafeAbs(path.Join(append([]string{a.String()}, elem...)...))
|
||||
}
|
||||
|
||||
// Dir calls [path.Dir] with [Absolute] as its argument.
|
||||
func (a *Absolute) Dir() *Absolute { return &Absolute{path.Dir(a.String())} }
|
||||
func (a *Absolute) Dir() *Absolute { return unsafeAbs(path.Dir(a.String())) }
|
||||
|
||||
func (a *Absolute) GobEncode() ([]byte, error) { return []byte(a.String()), nil }
|
||||
func (a *Absolute) GobDecode(data []byte) error {
|
||||
pathname := string(data)
|
||||
if !isAbs(pathname) {
|
||||
if !path.IsAbs(pathname) {
|
||||
return &AbsoluteError{pathname}
|
||||
}
|
||||
a.pathname = pathname
|
||||
@@ -89,7 +86,7 @@ func (a *Absolute) UnmarshalJSON(data []byte) error {
|
||||
if err := json.Unmarshal(data, &pathname); err != nil {
|
||||
return err
|
||||
}
|
||||
if !isAbs(pathname) {
|
||||
if !path.IsAbs(pathname) {
|
||||
return &AbsoluteError{pathname}
|
||||
}
|
||||
a.pathname = pathname
|
||||
@@ -1,4 +1,4 @@
|
||||
package container
|
||||
package check_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@@ -9,8 +9,14 @@ import (
|
||||
"strings"
|
||||
"syscall"
|
||||
"testing"
|
||||
_ "unsafe"
|
||||
|
||||
. "hakurei.app/container/check"
|
||||
)
|
||||
|
||||
//go:linkname unsafeAbs hakurei.app/container/check.unsafeAbs
|
||||
func unsafeAbs(_ string) *Absolute
|
||||
|
||||
func TestAbsoluteError(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
@@ -80,7 +86,7 @@ func TestNewAbs(t *testing.T) {
|
||||
func TestAbsoluteString(t *testing.T) {
|
||||
t.Run("passthrough", func(t *testing.T) {
|
||||
pathname := "/etc"
|
||||
if got := (&Absolute{pathname}).String(); got != pathname {
|
||||
if got := unsafeAbs(pathname).String(); got != pathname {
|
||||
t.Errorf("String: %q, want %q", got, pathname)
|
||||
}
|
||||
})
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
"time"
|
||||
|
||||
"hakurei.app/container/bits"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/seccomp"
|
||||
)
|
||||
|
||||
@@ -57,11 +58,11 @@ type (
|
||||
// Params holds container configuration and is safe to serialise.
|
||||
Params struct {
|
||||
// Working directory in the container.
|
||||
Dir *Absolute
|
||||
Dir *check.Absolute
|
||||
// Initial process environment.
|
||||
Env []string
|
||||
// Pathname of initial process in the container.
|
||||
Path *Absolute
|
||||
Path *check.Absolute
|
||||
// Initial process argv.
|
||||
Args []string
|
||||
// Deliver SIGINT to the initial process on context cancellation.
|
||||
@@ -407,7 +408,7 @@ func New(ctx context.Context, msg Msg) *Container {
|
||||
}
|
||||
|
||||
// NewCommand calls [New] and initialises the [Params.Path] and [Params.Args] fields.
|
||||
func NewCommand(ctx context.Context, msg Msg, pathname *Absolute, name string, args ...string) *Container {
|
||||
func NewCommand(ctx context.Context, msg Msg, pathname *check.Absolute, name string, args ...string) *Container {
|
||||
z := New(ctx, msg)
|
||||
z.Path = pathname
|
||||
z.Args = append([]string{name}, args...)
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
"hakurei.app/command"
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/bits"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/seccomp"
|
||||
"hakurei.app/container/vfs"
|
||||
"hakurei.app/hst"
|
||||
@@ -226,7 +227,7 @@ var containerTestCases = []struct {
|
||||
|
||||
{"dev", true, true /* go test output is not a tty */, false, false,
|
||||
earlyOps(new(container.Ops).
|
||||
Dev(container.MustAbs("/dev"), true),
|
||||
Dev(check.MustAbs("/dev"), true),
|
||||
),
|
||||
earlyMnt(
|
||||
ent("/", "/dev", "ro,nosuid,nodev,relatime", "tmpfs", "devtmpfs", ignore),
|
||||
@@ -244,7 +245,7 @@ var containerTestCases = []struct {
|
||||
|
||||
{"dev no mqueue", true, true /* go test output is not a tty */, false, false,
|
||||
earlyOps(new(container.Ops).
|
||||
Dev(container.MustAbs("/dev"), false),
|
||||
Dev(check.MustAbs("/dev"), false),
|
||||
),
|
||||
earlyMnt(
|
||||
ent("/", "/dev", "ro,nosuid,nodev,relatime", "tmpfs", "devtmpfs", ignore),
|
||||
@@ -261,13 +262,13 @@ var containerTestCases = []struct {
|
||||
|
||||
{"overlay", true, false, false, true,
|
||||
func(t *testing.T) (*container.Ops, context.Context) {
|
||||
tempDir := container.MustAbs(t.TempDir())
|
||||
tempDir := check.MustAbs(t.TempDir())
|
||||
lower0, lower1, upper, work :=
|
||||
tempDir.Append("lower0"),
|
||||
tempDir.Append("lower1"),
|
||||
tempDir.Append("upper"),
|
||||
tempDir.Append("work")
|
||||
for _, a := range []*container.Absolute{lower0, lower1, upper, work} {
|
||||
for _, a := range []*check.Absolute{lower0, lower1, upper, work} {
|
||||
if err := os.Mkdir(a.String(), 0755); err != nil {
|
||||
t.Fatalf("Mkdir: error = %v", err)
|
||||
}
|
||||
@@ -285,12 +286,12 @@ var containerTestCases = []struct {
|
||||
return []*vfs.MountInfoEntry{
|
||||
ent("/", hst.Tmp, "rw", "overlay", "overlay",
|
||||
"rw,lowerdir="+
|
||||
container.InternalToHostOvlEscape(ctx.Value(testVal("lower0")).(*container.Absolute).String())+":"+
|
||||
container.InternalToHostOvlEscape(ctx.Value(testVal("lower1")).(*container.Absolute).String())+
|
||||
container.InternalToHostOvlEscape(ctx.Value(testVal("lower0")).(*check.Absolute).String())+":"+
|
||||
container.InternalToHostOvlEscape(ctx.Value(testVal("lower1")).(*check.Absolute).String())+
|
||||
",upperdir="+
|
||||
container.InternalToHostOvlEscape(ctx.Value(testVal("upper")).(*container.Absolute).String())+
|
||||
container.InternalToHostOvlEscape(ctx.Value(testVal("upper")).(*check.Absolute).String())+
|
||||
",workdir="+
|
||||
container.InternalToHostOvlEscape(ctx.Value(testVal("work")).(*container.Absolute).String())+
|
||||
container.InternalToHostOvlEscape(ctx.Value(testVal("work")).(*check.Absolute).String())+
|
||||
",redirect_dir=nofollow,uuid=on,userxattr"),
|
||||
}
|
||||
},
|
||||
@@ -298,11 +299,11 @@ var containerTestCases = []struct {
|
||||
|
||||
{"overlay ephemeral", true, false, false, true,
|
||||
func(t *testing.T) (*container.Ops, context.Context) {
|
||||
tempDir := container.MustAbs(t.TempDir())
|
||||
tempDir := check.MustAbs(t.TempDir())
|
||||
lower0, lower1 :=
|
||||
tempDir.Append("lower0"),
|
||||
tempDir.Append("lower1")
|
||||
for _, a := range []*container.Absolute{lower0, lower1} {
|
||||
for _, a := range []*check.Absolute{lower0, lower1} {
|
||||
if err := os.Mkdir(a.String(), 0755); err != nil {
|
||||
t.Fatalf("Mkdir: error = %v", err)
|
||||
}
|
||||
@@ -322,11 +323,11 @@ var containerTestCases = []struct {
|
||||
|
||||
{"overlay readonly", true, false, false, true,
|
||||
func(t *testing.T) (*container.Ops, context.Context) {
|
||||
tempDir := container.MustAbs(t.TempDir())
|
||||
tempDir := check.MustAbs(t.TempDir())
|
||||
lower0, lower1 :=
|
||||
tempDir.Append("lower0"),
|
||||
tempDir.Append("lower1")
|
||||
for _, a := range []*container.Absolute{lower0, lower1} {
|
||||
for _, a := range []*check.Absolute{lower0, lower1} {
|
||||
if err := os.Mkdir(a.String(), 0755); err != nil {
|
||||
t.Fatalf("Mkdir: error = %v", err)
|
||||
}
|
||||
@@ -341,8 +342,8 @@ var containerTestCases = []struct {
|
||||
return []*vfs.MountInfoEntry{
|
||||
ent("/", hst.Tmp, "rw", "overlay", "overlay",
|
||||
"ro,lowerdir="+
|
||||
container.InternalToHostOvlEscape(ctx.Value(testVal("lower0")).(*container.Absolute).String())+":"+
|
||||
container.InternalToHostOvlEscape(ctx.Value(testVal("lower1")).(*container.Absolute).String())+
|
||||
container.InternalToHostOvlEscape(ctx.Value(testVal("lower0")).(*check.Absolute).String())+":"+
|
||||
container.InternalToHostOvlEscape(ctx.Value(testVal("lower1")).(*check.Absolute).String())+
|
||||
",redirect_dir=nofollow,userxattr"),
|
||||
}
|
||||
},
|
||||
@@ -389,7 +390,7 @@ func TestContainer(t *testing.T) {
|
||||
ctx, cancel := context.WithTimeout(t.Context(), helperDefaultTimeout)
|
||||
defer cancel()
|
||||
|
||||
var libPaths []*container.Absolute
|
||||
var libPaths []*check.Absolute
|
||||
c := helperNewContainerLibPaths(ctx, &libPaths, "container", strconv.Itoa(i))
|
||||
c.Uid = tc.uid
|
||||
c.Gid = tc.gid
|
||||
@@ -410,11 +411,11 @@ func TestContainer(t *testing.T) {
|
||||
c.HostNet = tc.net
|
||||
|
||||
c.
|
||||
Readonly(container.MustAbs(pathReadonly), 0755).
|
||||
Tmpfs(container.MustAbs("/tmp"), 0, 0755).
|
||||
Place(container.MustAbs("/etc/hostname"), []byte(c.Hostname))
|
||||
Readonly(check.MustAbs(pathReadonly), 0755).
|
||||
Tmpfs(check.MustAbs("/tmp"), 0, 0755).
|
||||
Place(check.MustAbs("/etc/hostname"), []byte(c.Hostname))
|
||||
// needs /proc to check mountinfo
|
||||
c.Proc(container.MustAbs("/proc"))
|
||||
c.Proc(check.MustAbs("/proc"))
|
||||
|
||||
// mountinfo cannot be resolved directly by helper due to libPaths nondeterminism
|
||||
mnt := make([]*vfs.MountInfoEntry, 0, 3+len(libPaths))
|
||||
@@ -445,10 +446,10 @@ func TestContainer(t *testing.T) {
|
||||
_, _ = output.WriteTo(os.Stdout)
|
||||
t.Fatalf("cannot serialise expected mount points: %v", err)
|
||||
}
|
||||
c.Place(container.MustAbs(pathWantMnt), want.Bytes())
|
||||
c.Place(check.MustAbs(pathWantMnt), want.Bytes())
|
||||
|
||||
if tc.ro {
|
||||
c.Remount(container.MustAbs("/"), syscall.MS_RDONLY)
|
||||
c.Remount(check.MustAbs("/"), syscall.MS_RDONLY)
|
||||
}
|
||||
|
||||
if err := c.Start(); err != nil {
|
||||
@@ -545,7 +546,7 @@ func testContainerCancel(
|
||||
|
||||
func TestContainerString(t *testing.T) {
|
||||
msg := container.NewMsg(nil)
|
||||
c := container.NewCommand(t.Context(), msg, container.MustAbs("/run/current-system/sw/bin/ldd"), "ldd", "/usr/bin/env")
|
||||
c := container.NewCommand(t.Context(), msg, check.MustAbs("/run/current-system/sw/bin/ldd"), "ldd", "/usr/bin/env")
|
||||
c.SeccompFlags |= seccomp.AllowMultiarch
|
||||
c.SeccompRules = seccomp.Preset(
|
||||
bits.PresetExt|bits.PresetDenyNS|bits.PresetDenyTTY,
|
||||
@@ -681,7 +682,7 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
absHelperInnerPath = container.MustAbs(helperInnerPath)
|
||||
absHelperInnerPath = check.MustAbs(helperInnerPath)
|
||||
)
|
||||
|
||||
var helperCommands []func(c command.Command)
|
||||
@@ -709,11 +710,11 @@ func TestMain(m *testing.M) {
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
|
||||
func helperNewContainerLibPaths(ctx context.Context, libPaths *[]*container.Absolute, args ...string) (c *container.Container) {
|
||||
func helperNewContainerLibPaths(ctx context.Context, libPaths *[]*check.Absolute, args ...string) (c *container.Container) {
|
||||
msg := container.NewMsg(nil)
|
||||
c = container.NewCommand(ctx, msg, absHelperInnerPath, "helper", args...)
|
||||
c.Env = append(c.Env, envDoCheck+"=1")
|
||||
c.Bind(container.MustAbs(os.Args[0]), absHelperInnerPath, 0)
|
||||
c.Bind(check.MustAbs(os.Args[0]), absHelperInnerPath, 0)
|
||||
|
||||
// in case test has cgo enabled
|
||||
if entries, err := ldd.Exec(ctx, msg, os.Args[0]); err != nil {
|
||||
@@ -729,5 +730,5 @@ func helperNewContainerLibPaths(ctx context.Context, libPaths *[]*container.Abso
|
||||
}
|
||||
|
||||
func helperNewContainer(ctx context.Context, args ...string) (c *container.Container) {
|
||||
return helperNewContainerLibPaths(ctx, new([]*container.Absolute), args...)
|
||||
return helperNewContainerLibPaths(ctx, new([]*check.Absolute), args...)
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"os"
|
||||
"syscall"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/vfs"
|
||||
)
|
||||
|
||||
@@ -16,7 +17,7 @@ func messageFromError(err error) (string, bool) {
|
||||
if m, ok := messagePrefixP[os.PathError]("cannot ", err); ok {
|
||||
return m, ok
|
||||
}
|
||||
if m, ok := messagePrefixP[AbsoluteError]("", err); ok {
|
||||
if m, ok := messagePrefixP[check.AbsoluteError]("", err); ok {
|
||||
return m, ok
|
||||
}
|
||||
if m, ok := messagePrefix[OpRepeatError]("", err); ok {
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"syscall"
|
||||
"testing"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/stub"
|
||||
"hakurei.app/container/vfs"
|
||||
)
|
||||
@@ -34,7 +35,7 @@ func TestMessageFromError(t *testing.T) {
|
||||
Err: stub.UniqueError(0xdeadbeef),
|
||||
}, "cannot mount /sysroot: unique error 3735928559 injected by the test suite", true},
|
||||
|
||||
{"absolute", &AbsoluteError{"etc/mtab"},
|
||||
{"absolute", &check.AbsoluteError{Pathname: "etc/mtab"},
|
||||
`path "etc/mtab" is not absolute`, true},
|
||||
|
||||
{"repeat", OpRepeatError("autoetc"),
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"time"
|
||||
|
||||
"hakurei.app/container/bits"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/seccomp"
|
||||
"hakurei.app/container/stub"
|
||||
)
|
||||
@@ -58,9 +59,9 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
@@ -82,9 +83,9 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
@@ -110,9 +111,9 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
@@ -139,9 +140,9 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
@@ -169,9 +170,9 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
@@ -200,9 +201,9 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
@@ -232,9 +233,9 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
@@ -266,9 +267,9 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
@@ -302,9 +303,9 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
@@ -340,9 +341,9 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
@@ -378,16 +379,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@@ -417,16 +418,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@@ -456,16 +457,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@@ -496,16 +497,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@@ -537,16 +538,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@@ -579,16 +580,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@@ -622,16 +623,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@@ -666,16 +667,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@@ -711,16 +712,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@@ -757,16 +758,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@@ -798,7 +799,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
|
||||
call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, stub.UniqueError(44)),
|
||||
call("fatalf", stub.ExpectArgs{"cannot apply op at index %d: %v", []any{1, stub.UniqueError(44)}}, nil, nil),
|
||||
@@ -812,16 +813,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@@ -853,7 +854,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
|
||||
call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, &MountError{"proc", "/sysroot/proc", "proc", uintptr(0xe), "", syscall.ENOTRECOVERABLE}),
|
||||
call("fatal", stub.ExpectArgs{[]any{"cannot mount proc on /sysroot/proc: state not recoverable"}}, nil, nil),
|
||||
@@ -867,16 +868,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@@ -908,7 +909,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
|
||||
call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil),
|
||||
/* end apply */
|
||||
@@ -923,16 +924,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@@ -964,7 +965,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
|
||||
call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil),
|
||||
/* end apply */
|
||||
@@ -980,16 +981,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@@ -1021,7 +1022,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
|
||||
call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil),
|
||||
/* end apply */
|
||||
@@ -1039,16 +1040,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@@ -1080,7 +1081,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
|
||||
call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil),
|
||||
/* end apply */
|
||||
@@ -1099,16 +1100,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@@ -1140,7 +1141,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
|
||||
call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil),
|
||||
/* end apply */
|
||||
@@ -1160,16 +1161,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@@ -1201,7 +1202,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
|
||||
call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil),
|
||||
/* end apply */
|
||||
@@ -1222,16 +1223,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@@ -1263,7 +1264,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
|
||||
call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil),
|
||||
/* end apply */
|
||||
@@ -1285,16 +1286,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@@ -1326,7 +1327,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
|
||||
call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil),
|
||||
/* end apply */
|
||||
@@ -1349,16 +1350,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@@ -1390,7 +1391,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
|
||||
call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil),
|
||||
/* end apply */
|
||||
@@ -1414,16 +1415,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@@ -1455,7 +1456,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
|
||||
call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil),
|
||||
/* end apply */
|
||||
@@ -1480,16 +1481,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@@ -1521,7 +1522,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
|
||||
call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil),
|
||||
/* end apply */
|
||||
@@ -1554,16 +1555,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@@ -1595,7 +1596,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
|
||||
call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil),
|
||||
/* end apply */
|
||||
@@ -1661,16 +1662,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@@ -1702,7 +1703,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
|
||||
call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil),
|
||||
/* end apply */
|
||||
@@ -1769,16 +1770,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@@ -1810,7 +1811,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
|
||||
call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil),
|
||||
/* end apply */
|
||||
@@ -1880,15 +1881,15 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, 0, stub.UniqueError(14)),
|
||||
call("verbosef", stub.ExpectArgs{"cannot enable ptrace protection via Yama LSM: %v", []any{stub.UniqueError(14)}}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei/nonexistent"),
|
||||
Path: MustAbs("/run/current-system/sw/bin/bash"),
|
||||
Dir: check.MustAbs("/.hakurei/nonexistent"),
|
||||
Path: check.MustAbs("/run/current-system/sw/bin/bash"),
|
||||
Args: []string{"bash", "-c", "false"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 24,
|
||||
Gid: 1 << 47,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompDisable: true,
|
||||
ParentPerm: 0750,
|
||||
@@ -1919,7 +1920,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
|
||||
call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0750)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil),
|
||||
/* end apply */
|
||||
@@ -1980,7 +1981,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("newFile", stub.ExpectArgs{uintptr(0x3a), "extra file 0"}, (*os.File)(nil), nil),
|
||||
call("newFile", stub.ExpectArgs{uintptr(0x3b), "extra file 1"}, (*os.File)(nil), nil),
|
||||
call("umask", stub.ExpectArgs{022}, 0, nil),
|
||||
call("verbosef", stub.ExpectArgs{"starting initial program %s", []any{MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"starting initial program %s", []any{check.MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil),
|
||||
call("start", stub.ExpectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent"}, nil, stub.UniqueError(12)),
|
||||
call("fatalf", stub.ExpectArgs{"%v", []any{stub.UniqueError(12)}}, nil, nil),
|
||||
},
|
||||
@@ -1994,15 +1995,15 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, 0, stub.UniqueError(11)),
|
||||
call("verbosef", stub.ExpectArgs{"cannot enable ptrace protection via Yama LSM: %v", []any{stub.UniqueError(11)}}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei/nonexistent"),
|
||||
Path: MustAbs("/run/current-system/sw/bin/bash"),
|
||||
Dir: check.MustAbs("/.hakurei/nonexistent"),
|
||||
Path: check.MustAbs("/run/current-system/sw/bin/bash"),
|
||||
Args: []string{"bash", "-c", "false"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Nanosecond,
|
||||
Uid: 1 << 24,
|
||||
Gid: 1 << 47,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompDisable: true,
|
||||
ParentPerm: 0750,
|
||||
@@ -2033,7 +2034,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
|
||||
call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0750)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil),
|
||||
/* end apply */
|
||||
@@ -2058,7 +2059,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("newFile", stub.ExpectArgs{uintptr(0x3a), "extra file 0"}, (*os.File)(nil), nil),
|
||||
call("newFile", stub.ExpectArgs{uintptr(0x3b), "extra file 1"}, (*os.File)(nil), nil),
|
||||
call("umask", stub.ExpectArgs{022}, 0, nil),
|
||||
call("verbosef", stub.ExpectArgs{"starting initial program %s", []any{MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"starting initial program %s", []any{check.MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil),
|
||||
call("start", stub.ExpectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent"}, &os.Process{Pid: 0xbad}, nil),
|
||||
call("suspend", stub.ExpectArgs{}, true, nil),
|
||||
call("printf", stub.ExpectArgs{"cannot close setup pipe: %v", []any{stub.UniqueError(10)}}, nil, nil),
|
||||
@@ -2094,15 +2095,15 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, 0, stub.UniqueError(8)),
|
||||
call("verbosef", stub.ExpectArgs{"cannot enable ptrace protection via Yama LSM: %v", []any{stub.UniqueError(8)}}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei/nonexistent"),
|
||||
Path: MustAbs("/run/current-system/sw/bin/bash"),
|
||||
Dir: check.MustAbs("/.hakurei/nonexistent"),
|
||||
Path: check.MustAbs("/run/current-system/sw/bin/bash"),
|
||||
Args: []string{"bash", "-c", "false"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Nanosecond,
|
||||
Uid: 1 << 24,
|
||||
Gid: 1 << 47,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompDisable: true,
|
||||
ParentPerm: 0750,
|
||||
@@ -2133,7 +2134,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
|
||||
call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0750)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil),
|
||||
/* end apply */
|
||||
@@ -2158,7 +2159,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("newFile", stub.ExpectArgs{uintptr(0x3a), "extra file 0"}, (*os.File)(nil), nil),
|
||||
call("newFile", stub.ExpectArgs{uintptr(0x3b), "extra file 1"}, (*os.File)(nil), nil),
|
||||
call("umask", stub.ExpectArgs{022}, 0, nil),
|
||||
call("verbosef", stub.ExpectArgs{"starting initial program %s", []any{MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"starting initial program %s", []any{check.MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil),
|
||||
call("start", stub.ExpectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent"}, &os.Process{Pid: 0xbad}, nil),
|
||||
call("suspend", stub.ExpectArgs{}, true, nil),
|
||||
call("printf", stub.ExpectArgs{"cannot close setup pipe: %v", []any{stub.UniqueError(7)}}, nil, nil),
|
||||
@@ -2185,15 +2186,15 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, 0, stub.UniqueError(6)),
|
||||
call("verbosef", stub.ExpectArgs{"cannot enable ptrace protection via Yama LSM: %v", []any{stub.UniqueError(6)}}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei/nonexistent"),
|
||||
Path: MustAbs("/run/current-system/sw/bin/bash"),
|
||||
Dir: check.MustAbs("/.hakurei/nonexistent"),
|
||||
Path: check.MustAbs("/run/current-system/sw/bin/bash"),
|
||||
Args: []string{"bash", "-c", "false"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Nanosecond,
|
||||
Uid: 1 << 24,
|
||||
Gid: 1 << 47,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompDisable: true,
|
||||
ParentPerm: 0750,
|
||||
@@ -2224,7 +2225,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
|
||||
call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0750)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil),
|
||||
/* end apply */
|
||||
@@ -2249,7 +2250,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("newFile", stub.ExpectArgs{uintptr(0x3a), "extra file 0"}, (*os.File)(nil), nil),
|
||||
call("newFile", stub.ExpectArgs{uintptr(0x3b), "extra file 1"}, (*os.File)(nil), nil),
|
||||
call("umask", stub.ExpectArgs{022}, 0, nil),
|
||||
call("verbosef", stub.ExpectArgs{"starting initial program %s", []any{MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"starting initial program %s", []any{check.MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil),
|
||||
call("start", stub.ExpectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent"}, &os.Process{Pid: 0xbad}, nil),
|
||||
call("suspend", stub.ExpectArgs{}, true, nil),
|
||||
call("printf", stub.ExpectArgs{"cannot close setup pipe: %v", []any{stub.UniqueError(5)}}, nil, nil),
|
||||
@@ -2278,15 +2279,15 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, 0, stub.UniqueError(4)),
|
||||
call("verbosef", stub.ExpectArgs{"cannot enable ptrace protection via Yama LSM: %v", []any{stub.UniqueError(4)}}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei/nonexistent"),
|
||||
Path: MustAbs("/run/current-system/sw/bin/bash"),
|
||||
Dir: check.MustAbs("/.hakurei/nonexistent"),
|
||||
Path: check.MustAbs("/run/current-system/sw/bin/bash"),
|
||||
Args: []string{"bash", "-c", "false"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 24,
|
||||
Gid: 1 << 47,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompDisable: true,
|
||||
ParentPerm: 0750,
|
||||
@@ -2317,7 +2318,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
|
||||
call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0750)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil),
|
||||
/* end apply */
|
||||
@@ -2342,7 +2343,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("newFile", stub.ExpectArgs{uintptr(0x3a), "extra file 0"}, (*os.File)(nil), nil),
|
||||
call("newFile", stub.ExpectArgs{uintptr(0x3b), "extra file 1"}, (*os.File)(nil), nil),
|
||||
call("umask", stub.ExpectArgs{022}, 0, nil),
|
||||
call("verbosef", stub.ExpectArgs{"starting initial program %s", []any{MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"starting initial program %s", []any{check.MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil),
|
||||
call("start", stub.ExpectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent"}, &os.Process{Pid: 0xbad}, nil),
|
||||
call("suspend", stub.ExpectArgs{}, true, nil),
|
||||
call("printf", stub.ExpectArgs{"cannot close setup pipe: %v", []any{stub.UniqueError(3)}}, nil, nil),
|
||||
@@ -2378,15 +2379,15 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, 0, stub.UniqueError(2)),
|
||||
call("verbosef", stub.ExpectArgs{"cannot enable ptrace protection via Yama LSM: %v", []any{stub.UniqueError(2)}}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei/nonexistent"),
|
||||
Path: MustAbs("/run/current-system/sw/bin/bash"),
|
||||
Dir: check.MustAbs("/.hakurei/nonexistent"),
|
||||
Path: check.MustAbs("/run/current-system/sw/bin/bash"),
|
||||
Args: []string{"bash", "-c", "false"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 24,
|
||||
Gid: 1 << 47,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompDisable: true,
|
||||
ParentPerm: 0750,
|
||||
@@ -2417,7 +2418,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
|
||||
call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0750)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil),
|
||||
/* end apply */
|
||||
@@ -2478,7 +2479,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("newFile", stub.ExpectArgs{uintptr(0x3a), "extra file 0"}, (*os.File)(nil), nil),
|
||||
call("newFile", stub.ExpectArgs{uintptr(0x3b), "extra file 1"}, (*os.File)(nil), nil),
|
||||
call("umask", stub.ExpectArgs{022}, 0, nil),
|
||||
call("verbosef", stub.ExpectArgs{"starting initial program %s", []any{MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"starting initial program %s", []any{check.MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil),
|
||||
call("start", stub.ExpectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent"}, &os.Process{Pid: 0xbad}, nil),
|
||||
call("suspend", stub.ExpectArgs{}, true, nil),
|
||||
call("printf", stub.ExpectArgs{"cannot close setup pipe: %v", []any{stub.UniqueError(1)}}, nil, nil),
|
||||
@@ -2513,16 +2514,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@@ -2554,7 +2555,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
|
||||
call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil),
|
||||
/* end apply */
|
||||
@@ -2618,7 +2619,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("newFile", stub.ExpectArgs{uintptr(11), "extra file 1"}, (*os.File)(nil), nil),
|
||||
call("newFile", stub.ExpectArgs{uintptr(12), "extra file 2"}, (*os.File)(nil), nil),
|
||||
call("umask", stub.ExpectArgs{022}, 0, nil),
|
||||
call("verbosef", stub.ExpectArgs{"starting initial program %s", []any{MustAbs("/bin/zsh")}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"starting initial program %s", []any{check.MustAbs("/bin/zsh")}}, nil, nil),
|
||||
call("start", stub.ExpectArgs{"/bin/zsh", []string{"zsh", "-c", "exec vim"}, []string{"DISPLAY=:0"}, "/.hakurei"}, &os.Process{Pid: 0xcafe}, nil),
|
||||
call("suspend", stub.ExpectArgs{}, true, nil),
|
||||
call("printf", stub.ExpectArgs{"cannot close setup pipe: %v", []any{stub.UniqueError(0)}}, nil, nil),
|
||||
|
||||
@@ -5,12 +5,14 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"syscall"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
)
|
||||
|
||||
func init() { gob.Register(new(BindMountOp)) }
|
||||
|
||||
// Bind appends an [Op] that bind mounts host path [BindMountOp.Source] on container path [BindMountOp.Target].
|
||||
func (f *Ops) Bind(source, target *Absolute, flags int) *Ops {
|
||||
func (f *Ops) Bind(source, target *check.Absolute, flags int) *Ops {
|
||||
*f = append(*f, &BindMountOp{nil, source, target, flags})
|
||||
return f
|
||||
}
|
||||
@@ -18,7 +20,7 @@ func (f *Ops) Bind(source, target *Absolute, flags int) *Ops {
|
||||
// BindMountOp bind mounts host path Source on container path Target.
|
||||
// Note that Flags uses bits declared in this package and should not be set with constants in [syscall].
|
||||
type BindMountOp struct {
|
||||
sourceFinal, Source, Target *Absolute
|
||||
sourceFinal, Source, Target *check.Absolute
|
||||
|
||||
Flags int
|
||||
}
|
||||
@@ -54,7 +56,7 @@ func (b *BindMountOp) early(_ *setupState, k syscallDispatcher) error {
|
||||
}
|
||||
return err
|
||||
} else {
|
||||
b.sourceFinal, err = NewAbs(pathname)
|
||||
b.sourceFinal, err = check.NewAbs(pathname)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,29 +6,30 @@ import (
|
||||
"syscall"
|
||||
"testing"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/stub"
|
||||
)
|
||||
|
||||
func TestBindMountOp(t *testing.T) {
|
||||
checkOpBehaviour(t, []opBehaviourTestCase{
|
||||
{"ENOENT not optional", new(Params), &BindMountOp{
|
||||
Source: MustAbs("/bin/"),
|
||||
Target: MustAbs("/bin/"),
|
||||
Source: check.MustAbs("/bin/"),
|
||||
Target: check.MustAbs("/bin/"),
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/bin/"}, "", syscall.ENOENT),
|
||||
}, syscall.ENOENT, nil, nil},
|
||||
|
||||
{"skip optional", new(Params), &BindMountOp{
|
||||
Source: MustAbs("/bin/"),
|
||||
Target: MustAbs("/bin/"),
|
||||
Source: check.MustAbs("/bin/"),
|
||||
Target: check.MustAbs("/bin/"),
|
||||
Flags: BindOptional,
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/bin/"}, "", syscall.ENOENT),
|
||||
}, nil, nil, nil},
|
||||
|
||||
{"success optional", new(Params), &BindMountOp{
|
||||
Source: MustAbs("/bin/"),
|
||||
Target: MustAbs("/bin/"),
|
||||
Source: check.MustAbs("/bin/"),
|
||||
Target: check.MustAbs("/bin/"),
|
||||
Flags: BindOptional,
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/bin/"}, "/usr/bin", nil),
|
||||
@@ -40,8 +41,8 @@ func TestBindMountOp(t *testing.T) {
|
||||
}, nil},
|
||||
|
||||
{"ensureFile device", new(Params), &BindMountOp{
|
||||
Source: MustAbs("/dev/null"),
|
||||
Target: MustAbs("/dev/null"),
|
||||
Source: check.MustAbs("/dev/null"),
|
||||
Target: check.MustAbs("/dev/null"),
|
||||
Flags: BindWritable | BindDevice,
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/dev/null"}, "/dev/null", nil),
|
||||
@@ -51,16 +52,16 @@ func TestBindMountOp(t *testing.T) {
|
||||
}, stub.UniqueError(5)},
|
||||
|
||||
{"mkdirAll ensure", new(Params), &BindMountOp{
|
||||
Source: MustAbs("/bin/"),
|
||||
Target: MustAbs("/bin/"),
|
||||
Source: check.MustAbs("/bin/"),
|
||||
Target: check.MustAbs("/bin/"),
|
||||
Flags: BindEnsure,
|
||||
}, []stub.Call{
|
||||
call("mkdirAll", stub.ExpectArgs{"/bin/", os.FileMode(0700)}, nil, stub.UniqueError(4)),
|
||||
}, stub.UniqueError(4), nil, nil},
|
||||
|
||||
{"success ensure", new(Params), &BindMountOp{
|
||||
Source: MustAbs("/bin/"),
|
||||
Target: MustAbs("/usr/bin/"),
|
||||
Source: check.MustAbs("/bin/"),
|
||||
Target: check.MustAbs("/usr/bin/"),
|
||||
Flags: BindEnsure,
|
||||
}, []stub.Call{
|
||||
call("mkdirAll", stub.ExpectArgs{"/bin/", os.FileMode(0700)}, nil, nil),
|
||||
@@ -73,8 +74,8 @@ func TestBindMountOp(t *testing.T) {
|
||||
}, nil},
|
||||
|
||||
{"success device ro", new(Params), &BindMountOp{
|
||||
Source: MustAbs("/dev/null"),
|
||||
Target: MustAbs("/dev/null"),
|
||||
Source: check.MustAbs("/dev/null"),
|
||||
Target: check.MustAbs("/dev/null"),
|
||||
Flags: BindDevice,
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/dev/null"}, "/dev/null", nil),
|
||||
@@ -86,8 +87,8 @@ func TestBindMountOp(t *testing.T) {
|
||||
}, nil},
|
||||
|
||||
{"success device", new(Params), &BindMountOp{
|
||||
Source: MustAbs("/dev/null"),
|
||||
Target: MustAbs("/dev/null"),
|
||||
Source: check.MustAbs("/dev/null"),
|
||||
Target: check.MustAbs("/dev/null"),
|
||||
Flags: BindWritable | BindDevice,
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/dev/null"}, "/dev/null", nil),
|
||||
@@ -99,15 +100,15 @@ func TestBindMountOp(t *testing.T) {
|
||||
}, nil},
|
||||
|
||||
{"evalSymlinks", new(Params), &BindMountOp{
|
||||
Source: MustAbs("/bin/"),
|
||||
Target: MustAbs("/bin/"),
|
||||
Source: check.MustAbs("/bin/"),
|
||||
Target: check.MustAbs("/bin/"),
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/bin/"}, "/usr/bin", stub.UniqueError(3)),
|
||||
}, stub.UniqueError(3), nil, nil},
|
||||
|
||||
{"stat", new(Params), &BindMountOp{
|
||||
Source: MustAbs("/bin/"),
|
||||
Target: MustAbs("/bin/"),
|
||||
Source: check.MustAbs("/bin/"),
|
||||
Target: check.MustAbs("/bin/"),
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/bin/"}, "/usr/bin", nil),
|
||||
}, nil, []stub.Call{
|
||||
@@ -115,8 +116,8 @@ func TestBindMountOp(t *testing.T) {
|
||||
}, stub.UniqueError(2)},
|
||||
|
||||
{"mkdirAll", new(Params), &BindMountOp{
|
||||
Source: MustAbs("/bin/"),
|
||||
Target: MustAbs("/bin/"),
|
||||
Source: check.MustAbs("/bin/"),
|
||||
Target: check.MustAbs("/bin/"),
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/bin/"}, "/usr/bin", nil),
|
||||
}, nil, []stub.Call{
|
||||
@@ -125,8 +126,8 @@ func TestBindMountOp(t *testing.T) {
|
||||
}, stub.UniqueError(1)},
|
||||
|
||||
{"bindMount", new(Params), &BindMountOp{
|
||||
Source: MustAbs("/bin/"),
|
||||
Target: MustAbs("/bin/"),
|
||||
Source: check.MustAbs("/bin/"),
|
||||
Target: check.MustAbs("/bin/"),
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/bin/"}, "/usr/bin", nil),
|
||||
}, nil, []stub.Call{
|
||||
@@ -137,8 +138,8 @@ func TestBindMountOp(t *testing.T) {
|
||||
}, stub.UniqueError(0)},
|
||||
|
||||
{"success eval equals", new(Params), &BindMountOp{
|
||||
Source: MustAbs("/bin/"),
|
||||
Target: MustAbs("/bin/"),
|
||||
Source: check.MustAbs("/bin/"),
|
||||
Target: check.MustAbs("/bin/"),
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/bin/"}, "/bin", nil),
|
||||
}, nil, []stub.Call{
|
||||
@@ -149,8 +150,8 @@ func TestBindMountOp(t *testing.T) {
|
||||
}, nil},
|
||||
|
||||
{"success", new(Params), &BindMountOp{
|
||||
Source: MustAbs("/bin/"),
|
||||
Target: MustAbs("/bin/"),
|
||||
Source: check.MustAbs("/bin/"),
|
||||
Target: check.MustAbs("/bin/"),
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/bin/"}, "/usr/bin", nil),
|
||||
}, nil, []stub.Call{
|
||||
@@ -173,21 +174,21 @@ func TestBindMountOp(t *testing.T) {
|
||||
checkOpsValid(t, []opValidTestCase{
|
||||
{"nil", (*BindMountOp)(nil), false},
|
||||
{"zero", new(BindMountOp), false},
|
||||
{"nil source", &BindMountOp{Target: MustAbs("/")}, false},
|
||||
{"nil target", &BindMountOp{Source: MustAbs("/")}, false},
|
||||
{"flag optional ensure", &BindMountOp{Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindOptional | BindEnsure}, false},
|
||||
{"valid", &BindMountOp{Source: MustAbs("/"), Target: MustAbs("/")}, true},
|
||||
{"nil source", &BindMountOp{Target: check.MustAbs("/")}, false},
|
||||
{"nil target", &BindMountOp{Source: check.MustAbs("/")}, false},
|
||||
{"flag optional ensure", &BindMountOp{Source: check.MustAbs("/"), Target: check.MustAbs("/"), Flags: BindOptional | BindEnsure}, false},
|
||||
{"valid", &BindMountOp{Source: check.MustAbs("/"), Target: check.MustAbs("/")}, true},
|
||||
})
|
||||
|
||||
checkOpsBuilder(t, []opsBuilderTestCase{
|
||||
{"autoetc", new(Ops).Bind(
|
||||
MustAbs("/etc/"),
|
||||
MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
check.MustAbs("/etc/"),
|
||||
check.MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
0,
|
||||
), Ops{
|
||||
&BindMountOp{
|
||||
Source: MustAbs("/etc/"),
|
||||
Target: MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
Source: check.MustAbs("/etc/"),
|
||||
Target: check.MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
},
|
||||
}},
|
||||
})
|
||||
@@ -196,45 +197,45 @@ func TestBindMountOp(t *testing.T) {
|
||||
{"zero", new(BindMountOp), new(BindMountOp), false},
|
||||
|
||||
{"internal ne", &BindMountOp{
|
||||
Source: MustAbs("/etc/"),
|
||||
Target: MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
Source: check.MustAbs("/etc/"),
|
||||
Target: check.MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
}, &BindMountOp{
|
||||
Source: MustAbs("/etc/"),
|
||||
Target: MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
sourceFinal: MustAbs("/etc/"),
|
||||
Source: check.MustAbs("/etc/"),
|
||||
Target: check.MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
sourceFinal: check.MustAbs("/etc/"),
|
||||
}, true},
|
||||
|
||||
{"flags differs", &BindMountOp{
|
||||
Source: MustAbs("/etc/"),
|
||||
Target: MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
Source: check.MustAbs("/etc/"),
|
||||
Target: check.MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
}, &BindMountOp{
|
||||
Source: MustAbs("/etc/"),
|
||||
Target: MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
Source: check.MustAbs("/etc/"),
|
||||
Target: check.MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
Flags: BindOptional,
|
||||
}, false},
|
||||
|
||||
{"source differs", &BindMountOp{
|
||||
Source: MustAbs("/.hakurei/etc/"),
|
||||
Target: MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
Source: check.MustAbs("/.hakurei/etc/"),
|
||||
Target: check.MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
}, &BindMountOp{
|
||||
Source: MustAbs("/etc/"),
|
||||
Target: MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
Source: check.MustAbs("/etc/"),
|
||||
Target: check.MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
}, false},
|
||||
|
||||
{"target differs", &BindMountOp{
|
||||
Source: MustAbs("/etc/"),
|
||||
Target: MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
Source: check.MustAbs("/etc/"),
|
||||
Target: check.MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
}, &BindMountOp{
|
||||
Source: MustAbs("/etc/"),
|
||||
Target: MustAbs("/etc/"),
|
||||
Source: check.MustAbs("/etc/"),
|
||||
Target: check.MustAbs("/etc/"),
|
||||
}, false},
|
||||
|
||||
{"equals", &BindMountOp{
|
||||
Source: MustAbs("/etc/"),
|
||||
Target: MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
Source: check.MustAbs("/etc/"),
|
||||
Target: check.MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
}, &BindMountOp{
|
||||
Source: MustAbs("/etc/"),
|
||||
Target: MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
Source: check.MustAbs("/etc/"),
|
||||
Target: check.MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
}, true},
|
||||
})
|
||||
|
||||
@@ -242,13 +243,13 @@ func TestBindMountOp(t *testing.T) {
|
||||
{"invalid", new(BindMountOp), "mounting", "<invalid>"},
|
||||
|
||||
{"autoetc", &BindMountOp{
|
||||
Source: MustAbs("/etc/"),
|
||||
Target: MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
Source: check.MustAbs("/etc/"),
|
||||
Target: check.MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
}, "mounting", `"/etc/" on "/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659" flags 0x0`},
|
||||
|
||||
{"hostdev", &BindMountOp{
|
||||
Source: MustAbs("/dev/"),
|
||||
Target: MustAbs("/dev/"),
|
||||
Source: check.MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Flags: BindWritable | BindDevice,
|
||||
}, "mounting", `"/dev/" flags 0x6`},
|
||||
})
|
||||
|
||||
@@ -5,19 +5,21 @@ import (
|
||||
"fmt"
|
||||
"path"
|
||||
. "syscall"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
)
|
||||
|
||||
func init() { gob.Register(new(MountDevOp)) }
|
||||
|
||||
// Dev appends an [Op] that mounts a subset of host /dev.
|
||||
func (f *Ops) Dev(target *Absolute, mqueue bool) *Ops {
|
||||
func (f *Ops) Dev(target *check.Absolute, mqueue bool) *Ops {
|
||||
*f = append(*f, &MountDevOp{target, mqueue, false})
|
||||
return f
|
||||
}
|
||||
|
||||
// DevWritable appends an [Op] that mounts a writable subset of host /dev.
|
||||
// There is usually no good reason to write to /dev, so this should always be followed by a [RemountOp].
|
||||
func (f *Ops) DevWritable(target *Absolute, mqueue bool) *Ops {
|
||||
func (f *Ops) DevWritable(target *check.Absolute, mqueue bool) *Ops {
|
||||
*f = append(*f, &MountDevOp{target, mqueue, true})
|
||||
return f
|
||||
}
|
||||
@@ -26,7 +28,7 @@ func (f *Ops) DevWritable(target *Absolute, mqueue bool) *Ops {
|
||||
// If Mqueue is true, a private instance of [FstypeMqueue] is mounted.
|
||||
// If Write is true, the resulting mount point is left writable.
|
||||
type MountDevOp struct {
|
||||
Target *Absolute
|
||||
Target *check.Absolute
|
||||
Mqueue bool
|
||||
Write bool
|
||||
}
|
||||
|
||||
@@ -4,20 +4,21 @@ import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/stub"
|
||||
)
|
||||
|
||||
func TestMountDevOp(t *testing.T) {
|
||||
checkOpBehaviour(t, []opBehaviourTestCase{
|
||||
{"mountTmpfs", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, stub.UniqueError(27)),
|
||||
}, stub.UniqueError(27)},
|
||||
|
||||
{"ensureFile null", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@@ -25,7 +26,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(26)},
|
||||
|
||||
{"bindMount null", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@@ -34,7 +35,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(25)},
|
||||
|
||||
{"ensureFile zero", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@@ -44,7 +45,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(24)},
|
||||
|
||||
{"bindMount zero", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@@ -55,7 +56,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(23)},
|
||||
|
||||
{"ensureFile full", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@@ -67,7 +68,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(22)},
|
||||
|
||||
{"bindMount full", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@@ -80,7 +81,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(21)},
|
||||
|
||||
{"ensureFile random", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@@ -94,7 +95,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(20)},
|
||||
|
||||
{"bindMount random", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@@ -109,7 +110,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(19)},
|
||||
|
||||
{"ensureFile urandom", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@@ -125,7 +126,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(18)},
|
||||
|
||||
{"bindMount urandom", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@@ -142,7 +143,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(17)},
|
||||
|
||||
{"ensureFile tty", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@@ -160,7 +161,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(16)},
|
||||
|
||||
{"bindMount tty", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@@ -179,7 +180,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(15)},
|
||||
|
||||
{"symlink stdin", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@@ -199,7 +200,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(14)},
|
||||
|
||||
{"symlink stdout", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@@ -220,7 +221,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(13)},
|
||||
|
||||
{"symlink stderr", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@@ -242,7 +243,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(12)},
|
||||
|
||||
{"symlink fd", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@@ -265,7 +266,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(11)},
|
||||
|
||||
{"symlink kcore", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@@ -289,7 +290,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(10)},
|
||||
|
||||
{"symlink ptmx", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@@ -314,7 +315,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(9)},
|
||||
|
||||
{"mkdir shm", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@@ -340,7 +341,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(8)},
|
||||
|
||||
{"mkdir devpts", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@@ -367,7 +368,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(7)},
|
||||
|
||||
{"mount devpts", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@@ -395,7 +396,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(6)},
|
||||
|
||||
{"ensureFile stdout", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@@ -425,7 +426,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(5)},
|
||||
|
||||
{"readlink stdout", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@@ -456,7 +457,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(4)},
|
||||
|
||||
{"bindMount stdout", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@@ -488,7 +489,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(3)},
|
||||
|
||||
{"mkdir mqueue", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@@ -521,7 +522,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(2)},
|
||||
|
||||
{"mount mqueue", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@@ -555,7 +556,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(1)},
|
||||
|
||||
{"success no session", &Params{ParentPerm: 0755}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
Write: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
@@ -586,7 +587,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, nil},
|
||||
|
||||
{"success no tty", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
Write: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
@@ -618,7 +619,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, nil},
|
||||
|
||||
{"remount", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
call("ensureFile", stub.ExpectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil),
|
||||
@@ -650,7 +651,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(0)},
|
||||
|
||||
{"success no mqueue", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
call("ensureFile", stub.ExpectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil),
|
||||
@@ -683,7 +684,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, nil},
|
||||
|
||||
{"success rw", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
Write: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
@@ -718,7 +719,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, nil},
|
||||
|
||||
{"success", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@@ -757,20 +758,20 @@ func TestMountDevOp(t *testing.T) {
|
||||
checkOpsValid(t, []opValidTestCase{
|
||||
{"nil", (*MountDevOp)(nil), false},
|
||||
{"zero", new(MountDevOp), false},
|
||||
{"valid", &MountDevOp{Target: MustAbs("/dev/")}, true},
|
||||
{"valid", &MountDevOp{Target: check.MustAbs("/dev/")}, true},
|
||||
})
|
||||
|
||||
checkOpsBuilder(t, []opsBuilderTestCase{
|
||||
{"dev", new(Ops).Dev(MustAbs("/dev/"), true), Ops{
|
||||
{"dev", new(Ops).Dev(check.MustAbs("/dev/"), true), Ops{
|
||||
&MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
},
|
||||
}},
|
||||
|
||||
{"dev writable", new(Ops).DevWritable(MustAbs("/.hakurei/dev/"), false), Ops{
|
||||
{"dev writable", new(Ops).DevWritable(check.MustAbs("/.hakurei/dev/"), false), Ops{
|
||||
&MountDevOp{
|
||||
Target: MustAbs("/.hakurei/dev/"),
|
||||
Target: check.MustAbs("/.hakurei/dev/"),
|
||||
Write: true,
|
||||
},
|
||||
}},
|
||||
@@ -780,46 +781,46 @@ func TestMountDevOp(t *testing.T) {
|
||||
{"zero", new(MountDevOp), new(MountDevOp), false},
|
||||
|
||||
{"write differs", &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
Write: true,
|
||||
}, false},
|
||||
|
||||
{"mqueue differs", &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, false},
|
||||
|
||||
{"target differs", &MountDevOp{
|
||||
Target: MustAbs("/"),
|
||||
Target: check.MustAbs("/"),
|
||||
Mqueue: true,
|
||||
}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, false},
|
||||
|
||||
{"equals", &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, true},
|
||||
})
|
||||
|
||||
checkOpMeta(t, []opMetaTestCase{
|
||||
{"mqueue", &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, "mounting", `dev on "/dev/" with mqueue`},
|
||||
|
||||
{"dev", &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
}, "mounting", `dev on "/dev/"`},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -4,19 +4,21 @@ import (
|
||||
"encoding/gob"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
)
|
||||
|
||||
func init() { gob.Register(new(MkdirOp)) }
|
||||
|
||||
// Mkdir appends an [Op] that creates a directory in the container filesystem.
|
||||
func (f *Ops) Mkdir(name *Absolute, perm os.FileMode) *Ops {
|
||||
func (f *Ops) Mkdir(name *check.Absolute, perm os.FileMode) *Ops {
|
||||
*f = append(*f, &MkdirOp{name, perm})
|
||||
return f
|
||||
}
|
||||
|
||||
// MkdirOp creates a directory at container Path with permission bits set to Perm.
|
||||
type MkdirOp struct {
|
||||
Path *Absolute
|
||||
Path *check.Absolute
|
||||
Perm os.FileMode
|
||||
}
|
||||
|
||||
|
||||
@@ -4,13 +4,14 @@ import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/stub"
|
||||
)
|
||||
|
||||
func TestMkdirOp(t *testing.T) {
|
||||
checkOpBehaviour(t, []opBehaviourTestCase{
|
||||
{"success", new(Params), &MkdirOp{
|
||||
Path: MustAbs("/.hakurei"),
|
||||
Path: check.MustAbs("/.hakurei"),
|
||||
Perm: 0500,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/.hakurei", os.FileMode(0500)}, nil, nil),
|
||||
@@ -20,25 +21,25 @@ func TestMkdirOp(t *testing.T) {
|
||||
checkOpsValid(t, []opValidTestCase{
|
||||
{"nil", (*MkdirOp)(nil), false},
|
||||
{"zero", new(MkdirOp), false},
|
||||
{"valid", &MkdirOp{Path: MustAbs("/.hakurei")}, true},
|
||||
{"valid", &MkdirOp{Path: check.MustAbs("/.hakurei")}, true},
|
||||
})
|
||||
|
||||
checkOpsBuilder(t, []opsBuilderTestCase{
|
||||
{"etc", new(Ops).Mkdir(MustAbs("/etc/"), 0), Ops{
|
||||
&MkdirOp{Path: MustAbs("/etc/")},
|
||||
{"etc", new(Ops).Mkdir(check.MustAbs("/etc/"), 0), Ops{
|
||||
&MkdirOp{Path: check.MustAbs("/etc/")},
|
||||
}},
|
||||
})
|
||||
|
||||
checkOpIs(t, []opIsTestCase{
|
||||
{"zero", new(MkdirOp), new(MkdirOp), false},
|
||||
{"path differs", &MkdirOp{Path: MustAbs("/"), Perm: 0755}, &MkdirOp{Path: MustAbs("/etc/"), Perm: 0755}, false},
|
||||
{"perm differs", &MkdirOp{Path: MustAbs("/")}, &MkdirOp{Path: MustAbs("/"), Perm: 0755}, false},
|
||||
{"equals", &MkdirOp{Path: MustAbs("/")}, &MkdirOp{Path: MustAbs("/")}, true},
|
||||
{"path differs", &MkdirOp{Path: check.MustAbs("/"), Perm: 0755}, &MkdirOp{Path: check.MustAbs("/etc/"), Perm: 0755}, false},
|
||||
{"perm differs", &MkdirOp{Path: check.MustAbs("/")}, &MkdirOp{Path: check.MustAbs("/"), Perm: 0755}, false},
|
||||
{"equals", &MkdirOp{Path: check.MustAbs("/")}, &MkdirOp{Path: check.MustAbs("/")}, true},
|
||||
})
|
||||
|
||||
checkOpMeta(t, []opMetaTestCase{
|
||||
{"etc", &MkdirOp{
|
||||
Path: MustAbs("/etc/"),
|
||||
Path: check.MustAbs("/etc/"),
|
||||
}, "creating", `directory "/etc/" perm ----------`},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ import (
|
||||
"fmt"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -52,7 +54,7 @@ func (e *OverlayArgumentError) Error() string {
|
||||
}
|
||||
|
||||
// Overlay appends an [Op] that mounts the overlay pseudo filesystem on [MountOverlayOp.Target].
|
||||
func (f *Ops) Overlay(target, state, work *Absolute, layers ...*Absolute) *Ops {
|
||||
func (f *Ops) Overlay(target, state, work *check.Absolute, layers ...*check.Absolute) *Ops {
|
||||
*f = append(*f, &MountOverlayOp{
|
||||
Target: target,
|
||||
Lower: layers,
|
||||
@@ -64,21 +66,21 @@ func (f *Ops) Overlay(target, state, work *Absolute, layers ...*Absolute) *Ops {
|
||||
|
||||
// OverlayEphemeral appends an [Op] that mounts the overlay pseudo filesystem on [MountOverlayOp.Target]
|
||||
// with an ephemeral upperdir and workdir.
|
||||
func (f *Ops) OverlayEphemeral(target *Absolute, layers ...*Absolute) *Ops {
|
||||
func (f *Ops) OverlayEphemeral(target *check.Absolute, layers ...*check.Absolute) *Ops {
|
||||
return f.Overlay(target, AbsFHSRoot, nil, layers...)
|
||||
}
|
||||
|
||||
// OverlayReadonly appends an [Op] that mounts the overlay pseudo filesystem readonly on [MountOverlayOp.Target]
|
||||
func (f *Ops) OverlayReadonly(target *Absolute, layers ...*Absolute) *Ops {
|
||||
func (f *Ops) OverlayReadonly(target *check.Absolute, layers ...*check.Absolute) *Ops {
|
||||
return f.Overlay(target, nil, nil, layers...)
|
||||
}
|
||||
|
||||
// MountOverlayOp mounts [FstypeOverlay] on container path Target.
|
||||
type MountOverlayOp struct {
|
||||
Target *Absolute
|
||||
Target *check.Absolute
|
||||
|
||||
// Any filesystem, does not need to be on a writable filesystem.
|
||||
Lower []*Absolute
|
||||
Lower []*check.Absolute
|
||||
// formatted for [OptionOverlayLowerdir], resolved, prefixed and escaped during early
|
||||
lower []string
|
||||
// The upperdir is normally on a writable filesystem.
|
||||
@@ -87,11 +89,11 @@ type MountOverlayOp struct {
|
||||
// an ephemeral upperdir and workdir will be set up.
|
||||
//
|
||||
// If both Work and Upper are nil, upperdir and workdir is omitted and the overlay is mounted readonly.
|
||||
Upper *Absolute
|
||||
Upper *check.Absolute
|
||||
// formatted for [OptionOverlayUpperdir], resolved, prefixed and escaped during early
|
||||
upper string
|
||||
// The workdir needs to be an empty directory on the same filesystem as upperdir.
|
||||
Work *Absolute
|
||||
Work *check.Absolute
|
||||
// formatted for [OptionOverlayWorkdir], resolved, prefixed and escaped during early
|
||||
work string
|
||||
|
||||
@@ -206,7 +208,7 @@ func (o *MountOverlayOp) Is(op Op) bool {
|
||||
vo, ok := op.(*MountOverlayOp)
|
||||
return ok && o.Valid() && vo.Valid() &&
|
||||
o.Target.Is(vo.Target) &&
|
||||
slices.EqualFunc(o.Lower, vo.Lower, func(a *Absolute, v *Absolute) bool { return a.Is(v) }) &&
|
||||
slices.EqualFunc(o.Lower, vo.Lower, func(a, v *check.Absolute) bool { return a.Is(v) }) &&
|
||||
o.Upper.Is(vo.Upper) && o.Work.Is(vo.Work)
|
||||
}
|
||||
func (*MountOverlayOp) prefix() (string, bool) { return "mounting", true }
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/stub"
|
||||
)
|
||||
|
||||
@@ -38,21 +39,21 @@ 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"),
|
||||
Target: check.MustAbs("/"),
|
||||
Lower: []*check.Absolute{
|
||||
check.MustAbs("/var/lib/planterette/base/debian:f92c9052"),
|
||||
check.MustAbs("/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052"),
|
||||
},
|
||||
Upper: MustAbs("/proc/"),
|
||||
Upper: check.MustAbs("/proc/"),
|
||||
}, nil, &OverlayArgumentError{OverlayEphemeralUnexpectedUpper, "/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"),
|
||||
Target: check.MustAbs("/"),
|
||||
Lower: []*check.Absolute{
|
||||
check.MustAbs("/var/lib/planterette/base/debian:f92c9052"),
|
||||
check.MustAbs("/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052"),
|
||||
},
|
||||
Upper: MustAbs("/"),
|
||||
Upper: check.MustAbs("/"),
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/var/lib/planterette/base/debian:f92c9052"}, "/var/lib/planterette/base/debian:f92c9052", nil),
|
||||
call("evalSymlinks", stub.ExpectArgs{"/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052"}, "/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052", nil),
|
||||
@@ -62,12 +63,12 @@ func TestMountOverlayOp(t *testing.T) {
|
||||
}, stub.UniqueError(6)},
|
||||
|
||||
{"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"),
|
||||
Target: check.MustAbs("/"),
|
||||
Lower: []*check.Absolute{
|
||||
check.MustAbs("/var/lib/planterette/base/debian:f92c9052"),
|
||||
check.MustAbs("/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052"),
|
||||
},
|
||||
Upper: MustAbs("/"),
|
||||
Upper: check.MustAbs("/"),
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/var/lib/planterette/base/debian:f92c9052"}, "/var/lib/planterette/base/debian:f92c9052", nil),
|
||||
call("evalSymlinks", stub.ExpectArgs{"/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052"}, "/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052", nil),
|
||||
@@ -78,12 +79,12 @@ func TestMountOverlayOp(t *testing.T) {
|
||||
}, stub.UniqueError(5)},
|
||||
|
||||
{"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"),
|
||||
Target: check.MustAbs("/"),
|
||||
Lower: []*check.Absolute{
|
||||
check.MustAbs("/var/lib/planterette/base/debian:f92c9052"),
|
||||
check.MustAbs("/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052"),
|
||||
},
|
||||
Upper: MustAbs("/"),
|
||||
Upper: check.MustAbs("/"),
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/var/lib/planterette/base/debian:f92c9052"}, "/var/lib/planterette/base/debian:f92c9052", nil),
|
||||
call("evalSymlinks", stub.ExpectArgs{"/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052"}, "/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052", nil),
|
||||
@@ -101,9 +102,9 @@ func TestMountOverlayOp(t *testing.T) {
|
||||
}, nil},
|
||||
|
||||
{"short lower ro", &Params{ParentPerm: 0755}, &MountOverlayOp{
|
||||
Target: MustAbs("/nix/store"),
|
||||
Lower: []*Absolute{
|
||||
MustAbs("/mnt-root/nix/.ro-store"),
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{
|
||||
check.MustAbs("/mnt-root/nix/.ro-store"),
|
||||
},
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.ro-store"}, "/mnt-root/nix/.ro-store", nil),
|
||||
@@ -112,10 +113,10 @@ func TestMountOverlayOp(t *testing.T) {
|
||||
}, &OverlayArgumentError{OverlayReadonlyLower, zeroString}},
|
||||
|
||||
{"success ro noPrefix", &Params{ParentPerm: 0755}, &MountOverlayOp{
|
||||
Target: MustAbs("/nix/store"),
|
||||
Lower: []*Absolute{
|
||||
MustAbs("/mnt-root/nix/.ro-store"),
|
||||
MustAbs("/mnt-root/nix/.ro-store0"),
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{
|
||||
check.MustAbs("/mnt-root/nix/.ro-store"),
|
||||
check.MustAbs("/mnt-root/nix/.ro-store0"),
|
||||
},
|
||||
noPrefix: true,
|
||||
}, []stub.Call{
|
||||
@@ -131,10 +132,10 @@ func TestMountOverlayOp(t *testing.T) {
|
||||
}, nil},
|
||||
|
||||
{"success ro", &Params{ParentPerm: 0755}, &MountOverlayOp{
|
||||
Target: MustAbs("/nix/store"),
|
||||
Lower: []*Absolute{
|
||||
MustAbs("/mnt-root/nix/.ro-store"),
|
||||
MustAbs("/mnt-root/nix/.ro-store0"),
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{
|
||||
check.MustAbs("/mnt-root/nix/.ro-store"),
|
||||
check.MustAbs("/mnt-root/nix/.ro-store0"),
|
||||
},
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.ro-store"}, "/mnt-root/nix/.ro-store", nil),
|
||||
@@ -149,9 +150,9 @@ func TestMountOverlayOp(t *testing.T) {
|
||||
}, 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"),
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Upper: check.MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: check.MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.rw-store/upper"}, "/mnt-root/nix/.rw-store/.upper", nil),
|
||||
call("evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.rw-store/work"}, "/mnt-root/nix/.rw-store/.work", nil),
|
||||
@@ -160,29 +161,29 @@ func TestMountOverlayOp(t *testing.T) {
|
||||
}, &OverlayArgumentError{OverlayEmptyLower, zeroString}},
|
||||
|
||||
{"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"),
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{check.MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: check.MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: check.MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.rw-store/upper"}, "/mnt-root/nix/.rw-store/.upper", stub.UniqueError(4)),
|
||||
}, stub.UniqueError(4), 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"),
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{check.MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: check.MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: check.MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.rw-store/upper"}, "/mnt-root/nix/.rw-store/.upper", nil),
|
||||
call("evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.rw-store/work"}, "/mnt-root/nix/.rw-store/.work", stub.UniqueError(3)),
|
||||
}, stub.UniqueError(3), 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"),
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{check.MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: check.MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: check.MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.rw-store/upper"}, "/mnt-root/nix/.rw-store/.upper", nil),
|
||||
call("evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.rw-store/work"}, "/mnt-root/nix/.rw-store/.work", nil),
|
||||
@@ -190,10 +191,10 @@ func TestMountOverlayOp(t *testing.T) {
|
||||
}, stub.UniqueError(2), 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"),
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{check.MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: check.MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: check.MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.rw-store/upper"}, "/mnt-root/nix/.rw-store/.upper", nil),
|
||||
call("evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.rw-store/work"}, "/mnt-root/nix/.rw-store/.work", nil),
|
||||
@@ -203,10 +204,10 @@ func TestMountOverlayOp(t *testing.T) {
|
||||
}, stub.UniqueError(1)},
|
||||
|
||||
{"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"),
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{check.MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: check.MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: check.MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.rw-store/upper"}, "/mnt-root/nix/.rw-store/.upper", nil),
|
||||
call("evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.rw-store/work"}, "/mnt-root/nix/.rw-store/.work", nil),
|
||||
@@ -217,10 +218,10 @@ func TestMountOverlayOp(t *testing.T) {
|
||||
}, stub.UniqueError(0)},
|
||||
|
||||
{"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"),
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{check.MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: check.MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: check.MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.rw-store/upper"}, "/mnt-root/nix/.rw-store/.upper", nil),
|
||||
call("evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.rw-store/work"}, "/mnt-root/nix/.rw-store/.work", nil),
|
||||
@@ -235,16 +236,16 @@ func TestMountOverlayOp(t *testing.T) {
|
||||
}, 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"),
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{
|
||||
check.MustAbs("/mnt-root/nix/.ro-store"),
|
||||
check.MustAbs("/mnt-root/nix/.ro-store0"),
|
||||
check.MustAbs("/mnt-root/nix/.ro-store1"),
|
||||
check.MustAbs("/mnt-root/nix/.ro-store2"),
|
||||
check.MustAbs("/mnt-root/nix/.ro-store3"),
|
||||
},
|
||||
Upper: MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
Upper: check.MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: check.MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.rw-store/upper"}, "/mnt-root/nix/.rw-store/.upper", nil),
|
||||
call("evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.rw-store/work"}, "/mnt-root/nix/.rw-store/.work", nil),
|
||||
@@ -272,7 +273,7 @@ func TestMountOverlayOp(t *testing.T) {
|
||||
t.Run("nil Upper non-nil Work not ephemeral", func(t *testing.T) {
|
||||
wantErr := OpStateError("overlay")
|
||||
if err := (&MountOverlayOp{
|
||||
Work: MustAbs("/"),
|
||||
Work: check.MustAbs("/"),
|
||||
}).early(nil, nil); !errors.Is(err, wantErr) {
|
||||
t.Errorf("apply: error = %v, want %v", err, wantErr)
|
||||
}
|
||||
@@ -282,39 +283,39 @@ func TestMountOverlayOp(t *testing.T) {
|
||||
checkOpsValid(t, []opValidTestCase{
|
||||
{"nil", (*MountOverlayOp)(nil), false},
|
||||
{"zero", new(MountOverlayOp), false},
|
||||
{"nil lower", &MountOverlayOp{Target: MustAbs("/"), Lower: []*Absolute{nil}}, false},
|
||||
{"ro", &MountOverlayOp{Target: MustAbs("/"), Lower: []*Absolute{MustAbs("/")}}, true},
|
||||
{"ro work", &MountOverlayOp{Target: MustAbs("/"), Work: MustAbs("/tmp/")}, false},
|
||||
{"rw", &MountOverlayOp{Target: MustAbs("/"), Lower: []*Absolute{MustAbs("/")}, Upper: MustAbs("/"), Work: MustAbs("/")}, true},
|
||||
{"nil lower", &MountOverlayOp{Target: check.MustAbs("/"), Lower: []*check.Absolute{nil}}, false},
|
||||
{"ro", &MountOverlayOp{Target: check.MustAbs("/"), Lower: []*check.Absolute{check.MustAbs("/")}}, true},
|
||||
{"ro work", &MountOverlayOp{Target: check.MustAbs("/"), Work: check.MustAbs("/tmp/")}, false},
|
||||
{"rw", &MountOverlayOp{Target: check.MustAbs("/"), Lower: []*check.Absolute{check.MustAbs("/")}, Upper: check.MustAbs("/"), Work: check.MustAbs("/")}, true},
|
||||
})
|
||||
|
||||
checkOpsBuilder(t, []opsBuilderTestCase{
|
||||
{"full", new(Ops).Overlay(
|
||||
MustAbs("/nix/store"),
|
||||
MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
MustAbs("/mnt-root/nix/.ro-store"),
|
||||
check.MustAbs("/nix/store"),
|
||||
check.MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
check.MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
check.MustAbs("/mnt-root/nix/.ro-store"),
|
||||
), Ops{
|
||||
&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"),
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{check.MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: check.MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: check.MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
},
|
||||
}},
|
||||
|
||||
{"ephemeral", new(Ops).OverlayEphemeral(MustAbs("/nix/store"), MustAbs("/mnt-root/nix/.ro-store")), Ops{
|
||||
{"ephemeral", new(Ops).OverlayEphemeral(check.MustAbs("/nix/store"), check.MustAbs("/mnt-root/nix/.ro-store")), Ops{
|
||||
&MountOverlayOp{
|
||||
Target: MustAbs("/nix/store"),
|
||||
Lower: []*Absolute{MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: MustAbs("/"),
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{check.MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: check.MustAbs("/"),
|
||||
},
|
||||
}},
|
||||
|
||||
{"readonly", new(Ops).OverlayReadonly(MustAbs("/nix/store"), MustAbs("/mnt-root/nix/.ro-store")), Ops{
|
||||
{"readonly", new(Ops).OverlayReadonly(check.MustAbs("/nix/store"), check.MustAbs("/mnt-root/nix/.ro-store")), Ops{
|
||||
&MountOverlayOp{
|
||||
Target: MustAbs("/nix/store"),
|
||||
Lower: []*Absolute{MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{check.MustAbs("/mnt-root/nix/.ro-store")},
|
||||
},
|
||||
}},
|
||||
})
|
||||
@@ -323,74 +324,74 @@ func TestMountOverlayOp(t *testing.T) {
|
||||
{"zero", new(MountOverlayOp), new(MountOverlayOp), false},
|
||||
|
||||
{"differs target", &MountOverlayOp{
|
||||
Target: MustAbs("/nix/store/differs"),
|
||||
Lower: []*Absolute{MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
Target: check.MustAbs("/nix/store/differs"),
|
||||
Lower: []*check.Absolute{check.MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: check.MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: check.MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
}, &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")}, false},
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{check.MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: check.MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: check.MustAbs("/mnt-root/nix/.rw-store/work")}, false},
|
||||
|
||||
{"differs lower", &MountOverlayOp{
|
||||
Target: MustAbs("/nix/store"),
|
||||
Lower: []*Absolute{MustAbs("/mnt-root/nix/.ro-store/differs")},
|
||||
Upper: MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{check.MustAbs("/mnt-root/nix/.ro-store/differs")},
|
||||
Upper: check.MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: check.MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
}, &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")}, false},
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{check.MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: check.MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: check.MustAbs("/mnt-root/nix/.rw-store/work")}, false},
|
||||
|
||||
{"differs upper", &MountOverlayOp{
|
||||
Target: MustAbs("/nix/store"),
|
||||
Lower: []*Absolute{MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: MustAbs("/mnt-root/nix/.rw-store/upper/differs"),
|
||||
Work: MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{check.MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: check.MustAbs("/mnt-root/nix/.rw-store/upper/differs"),
|
||||
Work: check.MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
}, &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")}, false},
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{check.MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: check.MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: check.MustAbs("/mnt-root/nix/.rw-store/work")}, false},
|
||||
|
||||
{"differs work", &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/differs"),
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{check.MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: check.MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: check.MustAbs("/mnt-root/nix/.rw-store/work/differs"),
|
||||
}, &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")}, false},
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{check.MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: check.MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: check.MustAbs("/mnt-root/nix/.rw-store/work")}, false},
|
||||
|
||||
{"equals ro", &MountOverlayOp{
|
||||
Target: MustAbs("/nix/store"),
|
||||
Lower: []*Absolute{MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{check.MustAbs("/mnt-root/nix/.ro-store")},
|
||||
}, &MountOverlayOp{
|
||||
Target: MustAbs("/nix/store"),
|
||||
Lower: []*Absolute{MustAbs("/mnt-root/nix/.ro-store")}}, true},
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{check.MustAbs("/mnt-root/nix/.ro-store")}}, true},
|
||||
|
||||
{"equals", &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"),
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{check.MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: check.MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: check.MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
}, &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")}, true},
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{check.MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: check.MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: check.MustAbs("/mnt-root/nix/.rw-store/work")}, true},
|
||||
})
|
||||
|
||||
checkOpMeta(t, []opMetaTestCase{
|
||||
{"nix", &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"),
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{check.MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: check.MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: check.MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
}, "mounting", `overlay on "/nix/store" with 1 layers`},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ import (
|
||||
"encoding/gob"
|
||||
"fmt"
|
||||
"syscall"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -14,13 +16,13 @@ const (
|
||||
func init() { gob.Register(new(TmpfileOp)) }
|
||||
|
||||
// Place appends an [Op] that places a file in container path [TmpfileOp.Path] containing [TmpfileOp.Data].
|
||||
func (f *Ops) Place(name *Absolute, data []byte) *Ops {
|
||||
func (f *Ops) Place(name *check.Absolute, data []byte) *Ops {
|
||||
*f = append(*f, &TmpfileOp{name, data})
|
||||
return f
|
||||
}
|
||||
|
||||
// PlaceP is like Place but writes the address of [TmpfileOp.Data] to the pointer dataP points to.
|
||||
func (f *Ops) PlaceP(name *Absolute, dataP **[]byte) *Ops {
|
||||
func (f *Ops) PlaceP(name *check.Absolute, dataP **[]byte) *Ops {
|
||||
t := &TmpfileOp{Path: name}
|
||||
*dataP = &t.Data
|
||||
|
||||
@@ -30,7 +32,7 @@ func (f *Ops) PlaceP(name *Absolute, dataP **[]byte) *Ops {
|
||||
|
||||
// TmpfileOp places a file on container Path containing Data.
|
||||
type TmpfileOp struct {
|
||||
Path *Absolute
|
||||
Path *check.Absolute
|
||||
Data []byte
|
||||
}
|
||||
|
||||
|
||||
@@ -4,13 +4,14 @@ import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/stub"
|
||||
)
|
||||
|
||||
func TestTmpfileOp(t *testing.T) {
|
||||
const sampleDataString = `chronos:x:65534:65534:Hakurei:/var/empty:/bin/zsh`
|
||||
var (
|
||||
samplePath = MustAbs("/etc/passwd")
|
||||
samplePath = check.MustAbs("/etc/passwd")
|
||||
sampleData = []byte(sampleDataString)
|
||||
)
|
||||
|
||||
@@ -100,7 +101,7 @@ func TestTmpfileOp(t *testing.T) {
|
||||
{"zero", new(TmpfileOp), new(TmpfileOp), false},
|
||||
|
||||
{"differs path", &TmpfileOp{
|
||||
Path: MustAbs("/etc/group"),
|
||||
Path: check.MustAbs("/etc/group"),
|
||||
Data: sampleData,
|
||||
}, &TmpfileOp{
|
||||
Path: samplePath,
|
||||
|
||||
@@ -4,18 +4,20 @@ import (
|
||||
"encoding/gob"
|
||||
"fmt"
|
||||
. "syscall"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
)
|
||||
|
||||
func init() { gob.Register(new(MountProcOp)) }
|
||||
|
||||
// Proc appends an [Op] that mounts a private instance of proc.
|
||||
func (f *Ops) Proc(target *Absolute) *Ops {
|
||||
func (f *Ops) Proc(target *check.Absolute) *Ops {
|
||||
*f = append(*f, &MountProcOp{target})
|
||||
return f
|
||||
}
|
||||
|
||||
// MountProcOp mounts a new instance of [FstypeProc] on container path Target.
|
||||
type MountProcOp struct{ Target *Absolute }
|
||||
type MountProcOp struct{ Target *check.Absolute }
|
||||
|
||||
func (p *MountProcOp) Valid() bool { return p != nil && p.Target != nil }
|
||||
func (p *MountProcOp) early(*setupState, syscallDispatcher) error { return nil }
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/stub"
|
||||
)
|
||||
|
||||
@@ -11,14 +12,14 @@ func TestMountProcOp(t *testing.T) {
|
||||
checkOpBehaviour(t, []opBehaviourTestCase{
|
||||
{"mkdir", &Params{ParentPerm: 0755},
|
||||
&MountProcOp{
|
||||
Target: MustAbs("/proc/"),
|
||||
Target: check.MustAbs("/proc/"),
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, stub.UniqueError(0)),
|
||||
}, stub.UniqueError(0)},
|
||||
|
||||
{"success", &Params{ParentPerm: 0700},
|
||||
&MountProcOp{
|
||||
Target: MustAbs("/proc/"),
|
||||
Target: check.MustAbs("/proc/"),
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0700)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil),
|
||||
@@ -28,12 +29,12 @@ func TestMountProcOp(t *testing.T) {
|
||||
checkOpsValid(t, []opValidTestCase{
|
||||
{"nil", (*MountProcOp)(nil), false},
|
||||
{"zero", new(MountProcOp), false},
|
||||
{"valid", &MountProcOp{Target: MustAbs("/proc/")}, true},
|
||||
{"valid", &MountProcOp{Target: check.MustAbs("/proc/")}, true},
|
||||
})
|
||||
|
||||
checkOpsBuilder(t, []opsBuilderTestCase{
|
||||
{"proc", new(Ops).Proc(MustAbs("/proc/")), Ops{
|
||||
&MountProcOp{Target: MustAbs("/proc/")},
|
||||
{"proc", new(Ops).Proc(check.MustAbs("/proc/")), Ops{
|
||||
&MountProcOp{Target: check.MustAbs("/proc/")},
|
||||
}},
|
||||
})
|
||||
|
||||
@@ -41,20 +42,20 @@ func TestMountProcOp(t *testing.T) {
|
||||
{"zero", new(MountProcOp), new(MountProcOp), false},
|
||||
|
||||
{"target differs", &MountProcOp{
|
||||
Target: MustAbs("/proc/nonexistent"),
|
||||
Target: check.MustAbs("/proc/nonexistent"),
|
||||
}, &MountProcOp{
|
||||
Target: MustAbs("/proc/"),
|
||||
Target: check.MustAbs("/proc/"),
|
||||
}, false},
|
||||
|
||||
{"equals", &MountProcOp{
|
||||
Target: MustAbs("/proc/"),
|
||||
Target: check.MustAbs("/proc/"),
|
||||
}, &MountProcOp{
|
||||
Target: MustAbs("/proc/"),
|
||||
Target: check.MustAbs("/proc/"),
|
||||
}, true},
|
||||
})
|
||||
|
||||
checkOpMeta(t, []opMetaTestCase{
|
||||
{"proc", &MountProcOp{Target: MustAbs("/proc/")},
|
||||
{"proc", &MountProcOp{Target: check.MustAbs("/proc/")},
|
||||
"mounting", `proc on "/proc/"`},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,19 +3,21 @@ package container
|
||||
import (
|
||||
"encoding/gob"
|
||||
"fmt"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
)
|
||||
|
||||
func init() { gob.Register(new(RemountOp)) }
|
||||
|
||||
// Remount appends an [Op] that applies [RemountOp.Flags] on container path [RemountOp.Target].
|
||||
func (f *Ops) Remount(target *Absolute, flags uintptr) *Ops {
|
||||
func (f *Ops) Remount(target *check.Absolute, flags uintptr) *Ops {
|
||||
*f = append(*f, &RemountOp{target, flags})
|
||||
return f
|
||||
}
|
||||
|
||||
// RemountOp remounts Target with Flags.
|
||||
type RemountOp struct {
|
||||
Target *Absolute
|
||||
Target *check.Absolute
|
||||
Flags uintptr
|
||||
}
|
||||
|
||||
|
||||
@@ -4,13 +4,14 @@ import (
|
||||
"syscall"
|
||||
"testing"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/stub"
|
||||
)
|
||||
|
||||
func TestRemountOp(t *testing.T) {
|
||||
checkOpBehaviour(t, []opBehaviourTestCase{
|
||||
{"success", new(Params), &RemountOp{
|
||||
Target: MustAbs("/"),
|
||||
Target: check.MustAbs("/"),
|
||||
Flags: syscall.MS_RDONLY,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("remount", stub.ExpectArgs{"/sysroot", uintptr(1)}, nil, nil),
|
||||
@@ -20,13 +21,13 @@ func TestRemountOp(t *testing.T) {
|
||||
checkOpsValid(t, []opValidTestCase{
|
||||
{"nil", (*RemountOp)(nil), false},
|
||||
{"zero", new(RemountOp), false},
|
||||
{"valid", &RemountOp{Target: MustAbs("/"), Flags: syscall.MS_RDONLY}, true},
|
||||
{"valid", &RemountOp{Target: check.MustAbs("/"), Flags: syscall.MS_RDONLY}, true},
|
||||
})
|
||||
|
||||
checkOpsBuilder(t, []opsBuilderTestCase{
|
||||
{"root", new(Ops).Remount(MustAbs("/"), syscall.MS_RDONLY), Ops{
|
||||
{"root", new(Ops).Remount(check.MustAbs("/"), syscall.MS_RDONLY), Ops{
|
||||
&RemountOp{
|
||||
Target: MustAbs("/"),
|
||||
Target: check.MustAbs("/"),
|
||||
Flags: syscall.MS_RDONLY,
|
||||
},
|
||||
}},
|
||||
@@ -36,33 +37,33 @@ func TestRemountOp(t *testing.T) {
|
||||
{"zero", new(RemountOp), new(RemountOp), false},
|
||||
|
||||
{"target differs", &RemountOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Flags: syscall.MS_RDONLY,
|
||||
}, &RemountOp{
|
||||
Target: MustAbs("/"),
|
||||
Target: check.MustAbs("/"),
|
||||
Flags: syscall.MS_RDONLY,
|
||||
}, false},
|
||||
|
||||
{"flags differs", &RemountOp{
|
||||
Target: MustAbs("/"),
|
||||
Target: check.MustAbs("/"),
|
||||
Flags: syscall.MS_RDONLY | syscall.MS_NODEV,
|
||||
}, &RemountOp{
|
||||
Target: MustAbs("/"),
|
||||
Target: check.MustAbs("/"),
|
||||
Flags: syscall.MS_RDONLY,
|
||||
}, false},
|
||||
|
||||
{"equals", &RemountOp{
|
||||
Target: MustAbs("/"),
|
||||
Target: check.MustAbs("/"),
|
||||
Flags: syscall.MS_RDONLY,
|
||||
}, &RemountOp{
|
||||
Target: MustAbs("/"),
|
||||
Target: check.MustAbs("/"),
|
||||
Flags: syscall.MS_RDONLY,
|
||||
}, true},
|
||||
})
|
||||
|
||||
checkOpMeta(t, []opMetaTestCase{
|
||||
{"root", &RemountOp{
|
||||
Target: MustAbs("/"),
|
||||
Target: check.MustAbs("/"),
|
||||
Flags: syscall.MS_RDONLY,
|
||||
}, "remounting", `"/" flags 0x1`},
|
||||
})
|
||||
|
||||
@@ -4,19 +4,21 @@ import (
|
||||
"encoding/gob"
|
||||
"fmt"
|
||||
"path"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
)
|
||||
|
||||
func init() { gob.Register(new(SymlinkOp)) }
|
||||
|
||||
// Link appends an [Op] that creates a symlink in the container filesystem.
|
||||
func (f *Ops) Link(target *Absolute, linkName string, dereference bool) *Ops {
|
||||
func (f *Ops) Link(target *check.Absolute, linkName string, dereference bool) *Ops {
|
||||
*f = append(*f, &SymlinkOp{target, linkName, dereference})
|
||||
return f
|
||||
}
|
||||
|
||||
// SymlinkOp optionally dereferences LinkName and creates a symlink at container path Target.
|
||||
type SymlinkOp struct {
|
||||
Target *Absolute
|
||||
Target *check.Absolute
|
||||
// LinkName is an arbitrary uninterpreted pathname.
|
||||
LinkName string
|
||||
|
||||
@@ -28,8 +30,8 @@ func (l *SymlinkOp) Valid() bool { return l != nil && l.Target != nil && l.LinkN
|
||||
|
||||
func (l *SymlinkOp) early(_ *setupState, k syscallDispatcher) error {
|
||||
if l.Dereference {
|
||||
if !isAbs(l.LinkName) {
|
||||
return &AbsoluteError{l.LinkName}
|
||||
if !path.IsAbs(l.LinkName) {
|
||||
return &check.AbsoluteError{Pathname: l.LinkName}
|
||||
}
|
||||
if name, err := k.readlink(l.LinkName); err != nil {
|
||||
return err
|
||||
|
||||
@@ -4,26 +4,27 @@ import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/stub"
|
||||
)
|
||||
|
||||
func TestSymlinkOp(t *testing.T) {
|
||||
checkOpBehaviour(t, []opBehaviourTestCase{
|
||||
{"mkdir", &Params{ParentPerm: 0700}, &SymlinkOp{
|
||||
Target: MustAbs("/etc/nixos"),
|
||||
Target: check.MustAbs("/etc/nixos"),
|
||||
LinkName: "/etc/static/nixos",
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/etc", os.FileMode(0700)}, nil, stub.UniqueError(1)),
|
||||
}, stub.UniqueError(1)},
|
||||
|
||||
{"abs", &Params{ParentPerm: 0755}, &SymlinkOp{
|
||||
Target: MustAbs("/etc/mtab"),
|
||||
Target: check.MustAbs("/etc/mtab"),
|
||||
LinkName: "etc/mtab",
|
||||
Dereference: true,
|
||||
}, nil, &AbsoluteError{"etc/mtab"}, nil, nil},
|
||||
}, nil, &check.AbsoluteError{Pathname: "etc/mtab"}, nil, nil},
|
||||
|
||||
{"readlink", &Params{ParentPerm: 0755}, &SymlinkOp{
|
||||
Target: MustAbs("/etc/mtab"),
|
||||
Target: check.MustAbs("/etc/mtab"),
|
||||
LinkName: "/etc/mtab",
|
||||
Dereference: true,
|
||||
}, []stub.Call{
|
||||
@@ -31,7 +32,7 @@ func TestSymlinkOp(t *testing.T) {
|
||||
}, stub.UniqueError(0), nil, nil},
|
||||
|
||||
{"success noderef", &Params{ParentPerm: 0700}, &SymlinkOp{
|
||||
Target: MustAbs("/etc/nixos"),
|
||||
Target: check.MustAbs("/etc/nixos"),
|
||||
LinkName: "/etc/static/nixos",
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/etc", os.FileMode(0700)}, nil, nil),
|
||||
@@ -39,7 +40,7 @@ func TestSymlinkOp(t *testing.T) {
|
||||
}, nil},
|
||||
|
||||
{"success", &Params{ParentPerm: 0755}, &SymlinkOp{
|
||||
Target: MustAbs("/etc/mtab"),
|
||||
Target: check.MustAbs("/etc/mtab"),
|
||||
LinkName: "/etc/mtab",
|
||||
Dereference: true,
|
||||
}, []stub.Call{
|
||||
@@ -54,18 +55,18 @@ func TestSymlinkOp(t *testing.T) {
|
||||
{"nil", (*SymlinkOp)(nil), false},
|
||||
{"zero", new(SymlinkOp), false},
|
||||
{"nil target", &SymlinkOp{LinkName: "/run/current-system"}, false},
|
||||
{"zero linkname", &SymlinkOp{Target: MustAbs("/run/current-system")}, false},
|
||||
{"valid", &SymlinkOp{Target: MustAbs("/run/current-system"), LinkName: "/run/current-system", Dereference: true}, true},
|
||||
{"zero linkname", &SymlinkOp{Target: check.MustAbs("/run/current-system")}, false},
|
||||
{"valid", &SymlinkOp{Target: check.MustAbs("/run/current-system"), LinkName: "/run/current-system", Dereference: true}, true},
|
||||
})
|
||||
|
||||
checkOpsBuilder(t, []opsBuilderTestCase{
|
||||
{"current-system", new(Ops).Link(
|
||||
MustAbs("/run/current-system"),
|
||||
check.MustAbs("/run/current-system"),
|
||||
"/run/current-system",
|
||||
true,
|
||||
), Ops{
|
||||
&SymlinkOp{
|
||||
Target: MustAbs("/run/current-system"),
|
||||
Target: check.MustAbs("/run/current-system"),
|
||||
LinkName: "/run/current-system",
|
||||
Dereference: true,
|
||||
},
|
||||
@@ -76,40 +77,40 @@ func TestSymlinkOp(t *testing.T) {
|
||||
{"zero", new(SymlinkOp), new(SymlinkOp), false},
|
||||
|
||||
{"target differs", &SymlinkOp{
|
||||
Target: MustAbs("/run/current-system/differs"),
|
||||
Target: check.MustAbs("/run/current-system/differs"),
|
||||
LinkName: "/run/current-system",
|
||||
Dereference: true,
|
||||
}, &SymlinkOp{
|
||||
Target: MustAbs("/run/current-system"),
|
||||
Target: check.MustAbs("/run/current-system"),
|
||||
LinkName: "/run/current-system",
|
||||
Dereference: true,
|
||||
}, false},
|
||||
|
||||
{"linkname differs", &SymlinkOp{
|
||||
Target: MustAbs("/run/current-system"),
|
||||
Target: check.MustAbs("/run/current-system"),
|
||||
LinkName: "/run/current-system/differs",
|
||||
Dereference: true,
|
||||
}, &SymlinkOp{
|
||||
Target: MustAbs("/run/current-system"),
|
||||
Target: check.MustAbs("/run/current-system"),
|
||||
LinkName: "/run/current-system",
|
||||
Dereference: true,
|
||||
}, false},
|
||||
|
||||
{"dereference differs", &SymlinkOp{
|
||||
Target: MustAbs("/run/current-system"),
|
||||
Target: check.MustAbs("/run/current-system"),
|
||||
LinkName: "/run/current-system",
|
||||
}, &SymlinkOp{
|
||||
Target: MustAbs("/run/current-system"),
|
||||
Target: check.MustAbs("/run/current-system"),
|
||||
LinkName: "/run/current-system",
|
||||
Dereference: true,
|
||||
}, false},
|
||||
|
||||
{"equals", &SymlinkOp{
|
||||
Target: MustAbs("/run/current-system"),
|
||||
Target: check.MustAbs("/run/current-system"),
|
||||
LinkName: "/run/current-system",
|
||||
Dereference: true,
|
||||
}, &SymlinkOp{
|
||||
Target: MustAbs("/run/current-system"),
|
||||
Target: check.MustAbs("/run/current-system"),
|
||||
LinkName: "/run/current-system",
|
||||
Dereference: true,
|
||||
}, true},
|
||||
@@ -117,7 +118,7 @@ func TestSymlinkOp(t *testing.T) {
|
||||
|
||||
checkOpMeta(t, []opMetaTestCase{
|
||||
{"current-system", &SymlinkOp{
|
||||
Target: MustAbs("/run/current-system"),
|
||||
Target: check.MustAbs("/run/current-system"),
|
||||
LinkName: "/run/current-system",
|
||||
Dereference: true,
|
||||
}, "creating", `symlink on "/run/current-system" linkname "/run/current-system"`},
|
||||
|
||||
@@ -7,6 +7,8 @@ import (
|
||||
"os"
|
||||
"strconv"
|
||||
. "syscall"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
)
|
||||
|
||||
func init() { gob.Register(new(MountTmpfsOp)) }
|
||||
@@ -18,13 +20,13 @@ func (e TmpfsSizeError) Error() string {
|
||||
}
|
||||
|
||||
// Tmpfs appends an [Op] that mounts tmpfs on container path [MountTmpfsOp.Path].
|
||||
func (f *Ops) Tmpfs(target *Absolute, size int, perm os.FileMode) *Ops {
|
||||
func (f *Ops) Tmpfs(target *check.Absolute, size int, perm os.FileMode) *Ops {
|
||||
*f = append(*f, &MountTmpfsOp{SourceTmpfsEphemeral, target, MS_NOSUID | MS_NODEV, size, perm})
|
||||
return f
|
||||
}
|
||||
|
||||
// Readonly appends an [Op] that mounts read-only tmpfs on container path [MountTmpfsOp.Path].
|
||||
func (f *Ops) Readonly(target *Absolute, perm os.FileMode) *Ops {
|
||||
func (f *Ops) Readonly(target *check.Absolute, perm os.FileMode) *Ops {
|
||||
*f = append(*f, &MountTmpfsOp{SourceTmpfsReadonly, target, MS_RDONLY | MS_NOSUID | MS_NODEV, 0, perm})
|
||||
return f
|
||||
}
|
||||
@@ -32,7 +34,7 @@ func (f *Ops) Readonly(target *Absolute, perm os.FileMode) *Ops {
|
||||
// MountTmpfsOp mounts [FstypeTmpfs] on container Path.
|
||||
type MountTmpfsOp struct {
|
||||
FSName string
|
||||
Path *Absolute
|
||||
Path *check.Absolute
|
||||
Flags uintptr
|
||||
Size int
|
||||
Perm os.FileMode
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"syscall"
|
||||
"testing"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/stub"
|
||||
)
|
||||
|
||||
@@ -24,7 +25,7 @@ func TestMountTmpfsOp(t *testing.T) {
|
||||
|
||||
{"success", new(Params), &MountTmpfsOp{
|
||||
FSName: "ephemeral",
|
||||
Path: MustAbs("/run/user/1000/"),
|
||||
Path: check.MustAbs("/run/user/1000/"),
|
||||
Size: 1 << 10,
|
||||
Perm: 0700,
|
||||
}, nil, nil, []stub.Call{
|
||||
@@ -42,19 +43,19 @@ func TestMountTmpfsOp(t *testing.T) {
|
||||
{"nil", (*MountTmpfsOp)(nil), false},
|
||||
{"zero", new(MountTmpfsOp), false},
|
||||
{"nil path", &MountTmpfsOp{FSName: "tmpfs"}, false},
|
||||
{"zero fsname", &MountTmpfsOp{Path: MustAbs("/tmp/")}, false},
|
||||
{"valid", &MountTmpfsOp{FSName: "tmpfs", Path: MustAbs("/tmp/")}, true},
|
||||
{"zero fsname", &MountTmpfsOp{Path: check.MustAbs("/tmp/")}, false},
|
||||
{"valid", &MountTmpfsOp{FSName: "tmpfs", Path: check.MustAbs("/tmp/")}, true},
|
||||
})
|
||||
|
||||
checkOpsBuilder(t, []opsBuilderTestCase{
|
||||
{"runtime", new(Ops).Tmpfs(
|
||||
MustAbs("/run/user"),
|
||||
check.MustAbs("/run/user"),
|
||||
1<<10,
|
||||
0755,
|
||||
), Ops{
|
||||
&MountTmpfsOp{
|
||||
FSName: "ephemeral",
|
||||
Path: MustAbs("/run/user"),
|
||||
Path: check.MustAbs("/run/user"),
|
||||
Flags: syscall.MS_NOSUID | syscall.MS_NODEV,
|
||||
Size: 1 << 10,
|
||||
Perm: 0755,
|
||||
@@ -62,12 +63,12 @@ func TestMountTmpfsOp(t *testing.T) {
|
||||
}},
|
||||
|
||||
{"nscd", new(Ops).Readonly(
|
||||
MustAbs("/var/run/nscd"),
|
||||
check.MustAbs("/var/run/nscd"),
|
||||
0755,
|
||||
), Ops{
|
||||
&MountTmpfsOp{
|
||||
FSName: "readonly",
|
||||
Path: MustAbs("/var/run/nscd"),
|
||||
Path: check.MustAbs("/var/run/nscd"),
|
||||
Flags: syscall.MS_NOSUID | syscall.MS_NODEV | syscall.MS_RDONLY,
|
||||
Perm: 0755,
|
||||
},
|
||||
@@ -79,13 +80,13 @@ func TestMountTmpfsOp(t *testing.T) {
|
||||
|
||||
{"fsname differs", &MountTmpfsOp{
|
||||
FSName: "readonly",
|
||||
Path: MustAbs("/run/user"),
|
||||
Path: check.MustAbs("/run/user"),
|
||||
Flags: syscall.MS_NOSUID | syscall.MS_NODEV,
|
||||
Size: 1 << 10,
|
||||
Perm: 0755,
|
||||
}, &MountTmpfsOp{
|
||||
FSName: "ephemeral",
|
||||
Path: MustAbs("/run/user"),
|
||||
Path: check.MustAbs("/run/user"),
|
||||
Flags: syscall.MS_NOSUID | syscall.MS_NODEV,
|
||||
Size: 1 << 10,
|
||||
Perm: 0755,
|
||||
@@ -93,13 +94,13 @@ func TestMountTmpfsOp(t *testing.T) {
|
||||
|
||||
{"path differs", &MountTmpfsOp{
|
||||
FSName: "ephemeral",
|
||||
Path: MustAbs("/run/user/differs"),
|
||||
Path: check.MustAbs("/run/user/differs"),
|
||||
Flags: syscall.MS_NOSUID | syscall.MS_NODEV,
|
||||
Size: 1 << 10,
|
||||
Perm: 0755,
|
||||
}, &MountTmpfsOp{
|
||||
FSName: "ephemeral",
|
||||
Path: MustAbs("/run/user"),
|
||||
Path: check.MustAbs("/run/user"),
|
||||
Flags: syscall.MS_NOSUID | syscall.MS_NODEV,
|
||||
Size: 1 << 10,
|
||||
Perm: 0755,
|
||||
@@ -107,13 +108,13 @@ func TestMountTmpfsOp(t *testing.T) {
|
||||
|
||||
{"flags differs", &MountTmpfsOp{
|
||||
FSName: "ephemeral",
|
||||
Path: MustAbs("/run/user"),
|
||||
Path: check.MustAbs("/run/user"),
|
||||
Flags: syscall.MS_NOSUID | syscall.MS_NODEV | syscall.MS_RDONLY,
|
||||
Size: 1 << 10,
|
||||
Perm: 0755,
|
||||
}, &MountTmpfsOp{
|
||||
FSName: "ephemeral",
|
||||
Path: MustAbs("/run/user"),
|
||||
Path: check.MustAbs("/run/user"),
|
||||
Flags: syscall.MS_NOSUID | syscall.MS_NODEV,
|
||||
Size: 1 << 10,
|
||||
Perm: 0755,
|
||||
@@ -121,13 +122,13 @@ func TestMountTmpfsOp(t *testing.T) {
|
||||
|
||||
{"size differs", &MountTmpfsOp{
|
||||
FSName: "ephemeral",
|
||||
Path: MustAbs("/run/user"),
|
||||
Path: check.MustAbs("/run/user"),
|
||||
Flags: syscall.MS_NOSUID | syscall.MS_NODEV,
|
||||
Size: 1,
|
||||
Perm: 0755,
|
||||
}, &MountTmpfsOp{
|
||||
FSName: "ephemeral",
|
||||
Path: MustAbs("/run/user"),
|
||||
Path: check.MustAbs("/run/user"),
|
||||
Flags: syscall.MS_NOSUID | syscall.MS_NODEV,
|
||||
Size: 1 << 10,
|
||||
Perm: 0755,
|
||||
@@ -135,13 +136,13 @@ func TestMountTmpfsOp(t *testing.T) {
|
||||
|
||||
{"perm differs", &MountTmpfsOp{
|
||||
FSName: "ephemeral",
|
||||
Path: MustAbs("/run/user"),
|
||||
Path: check.MustAbs("/run/user"),
|
||||
Flags: syscall.MS_NOSUID | syscall.MS_NODEV,
|
||||
Size: 1 << 10,
|
||||
Perm: 0700,
|
||||
}, &MountTmpfsOp{
|
||||
FSName: "ephemeral",
|
||||
Path: MustAbs("/run/user"),
|
||||
Path: check.MustAbs("/run/user"),
|
||||
Flags: syscall.MS_NOSUID | syscall.MS_NODEV,
|
||||
Size: 1 << 10,
|
||||
Perm: 0755,
|
||||
@@ -149,13 +150,13 @@ func TestMountTmpfsOp(t *testing.T) {
|
||||
|
||||
{"equals", &MountTmpfsOp{
|
||||
FSName: "ephemeral",
|
||||
Path: MustAbs("/run/user"),
|
||||
Path: check.MustAbs("/run/user"),
|
||||
Flags: syscall.MS_NOSUID | syscall.MS_NODEV,
|
||||
Size: 1 << 10,
|
||||
Perm: 0755,
|
||||
}, &MountTmpfsOp{
|
||||
FSName: "ephemeral",
|
||||
Path: MustAbs("/run/user"),
|
||||
Path: check.MustAbs("/run/user"),
|
||||
Flags: syscall.MS_NOSUID | syscall.MS_NODEV,
|
||||
Size: 1 << 10,
|
||||
Perm: 0755,
|
||||
@@ -165,7 +166,7 @@ func TestMountTmpfsOp(t *testing.T) {
|
||||
checkOpMeta(t, []opMetaTestCase{
|
||||
{"runtime", &MountTmpfsOp{
|
||||
FSName: "ephemeral",
|
||||
Path: MustAbs("/run/user"),
|
||||
Path: check.MustAbs("/run/user"),
|
||||
Flags: syscall.MS_NOSUID | syscall.MS_NODEV,
|
||||
Size: 1 << 10,
|
||||
Perm: 0755,
|
||||
|
||||
@@ -8,12 +8,17 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
_ "unsafe"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/vfs"
|
||||
)
|
||||
|
||||
/* constants in this file bypass abs check, be extremely careful when changing them! */
|
||||
|
||||
//go:linkname unsafeAbs hakurei.app/container/check.unsafeAbs
|
||||
func unsafeAbs(_ string) *check.Absolute
|
||||
|
||||
const (
|
||||
// FHSRoot points to the file system root.
|
||||
FHSRoot = "/"
|
||||
@@ -52,31 +57,31 @@ const (
|
||||
|
||||
var (
|
||||
// AbsFHSRoot is [FHSRoot] as [Absolute].
|
||||
AbsFHSRoot = &Absolute{FHSRoot}
|
||||
AbsFHSRoot = unsafeAbs(FHSRoot)
|
||||
// AbsFHSEtc is [FHSEtc] as [Absolute].
|
||||
AbsFHSEtc = &Absolute{FHSEtc}
|
||||
AbsFHSEtc = unsafeAbs(FHSEtc)
|
||||
// AbsFHSTmp is [FHSTmp] as [Absolute].
|
||||
AbsFHSTmp = &Absolute{FHSTmp}
|
||||
AbsFHSTmp = unsafeAbs(FHSTmp)
|
||||
|
||||
// AbsFHSRun is [FHSRun] as [Absolute].
|
||||
AbsFHSRun = &Absolute{FHSRun}
|
||||
AbsFHSRun = unsafeAbs(FHSRun)
|
||||
// AbsFHSRunUser is [FHSRunUser] as [Absolute].
|
||||
AbsFHSRunUser = &Absolute{FHSRunUser}
|
||||
AbsFHSRunUser = unsafeAbs(FHSRunUser)
|
||||
|
||||
// AbsFHSUsrBin is [FHSUsrBin] as [Absolute].
|
||||
AbsFHSUsrBin = &Absolute{FHSUsrBin}
|
||||
AbsFHSUsrBin = unsafeAbs(FHSUsrBin)
|
||||
|
||||
// AbsFHSVar is [FHSVar] as [Absolute].
|
||||
AbsFHSVar = &Absolute{FHSVar}
|
||||
AbsFHSVar = unsafeAbs(FHSVar)
|
||||
// AbsFHSVarLib is [FHSVarLib] as [Absolute].
|
||||
AbsFHSVarLib = &Absolute{FHSVarLib}
|
||||
AbsFHSVarLib = unsafeAbs(FHSVarLib)
|
||||
|
||||
// AbsFHSDev is [FHSDev] as [Absolute].
|
||||
AbsFHSDev = &Absolute{FHSDev}
|
||||
AbsFHSDev = unsafeAbs(FHSDev)
|
||||
// AbsFHSProc is [FHSProc] as [Absolute].
|
||||
AbsFHSProc = &Absolute{FHSProc}
|
||||
AbsFHSProc = unsafeAbs(FHSProc)
|
||||
// AbsFHSSys is [FHSSys] as [Absolute].
|
||||
AbsFHSSys = &Absolute{FHSSys}
|
||||
AbsFHSSys = unsafeAbs(FHSSys)
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
Reference in New Issue
Block a user