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

This allows use of absolute pathname values without importing container.

Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
2025-10-07 20:06:26 +09:00
parent d23b4dc9e6
commit 0e6c1a5026
72 changed files with 815 additions and 742 deletions

View File

@@ -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)

View File

@@ -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"},
}},

View File

@@ -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

View File

@@ -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`},
})

View File

@@ -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

View File

@@ -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)
}
})

View File

@@ -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...)

View File

@@ -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...)
}

View File

@@ -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 {

View File

@@ -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"),

View File

@@ -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),

View File

@@ -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
}
}

View File

@@ -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`},
})

View File

@@ -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
}

View File

@@ -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/"`},
})
}

View File

@@ -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
}

View File

@@ -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 ----------`},
})
}

View File

@@ -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 }

View File

@@ -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`},
})
}

View File

@@ -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
}

View File

@@ -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,

View File

@@ -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 }

View File

@@ -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/"`},
})
}

View File

@@ -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
}

View File

@@ -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`},
})

View File

@@ -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

View File

@@ -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"`},

View File

@@ -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

View File

@@ -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,

View File

@@ -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 (