container/check: move absolute pathname
All checks were successful
Test / Create distribution (push) Successful in 34s
Test / Hpkg (push) Successful in 4m3s
Test / Sandbox (race detector) (push) Successful in 4m26s
Test / Hakurei (race detector) (push) Successful in 5m19s
Test / Sandbox (push) Successful in 1m28s
Test / Hakurei (push) Successful in 2m16s
Test / Flake checks (push) Successful in 1m37s
All checks were successful
Test / Create distribution (push) Successful in 34s
Test / Hpkg (push) Successful in 4m3s
Test / Sandbox (race detector) (push) Successful in 4m26s
Test / Hakurei (race detector) (push) Successful in 5m19s
Test / Sandbox (push) Successful in 1m28s
Test / Hakurei (push) Successful in 2m16s
Test / Flake checks (push) Successful in 1m37s
This allows use of absolute pathname values without importing container. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
parent
d23b4dc9e6
commit
0e6c1a5026
@ -16,6 +16,7 @@ import (
|
||||
|
||||
"hakurei.app/command"
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/hst"
|
||||
"hakurei.app/internal"
|
||||
"hakurei.app/internal/app"
|
||||
@ -107,7 +108,7 @@ func buildCommand(ctx context.Context, msg container.Msg, early *earlyHardeningE
|
||||
|
||||
// paths are identical, resolve inner shell and program path
|
||||
shell := container.AbsFHSRoot.Append("bin", "sh")
|
||||
if a, err := container.NewAbs(os.Getenv("SHELL")); err == nil {
|
||||
if a, err := check.NewAbs(os.Getenv("SHELL")); err == nil {
|
||||
shell = a
|
||||
}
|
||||
progPath := shell
|
||||
@ -115,7 +116,7 @@ func buildCommand(ctx context.Context, msg container.Msg, early *earlyHardeningE
|
||||
if p, err := exec.LookPath(args[0]); err != nil {
|
||||
log.Fatal(errors.Unwrap(err))
|
||||
return err
|
||||
} else if progPath, err = container.NewAbs(p); err != nil {
|
||||
} else if progPath, err = check.NewAbs(p); err != nil {
|
||||
log.Fatal(err.Error())
|
||||
return err
|
||||
}
|
||||
@ -201,7 +202,7 @@ func buildCommand(ctx context.Context, msg container.Msg, early *earlyHardeningE
|
||||
passwdOnce.Do(passwdFunc)
|
||||
homeDir = passwd.HomeDir
|
||||
}
|
||||
if a, err := container.NewAbs(homeDir); err != nil {
|
||||
if a, err := check.NewAbs(homeDir); err != nil {
|
||||
log.Fatal(err.Error())
|
||||
return err
|
||||
} else {
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"os"
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/hst"
|
||||
)
|
||||
|
||||
@ -54,14 +55,14 @@ type appInfo struct {
|
||||
// store path to nixGL source
|
||||
NixGL string `json:"nix_gl,omitempty"`
|
||||
// store path to activate-and-exec script
|
||||
Launcher *container.Absolute `json:"launcher"`
|
||||
Launcher *check.Absolute `json:"launcher"`
|
||||
// store path to /run/current-system
|
||||
CurrentSystem *container.Absolute `json:"current_system"`
|
||||
CurrentSystem *check.Absolute `json:"current_system"`
|
||||
// store path to home-manager activation package
|
||||
ActivationPackage string `json:"activation_package"`
|
||||
}
|
||||
|
||||
func (app *appInfo) toHst(pathSet *appPathSet, pathname *container.Absolute, argv []string, flagDropShell bool) *hst.Config {
|
||||
func (app *appInfo) toHst(pathSet *appPathSet, pathname *check.Absolute, argv []string, flagDropShell bool) *hst.Config {
|
||||
config := &hst.Config{
|
||||
ID: app.ID,
|
||||
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
|
||||
"hakurei.app/command"
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/hst"
|
||||
)
|
||||
|
||||
@ -79,11 +80,11 @@ func main() {
|
||||
Extract package and set up for cleanup.
|
||||
*/
|
||||
|
||||
var workDir *container.Absolute
|
||||
var workDir *check.Absolute
|
||||
if p, err := os.MkdirTemp("", "hpkg.*"); err != nil {
|
||||
log.Printf("cannot create temporary directory: %v", err)
|
||||
return err
|
||||
} else if workDir, err = container.NewAbs(p); err != nil {
|
||||
} else if workDir, err = check.NewAbs(p); err != nil {
|
||||
log.Printf("invalid temporary directory: %v", err)
|
||||
return err
|
||||
}
|
||||
|
@ -8,18 +8,19 @@ import (
|
||||
"sync/atomic"
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/hst"
|
||||
)
|
||||
|
||||
const bash = "bash"
|
||||
|
||||
var (
|
||||
dataHome *container.Absolute
|
||||
dataHome *check.Absolute
|
||||
)
|
||||
|
||||
func init() {
|
||||
// dataHome
|
||||
if a, err := container.NewAbs(os.Getenv("HAKUREI_DATA_HOME")); err == nil {
|
||||
if a, err := check.NewAbs(os.Getenv("HAKUREI_DATA_HOME")); err == nil {
|
||||
dataHome = a
|
||||
} else {
|
||||
dataHome = container.AbsFHSVarLib.Append("hakurei/" + strconv.Itoa(os.Getuid()))
|
||||
@ -29,13 +30,13 @@ func init() {
|
||||
var (
|
||||
pathBin = container.AbsFHSRoot.Append("bin")
|
||||
|
||||
pathNix = container.MustAbs("/nix/")
|
||||
pathNix = check.MustAbs("/nix/")
|
||||
pathNixStore = pathNix.Append("store/")
|
||||
pathCurrentSystem = container.AbsFHSRun.Append("current-system")
|
||||
pathSwBin = pathCurrentSystem.Append("sw/bin/")
|
||||
pathShell = pathSwBin.Append(bash)
|
||||
|
||||
pathData = container.MustAbs("/data")
|
||||
pathData = check.MustAbs("/data")
|
||||
pathDataData = pathData.Append("data")
|
||||
)
|
||||
|
||||
@ -64,15 +65,15 @@ func mustRun(msg container.Msg, name string, arg ...string) {
|
||||
|
||||
type appPathSet struct {
|
||||
// ${dataHome}/${id}
|
||||
baseDir *container.Absolute
|
||||
baseDir *check.Absolute
|
||||
// ${baseDir}/app
|
||||
metaPath *container.Absolute
|
||||
metaPath *check.Absolute
|
||||
// ${baseDir}/files
|
||||
homeDir *container.Absolute
|
||||
homeDir *check.Absolute
|
||||
// ${baseDir}/cache
|
||||
cacheDir *container.Absolute
|
||||
cacheDir *check.Absolute
|
||||
// ${baseDir}/cache/nix
|
||||
nixPath *container.Absolute
|
||||
nixPath *check.Absolute
|
||||
}
|
||||
|
||||
func pathSetByApp(id string) *appPathSet {
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/hst"
|
||||
)
|
||||
|
||||
@ -63,7 +64,7 @@ func withNixDaemon(
|
||||
func withCacheDir(
|
||||
ctx context.Context,
|
||||
msg container.Msg,
|
||||
action string, command []string, workDir *container.Absolute,
|
||||
action string, command []string, workDir *check.Absolute,
|
||||
app *appInfo, pathSet *appPathSet, dropShell bool, beforeFail func()) {
|
||||
mustRunAppDropShell(ctx, msg, &hst.Config{
|
||||
ID: app.ID,
|
||||
|
@ -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,7 +59,7 @@ func (e *AutoEtcOp) apply(state *setupState, k syscallDispatcher) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *AutoEtcOp) hostPath() *Absolute { return AbsFHSEtc.Append(e.hostRel()) }
|
||||
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 {
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/stub"
|
||||
)
|
||||
|
||||
@ -256,11 +257,11 @@ func TestAutoEtcOp(t *testing.T) {
|
||||
})
|
||||
|
||||
checkOpsBuilder(t, []opsBuilderTestCase{
|
||||
{"pd", new(Ops).Etc(MustAbs("/etc/"), "048090b6ed8f9ebb10e275ff5d8c0659"), Ops{
|
||||
&MkdirOp{Path: MustAbs("/etc/"), Perm: 0755},
|
||||
{"pd", new(Ops).Etc(check.MustAbs("/etc/"), "048090b6ed8f9ebb10e275ff5d8c0659"), Ops{
|
||||
&MkdirOp{Path: check.MustAbs("/etc/"), Perm: 0755},
|
||||
&BindMountOp{
|
||||
Source: MustAbs("/etc/"),
|
||||
Target: MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
Source: check.MustAbs("/etc/"),
|
||||
Target: check.MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
},
|
||||
&AutoEtcOp{Prefix: "048090b6ed8f9ebb10e275ff5d8c0659"},
|
||||
}},
|
||||
|
@ -3,19 +3,21 @@ package container
|
||||
import (
|
||||
"encoding/gob"
|
||||
"fmt"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
)
|
||||
|
||||
func init() { gob.Register(new(AutoRootOp)) }
|
||||
|
||||
// Root appends an [Op] that expands a directory into a toplevel bind mount mirror on container root.
|
||||
// This is not a generic setup op. It is implemented here to reduce ipc overhead.
|
||||
func (f *Ops) Root(host *Absolute, flags int) *Ops {
|
||||
func (f *Ops) Root(host *check.Absolute, flags int) *Ops {
|
||||
*f = append(*f, &AutoRootOp{host, flags, nil})
|
||||
return f
|
||||
}
|
||||
|
||||
type AutoRootOp struct {
|
||||
Host *Absolute
|
||||
Host *check.Absolute
|
||||
// passed through to bindMount
|
||||
Flags int
|
||||
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/stub"
|
||||
)
|
||||
|
||||
@ -18,14 +19,14 @@ func TestAutoRootOp(t *testing.T) {
|
||||
|
||||
checkOpBehaviour(t, []opBehaviourTestCase{
|
||||
{"readdir", &Params{ParentPerm: 0750}, &AutoRootOp{
|
||||
Host: MustAbs("/"),
|
||||
Host: check.MustAbs("/"),
|
||||
Flags: BindWritable,
|
||||
}, []stub.Call{
|
||||
call("readdir", stub.ExpectArgs{"/"}, stubDir(), stub.UniqueError(2)),
|
||||
}, stub.UniqueError(2), nil, nil},
|
||||
|
||||
{"early", &Params{ParentPerm: 0750}, &AutoRootOp{
|
||||
Host: MustAbs("/"),
|
||||
Host: check.MustAbs("/"),
|
||||
Flags: BindWritable,
|
||||
}, []stub.Call{
|
||||
call("readdir", stub.ExpectArgs{"/"}, stubDir("bin", "dev", "etc", "home", "lib64",
|
||||
@ -34,7 +35,7 @@ func TestAutoRootOp(t *testing.T) {
|
||||
}, stub.UniqueError(1), nil, nil},
|
||||
|
||||
{"apply", &Params{ParentPerm: 0750}, &AutoRootOp{
|
||||
Host: MustAbs("/"),
|
||||
Host: check.MustAbs("/"),
|
||||
Flags: BindWritable,
|
||||
}, []stub.Call{
|
||||
call("readdir", stub.ExpectArgs{"/"}, stubDir("bin", "dev", "etc", "home", "lib64",
|
||||
@ -55,7 +56,7 @@ func TestAutoRootOp(t *testing.T) {
|
||||
}, stub.UniqueError(0)},
|
||||
|
||||
{"success pd", &Params{ParentPerm: 0750}, &AutoRootOp{
|
||||
Host: MustAbs("/"),
|
||||
Host: check.MustAbs("/"),
|
||||
Flags: BindWritable,
|
||||
}, []stub.Call{
|
||||
call("readdir", stub.ExpectArgs{"/"}, stubDir("bin", "dev", "etc", "home", "lib64",
|
||||
@ -86,7 +87,7 @@ func TestAutoRootOp(t *testing.T) {
|
||||
}, nil},
|
||||
|
||||
{"success", &Params{ParentPerm: 0750}, &AutoRootOp{
|
||||
Host: MustAbs("/var/lib/planterette/base/debian:f92c9052"),
|
||||
Host: check.MustAbs("/var/lib/planterette/base/debian:f92c9052"),
|
||||
}, []stub.Call{
|
||||
call("readdir", stub.ExpectArgs{"/var/lib/planterette/base/debian:f92c9052"}, stubDir("bin", "dev", "etc", "home", "lib64",
|
||||
"lost+found", "mnt", "nix", "proc", "root", "run", "srv", "sys", "tmp", "usr", "var"), nil),
|
||||
@ -119,13 +120,13 @@ func TestAutoRootOp(t *testing.T) {
|
||||
checkOpsValid(t, []opValidTestCase{
|
||||
{"nil", (*AutoRootOp)(nil), false},
|
||||
{"zero", new(AutoRootOp), false},
|
||||
{"valid", &AutoRootOp{Host: MustAbs("/")}, true},
|
||||
{"valid", &AutoRootOp{Host: check.MustAbs("/")}, true},
|
||||
})
|
||||
|
||||
checkOpsBuilder(t, []opsBuilderTestCase{
|
||||
{"pd", new(Ops).Root(MustAbs("/"), BindWritable), Ops{
|
||||
{"pd", new(Ops).Root(check.MustAbs("/"), BindWritable), Ops{
|
||||
&AutoRootOp{
|
||||
Host: MustAbs("/"),
|
||||
Host: check.MustAbs("/"),
|
||||
Flags: BindWritable,
|
||||
},
|
||||
}},
|
||||
@ -135,42 +136,42 @@ func TestAutoRootOp(t *testing.T) {
|
||||
{"zero", new(AutoRootOp), new(AutoRootOp), false},
|
||||
|
||||
{"internal ne", &AutoRootOp{
|
||||
Host: MustAbs("/"),
|
||||
Host: check.MustAbs("/"),
|
||||
Flags: BindWritable,
|
||||
}, &AutoRootOp{
|
||||
Host: MustAbs("/"),
|
||||
Host: check.MustAbs("/"),
|
||||
Flags: BindWritable,
|
||||
resolved: []*BindMountOp{new(BindMountOp)},
|
||||
}, true},
|
||||
|
||||
{"flags differs", &AutoRootOp{
|
||||
Host: MustAbs("/"),
|
||||
Host: check.MustAbs("/"),
|
||||
Flags: BindWritable | BindDevice,
|
||||
}, &AutoRootOp{
|
||||
Host: MustAbs("/"),
|
||||
Host: check.MustAbs("/"),
|
||||
Flags: BindWritable,
|
||||
}, false},
|
||||
|
||||
{"host differs", &AutoRootOp{
|
||||
Host: MustAbs("/tmp/"),
|
||||
Host: check.MustAbs("/tmp/"),
|
||||
Flags: BindWritable,
|
||||
}, &AutoRootOp{
|
||||
Host: MustAbs("/"),
|
||||
Host: check.MustAbs("/"),
|
||||
Flags: BindWritable,
|
||||
}, false},
|
||||
|
||||
{"equals", &AutoRootOp{
|
||||
Host: MustAbs("/"),
|
||||
Host: check.MustAbs("/"),
|
||||
Flags: BindWritable,
|
||||
}, &AutoRootOp{
|
||||
Host: MustAbs("/"),
|
||||
Host: check.MustAbs("/"),
|
||||
Flags: BindWritable,
|
||||
}, true},
|
||||
})
|
||||
|
||||
checkOpMeta(t, []opMetaTestCase{
|
||||
{"root", &AutoRootOp{
|
||||
Host: MustAbs("/"),
|
||||
Host: check.MustAbs("/"),
|
||||
Flags: BindWritable,
|
||||
}, "setting up", `auto root "/" flags 0x2`},
|
||||
})
|
||||
|
@ -1,4 +1,5 @@
|
||||
package container
|
||||
// Package check provides types yielding values checked to meet a condition.
|
||||
package check
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
@ -11,9 +12,7 @@ import (
|
||||
)
|
||||
|
||||
// AbsoluteError is returned by [NewAbs] and holds the invalid pathname.
|
||||
type AbsoluteError struct {
|
||||
Pathname string
|
||||
}
|
||||
type AbsoluteError struct{ Pathname string }
|
||||
|
||||
func (e *AbsoluteError) Error() string { return fmt.Sprintf("path %q is not absolute", e.Pathname) }
|
||||
func (e *AbsoluteError) Is(target error) bool {
|
||||
@ -25,15 +24,13 @@ func (e *AbsoluteError) Is(target error) bool {
|
||||
}
|
||||
|
||||
// Absolute holds a pathname checked to be absolute.
|
||||
type Absolute struct {
|
||||
pathname string
|
||||
}
|
||||
type Absolute struct{ pathname string }
|
||||
|
||||
// isAbs wraps [path.IsAbs] in case additional checks are added in the future.
|
||||
func isAbs(pathname string) bool { return path.IsAbs(pathname) }
|
||||
// unsafeAbs returns [check.Absolute] on any string value.
|
||||
func unsafeAbs(pathname string) *Absolute { return &Absolute{pathname} }
|
||||
|
||||
func (a *Absolute) String() string {
|
||||
if a.pathname == zeroString {
|
||||
if a.pathname == "" {
|
||||
panic("attempted use of zero Absolute")
|
||||
}
|
||||
return a.pathname
|
||||
@ -44,16 +41,16 @@ func (a *Absolute) Is(v *Absolute) bool {
|
||||
return true
|
||||
}
|
||||
return a != nil && v != nil &&
|
||||
a.pathname != zeroString && v.pathname != zeroString &&
|
||||
a.pathname != "" && v.pathname != "" &&
|
||||
a.pathname == v.pathname
|
||||
}
|
||||
|
||||
// NewAbs checks pathname and returns a new [Absolute] if pathname is absolute.
|
||||
func NewAbs(pathname string) (*Absolute, error) {
|
||||
if !isAbs(pathname) {
|
||||
if !path.IsAbs(pathname) {
|
||||
return nil, &AbsoluteError{pathname}
|
||||
}
|
||||
return &Absolute{pathname}, nil
|
||||
return unsafeAbs(pathname), nil
|
||||
}
|
||||
|
||||
// MustAbs calls [NewAbs] and panics on error.
|
||||
@ -67,16 +64,16 @@ func MustAbs(pathname string) *Absolute {
|
||||
|
||||
// Append calls [path.Join] with [Absolute] as the first element.
|
||||
func (a *Absolute) Append(elem ...string) *Absolute {
|
||||
return &Absolute{path.Join(append([]string{a.String()}, elem...)...)}
|
||||
return unsafeAbs(path.Join(append([]string{a.String()}, elem...)...))
|
||||
}
|
||||
|
||||
// Dir calls [path.Dir] with [Absolute] as its argument.
|
||||
func (a *Absolute) Dir() *Absolute { return &Absolute{path.Dir(a.String())} }
|
||||
func (a *Absolute) Dir() *Absolute { return unsafeAbs(path.Dir(a.String())) }
|
||||
|
||||
func (a *Absolute) GobEncode() ([]byte, error) { return []byte(a.String()), nil }
|
||||
func (a *Absolute) GobDecode(data []byte) error {
|
||||
pathname := string(data)
|
||||
if !isAbs(pathname) {
|
||||
if !path.IsAbs(pathname) {
|
||||
return &AbsoluteError{pathname}
|
||||
}
|
||||
a.pathname = pathname
|
||||
@ -89,7 +86,7 @@ func (a *Absolute) UnmarshalJSON(data []byte) error {
|
||||
if err := json.Unmarshal(data, &pathname); err != nil {
|
||||
return err
|
||||
}
|
||||
if !isAbs(pathname) {
|
||||
if !path.IsAbs(pathname) {
|
||||
return &AbsoluteError{pathname}
|
||||
}
|
||||
a.pathname = pathname
|
@ -1,4 +1,4 @@
|
||||
package container
|
||||
package check_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@ -9,8 +9,14 @@ import (
|
||||
"strings"
|
||||
"syscall"
|
||||
"testing"
|
||||
_ "unsafe"
|
||||
|
||||
. "hakurei.app/container/check"
|
||||
)
|
||||
|
||||
//go:linkname unsafeAbs hakurei.app/container/check.unsafeAbs
|
||||
func unsafeAbs(_ string) *Absolute
|
||||
|
||||
func TestAbsoluteError(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
@ -80,7 +86,7 @@ func TestNewAbs(t *testing.T) {
|
||||
func TestAbsoluteString(t *testing.T) {
|
||||
t.Run("passthrough", func(t *testing.T) {
|
||||
pathname := "/etc"
|
||||
if got := (&Absolute{pathname}).String(); got != pathname {
|
||||
if got := unsafeAbs(pathname).String(); got != pathname {
|
||||
t.Errorf("String: %q, want %q", got, pathname)
|
||||
}
|
||||
})
|
@ -15,6 +15,7 @@ import (
|
||||
"time"
|
||||
|
||||
"hakurei.app/container/bits"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/seccomp"
|
||||
)
|
||||
|
||||
@ -57,11 +58,11 @@ type (
|
||||
// Params holds container configuration and is safe to serialise.
|
||||
Params struct {
|
||||
// Working directory in the container.
|
||||
Dir *Absolute
|
||||
Dir *check.Absolute
|
||||
// Initial process environment.
|
||||
Env []string
|
||||
// Pathname of initial process in the container.
|
||||
Path *Absolute
|
||||
Path *check.Absolute
|
||||
// Initial process argv.
|
||||
Args []string
|
||||
// Deliver SIGINT to the initial process on context cancellation.
|
||||
@ -407,7 +408,7 @@ func New(ctx context.Context, msg Msg) *Container {
|
||||
}
|
||||
|
||||
// NewCommand calls [New] and initialises the [Params.Path] and [Params.Args] fields.
|
||||
func NewCommand(ctx context.Context, msg Msg, pathname *Absolute, name string, args ...string) *Container {
|
||||
func NewCommand(ctx context.Context, msg Msg, pathname *check.Absolute, name string, args ...string) *Container {
|
||||
z := New(ctx, msg)
|
||||
z.Path = pathname
|
||||
z.Args = append([]string{name}, args...)
|
||||
|
@ -21,6 +21,7 @@ import (
|
||||
"hakurei.app/command"
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/bits"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/seccomp"
|
||||
"hakurei.app/container/vfs"
|
||||
"hakurei.app/hst"
|
||||
@ -226,7 +227,7 @@ var containerTestCases = []struct {
|
||||
|
||||
{"dev", true, true /* go test output is not a tty */, false, false,
|
||||
earlyOps(new(container.Ops).
|
||||
Dev(container.MustAbs("/dev"), true),
|
||||
Dev(check.MustAbs("/dev"), true),
|
||||
),
|
||||
earlyMnt(
|
||||
ent("/", "/dev", "ro,nosuid,nodev,relatime", "tmpfs", "devtmpfs", ignore),
|
||||
@ -244,7 +245,7 @@ var containerTestCases = []struct {
|
||||
|
||||
{"dev no mqueue", true, true /* go test output is not a tty */, false, false,
|
||||
earlyOps(new(container.Ops).
|
||||
Dev(container.MustAbs("/dev"), false),
|
||||
Dev(check.MustAbs("/dev"), false),
|
||||
),
|
||||
earlyMnt(
|
||||
ent("/", "/dev", "ro,nosuid,nodev,relatime", "tmpfs", "devtmpfs", ignore),
|
||||
@ -261,13 +262,13 @@ var containerTestCases = []struct {
|
||||
|
||||
{"overlay", true, false, false, true,
|
||||
func(t *testing.T) (*container.Ops, context.Context) {
|
||||
tempDir := container.MustAbs(t.TempDir())
|
||||
tempDir := check.MustAbs(t.TempDir())
|
||||
lower0, lower1, upper, work :=
|
||||
tempDir.Append("lower0"),
|
||||
tempDir.Append("lower1"),
|
||||
tempDir.Append("upper"),
|
||||
tempDir.Append("work")
|
||||
for _, a := range []*container.Absolute{lower0, lower1, upper, work} {
|
||||
for _, a := range []*check.Absolute{lower0, lower1, upper, work} {
|
||||
if err := os.Mkdir(a.String(), 0755); err != nil {
|
||||
t.Fatalf("Mkdir: error = %v", err)
|
||||
}
|
||||
@ -285,12 +286,12 @@ var containerTestCases = []struct {
|
||||
return []*vfs.MountInfoEntry{
|
||||
ent("/", hst.Tmp, "rw", "overlay", "overlay",
|
||||
"rw,lowerdir="+
|
||||
container.InternalToHostOvlEscape(ctx.Value(testVal("lower0")).(*container.Absolute).String())+":"+
|
||||
container.InternalToHostOvlEscape(ctx.Value(testVal("lower1")).(*container.Absolute).String())+
|
||||
container.InternalToHostOvlEscape(ctx.Value(testVal("lower0")).(*check.Absolute).String())+":"+
|
||||
container.InternalToHostOvlEscape(ctx.Value(testVal("lower1")).(*check.Absolute).String())+
|
||||
",upperdir="+
|
||||
container.InternalToHostOvlEscape(ctx.Value(testVal("upper")).(*container.Absolute).String())+
|
||||
container.InternalToHostOvlEscape(ctx.Value(testVal("upper")).(*check.Absolute).String())+
|
||||
",workdir="+
|
||||
container.InternalToHostOvlEscape(ctx.Value(testVal("work")).(*container.Absolute).String())+
|
||||
container.InternalToHostOvlEscape(ctx.Value(testVal("work")).(*check.Absolute).String())+
|
||||
",redirect_dir=nofollow,uuid=on,userxattr"),
|
||||
}
|
||||
},
|
||||
@ -298,11 +299,11 @@ var containerTestCases = []struct {
|
||||
|
||||
{"overlay ephemeral", true, false, false, true,
|
||||
func(t *testing.T) (*container.Ops, context.Context) {
|
||||
tempDir := container.MustAbs(t.TempDir())
|
||||
tempDir := check.MustAbs(t.TempDir())
|
||||
lower0, lower1 :=
|
||||
tempDir.Append("lower0"),
|
||||
tempDir.Append("lower1")
|
||||
for _, a := range []*container.Absolute{lower0, lower1} {
|
||||
for _, a := range []*check.Absolute{lower0, lower1} {
|
||||
if err := os.Mkdir(a.String(), 0755); err != nil {
|
||||
t.Fatalf("Mkdir: error = %v", err)
|
||||
}
|
||||
@ -322,11 +323,11 @@ var containerTestCases = []struct {
|
||||
|
||||
{"overlay readonly", true, false, false, true,
|
||||
func(t *testing.T) (*container.Ops, context.Context) {
|
||||
tempDir := container.MustAbs(t.TempDir())
|
||||
tempDir := check.MustAbs(t.TempDir())
|
||||
lower0, lower1 :=
|
||||
tempDir.Append("lower0"),
|
||||
tempDir.Append("lower1")
|
||||
for _, a := range []*container.Absolute{lower0, lower1} {
|
||||
for _, a := range []*check.Absolute{lower0, lower1} {
|
||||
if err := os.Mkdir(a.String(), 0755); err != nil {
|
||||
t.Fatalf("Mkdir: error = %v", err)
|
||||
}
|
||||
@ -341,8 +342,8 @@ var containerTestCases = []struct {
|
||||
return []*vfs.MountInfoEntry{
|
||||
ent("/", hst.Tmp, "rw", "overlay", "overlay",
|
||||
"ro,lowerdir="+
|
||||
container.InternalToHostOvlEscape(ctx.Value(testVal("lower0")).(*container.Absolute).String())+":"+
|
||||
container.InternalToHostOvlEscape(ctx.Value(testVal("lower1")).(*container.Absolute).String())+
|
||||
container.InternalToHostOvlEscape(ctx.Value(testVal("lower0")).(*check.Absolute).String())+":"+
|
||||
container.InternalToHostOvlEscape(ctx.Value(testVal("lower1")).(*check.Absolute).String())+
|
||||
",redirect_dir=nofollow,userxattr"),
|
||||
}
|
||||
},
|
||||
@ -389,7 +390,7 @@ func TestContainer(t *testing.T) {
|
||||
ctx, cancel := context.WithTimeout(t.Context(), helperDefaultTimeout)
|
||||
defer cancel()
|
||||
|
||||
var libPaths []*container.Absolute
|
||||
var libPaths []*check.Absolute
|
||||
c := helperNewContainerLibPaths(ctx, &libPaths, "container", strconv.Itoa(i))
|
||||
c.Uid = tc.uid
|
||||
c.Gid = tc.gid
|
||||
@ -410,11 +411,11 @@ func TestContainer(t *testing.T) {
|
||||
c.HostNet = tc.net
|
||||
|
||||
c.
|
||||
Readonly(container.MustAbs(pathReadonly), 0755).
|
||||
Tmpfs(container.MustAbs("/tmp"), 0, 0755).
|
||||
Place(container.MustAbs("/etc/hostname"), []byte(c.Hostname))
|
||||
Readonly(check.MustAbs(pathReadonly), 0755).
|
||||
Tmpfs(check.MustAbs("/tmp"), 0, 0755).
|
||||
Place(check.MustAbs("/etc/hostname"), []byte(c.Hostname))
|
||||
// needs /proc to check mountinfo
|
||||
c.Proc(container.MustAbs("/proc"))
|
||||
c.Proc(check.MustAbs("/proc"))
|
||||
|
||||
// mountinfo cannot be resolved directly by helper due to libPaths nondeterminism
|
||||
mnt := make([]*vfs.MountInfoEntry, 0, 3+len(libPaths))
|
||||
@ -445,10 +446,10 @@ func TestContainer(t *testing.T) {
|
||||
_, _ = output.WriteTo(os.Stdout)
|
||||
t.Fatalf("cannot serialise expected mount points: %v", err)
|
||||
}
|
||||
c.Place(container.MustAbs(pathWantMnt), want.Bytes())
|
||||
c.Place(check.MustAbs(pathWantMnt), want.Bytes())
|
||||
|
||||
if tc.ro {
|
||||
c.Remount(container.MustAbs("/"), syscall.MS_RDONLY)
|
||||
c.Remount(check.MustAbs("/"), syscall.MS_RDONLY)
|
||||
}
|
||||
|
||||
if err := c.Start(); err != nil {
|
||||
@ -545,7 +546,7 @@ func testContainerCancel(
|
||||
|
||||
func TestContainerString(t *testing.T) {
|
||||
msg := container.NewMsg(nil)
|
||||
c := container.NewCommand(t.Context(), msg, container.MustAbs("/run/current-system/sw/bin/ldd"), "ldd", "/usr/bin/env")
|
||||
c := container.NewCommand(t.Context(), msg, check.MustAbs("/run/current-system/sw/bin/ldd"), "ldd", "/usr/bin/env")
|
||||
c.SeccompFlags |= seccomp.AllowMultiarch
|
||||
c.SeccompRules = seccomp.Preset(
|
||||
bits.PresetExt|bits.PresetDenyNS|bits.PresetDenyTTY,
|
||||
@ -681,7 +682,7 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
absHelperInnerPath = container.MustAbs(helperInnerPath)
|
||||
absHelperInnerPath = check.MustAbs(helperInnerPath)
|
||||
)
|
||||
|
||||
var helperCommands []func(c command.Command)
|
||||
@ -709,11 +710,11 @@ func TestMain(m *testing.M) {
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
|
||||
func helperNewContainerLibPaths(ctx context.Context, libPaths *[]*container.Absolute, args ...string) (c *container.Container) {
|
||||
func helperNewContainerLibPaths(ctx context.Context, libPaths *[]*check.Absolute, args ...string) (c *container.Container) {
|
||||
msg := container.NewMsg(nil)
|
||||
c = container.NewCommand(ctx, msg, absHelperInnerPath, "helper", args...)
|
||||
c.Env = append(c.Env, envDoCheck+"=1")
|
||||
c.Bind(container.MustAbs(os.Args[0]), absHelperInnerPath, 0)
|
||||
c.Bind(check.MustAbs(os.Args[0]), absHelperInnerPath, 0)
|
||||
|
||||
// in case test has cgo enabled
|
||||
if entries, err := ldd.Exec(ctx, msg, os.Args[0]); err != nil {
|
||||
@ -729,5 +730,5 @@ func helperNewContainerLibPaths(ctx context.Context, libPaths *[]*container.Abso
|
||||
}
|
||||
|
||||
func helperNewContainer(ctx context.Context, args ...string) (c *container.Container) {
|
||||
return helperNewContainerLibPaths(ctx, new([]*container.Absolute), args...)
|
||||
return helperNewContainerLibPaths(ctx, new([]*check.Absolute), args...)
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"os"
|
||||
"syscall"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/vfs"
|
||||
)
|
||||
|
||||
@ -16,7 +17,7 @@ func messageFromError(err error) (string, bool) {
|
||||
if m, ok := messagePrefixP[os.PathError]("cannot ", err); ok {
|
||||
return m, ok
|
||||
}
|
||||
if m, ok := messagePrefixP[AbsoluteError]("", err); ok {
|
||||
if m, ok := messagePrefixP[check.AbsoluteError]("", err); ok {
|
||||
return m, ok
|
||||
}
|
||||
if m, ok := messagePrefix[OpRepeatError]("", err); ok {
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
"syscall"
|
||||
"testing"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/stub"
|
||||
"hakurei.app/container/vfs"
|
||||
)
|
||||
@ -34,7 +35,7 @@ func TestMessageFromError(t *testing.T) {
|
||||
Err: stub.UniqueError(0xdeadbeef),
|
||||
}, "cannot mount /sysroot: unique error 3735928559 injected by the test suite", true},
|
||||
|
||||
{"absolute", &AbsoluteError{"etc/mtab"},
|
||||
{"absolute", &check.AbsoluteError{Pathname: "etc/mtab"},
|
||||
`path "etc/mtab" is not absolute`, true},
|
||||
|
||||
{"repeat", OpRepeatError("autoetc"),
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
"time"
|
||||
|
||||
"hakurei.app/container/bits"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/seccomp"
|
||||
"hakurei.app/container/stub"
|
||||
)
|
||||
@ -58,9 +59,9 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
@ -82,9 +83,9 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
@ -110,9 +111,9 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
@ -139,9 +140,9 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
@ -169,9 +170,9 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
@ -200,9 +201,9 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
@ -232,9 +233,9 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
@ -266,9 +267,9 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
@ -302,9 +303,9 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
@ -340,9 +341,9 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
@ -378,16 +379,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@ -417,16 +418,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@ -456,16 +457,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@ -496,16 +497,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@ -537,16 +538,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@ -579,16 +580,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@ -622,16 +623,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@ -666,16 +667,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@ -711,16 +712,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@ -757,16 +758,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@ -798,7 +799,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
|
||||
call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, stub.UniqueError(44)),
|
||||
call("fatalf", stub.ExpectArgs{"cannot apply op at index %d: %v", []any{1, stub.UniqueError(44)}}, nil, nil),
|
||||
@ -812,16 +813,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@ -853,7 +854,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
|
||||
call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, &MountError{"proc", "/sysroot/proc", "proc", uintptr(0xe), "", syscall.ENOTRECOVERABLE}),
|
||||
call("fatal", stub.ExpectArgs{[]any{"cannot mount proc on /sysroot/proc: state not recoverable"}}, nil, nil),
|
||||
@ -867,16 +868,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@ -908,7 +909,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
|
||||
call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil),
|
||||
/* end apply */
|
||||
@ -923,16 +924,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@ -964,7 +965,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
|
||||
call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil),
|
||||
/* end apply */
|
||||
@ -980,16 +981,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@ -1021,7 +1022,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
|
||||
call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil),
|
||||
/* end apply */
|
||||
@ -1039,16 +1040,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@ -1080,7 +1081,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
|
||||
call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil),
|
||||
/* end apply */
|
||||
@ -1099,16 +1100,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@ -1140,7 +1141,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
|
||||
call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil),
|
||||
/* end apply */
|
||||
@ -1160,16 +1161,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@ -1201,7 +1202,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
|
||||
call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil),
|
||||
/* end apply */
|
||||
@ -1222,16 +1223,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@ -1263,7 +1264,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
|
||||
call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil),
|
||||
/* end apply */
|
||||
@ -1285,16 +1286,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@ -1326,7 +1327,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
|
||||
call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil),
|
||||
/* end apply */
|
||||
@ -1349,16 +1350,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@ -1390,7 +1391,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
|
||||
call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil),
|
||||
/* end apply */
|
||||
@ -1414,16 +1415,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@ -1455,7 +1456,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
|
||||
call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil),
|
||||
/* end apply */
|
||||
@ -1480,16 +1481,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@ -1521,7 +1522,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
|
||||
call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil),
|
||||
/* end apply */
|
||||
@ -1554,16 +1555,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@ -1595,7 +1596,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
|
||||
call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil),
|
||||
/* end apply */
|
||||
@ -1661,16 +1662,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@ -1702,7 +1703,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
|
||||
call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil),
|
||||
/* end apply */
|
||||
@ -1769,16 +1770,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@ -1810,7 +1811,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
|
||||
call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil),
|
||||
/* end apply */
|
||||
@ -1880,15 +1881,15 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, 0, stub.UniqueError(14)),
|
||||
call("verbosef", stub.ExpectArgs{"cannot enable ptrace protection via Yama LSM: %v", []any{stub.UniqueError(14)}}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei/nonexistent"),
|
||||
Path: MustAbs("/run/current-system/sw/bin/bash"),
|
||||
Dir: check.MustAbs("/.hakurei/nonexistent"),
|
||||
Path: check.MustAbs("/run/current-system/sw/bin/bash"),
|
||||
Args: []string{"bash", "-c", "false"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 24,
|
||||
Gid: 1 << 47,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompDisable: true,
|
||||
ParentPerm: 0750,
|
||||
@ -1919,7 +1920,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
|
||||
call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0750)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil),
|
||||
/* end apply */
|
||||
@ -1980,7 +1981,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("newFile", stub.ExpectArgs{uintptr(0x3a), "extra file 0"}, (*os.File)(nil), nil),
|
||||
call("newFile", stub.ExpectArgs{uintptr(0x3b), "extra file 1"}, (*os.File)(nil), nil),
|
||||
call("umask", stub.ExpectArgs{022}, 0, nil),
|
||||
call("verbosef", stub.ExpectArgs{"starting initial program %s", []any{MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"starting initial program %s", []any{check.MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil),
|
||||
call("start", stub.ExpectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent"}, nil, stub.UniqueError(12)),
|
||||
call("fatalf", stub.ExpectArgs{"%v", []any{stub.UniqueError(12)}}, nil, nil),
|
||||
},
|
||||
@ -1994,15 +1995,15 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, 0, stub.UniqueError(11)),
|
||||
call("verbosef", stub.ExpectArgs{"cannot enable ptrace protection via Yama LSM: %v", []any{stub.UniqueError(11)}}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei/nonexistent"),
|
||||
Path: MustAbs("/run/current-system/sw/bin/bash"),
|
||||
Dir: check.MustAbs("/.hakurei/nonexistent"),
|
||||
Path: check.MustAbs("/run/current-system/sw/bin/bash"),
|
||||
Args: []string{"bash", "-c", "false"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Nanosecond,
|
||||
Uid: 1 << 24,
|
||||
Gid: 1 << 47,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompDisable: true,
|
||||
ParentPerm: 0750,
|
||||
@ -2033,7 +2034,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
|
||||
call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0750)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil),
|
||||
/* end apply */
|
||||
@ -2058,7 +2059,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("newFile", stub.ExpectArgs{uintptr(0x3a), "extra file 0"}, (*os.File)(nil), nil),
|
||||
call("newFile", stub.ExpectArgs{uintptr(0x3b), "extra file 1"}, (*os.File)(nil), nil),
|
||||
call("umask", stub.ExpectArgs{022}, 0, nil),
|
||||
call("verbosef", stub.ExpectArgs{"starting initial program %s", []any{MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"starting initial program %s", []any{check.MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil),
|
||||
call("start", stub.ExpectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent"}, &os.Process{Pid: 0xbad}, nil),
|
||||
call("suspend", stub.ExpectArgs{}, true, nil),
|
||||
call("printf", stub.ExpectArgs{"cannot close setup pipe: %v", []any{stub.UniqueError(10)}}, nil, nil),
|
||||
@ -2094,15 +2095,15 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, 0, stub.UniqueError(8)),
|
||||
call("verbosef", stub.ExpectArgs{"cannot enable ptrace protection via Yama LSM: %v", []any{stub.UniqueError(8)}}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei/nonexistent"),
|
||||
Path: MustAbs("/run/current-system/sw/bin/bash"),
|
||||
Dir: check.MustAbs("/.hakurei/nonexistent"),
|
||||
Path: check.MustAbs("/run/current-system/sw/bin/bash"),
|
||||
Args: []string{"bash", "-c", "false"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Nanosecond,
|
||||
Uid: 1 << 24,
|
||||
Gid: 1 << 47,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompDisable: true,
|
||||
ParentPerm: 0750,
|
||||
@ -2133,7 +2134,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
|
||||
call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0750)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil),
|
||||
/* end apply */
|
||||
@ -2158,7 +2159,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("newFile", stub.ExpectArgs{uintptr(0x3a), "extra file 0"}, (*os.File)(nil), nil),
|
||||
call("newFile", stub.ExpectArgs{uintptr(0x3b), "extra file 1"}, (*os.File)(nil), nil),
|
||||
call("umask", stub.ExpectArgs{022}, 0, nil),
|
||||
call("verbosef", stub.ExpectArgs{"starting initial program %s", []any{MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"starting initial program %s", []any{check.MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil),
|
||||
call("start", stub.ExpectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent"}, &os.Process{Pid: 0xbad}, nil),
|
||||
call("suspend", stub.ExpectArgs{}, true, nil),
|
||||
call("printf", stub.ExpectArgs{"cannot close setup pipe: %v", []any{stub.UniqueError(7)}}, nil, nil),
|
||||
@ -2185,15 +2186,15 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, 0, stub.UniqueError(6)),
|
||||
call("verbosef", stub.ExpectArgs{"cannot enable ptrace protection via Yama LSM: %v", []any{stub.UniqueError(6)}}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei/nonexistent"),
|
||||
Path: MustAbs("/run/current-system/sw/bin/bash"),
|
||||
Dir: check.MustAbs("/.hakurei/nonexistent"),
|
||||
Path: check.MustAbs("/run/current-system/sw/bin/bash"),
|
||||
Args: []string{"bash", "-c", "false"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Nanosecond,
|
||||
Uid: 1 << 24,
|
||||
Gid: 1 << 47,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompDisable: true,
|
||||
ParentPerm: 0750,
|
||||
@ -2224,7 +2225,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
|
||||
call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0750)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil),
|
||||
/* end apply */
|
||||
@ -2249,7 +2250,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("newFile", stub.ExpectArgs{uintptr(0x3a), "extra file 0"}, (*os.File)(nil), nil),
|
||||
call("newFile", stub.ExpectArgs{uintptr(0x3b), "extra file 1"}, (*os.File)(nil), nil),
|
||||
call("umask", stub.ExpectArgs{022}, 0, nil),
|
||||
call("verbosef", stub.ExpectArgs{"starting initial program %s", []any{MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"starting initial program %s", []any{check.MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil),
|
||||
call("start", stub.ExpectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent"}, &os.Process{Pid: 0xbad}, nil),
|
||||
call("suspend", stub.ExpectArgs{}, true, nil),
|
||||
call("printf", stub.ExpectArgs{"cannot close setup pipe: %v", []any{stub.UniqueError(5)}}, nil, nil),
|
||||
@ -2278,15 +2279,15 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, 0, stub.UniqueError(4)),
|
||||
call("verbosef", stub.ExpectArgs{"cannot enable ptrace protection via Yama LSM: %v", []any{stub.UniqueError(4)}}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei/nonexistent"),
|
||||
Path: MustAbs("/run/current-system/sw/bin/bash"),
|
||||
Dir: check.MustAbs("/.hakurei/nonexistent"),
|
||||
Path: check.MustAbs("/run/current-system/sw/bin/bash"),
|
||||
Args: []string{"bash", "-c", "false"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 24,
|
||||
Gid: 1 << 47,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompDisable: true,
|
||||
ParentPerm: 0750,
|
||||
@ -2317,7 +2318,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
|
||||
call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0750)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil),
|
||||
/* end apply */
|
||||
@ -2342,7 +2343,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("newFile", stub.ExpectArgs{uintptr(0x3a), "extra file 0"}, (*os.File)(nil), nil),
|
||||
call("newFile", stub.ExpectArgs{uintptr(0x3b), "extra file 1"}, (*os.File)(nil), nil),
|
||||
call("umask", stub.ExpectArgs{022}, 0, nil),
|
||||
call("verbosef", stub.ExpectArgs{"starting initial program %s", []any{MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"starting initial program %s", []any{check.MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil),
|
||||
call("start", stub.ExpectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent"}, &os.Process{Pid: 0xbad}, nil),
|
||||
call("suspend", stub.ExpectArgs{}, true, nil),
|
||||
call("printf", stub.ExpectArgs{"cannot close setup pipe: %v", []any{stub.UniqueError(3)}}, nil, nil),
|
||||
@ -2378,15 +2379,15 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, 0, stub.UniqueError(2)),
|
||||
call("verbosef", stub.ExpectArgs{"cannot enable ptrace protection via Yama LSM: %v", []any{stub.UniqueError(2)}}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei/nonexistent"),
|
||||
Path: MustAbs("/run/current-system/sw/bin/bash"),
|
||||
Dir: check.MustAbs("/.hakurei/nonexistent"),
|
||||
Path: check.MustAbs("/run/current-system/sw/bin/bash"),
|
||||
Args: []string{"bash", "-c", "false"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 24,
|
||||
Gid: 1 << 47,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompDisable: true,
|
||||
ParentPerm: 0750,
|
||||
@ -2417,7 +2418,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
|
||||
call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0750)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil),
|
||||
/* end apply */
|
||||
@ -2478,7 +2479,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("newFile", stub.ExpectArgs{uintptr(0x3a), "extra file 0"}, (*os.File)(nil), nil),
|
||||
call("newFile", stub.ExpectArgs{uintptr(0x3b), "extra file 1"}, (*os.File)(nil), nil),
|
||||
call("umask", stub.ExpectArgs{022}, 0, nil),
|
||||
call("verbosef", stub.ExpectArgs{"starting initial program %s", []any{MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"starting initial program %s", []any{check.MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil),
|
||||
call("start", stub.ExpectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent"}, &os.Process{Pid: 0xbad}, nil),
|
||||
call("suspend", stub.ExpectArgs{}, true, nil),
|
||||
call("printf", stub.ExpectArgs{"cannot close setup pipe: %v", []any{stub.UniqueError(1)}}, nil, nil),
|
||||
@ -2513,16 +2514,16 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("getpid", stub.ExpectArgs{}, 1, nil),
|
||||
call("setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
|
||||
Dir: MustAbs("/.hakurei"),
|
||||
Dir: check.MustAbs("/.hakurei"),
|
||||
Env: []string{"DISPLAY=:0"},
|
||||
Path: MustAbs("/bin/zsh"),
|
||||
Path: check.MustAbs("/bin/zsh"),
|
||||
Args: []string{"zsh", "-c", "exec vim"},
|
||||
ForwardCancel: true,
|
||||
AdoptWaitDelay: 5 * time.Second,
|
||||
Uid: 1 << 32,
|
||||
Gid: 1 << 31,
|
||||
Hostname: "hakurei-check",
|
||||
Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")),
|
||||
Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")),
|
||||
SeccompRules: make([]seccomp.NativeRule, 0),
|
||||
SeccompPresets: bits.PresetStrict,
|
||||
RetainSession: true,
|
||||
@ -2554,7 +2555,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
|
||||
call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil),
|
||||
/* end apply */
|
||||
@ -2618,7 +2619,7 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
call("newFile", stub.ExpectArgs{uintptr(11), "extra file 1"}, (*os.File)(nil), nil),
|
||||
call("newFile", stub.ExpectArgs{uintptr(12), "extra file 2"}, (*os.File)(nil), nil),
|
||||
call("umask", stub.ExpectArgs{022}, 0, nil),
|
||||
call("verbosef", stub.ExpectArgs{"starting initial program %s", []any{MustAbs("/bin/zsh")}}, nil, nil),
|
||||
call("verbosef", stub.ExpectArgs{"starting initial program %s", []any{check.MustAbs("/bin/zsh")}}, nil, nil),
|
||||
call("start", stub.ExpectArgs{"/bin/zsh", []string{"zsh", "-c", "exec vim"}, []string{"DISPLAY=:0"}, "/.hakurei"}, &os.Process{Pid: 0xcafe}, nil),
|
||||
call("suspend", stub.ExpectArgs{}, true, nil),
|
||||
call("printf", stub.ExpectArgs{"cannot close setup pipe: %v", []any{stub.UniqueError(0)}}, nil, nil),
|
||||
|
@ -5,12 +5,14 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"syscall"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
)
|
||||
|
||||
func init() { gob.Register(new(BindMountOp)) }
|
||||
|
||||
// Bind appends an [Op] that bind mounts host path [BindMountOp.Source] on container path [BindMountOp.Target].
|
||||
func (f *Ops) Bind(source, target *Absolute, flags int) *Ops {
|
||||
func (f *Ops) Bind(source, target *check.Absolute, flags int) *Ops {
|
||||
*f = append(*f, &BindMountOp{nil, source, target, flags})
|
||||
return f
|
||||
}
|
||||
@ -18,7 +20,7 @@ func (f *Ops) Bind(source, target *Absolute, flags int) *Ops {
|
||||
// BindMountOp bind mounts host path Source on container path Target.
|
||||
// Note that Flags uses bits declared in this package and should not be set with constants in [syscall].
|
||||
type BindMountOp struct {
|
||||
sourceFinal, Source, Target *Absolute
|
||||
sourceFinal, Source, Target *check.Absolute
|
||||
|
||||
Flags int
|
||||
}
|
||||
@ -54,7 +56,7 @@ func (b *BindMountOp) early(_ *setupState, k syscallDispatcher) error {
|
||||
}
|
||||
return err
|
||||
} else {
|
||||
b.sourceFinal, err = NewAbs(pathname)
|
||||
b.sourceFinal, err = check.NewAbs(pathname)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -6,29 +6,30 @@ import (
|
||||
"syscall"
|
||||
"testing"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/stub"
|
||||
)
|
||||
|
||||
func TestBindMountOp(t *testing.T) {
|
||||
checkOpBehaviour(t, []opBehaviourTestCase{
|
||||
{"ENOENT not optional", new(Params), &BindMountOp{
|
||||
Source: MustAbs("/bin/"),
|
||||
Target: MustAbs("/bin/"),
|
||||
Source: check.MustAbs("/bin/"),
|
||||
Target: check.MustAbs("/bin/"),
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/bin/"}, "", syscall.ENOENT),
|
||||
}, syscall.ENOENT, nil, nil},
|
||||
|
||||
{"skip optional", new(Params), &BindMountOp{
|
||||
Source: MustAbs("/bin/"),
|
||||
Target: MustAbs("/bin/"),
|
||||
Source: check.MustAbs("/bin/"),
|
||||
Target: check.MustAbs("/bin/"),
|
||||
Flags: BindOptional,
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/bin/"}, "", syscall.ENOENT),
|
||||
}, nil, nil, nil},
|
||||
|
||||
{"success optional", new(Params), &BindMountOp{
|
||||
Source: MustAbs("/bin/"),
|
||||
Target: MustAbs("/bin/"),
|
||||
Source: check.MustAbs("/bin/"),
|
||||
Target: check.MustAbs("/bin/"),
|
||||
Flags: BindOptional,
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/bin/"}, "/usr/bin", nil),
|
||||
@ -40,8 +41,8 @@ func TestBindMountOp(t *testing.T) {
|
||||
}, nil},
|
||||
|
||||
{"ensureFile device", new(Params), &BindMountOp{
|
||||
Source: MustAbs("/dev/null"),
|
||||
Target: MustAbs("/dev/null"),
|
||||
Source: check.MustAbs("/dev/null"),
|
||||
Target: check.MustAbs("/dev/null"),
|
||||
Flags: BindWritable | BindDevice,
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/dev/null"}, "/dev/null", nil),
|
||||
@ -51,16 +52,16 @@ func TestBindMountOp(t *testing.T) {
|
||||
}, stub.UniqueError(5)},
|
||||
|
||||
{"mkdirAll ensure", new(Params), &BindMountOp{
|
||||
Source: MustAbs("/bin/"),
|
||||
Target: MustAbs("/bin/"),
|
||||
Source: check.MustAbs("/bin/"),
|
||||
Target: check.MustAbs("/bin/"),
|
||||
Flags: BindEnsure,
|
||||
}, []stub.Call{
|
||||
call("mkdirAll", stub.ExpectArgs{"/bin/", os.FileMode(0700)}, nil, stub.UniqueError(4)),
|
||||
}, stub.UniqueError(4), nil, nil},
|
||||
|
||||
{"success ensure", new(Params), &BindMountOp{
|
||||
Source: MustAbs("/bin/"),
|
||||
Target: MustAbs("/usr/bin/"),
|
||||
Source: check.MustAbs("/bin/"),
|
||||
Target: check.MustAbs("/usr/bin/"),
|
||||
Flags: BindEnsure,
|
||||
}, []stub.Call{
|
||||
call("mkdirAll", stub.ExpectArgs{"/bin/", os.FileMode(0700)}, nil, nil),
|
||||
@ -73,8 +74,8 @@ func TestBindMountOp(t *testing.T) {
|
||||
}, nil},
|
||||
|
||||
{"success device ro", new(Params), &BindMountOp{
|
||||
Source: MustAbs("/dev/null"),
|
||||
Target: MustAbs("/dev/null"),
|
||||
Source: check.MustAbs("/dev/null"),
|
||||
Target: check.MustAbs("/dev/null"),
|
||||
Flags: BindDevice,
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/dev/null"}, "/dev/null", nil),
|
||||
@ -86,8 +87,8 @@ func TestBindMountOp(t *testing.T) {
|
||||
}, nil},
|
||||
|
||||
{"success device", new(Params), &BindMountOp{
|
||||
Source: MustAbs("/dev/null"),
|
||||
Target: MustAbs("/dev/null"),
|
||||
Source: check.MustAbs("/dev/null"),
|
||||
Target: check.MustAbs("/dev/null"),
|
||||
Flags: BindWritable | BindDevice,
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/dev/null"}, "/dev/null", nil),
|
||||
@ -99,15 +100,15 @@ func TestBindMountOp(t *testing.T) {
|
||||
}, nil},
|
||||
|
||||
{"evalSymlinks", new(Params), &BindMountOp{
|
||||
Source: MustAbs("/bin/"),
|
||||
Target: MustAbs("/bin/"),
|
||||
Source: check.MustAbs("/bin/"),
|
||||
Target: check.MustAbs("/bin/"),
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/bin/"}, "/usr/bin", stub.UniqueError(3)),
|
||||
}, stub.UniqueError(3), nil, nil},
|
||||
|
||||
{"stat", new(Params), &BindMountOp{
|
||||
Source: MustAbs("/bin/"),
|
||||
Target: MustAbs("/bin/"),
|
||||
Source: check.MustAbs("/bin/"),
|
||||
Target: check.MustAbs("/bin/"),
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/bin/"}, "/usr/bin", nil),
|
||||
}, nil, []stub.Call{
|
||||
@ -115,8 +116,8 @@ func TestBindMountOp(t *testing.T) {
|
||||
}, stub.UniqueError(2)},
|
||||
|
||||
{"mkdirAll", new(Params), &BindMountOp{
|
||||
Source: MustAbs("/bin/"),
|
||||
Target: MustAbs("/bin/"),
|
||||
Source: check.MustAbs("/bin/"),
|
||||
Target: check.MustAbs("/bin/"),
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/bin/"}, "/usr/bin", nil),
|
||||
}, nil, []stub.Call{
|
||||
@ -125,8 +126,8 @@ func TestBindMountOp(t *testing.T) {
|
||||
}, stub.UniqueError(1)},
|
||||
|
||||
{"bindMount", new(Params), &BindMountOp{
|
||||
Source: MustAbs("/bin/"),
|
||||
Target: MustAbs("/bin/"),
|
||||
Source: check.MustAbs("/bin/"),
|
||||
Target: check.MustAbs("/bin/"),
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/bin/"}, "/usr/bin", nil),
|
||||
}, nil, []stub.Call{
|
||||
@ -137,8 +138,8 @@ func TestBindMountOp(t *testing.T) {
|
||||
}, stub.UniqueError(0)},
|
||||
|
||||
{"success eval equals", new(Params), &BindMountOp{
|
||||
Source: MustAbs("/bin/"),
|
||||
Target: MustAbs("/bin/"),
|
||||
Source: check.MustAbs("/bin/"),
|
||||
Target: check.MustAbs("/bin/"),
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/bin/"}, "/bin", nil),
|
||||
}, nil, []stub.Call{
|
||||
@ -149,8 +150,8 @@ func TestBindMountOp(t *testing.T) {
|
||||
}, nil},
|
||||
|
||||
{"success", new(Params), &BindMountOp{
|
||||
Source: MustAbs("/bin/"),
|
||||
Target: MustAbs("/bin/"),
|
||||
Source: check.MustAbs("/bin/"),
|
||||
Target: check.MustAbs("/bin/"),
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/bin/"}, "/usr/bin", nil),
|
||||
}, nil, []stub.Call{
|
||||
@ -173,21 +174,21 @@ func TestBindMountOp(t *testing.T) {
|
||||
checkOpsValid(t, []opValidTestCase{
|
||||
{"nil", (*BindMountOp)(nil), false},
|
||||
{"zero", new(BindMountOp), false},
|
||||
{"nil source", &BindMountOp{Target: MustAbs("/")}, false},
|
||||
{"nil target", &BindMountOp{Source: MustAbs("/")}, false},
|
||||
{"flag optional ensure", &BindMountOp{Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindOptional | BindEnsure}, false},
|
||||
{"valid", &BindMountOp{Source: MustAbs("/"), Target: MustAbs("/")}, true},
|
||||
{"nil source", &BindMountOp{Target: check.MustAbs("/")}, false},
|
||||
{"nil target", &BindMountOp{Source: check.MustAbs("/")}, false},
|
||||
{"flag optional ensure", &BindMountOp{Source: check.MustAbs("/"), Target: check.MustAbs("/"), Flags: BindOptional | BindEnsure}, false},
|
||||
{"valid", &BindMountOp{Source: check.MustAbs("/"), Target: check.MustAbs("/")}, true},
|
||||
})
|
||||
|
||||
checkOpsBuilder(t, []opsBuilderTestCase{
|
||||
{"autoetc", new(Ops).Bind(
|
||||
MustAbs("/etc/"),
|
||||
MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
check.MustAbs("/etc/"),
|
||||
check.MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
0,
|
||||
), Ops{
|
||||
&BindMountOp{
|
||||
Source: MustAbs("/etc/"),
|
||||
Target: MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
Source: check.MustAbs("/etc/"),
|
||||
Target: check.MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
},
|
||||
}},
|
||||
})
|
||||
@ -196,45 +197,45 @@ func TestBindMountOp(t *testing.T) {
|
||||
{"zero", new(BindMountOp), new(BindMountOp), false},
|
||||
|
||||
{"internal ne", &BindMountOp{
|
||||
Source: MustAbs("/etc/"),
|
||||
Target: MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
Source: check.MustAbs("/etc/"),
|
||||
Target: check.MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
}, &BindMountOp{
|
||||
Source: MustAbs("/etc/"),
|
||||
Target: MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
sourceFinal: MustAbs("/etc/"),
|
||||
Source: check.MustAbs("/etc/"),
|
||||
Target: check.MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
sourceFinal: check.MustAbs("/etc/"),
|
||||
}, true},
|
||||
|
||||
{"flags differs", &BindMountOp{
|
||||
Source: MustAbs("/etc/"),
|
||||
Target: MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
Source: check.MustAbs("/etc/"),
|
||||
Target: check.MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
}, &BindMountOp{
|
||||
Source: MustAbs("/etc/"),
|
||||
Target: MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
Source: check.MustAbs("/etc/"),
|
||||
Target: check.MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
Flags: BindOptional,
|
||||
}, false},
|
||||
|
||||
{"source differs", &BindMountOp{
|
||||
Source: MustAbs("/.hakurei/etc/"),
|
||||
Target: MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
Source: check.MustAbs("/.hakurei/etc/"),
|
||||
Target: check.MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
}, &BindMountOp{
|
||||
Source: MustAbs("/etc/"),
|
||||
Target: MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
Source: check.MustAbs("/etc/"),
|
||||
Target: check.MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
}, false},
|
||||
|
||||
{"target differs", &BindMountOp{
|
||||
Source: MustAbs("/etc/"),
|
||||
Target: MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
Source: check.MustAbs("/etc/"),
|
||||
Target: check.MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
}, &BindMountOp{
|
||||
Source: MustAbs("/etc/"),
|
||||
Target: MustAbs("/etc/"),
|
||||
Source: check.MustAbs("/etc/"),
|
||||
Target: check.MustAbs("/etc/"),
|
||||
}, false},
|
||||
|
||||
{"equals", &BindMountOp{
|
||||
Source: MustAbs("/etc/"),
|
||||
Target: MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
Source: check.MustAbs("/etc/"),
|
||||
Target: check.MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
}, &BindMountOp{
|
||||
Source: MustAbs("/etc/"),
|
||||
Target: MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
Source: check.MustAbs("/etc/"),
|
||||
Target: check.MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
}, true},
|
||||
})
|
||||
|
||||
@ -242,13 +243,13 @@ func TestBindMountOp(t *testing.T) {
|
||||
{"invalid", new(BindMountOp), "mounting", "<invalid>"},
|
||||
|
||||
{"autoetc", &BindMountOp{
|
||||
Source: MustAbs("/etc/"),
|
||||
Target: MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
Source: check.MustAbs("/etc/"),
|
||||
Target: check.MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
|
||||
}, "mounting", `"/etc/" on "/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659" flags 0x0`},
|
||||
|
||||
{"hostdev", &BindMountOp{
|
||||
Source: MustAbs("/dev/"),
|
||||
Target: MustAbs("/dev/"),
|
||||
Source: check.MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Flags: BindWritable | BindDevice,
|
||||
}, "mounting", `"/dev/" flags 0x6`},
|
||||
})
|
||||
|
@ -5,19 +5,21 @@ import (
|
||||
"fmt"
|
||||
"path"
|
||||
. "syscall"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
)
|
||||
|
||||
func init() { gob.Register(new(MountDevOp)) }
|
||||
|
||||
// Dev appends an [Op] that mounts a subset of host /dev.
|
||||
func (f *Ops) Dev(target *Absolute, mqueue bool) *Ops {
|
||||
func (f *Ops) Dev(target *check.Absolute, mqueue bool) *Ops {
|
||||
*f = append(*f, &MountDevOp{target, mqueue, false})
|
||||
return f
|
||||
}
|
||||
|
||||
// DevWritable appends an [Op] that mounts a writable subset of host /dev.
|
||||
// There is usually no good reason to write to /dev, so this should always be followed by a [RemountOp].
|
||||
func (f *Ops) DevWritable(target *Absolute, mqueue bool) *Ops {
|
||||
func (f *Ops) DevWritable(target *check.Absolute, mqueue bool) *Ops {
|
||||
*f = append(*f, &MountDevOp{target, mqueue, true})
|
||||
return f
|
||||
}
|
||||
@ -26,7 +28,7 @@ func (f *Ops) DevWritable(target *Absolute, mqueue bool) *Ops {
|
||||
// If Mqueue is true, a private instance of [FstypeMqueue] is mounted.
|
||||
// If Write is true, the resulting mount point is left writable.
|
||||
type MountDevOp struct {
|
||||
Target *Absolute
|
||||
Target *check.Absolute
|
||||
Mqueue bool
|
||||
Write bool
|
||||
}
|
||||
|
@ -4,20 +4,21 @@ import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/stub"
|
||||
)
|
||||
|
||||
func TestMountDevOp(t *testing.T) {
|
||||
checkOpBehaviour(t, []opBehaviourTestCase{
|
||||
{"mountTmpfs", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, stub.UniqueError(27)),
|
||||
}, stub.UniqueError(27)},
|
||||
|
||||
{"ensureFile null", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@ -25,7 +26,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(26)},
|
||||
|
||||
{"bindMount null", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@ -34,7 +35,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(25)},
|
||||
|
||||
{"ensureFile zero", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@ -44,7 +45,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(24)},
|
||||
|
||||
{"bindMount zero", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@ -55,7 +56,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(23)},
|
||||
|
||||
{"ensureFile full", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@ -67,7 +68,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(22)},
|
||||
|
||||
{"bindMount full", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@ -80,7 +81,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(21)},
|
||||
|
||||
{"ensureFile random", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@ -94,7 +95,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(20)},
|
||||
|
||||
{"bindMount random", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@ -109,7 +110,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(19)},
|
||||
|
||||
{"ensureFile urandom", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@ -125,7 +126,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(18)},
|
||||
|
||||
{"bindMount urandom", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@ -142,7 +143,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(17)},
|
||||
|
||||
{"ensureFile tty", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@ -160,7 +161,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(16)},
|
||||
|
||||
{"bindMount tty", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@ -179,7 +180,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(15)},
|
||||
|
||||
{"symlink stdin", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@ -199,7 +200,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(14)},
|
||||
|
||||
{"symlink stdout", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@ -220,7 +221,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(13)},
|
||||
|
||||
{"symlink stderr", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@ -242,7 +243,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(12)},
|
||||
|
||||
{"symlink fd", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@ -265,7 +266,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(11)},
|
||||
|
||||
{"symlink kcore", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@ -289,7 +290,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(10)},
|
||||
|
||||
{"symlink ptmx", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@ -314,7 +315,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(9)},
|
||||
|
||||
{"mkdir shm", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@ -340,7 +341,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(8)},
|
||||
|
||||
{"mkdir devpts", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@ -367,7 +368,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(7)},
|
||||
|
||||
{"mount devpts", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@ -395,7 +396,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(6)},
|
||||
|
||||
{"ensureFile stdout", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@ -425,7 +426,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(5)},
|
||||
|
||||
{"readlink stdout", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@ -456,7 +457,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(4)},
|
||||
|
||||
{"bindMount stdout", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@ -488,7 +489,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(3)},
|
||||
|
||||
{"mkdir mqueue", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@ -521,7 +522,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(2)},
|
||||
|
||||
{"mount mqueue", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@ -555,7 +556,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(1)},
|
||||
|
||||
{"success no session", &Params{ParentPerm: 0755}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
Write: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
@ -586,7 +587,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, nil},
|
||||
|
||||
{"success no tty", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
Write: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
@ -618,7 +619,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, nil},
|
||||
|
||||
{"remount", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
call("ensureFile", stub.ExpectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil),
|
||||
@ -650,7 +651,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, stub.UniqueError(0)},
|
||||
|
||||
{"success no mqueue", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
call("ensureFile", stub.ExpectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil),
|
||||
@ -683,7 +684,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, nil},
|
||||
|
||||
{"success rw", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
Write: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
@ -718,7 +719,7 @@ func TestMountDevOp(t *testing.T) {
|
||||
}, nil},
|
||||
|
||||
{"success", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil),
|
||||
@ -757,20 +758,20 @@ func TestMountDevOp(t *testing.T) {
|
||||
checkOpsValid(t, []opValidTestCase{
|
||||
{"nil", (*MountDevOp)(nil), false},
|
||||
{"zero", new(MountDevOp), false},
|
||||
{"valid", &MountDevOp{Target: MustAbs("/dev/")}, true},
|
||||
{"valid", &MountDevOp{Target: check.MustAbs("/dev/")}, true},
|
||||
})
|
||||
|
||||
checkOpsBuilder(t, []opsBuilderTestCase{
|
||||
{"dev", new(Ops).Dev(MustAbs("/dev/"), true), Ops{
|
||||
{"dev", new(Ops).Dev(check.MustAbs("/dev/"), true), Ops{
|
||||
&MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
},
|
||||
}},
|
||||
|
||||
{"dev writable", new(Ops).DevWritable(MustAbs("/.hakurei/dev/"), false), Ops{
|
||||
{"dev writable", new(Ops).DevWritable(check.MustAbs("/.hakurei/dev/"), false), Ops{
|
||||
&MountDevOp{
|
||||
Target: MustAbs("/.hakurei/dev/"),
|
||||
Target: check.MustAbs("/.hakurei/dev/"),
|
||||
Write: true,
|
||||
},
|
||||
}},
|
||||
@ -780,46 +781,46 @@ func TestMountDevOp(t *testing.T) {
|
||||
{"zero", new(MountDevOp), new(MountDevOp), false},
|
||||
|
||||
{"write differs", &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
Write: true,
|
||||
}, false},
|
||||
|
||||
{"mqueue differs", &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, false},
|
||||
|
||||
{"target differs", &MountDevOp{
|
||||
Target: MustAbs("/"),
|
||||
Target: check.MustAbs("/"),
|
||||
Mqueue: true,
|
||||
}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, false},
|
||||
|
||||
{"equals", &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, true},
|
||||
})
|
||||
|
||||
checkOpMeta(t, []opMetaTestCase{
|
||||
{"mqueue", &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Mqueue: true,
|
||||
}, "mounting", `dev on "/dev/" with mqueue`},
|
||||
|
||||
{"dev", &MountDevOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
}, "mounting", `dev on "/dev/"`},
|
||||
})
|
||||
}
|
||||
|
@ -4,19 +4,21 @@ import (
|
||||
"encoding/gob"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
)
|
||||
|
||||
func init() { gob.Register(new(MkdirOp)) }
|
||||
|
||||
// Mkdir appends an [Op] that creates a directory in the container filesystem.
|
||||
func (f *Ops) Mkdir(name *Absolute, perm os.FileMode) *Ops {
|
||||
func (f *Ops) Mkdir(name *check.Absolute, perm os.FileMode) *Ops {
|
||||
*f = append(*f, &MkdirOp{name, perm})
|
||||
return f
|
||||
}
|
||||
|
||||
// MkdirOp creates a directory at container Path with permission bits set to Perm.
|
||||
type MkdirOp struct {
|
||||
Path *Absolute
|
||||
Path *check.Absolute
|
||||
Perm os.FileMode
|
||||
}
|
||||
|
||||
|
@ -4,13 +4,14 @@ import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/stub"
|
||||
)
|
||||
|
||||
func TestMkdirOp(t *testing.T) {
|
||||
checkOpBehaviour(t, []opBehaviourTestCase{
|
||||
{"success", new(Params), &MkdirOp{
|
||||
Path: MustAbs("/.hakurei"),
|
||||
Path: check.MustAbs("/.hakurei"),
|
||||
Perm: 0500,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/.hakurei", os.FileMode(0500)}, nil, nil),
|
||||
@ -20,25 +21,25 @@ func TestMkdirOp(t *testing.T) {
|
||||
checkOpsValid(t, []opValidTestCase{
|
||||
{"nil", (*MkdirOp)(nil), false},
|
||||
{"zero", new(MkdirOp), false},
|
||||
{"valid", &MkdirOp{Path: MustAbs("/.hakurei")}, true},
|
||||
{"valid", &MkdirOp{Path: check.MustAbs("/.hakurei")}, true},
|
||||
})
|
||||
|
||||
checkOpsBuilder(t, []opsBuilderTestCase{
|
||||
{"etc", new(Ops).Mkdir(MustAbs("/etc/"), 0), Ops{
|
||||
&MkdirOp{Path: MustAbs("/etc/")},
|
||||
{"etc", new(Ops).Mkdir(check.MustAbs("/etc/"), 0), Ops{
|
||||
&MkdirOp{Path: check.MustAbs("/etc/")},
|
||||
}},
|
||||
})
|
||||
|
||||
checkOpIs(t, []opIsTestCase{
|
||||
{"zero", new(MkdirOp), new(MkdirOp), false},
|
||||
{"path differs", &MkdirOp{Path: MustAbs("/"), Perm: 0755}, &MkdirOp{Path: MustAbs("/etc/"), Perm: 0755}, false},
|
||||
{"perm differs", &MkdirOp{Path: MustAbs("/")}, &MkdirOp{Path: MustAbs("/"), Perm: 0755}, false},
|
||||
{"equals", &MkdirOp{Path: MustAbs("/")}, &MkdirOp{Path: MustAbs("/")}, true},
|
||||
{"path differs", &MkdirOp{Path: check.MustAbs("/"), Perm: 0755}, &MkdirOp{Path: check.MustAbs("/etc/"), Perm: 0755}, false},
|
||||
{"perm differs", &MkdirOp{Path: check.MustAbs("/")}, &MkdirOp{Path: check.MustAbs("/"), Perm: 0755}, false},
|
||||
{"equals", &MkdirOp{Path: check.MustAbs("/")}, &MkdirOp{Path: check.MustAbs("/")}, true},
|
||||
})
|
||||
|
||||
checkOpMeta(t, []opMetaTestCase{
|
||||
{"etc", &MkdirOp{
|
||||
Path: MustAbs("/etc/"),
|
||||
Path: check.MustAbs("/etc/"),
|
||||
}, "creating", `directory "/etc/" perm ----------`},
|
||||
})
|
||||
}
|
||||
|
@ -5,6 +5,8 @@ import (
|
||||
"fmt"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -52,7 +54,7 @@ func (e *OverlayArgumentError) Error() string {
|
||||
}
|
||||
|
||||
// Overlay appends an [Op] that mounts the overlay pseudo filesystem on [MountOverlayOp.Target].
|
||||
func (f *Ops) Overlay(target, state, work *Absolute, layers ...*Absolute) *Ops {
|
||||
func (f *Ops) Overlay(target, state, work *check.Absolute, layers ...*check.Absolute) *Ops {
|
||||
*f = append(*f, &MountOverlayOp{
|
||||
Target: target,
|
||||
Lower: layers,
|
||||
@ -64,21 +66,21 @@ func (f *Ops) Overlay(target, state, work *Absolute, layers ...*Absolute) *Ops {
|
||||
|
||||
// OverlayEphemeral appends an [Op] that mounts the overlay pseudo filesystem on [MountOverlayOp.Target]
|
||||
// with an ephemeral upperdir and workdir.
|
||||
func (f *Ops) OverlayEphemeral(target *Absolute, layers ...*Absolute) *Ops {
|
||||
func (f *Ops) OverlayEphemeral(target *check.Absolute, layers ...*check.Absolute) *Ops {
|
||||
return f.Overlay(target, AbsFHSRoot, nil, layers...)
|
||||
}
|
||||
|
||||
// OverlayReadonly appends an [Op] that mounts the overlay pseudo filesystem readonly on [MountOverlayOp.Target]
|
||||
func (f *Ops) OverlayReadonly(target *Absolute, layers ...*Absolute) *Ops {
|
||||
func (f *Ops) OverlayReadonly(target *check.Absolute, layers ...*check.Absolute) *Ops {
|
||||
return f.Overlay(target, nil, nil, layers...)
|
||||
}
|
||||
|
||||
// MountOverlayOp mounts [FstypeOverlay] on container path Target.
|
||||
type MountOverlayOp struct {
|
||||
Target *Absolute
|
||||
Target *check.Absolute
|
||||
|
||||
// Any filesystem, does not need to be on a writable filesystem.
|
||||
Lower []*Absolute
|
||||
Lower []*check.Absolute
|
||||
// formatted for [OptionOverlayLowerdir], resolved, prefixed and escaped during early
|
||||
lower []string
|
||||
// The upperdir is normally on a writable filesystem.
|
||||
@ -87,11 +89,11 @@ type MountOverlayOp struct {
|
||||
// an ephemeral upperdir and workdir will be set up.
|
||||
//
|
||||
// If both Work and Upper are nil, upperdir and workdir is omitted and the overlay is mounted readonly.
|
||||
Upper *Absolute
|
||||
Upper *check.Absolute
|
||||
// formatted for [OptionOverlayUpperdir], resolved, prefixed and escaped during early
|
||||
upper string
|
||||
// The workdir needs to be an empty directory on the same filesystem as upperdir.
|
||||
Work *Absolute
|
||||
Work *check.Absolute
|
||||
// formatted for [OptionOverlayWorkdir], resolved, prefixed and escaped during early
|
||||
work string
|
||||
|
||||
@ -206,7 +208,7 @@ func (o *MountOverlayOp) Is(op Op) bool {
|
||||
vo, ok := op.(*MountOverlayOp)
|
||||
return ok && o.Valid() && vo.Valid() &&
|
||||
o.Target.Is(vo.Target) &&
|
||||
slices.EqualFunc(o.Lower, vo.Lower, func(a *Absolute, v *Absolute) bool { return a.Is(v) }) &&
|
||||
slices.EqualFunc(o.Lower, vo.Lower, func(a, v *check.Absolute) bool { return a.Is(v) }) &&
|
||||
o.Upper.Is(vo.Upper) && o.Work.Is(vo.Work)
|
||||
}
|
||||
func (*MountOverlayOp) prefix() (string, bool) { return "mounting", true }
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/stub"
|
||||
)
|
||||
|
||||
@ -38,21 +39,21 @@ func TestMountOverlayOp(t *testing.T) {
|
||||
|
||||
checkOpBehaviour(t, []opBehaviourTestCase{
|
||||
{"mkdirTemp invalid ephemeral", &Params{ParentPerm: 0705}, &MountOverlayOp{
|
||||
Target: MustAbs("/"),
|
||||
Lower: []*Absolute{
|
||||
MustAbs("/var/lib/planterette/base/debian:f92c9052"),
|
||||
MustAbs("/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052"),
|
||||
Target: check.MustAbs("/"),
|
||||
Lower: []*check.Absolute{
|
||||
check.MustAbs("/var/lib/planterette/base/debian:f92c9052"),
|
||||
check.MustAbs("/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052"),
|
||||
},
|
||||
Upper: MustAbs("/proc/"),
|
||||
Upper: check.MustAbs("/proc/"),
|
||||
}, nil, &OverlayArgumentError{OverlayEphemeralUnexpectedUpper, "/proc/"}, nil, nil},
|
||||
|
||||
{"mkdirTemp upper ephemeral", &Params{ParentPerm: 0705}, &MountOverlayOp{
|
||||
Target: MustAbs("/"),
|
||||
Lower: []*Absolute{
|
||||
MustAbs("/var/lib/planterette/base/debian:f92c9052"),
|
||||
MustAbs("/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052"),
|
||||
Target: check.MustAbs("/"),
|
||||
Lower: []*check.Absolute{
|
||||
check.MustAbs("/var/lib/planterette/base/debian:f92c9052"),
|
||||
check.MustAbs("/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052"),
|
||||
},
|
||||
Upper: MustAbs("/"),
|
||||
Upper: check.MustAbs("/"),
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/var/lib/planterette/base/debian:f92c9052"}, "/var/lib/planterette/base/debian:f92c9052", nil),
|
||||
call("evalSymlinks", stub.ExpectArgs{"/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052"}, "/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052", nil),
|
||||
@ -62,12 +63,12 @@ func TestMountOverlayOp(t *testing.T) {
|
||||
}, stub.UniqueError(6)},
|
||||
|
||||
{"mkdirTemp work ephemeral", &Params{ParentPerm: 0705}, &MountOverlayOp{
|
||||
Target: MustAbs("/"),
|
||||
Lower: []*Absolute{
|
||||
MustAbs("/var/lib/planterette/base/debian:f92c9052"),
|
||||
MustAbs("/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052"),
|
||||
Target: check.MustAbs("/"),
|
||||
Lower: []*check.Absolute{
|
||||
check.MustAbs("/var/lib/planterette/base/debian:f92c9052"),
|
||||
check.MustAbs("/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052"),
|
||||
},
|
||||
Upper: MustAbs("/"),
|
||||
Upper: check.MustAbs("/"),
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/var/lib/planterette/base/debian:f92c9052"}, "/var/lib/planterette/base/debian:f92c9052", nil),
|
||||
call("evalSymlinks", stub.ExpectArgs{"/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052"}, "/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052", nil),
|
||||
@ -78,12 +79,12 @@ func TestMountOverlayOp(t *testing.T) {
|
||||
}, stub.UniqueError(5)},
|
||||
|
||||
{"success ephemeral", &Params{ParentPerm: 0705}, &MountOverlayOp{
|
||||
Target: MustAbs("/"),
|
||||
Lower: []*Absolute{
|
||||
MustAbs("/var/lib/planterette/base/debian:f92c9052"),
|
||||
MustAbs("/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052"),
|
||||
Target: check.MustAbs("/"),
|
||||
Lower: []*check.Absolute{
|
||||
check.MustAbs("/var/lib/planterette/base/debian:f92c9052"),
|
||||
check.MustAbs("/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052"),
|
||||
},
|
||||
Upper: MustAbs("/"),
|
||||
Upper: check.MustAbs("/"),
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/var/lib/planterette/base/debian:f92c9052"}, "/var/lib/planterette/base/debian:f92c9052", nil),
|
||||
call("evalSymlinks", stub.ExpectArgs{"/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052"}, "/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052", nil),
|
||||
@ -101,9 +102,9 @@ func TestMountOverlayOp(t *testing.T) {
|
||||
}, nil},
|
||||
|
||||
{"short lower ro", &Params{ParentPerm: 0755}, &MountOverlayOp{
|
||||
Target: MustAbs("/nix/store"),
|
||||
Lower: []*Absolute{
|
||||
MustAbs("/mnt-root/nix/.ro-store"),
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{
|
||||
check.MustAbs("/mnt-root/nix/.ro-store"),
|
||||
},
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.ro-store"}, "/mnt-root/nix/.ro-store", nil),
|
||||
@ -112,10 +113,10 @@ func TestMountOverlayOp(t *testing.T) {
|
||||
}, &OverlayArgumentError{OverlayReadonlyLower, zeroString}},
|
||||
|
||||
{"success ro noPrefix", &Params{ParentPerm: 0755}, &MountOverlayOp{
|
||||
Target: MustAbs("/nix/store"),
|
||||
Lower: []*Absolute{
|
||||
MustAbs("/mnt-root/nix/.ro-store"),
|
||||
MustAbs("/mnt-root/nix/.ro-store0"),
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{
|
||||
check.MustAbs("/mnt-root/nix/.ro-store"),
|
||||
check.MustAbs("/mnt-root/nix/.ro-store0"),
|
||||
},
|
||||
noPrefix: true,
|
||||
}, []stub.Call{
|
||||
@ -131,10 +132,10 @@ func TestMountOverlayOp(t *testing.T) {
|
||||
}, nil},
|
||||
|
||||
{"success ro", &Params{ParentPerm: 0755}, &MountOverlayOp{
|
||||
Target: MustAbs("/nix/store"),
|
||||
Lower: []*Absolute{
|
||||
MustAbs("/mnt-root/nix/.ro-store"),
|
||||
MustAbs("/mnt-root/nix/.ro-store0"),
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{
|
||||
check.MustAbs("/mnt-root/nix/.ro-store"),
|
||||
check.MustAbs("/mnt-root/nix/.ro-store0"),
|
||||
},
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.ro-store"}, "/mnt-root/nix/.ro-store", nil),
|
||||
@ -149,9 +150,9 @@ func TestMountOverlayOp(t *testing.T) {
|
||||
}, nil},
|
||||
|
||||
{"nil lower", &Params{ParentPerm: 0700}, &MountOverlayOp{
|
||||
Target: MustAbs("/nix/store"),
|
||||
Upper: MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Upper: check.MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: check.MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.rw-store/upper"}, "/mnt-root/nix/.rw-store/.upper", nil),
|
||||
call("evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.rw-store/work"}, "/mnt-root/nix/.rw-store/.work", nil),
|
||||
@ -160,29 +161,29 @@ func TestMountOverlayOp(t *testing.T) {
|
||||
}, &OverlayArgumentError{OverlayEmptyLower, zeroString}},
|
||||
|
||||
{"evalSymlinks upper", &Params{ParentPerm: 0700}, &MountOverlayOp{
|
||||
Target: MustAbs("/nix/store"),
|
||||
Lower: []*Absolute{MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{check.MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: check.MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: check.MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.rw-store/upper"}, "/mnt-root/nix/.rw-store/.upper", stub.UniqueError(4)),
|
||||
}, stub.UniqueError(4), nil, nil},
|
||||
|
||||
{"evalSymlinks work", &Params{ParentPerm: 0700}, &MountOverlayOp{
|
||||
Target: MustAbs("/nix/store"),
|
||||
Lower: []*Absolute{MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{check.MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: check.MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: check.MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.rw-store/upper"}, "/mnt-root/nix/.rw-store/.upper", nil),
|
||||
call("evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.rw-store/work"}, "/mnt-root/nix/.rw-store/.work", stub.UniqueError(3)),
|
||||
}, stub.UniqueError(3), nil, nil},
|
||||
|
||||
{"evalSymlinks lower", &Params{ParentPerm: 0700}, &MountOverlayOp{
|
||||
Target: MustAbs("/nix/store"),
|
||||
Lower: []*Absolute{MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{check.MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: check.MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: check.MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.rw-store/upper"}, "/mnt-root/nix/.rw-store/.upper", nil),
|
||||
call("evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.rw-store/work"}, "/mnt-root/nix/.rw-store/.work", nil),
|
||||
@ -190,10 +191,10 @@ func TestMountOverlayOp(t *testing.T) {
|
||||
}, stub.UniqueError(2), nil, nil},
|
||||
|
||||
{"mkdirAll", &Params{ParentPerm: 0700}, &MountOverlayOp{
|
||||
Target: MustAbs("/nix/store"),
|
||||
Lower: []*Absolute{MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{check.MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: check.MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: check.MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.rw-store/upper"}, "/mnt-root/nix/.rw-store/.upper", nil),
|
||||
call("evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.rw-store/work"}, "/mnt-root/nix/.rw-store/.work", nil),
|
||||
@ -203,10 +204,10 @@ func TestMountOverlayOp(t *testing.T) {
|
||||
}, stub.UniqueError(1)},
|
||||
|
||||
{"mount", &Params{ParentPerm: 0700}, &MountOverlayOp{
|
||||
Target: MustAbs("/nix/store"),
|
||||
Lower: []*Absolute{MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{check.MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: check.MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: check.MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.rw-store/upper"}, "/mnt-root/nix/.rw-store/.upper", nil),
|
||||
call("evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.rw-store/work"}, "/mnt-root/nix/.rw-store/.work", nil),
|
||||
@ -217,10 +218,10 @@ func TestMountOverlayOp(t *testing.T) {
|
||||
}, stub.UniqueError(0)},
|
||||
|
||||
{"success single layer", &Params{ParentPerm: 0700}, &MountOverlayOp{
|
||||
Target: MustAbs("/nix/store"),
|
||||
Lower: []*Absolute{MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{check.MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: check.MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: check.MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.rw-store/upper"}, "/mnt-root/nix/.rw-store/.upper", nil),
|
||||
call("evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.rw-store/work"}, "/mnt-root/nix/.rw-store/.work", nil),
|
||||
@ -235,16 +236,16 @@ func TestMountOverlayOp(t *testing.T) {
|
||||
}, nil},
|
||||
|
||||
{"success", &Params{ParentPerm: 0700}, &MountOverlayOp{
|
||||
Target: MustAbs("/nix/store"),
|
||||
Lower: []*Absolute{
|
||||
MustAbs("/mnt-root/nix/.ro-store"),
|
||||
MustAbs("/mnt-root/nix/.ro-store0"),
|
||||
MustAbs("/mnt-root/nix/.ro-store1"),
|
||||
MustAbs("/mnt-root/nix/.ro-store2"),
|
||||
MustAbs("/mnt-root/nix/.ro-store3"),
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{
|
||||
check.MustAbs("/mnt-root/nix/.ro-store"),
|
||||
check.MustAbs("/mnt-root/nix/.ro-store0"),
|
||||
check.MustAbs("/mnt-root/nix/.ro-store1"),
|
||||
check.MustAbs("/mnt-root/nix/.ro-store2"),
|
||||
check.MustAbs("/mnt-root/nix/.ro-store3"),
|
||||
},
|
||||
Upper: MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
Upper: check.MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: check.MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
}, []stub.Call{
|
||||
call("evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.rw-store/upper"}, "/mnt-root/nix/.rw-store/.upper", nil),
|
||||
call("evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.rw-store/work"}, "/mnt-root/nix/.rw-store/.work", nil),
|
||||
@ -272,7 +273,7 @@ func TestMountOverlayOp(t *testing.T) {
|
||||
t.Run("nil Upper non-nil Work not ephemeral", func(t *testing.T) {
|
||||
wantErr := OpStateError("overlay")
|
||||
if err := (&MountOverlayOp{
|
||||
Work: MustAbs("/"),
|
||||
Work: check.MustAbs("/"),
|
||||
}).early(nil, nil); !errors.Is(err, wantErr) {
|
||||
t.Errorf("apply: error = %v, want %v", err, wantErr)
|
||||
}
|
||||
@ -282,39 +283,39 @@ func TestMountOverlayOp(t *testing.T) {
|
||||
checkOpsValid(t, []opValidTestCase{
|
||||
{"nil", (*MountOverlayOp)(nil), false},
|
||||
{"zero", new(MountOverlayOp), false},
|
||||
{"nil lower", &MountOverlayOp{Target: MustAbs("/"), Lower: []*Absolute{nil}}, false},
|
||||
{"ro", &MountOverlayOp{Target: MustAbs("/"), Lower: []*Absolute{MustAbs("/")}}, true},
|
||||
{"ro work", &MountOverlayOp{Target: MustAbs("/"), Work: MustAbs("/tmp/")}, false},
|
||||
{"rw", &MountOverlayOp{Target: MustAbs("/"), Lower: []*Absolute{MustAbs("/")}, Upper: MustAbs("/"), Work: MustAbs("/")}, true},
|
||||
{"nil lower", &MountOverlayOp{Target: check.MustAbs("/"), Lower: []*check.Absolute{nil}}, false},
|
||||
{"ro", &MountOverlayOp{Target: check.MustAbs("/"), Lower: []*check.Absolute{check.MustAbs("/")}}, true},
|
||||
{"ro work", &MountOverlayOp{Target: check.MustAbs("/"), Work: check.MustAbs("/tmp/")}, false},
|
||||
{"rw", &MountOverlayOp{Target: check.MustAbs("/"), Lower: []*check.Absolute{check.MustAbs("/")}, Upper: check.MustAbs("/"), Work: check.MustAbs("/")}, true},
|
||||
})
|
||||
|
||||
checkOpsBuilder(t, []opsBuilderTestCase{
|
||||
{"full", new(Ops).Overlay(
|
||||
MustAbs("/nix/store"),
|
||||
MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
MustAbs("/mnt-root/nix/.ro-store"),
|
||||
check.MustAbs("/nix/store"),
|
||||
check.MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
check.MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
check.MustAbs("/mnt-root/nix/.ro-store"),
|
||||
), Ops{
|
||||
&MountOverlayOp{
|
||||
Target: MustAbs("/nix/store"),
|
||||
Lower: []*Absolute{MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{check.MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: check.MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: check.MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
},
|
||||
}},
|
||||
|
||||
{"ephemeral", new(Ops).OverlayEphemeral(MustAbs("/nix/store"), MustAbs("/mnt-root/nix/.ro-store")), Ops{
|
||||
{"ephemeral", new(Ops).OverlayEphemeral(check.MustAbs("/nix/store"), check.MustAbs("/mnt-root/nix/.ro-store")), Ops{
|
||||
&MountOverlayOp{
|
||||
Target: MustAbs("/nix/store"),
|
||||
Lower: []*Absolute{MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: MustAbs("/"),
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{check.MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: check.MustAbs("/"),
|
||||
},
|
||||
}},
|
||||
|
||||
{"readonly", new(Ops).OverlayReadonly(MustAbs("/nix/store"), MustAbs("/mnt-root/nix/.ro-store")), Ops{
|
||||
{"readonly", new(Ops).OverlayReadonly(check.MustAbs("/nix/store"), check.MustAbs("/mnt-root/nix/.ro-store")), Ops{
|
||||
&MountOverlayOp{
|
||||
Target: MustAbs("/nix/store"),
|
||||
Lower: []*Absolute{MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{check.MustAbs("/mnt-root/nix/.ro-store")},
|
||||
},
|
||||
}},
|
||||
})
|
||||
@ -323,74 +324,74 @@ func TestMountOverlayOp(t *testing.T) {
|
||||
{"zero", new(MountOverlayOp), new(MountOverlayOp), false},
|
||||
|
||||
{"differs target", &MountOverlayOp{
|
||||
Target: MustAbs("/nix/store/differs"),
|
||||
Lower: []*Absolute{MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
Target: check.MustAbs("/nix/store/differs"),
|
||||
Lower: []*check.Absolute{check.MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: check.MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: check.MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
}, &MountOverlayOp{
|
||||
Target: MustAbs("/nix/store"),
|
||||
Lower: []*Absolute{MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: MustAbs("/mnt-root/nix/.rw-store/work")}, false},
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{check.MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: check.MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: check.MustAbs("/mnt-root/nix/.rw-store/work")}, false},
|
||||
|
||||
{"differs lower", &MountOverlayOp{
|
||||
Target: MustAbs("/nix/store"),
|
||||
Lower: []*Absolute{MustAbs("/mnt-root/nix/.ro-store/differs")},
|
||||
Upper: MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{check.MustAbs("/mnt-root/nix/.ro-store/differs")},
|
||||
Upper: check.MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: check.MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
}, &MountOverlayOp{
|
||||
Target: MustAbs("/nix/store"),
|
||||
Lower: []*Absolute{MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: MustAbs("/mnt-root/nix/.rw-store/work")}, false},
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{check.MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: check.MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: check.MustAbs("/mnt-root/nix/.rw-store/work")}, false},
|
||||
|
||||
{"differs upper", &MountOverlayOp{
|
||||
Target: MustAbs("/nix/store"),
|
||||
Lower: []*Absolute{MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: MustAbs("/mnt-root/nix/.rw-store/upper/differs"),
|
||||
Work: MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{check.MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: check.MustAbs("/mnt-root/nix/.rw-store/upper/differs"),
|
||||
Work: check.MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
}, &MountOverlayOp{
|
||||
Target: MustAbs("/nix/store"),
|
||||
Lower: []*Absolute{MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: MustAbs("/mnt-root/nix/.rw-store/work")}, false},
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{check.MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: check.MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: check.MustAbs("/mnt-root/nix/.rw-store/work")}, false},
|
||||
|
||||
{"differs work", &MountOverlayOp{
|
||||
Target: MustAbs("/nix/store"),
|
||||
Lower: []*Absolute{MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: MustAbs("/mnt-root/nix/.rw-store/work/differs"),
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{check.MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: check.MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: check.MustAbs("/mnt-root/nix/.rw-store/work/differs"),
|
||||
}, &MountOverlayOp{
|
||||
Target: MustAbs("/nix/store"),
|
||||
Lower: []*Absolute{MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: MustAbs("/mnt-root/nix/.rw-store/work")}, false},
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{check.MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: check.MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: check.MustAbs("/mnt-root/nix/.rw-store/work")}, false},
|
||||
|
||||
{"equals ro", &MountOverlayOp{
|
||||
Target: MustAbs("/nix/store"),
|
||||
Lower: []*Absolute{MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{check.MustAbs("/mnt-root/nix/.ro-store")},
|
||||
}, &MountOverlayOp{
|
||||
Target: MustAbs("/nix/store"),
|
||||
Lower: []*Absolute{MustAbs("/mnt-root/nix/.ro-store")}}, true},
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{check.MustAbs("/mnt-root/nix/.ro-store")}}, true},
|
||||
|
||||
{"equals", &MountOverlayOp{
|
||||
Target: MustAbs("/nix/store"),
|
||||
Lower: []*Absolute{MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{check.MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: check.MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: check.MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
}, &MountOverlayOp{
|
||||
Target: MustAbs("/nix/store"),
|
||||
Lower: []*Absolute{MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: MustAbs("/mnt-root/nix/.rw-store/work")}, true},
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{check.MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: check.MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: check.MustAbs("/mnt-root/nix/.rw-store/work")}, true},
|
||||
})
|
||||
|
||||
checkOpMeta(t, []opMetaTestCase{
|
||||
{"nix", &MountOverlayOp{
|
||||
Target: MustAbs("/nix/store"),
|
||||
Lower: []*Absolute{MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
Target: check.MustAbs("/nix/store"),
|
||||
Lower: []*check.Absolute{check.MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: check.MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: check.MustAbs("/mnt-root/nix/.rw-store/work"),
|
||||
}, "mounting", `overlay on "/nix/store" with 1 layers`},
|
||||
})
|
||||
}
|
||||
|
@ -4,6 +4,8 @@ import (
|
||||
"encoding/gob"
|
||||
"fmt"
|
||||
"syscall"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -14,13 +16,13 @@ const (
|
||||
func init() { gob.Register(new(TmpfileOp)) }
|
||||
|
||||
// Place appends an [Op] that places a file in container path [TmpfileOp.Path] containing [TmpfileOp.Data].
|
||||
func (f *Ops) Place(name *Absolute, data []byte) *Ops {
|
||||
func (f *Ops) Place(name *check.Absolute, data []byte) *Ops {
|
||||
*f = append(*f, &TmpfileOp{name, data})
|
||||
return f
|
||||
}
|
||||
|
||||
// PlaceP is like Place but writes the address of [TmpfileOp.Data] to the pointer dataP points to.
|
||||
func (f *Ops) PlaceP(name *Absolute, dataP **[]byte) *Ops {
|
||||
func (f *Ops) PlaceP(name *check.Absolute, dataP **[]byte) *Ops {
|
||||
t := &TmpfileOp{Path: name}
|
||||
*dataP = &t.Data
|
||||
|
||||
@ -30,7 +32,7 @@ func (f *Ops) PlaceP(name *Absolute, dataP **[]byte) *Ops {
|
||||
|
||||
// TmpfileOp places a file on container Path containing Data.
|
||||
type TmpfileOp struct {
|
||||
Path *Absolute
|
||||
Path *check.Absolute
|
||||
Data []byte
|
||||
}
|
||||
|
||||
|
@ -4,13 +4,14 @@ import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/stub"
|
||||
)
|
||||
|
||||
func TestTmpfileOp(t *testing.T) {
|
||||
const sampleDataString = `chronos:x:65534:65534:Hakurei:/var/empty:/bin/zsh`
|
||||
var (
|
||||
samplePath = MustAbs("/etc/passwd")
|
||||
samplePath = check.MustAbs("/etc/passwd")
|
||||
sampleData = []byte(sampleDataString)
|
||||
)
|
||||
|
||||
@ -100,7 +101,7 @@ func TestTmpfileOp(t *testing.T) {
|
||||
{"zero", new(TmpfileOp), new(TmpfileOp), false},
|
||||
|
||||
{"differs path", &TmpfileOp{
|
||||
Path: MustAbs("/etc/group"),
|
||||
Path: check.MustAbs("/etc/group"),
|
||||
Data: sampleData,
|
||||
}, &TmpfileOp{
|
||||
Path: samplePath,
|
||||
|
@ -4,18 +4,20 @@ import (
|
||||
"encoding/gob"
|
||||
"fmt"
|
||||
. "syscall"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
)
|
||||
|
||||
func init() { gob.Register(new(MountProcOp)) }
|
||||
|
||||
// Proc appends an [Op] that mounts a private instance of proc.
|
||||
func (f *Ops) Proc(target *Absolute) *Ops {
|
||||
func (f *Ops) Proc(target *check.Absolute) *Ops {
|
||||
*f = append(*f, &MountProcOp{target})
|
||||
return f
|
||||
}
|
||||
|
||||
// MountProcOp mounts a new instance of [FstypeProc] on container path Target.
|
||||
type MountProcOp struct{ Target *Absolute }
|
||||
type MountProcOp struct{ Target *check.Absolute }
|
||||
|
||||
func (p *MountProcOp) Valid() bool { return p != nil && p.Target != nil }
|
||||
func (p *MountProcOp) early(*setupState, syscallDispatcher) error { return nil }
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/stub"
|
||||
)
|
||||
|
||||
@ -11,14 +12,14 @@ func TestMountProcOp(t *testing.T) {
|
||||
checkOpBehaviour(t, []opBehaviourTestCase{
|
||||
{"mkdir", &Params{ParentPerm: 0755},
|
||||
&MountProcOp{
|
||||
Target: MustAbs("/proc/"),
|
||||
Target: check.MustAbs("/proc/"),
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, stub.UniqueError(0)),
|
||||
}, stub.UniqueError(0)},
|
||||
|
||||
{"success", &Params{ParentPerm: 0700},
|
||||
&MountProcOp{
|
||||
Target: MustAbs("/proc/"),
|
||||
Target: check.MustAbs("/proc/"),
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0700)}, nil, nil),
|
||||
call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil),
|
||||
@ -28,12 +29,12 @@ func TestMountProcOp(t *testing.T) {
|
||||
checkOpsValid(t, []opValidTestCase{
|
||||
{"nil", (*MountProcOp)(nil), false},
|
||||
{"zero", new(MountProcOp), false},
|
||||
{"valid", &MountProcOp{Target: MustAbs("/proc/")}, true},
|
||||
{"valid", &MountProcOp{Target: check.MustAbs("/proc/")}, true},
|
||||
})
|
||||
|
||||
checkOpsBuilder(t, []opsBuilderTestCase{
|
||||
{"proc", new(Ops).Proc(MustAbs("/proc/")), Ops{
|
||||
&MountProcOp{Target: MustAbs("/proc/")},
|
||||
{"proc", new(Ops).Proc(check.MustAbs("/proc/")), Ops{
|
||||
&MountProcOp{Target: check.MustAbs("/proc/")},
|
||||
}},
|
||||
})
|
||||
|
||||
@ -41,20 +42,20 @@ func TestMountProcOp(t *testing.T) {
|
||||
{"zero", new(MountProcOp), new(MountProcOp), false},
|
||||
|
||||
{"target differs", &MountProcOp{
|
||||
Target: MustAbs("/proc/nonexistent"),
|
||||
Target: check.MustAbs("/proc/nonexistent"),
|
||||
}, &MountProcOp{
|
||||
Target: MustAbs("/proc/"),
|
||||
Target: check.MustAbs("/proc/"),
|
||||
}, false},
|
||||
|
||||
{"equals", &MountProcOp{
|
||||
Target: MustAbs("/proc/"),
|
||||
Target: check.MustAbs("/proc/"),
|
||||
}, &MountProcOp{
|
||||
Target: MustAbs("/proc/"),
|
||||
Target: check.MustAbs("/proc/"),
|
||||
}, true},
|
||||
})
|
||||
|
||||
checkOpMeta(t, []opMetaTestCase{
|
||||
{"proc", &MountProcOp{Target: MustAbs("/proc/")},
|
||||
{"proc", &MountProcOp{Target: check.MustAbs("/proc/")},
|
||||
"mounting", `proc on "/proc/"`},
|
||||
})
|
||||
}
|
||||
|
@ -3,19 +3,21 @@ package container
|
||||
import (
|
||||
"encoding/gob"
|
||||
"fmt"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
)
|
||||
|
||||
func init() { gob.Register(new(RemountOp)) }
|
||||
|
||||
// Remount appends an [Op] that applies [RemountOp.Flags] on container path [RemountOp.Target].
|
||||
func (f *Ops) Remount(target *Absolute, flags uintptr) *Ops {
|
||||
func (f *Ops) Remount(target *check.Absolute, flags uintptr) *Ops {
|
||||
*f = append(*f, &RemountOp{target, flags})
|
||||
return f
|
||||
}
|
||||
|
||||
// RemountOp remounts Target with Flags.
|
||||
type RemountOp struct {
|
||||
Target *Absolute
|
||||
Target *check.Absolute
|
||||
Flags uintptr
|
||||
}
|
||||
|
||||
|
@ -4,13 +4,14 @@ import (
|
||||
"syscall"
|
||||
"testing"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/stub"
|
||||
)
|
||||
|
||||
func TestRemountOp(t *testing.T) {
|
||||
checkOpBehaviour(t, []opBehaviourTestCase{
|
||||
{"success", new(Params), &RemountOp{
|
||||
Target: MustAbs("/"),
|
||||
Target: check.MustAbs("/"),
|
||||
Flags: syscall.MS_RDONLY,
|
||||
}, nil, nil, []stub.Call{
|
||||
call("remount", stub.ExpectArgs{"/sysroot", uintptr(1)}, nil, nil),
|
||||
@ -20,13 +21,13 @@ func TestRemountOp(t *testing.T) {
|
||||
checkOpsValid(t, []opValidTestCase{
|
||||
{"nil", (*RemountOp)(nil), false},
|
||||
{"zero", new(RemountOp), false},
|
||||
{"valid", &RemountOp{Target: MustAbs("/"), Flags: syscall.MS_RDONLY}, true},
|
||||
{"valid", &RemountOp{Target: check.MustAbs("/"), Flags: syscall.MS_RDONLY}, true},
|
||||
})
|
||||
|
||||
checkOpsBuilder(t, []opsBuilderTestCase{
|
||||
{"root", new(Ops).Remount(MustAbs("/"), syscall.MS_RDONLY), Ops{
|
||||
{"root", new(Ops).Remount(check.MustAbs("/"), syscall.MS_RDONLY), Ops{
|
||||
&RemountOp{
|
||||
Target: MustAbs("/"),
|
||||
Target: check.MustAbs("/"),
|
||||
Flags: syscall.MS_RDONLY,
|
||||
},
|
||||
}},
|
||||
@ -36,33 +37,33 @@ func TestRemountOp(t *testing.T) {
|
||||
{"zero", new(RemountOp), new(RemountOp), false},
|
||||
|
||||
{"target differs", &RemountOp{
|
||||
Target: MustAbs("/dev/"),
|
||||
Target: check.MustAbs("/dev/"),
|
||||
Flags: syscall.MS_RDONLY,
|
||||
}, &RemountOp{
|
||||
Target: MustAbs("/"),
|
||||
Target: check.MustAbs("/"),
|
||||
Flags: syscall.MS_RDONLY,
|
||||
}, false},
|
||||
|
||||
{"flags differs", &RemountOp{
|
||||
Target: MustAbs("/"),
|
||||
Target: check.MustAbs("/"),
|
||||
Flags: syscall.MS_RDONLY | syscall.MS_NODEV,
|
||||
}, &RemountOp{
|
||||
Target: MustAbs("/"),
|
||||
Target: check.MustAbs("/"),
|
||||
Flags: syscall.MS_RDONLY,
|
||||
}, false},
|
||||
|
||||
{"equals", &RemountOp{
|
||||
Target: MustAbs("/"),
|
||||
Target: check.MustAbs("/"),
|
||||
Flags: syscall.MS_RDONLY,
|
||||
}, &RemountOp{
|
||||
Target: MustAbs("/"),
|
||||
Target: check.MustAbs("/"),
|
||||
Flags: syscall.MS_RDONLY,
|
||||
}, true},
|
||||
})
|
||||
|
||||
checkOpMeta(t, []opMetaTestCase{
|
||||
{"root", &RemountOp{
|
||||
Target: MustAbs("/"),
|
||||
Target: check.MustAbs("/"),
|
||||
Flags: syscall.MS_RDONLY,
|
||||
}, "remounting", `"/" flags 0x1`},
|
||||
})
|
||||
|
@ -4,19 +4,21 @@ import (
|
||||
"encoding/gob"
|
||||
"fmt"
|
||||
"path"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
)
|
||||
|
||||
func init() { gob.Register(new(SymlinkOp)) }
|
||||
|
||||
// Link appends an [Op] that creates a symlink in the container filesystem.
|
||||
func (f *Ops) Link(target *Absolute, linkName string, dereference bool) *Ops {
|
||||
func (f *Ops) Link(target *check.Absolute, linkName string, dereference bool) *Ops {
|
||||
*f = append(*f, &SymlinkOp{target, linkName, dereference})
|
||||
return f
|
||||
}
|
||||
|
||||
// SymlinkOp optionally dereferences LinkName and creates a symlink at container path Target.
|
||||
type SymlinkOp struct {
|
||||
Target *Absolute
|
||||
Target *check.Absolute
|
||||
// LinkName is an arbitrary uninterpreted pathname.
|
||||
LinkName string
|
||||
|
||||
@ -28,8 +30,8 @@ func (l *SymlinkOp) Valid() bool { return l != nil && l.Target != nil && l.LinkN
|
||||
|
||||
func (l *SymlinkOp) early(_ *setupState, k syscallDispatcher) error {
|
||||
if l.Dereference {
|
||||
if !isAbs(l.LinkName) {
|
||||
return &AbsoluteError{l.LinkName}
|
||||
if !path.IsAbs(l.LinkName) {
|
||||
return &check.AbsoluteError{Pathname: l.LinkName}
|
||||
}
|
||||
if name, err := k.readlink(l.LinkName); err != nil {
|
||||
return err
|
||||
|
@ -4,26 +4,27 @@ import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/stub"
|
||||
)
|
||||
|
||||
func TestSymlinkOp(t *testing.T) {
|
||||
checkOpBehaviour(t, []opBehaviourTestCase{
|
||||
{"mkdir", &Params{ParentPerm: 0700}, &SymlinkOp{
|
||||
Target: MustAbs("/etc/nixos"),
|
||||
Target: check.MustAbs("/etc/nixos"),
|
||||
LinkName: "/etc/static/nixos",
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/etc", os.FileMode(0700)}, nil, stub.UniqueError(1)),
|
||||
}, stub.UniqueError(1)},
|
||||
|
||||
{"abs", &Params{ParentPerm: 0755}, &SymlinkOp{
|
||||
Target: MustAbs("/etc/mtab"),
|
||||
Target: check.MustAbs("/etc/mtab"),
|
||||
LinkName: "etc/mtab",
|
||||
Dereference: true,
|
||||
}, nil, &AbsoluteError{"etc/mtab"}, nil, nil},
|
||||
}, nil, &check.AbsoluteError{Pathname: "etc/mtab"}, nil, nil},
|
||||
|
||||
{"readlink", &Params{ParentPerm: 0755}, &SymlinkOp{
|
||||
Target: MustAbs("/etc/mtab"),
|
||||
Target: check.MustAbs("/etc/mtab"),
|
||||
LinkName: "/etc/mtab",
|
||||
Dereference: true,
|
||||
}, []stub.Call{
|
||||
@ -31,7 +32,7 @@ func TestSymlinkOp(t *testing.T) {
|
||||
}, stub.UniqueError(0), nil, nil},
|
||||
|
||||
{"success noderef", &Params{ParentPerm: 0700}, &SymlinkOp{
|
||||
Target: MustAbs("/etc/nixos"),
|
||||
Target: check.MustAbs("/etc/nixos"),
|
||||
LinkName: "/etc/static/nixos",
|
||||
}, nil, nil, []stub.Call{
|
||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/etc", os.FileMode(0700)}, nil, nil),
|
||||
@ -39,7 +40,7 @@ func TestSymlinkOp(t *testing.T) {
|
||||
}, nil},
|
||||
|
||||
{"success", &Params{ParentPerm: 0755}, &SymlinkOp{
|
||||
Target: MustAbs("/etc/mtab"),
|
||||
Target: check.MustAbs("/etc/mtab"),
|
||||
LinkName: "/etc/mtab",
|
||||
Dereference: true,
|
||||
}, []stub.Call{
|
||||
@ -54,18 +55,18 @@ func TestSymlinkOp(t *testing.T) {
|
||||
{"nil", (*SymlinkOp)(nil), false},
|
||||
{"zero", new(SymlinkOp), false},
|
||||
{"nil target", &SymlinkOp{LinkName: "/run/current-system"}, false},
|
||||
{"zero linkname", &SymlinkOp{Target: MustAbs("/run/current-system")}, false},
|
||||
{"valid", &SymlinkOp{Target: MustAbs("/run/current-system"), LinkName: "/run/current-system", Dereference: true}, true},
|
||||
{"zero linkname", &SymlinkOp{Target: check.MustAbs("/run/current-system")}, false},
|
||||
{"valid", &SymlinkOp{Target: check.MustAbs("/run/current-system"), LinkName: "/run/current-system", Dereference: true}, true},
|
||||
})
|
||||
|
||||
checkOpsBuilder(t, []opsBuilderTestCase{
|
||||
{"current-system", new(Ops).Link(
|
||||
MustAbs("/run/current-system"),
|
||||
check.MustAbs("/run/current-system"),
|
||||
"/run/current-system",
|
||||
true,
|
||||
), Ops{
|
||||
&SymlinkOp{
|
||||
Target: MustAbs("/run/current-system"),
|
||||
Target: check.MustAbs("/run/current-system"),
|
||||
LinkName: "/run/current-system",
|
||||
Dereference: true,
|
||||
},
|
||||
@ -76,40 +77,40 @@ func TestSymlinkOp(t *testing.T) {
|
||||
{"zero", new(SymlinkOp), new(SymlinkOp), false},
|
||||
|
||||
{"target differs", &SymlinkOp{
|
||||
Target: MustAbs("/run/current-system/differs"),
|
||||
Target: check.MustAbs("/run/current-system/differs"),
|
||||
LinkName: "/run/current-system",
|
||||
Dereference: true,
|
||||
}, &SymlinkOp{
|
||||
Target: MustAbs("/run/current-system"),
|
||||
Target: check.MustAbs("/run/current-system"),
|
||||
LinkName: "/run/current-system",
|
||||
Dereference: true,
|
||||
}, false},
|
||||
|
||||
{"linkname differs", &SymlinkOp{
|
||||
Target: MustAbs("/run/current-system"),
|
||||
Target: check.MustAbs("/run/current-system"),
|
||||
LinkName: "/run/current-system/differs",
|
||||
Dereference: true,
|
||||
}, &SymlinkOp{
|
||||
Target: MustAbs("/run/current-system"),
|
||||
Target: check.MustAbs("/run/current-system"),
|
||||
LinkName: "/run/current-system",
|
||||
Dereference: true,
|
||||
}, false},
|
||||
|
||||
{"dereference differs", &SymlinkOp{
|
||||
Target: MustAbs("/run/current-system"),
|
||||
Target: check.MustAbs("/run/current-system"),
|
||||
LinkName: "/run/current-system",
|
||||
}, &SymlinkOp{
|
||||
Target: MustAbs("/run/current-system"),
|
||||
Target: check.MustAbs("/run/current-system"),
|
||||
LinkName: "/run/current-system",
|
||||
Dereference: true,
|
||||
}, false},
|
||||
|
||||
{"equals", &SymlinkOp{
|
||||
Target: MustAbs("/run/current-system"),
|
||||
Target: check.MustAbs("/run/current-system"),
|
||||
LinkName: "/run/current-system",
|
||||
Dereference: true,
|
||||
}, &SymlinkOp{
|
||||
Target: MustAbs("/run/current-system"),
|
||||
Target: check.MustAbs("/run/current-system"),
|
||||
LinkName: "/run/current-system",
|
||||
Dereference: true,
|
||||
}, true},
|
||||
@ -117,7 +118,7 @@ func TestSymlinkOp(t *testing.T) {
|
||||
|
||||
checkOpMeta(t, []opMetaTestCase{
|
||||
{"current-system", &SymlinkOp{
|
||||
Target: MustAbs("/run/current-system"),
|
||||
Target: check.MustAbs("/run/current-system"),
|
||||
LinkName: "/run/current-system",
|
||||
Dereference: true,
|
||||
}, "creating", `symlink on "/run/current-system" linkname "/run/current-system"`},
|
||||
|
@ -7,6 +7,8 @@ import (
|
||||
"os"
|
||||
"strconv"
|
||||
. "syscall"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
)
|
||||
|
||||
func init() { gob.Register(new(MountTmpfsOp)) }
|
||||
@ -18,13 +20,13 @@ func (e TmpfsSizeError) Error() string {
|
||||
}
|
||||
|
||||
// Tmpfs appends an [Op] that mounts tmpfs on container path [MountTmpfsOp.Path].
|
||||
func (f *Ops) Tmpfs(target *Absolute, size int, perm os.FileMode) *Ops {
|
||||
func (f *Ops) Tmpfs(target *check.Absolute, size int, perm os.FileMode) *Ops {
|
||||
*f = append(*f, &MountTmpfsOp{SourceTmpfsEphemeral, target, MS_NOSUID | MS_NODEV, size, perm})
|
||||
return f
|
||||
}
|
||||
|
||||
// Readonly appends an [Op] that mounts read-only tmpfs on container path [MountTmpfsOp.Path].
|
||||
func (f *Ops) Readonly(target *Absolute, perm os.FileMode) *Ops {
|
||||
func (f *Ops) Readonly(target *check.Absolute, perm os.FileMode) *Ops {
|
||||
*f = append(*f, &MountTmpfsOp{SourceTmpfsReadonly, target, MS_RDONLY | MS_NOSUID | MS_NODEV, 0, perm})
|
||||
return f
|
||||
}
|
||||
@ -32,7 +34,7 @@ func (f *Ops) Readonly(target *Absolute, perm os.FileMode) *Ops {
|
||||
// MountTmpfsOp mounts [FstypeTmpfs] on container Path.
|
||||
type MountTmpfsOp struct {
|
||||
FSName string
|
||||
Path *Absolute
|
||||
Path *check.Absolute
|
||||
Flags uintptr
|
||||
Size int
|
||||
Perm os.FileMode
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"syscall"
|
||||
"testing"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/stub"
|
||||
)
|
||||
|
||||
@ -24,7 +25,7 @@ func TestMountTmpfsOp(t *testing.T) {
|
||||
|
||||
{"success", new(Params), &MountTmpfsOp{
|
||||
FSName: "ephemeral",
|
||||
Path: MustAbs("/run/user/1000/"),
|
||||
Path: check.MustAbs("/run/user/1000/"),
|
||||
Size: 1 << 10,
|
||||
Perm: 0700,
|
||||
}, nil, nil, []stub.Call{
|
||||
@ -42,19 +43,19 @@ func TestMountTmpfsOp(t *testing.T) {
|
||||
{"nil", (*MountTmpfsOp)(nil), false},
|
||||
{"zero", new(MountTmpfsOp), false},
|
||||
{"nil path", &MountTmpfsOp{FSName: "tmpfs"}, false},
|
||||
{"zero fsname", &MountTmpfsOp{Path: MustAbs("/tmp/")}, false},
|
||||
{"valid", &MountTmpfsOp{FSName: "tmpfs", Path: MustAbs("/tmp/")}, true},
|
||||
{"zero fsname", &MountTmpfsOp{Path: check.MustAbs("/tmp/")}, false},
|
||||
{"valid", &MountTmpfsOp{FSName: "tmpfs", Path: check.MustAbs("/tmp/")}, true},
|
||||
})
|
||||
|
||||
checkOpsBuilder(t, []opsBuilderTestCase{
|
||||
{"runtime", new(Ops).Tmpfs(
|
||||
MustAbs("/run/user"),
|
||||
check.MustAbs("/run/user"),
|
||||
1<<10,
|
||||
0755,
|
||||
), Ops{
|
||||
&MountTmpfsOp{
|
||||
FSName: "ephemeral",
|
||||
Path: MustAbs("/run/user"),
|
||||
Path: check.MustAbs("/run/user"),
|
||||
Flags: syscall.MS_NOSUID | syscall.MS_NODEV,
|
||||
Size: 1 << 10,
|
||||
Perm: 0755,
|
||||
@ -62,12 +63,12 @@ func TestMountTmpfsOp(t *testing.T) {
|
||||
}},
|
||||
|
||||
{"nscd", new(Ops).Readonly(
|
||||
MustAbs("/var/run/nscd"),
|
||||
check.MustAbs("/var/run/nscd"),
|
||||
0755,
|
||||
), Ops{
|
||||
&MountTmpfsOp{
|
||||
FSName: "readonly",
|
||||
Path: MustAbs("/var/run/nscd"),
|
||||
Path: check.MustAbs("/var/run/nscd"),
|
||||
Flags: syscall.MS_NOSUID | syscall.MS_NODEV | syscall.MS_RDONLY,
|
||||
Perm: 0755,
|
||||
},
|
||||
@ -79,13 +80,13 @@ func TestMountTmpfsOp(t *testing.T) {
|
||||
|
||||
{"fsname differs", &MountTmpfsOp{
|
||||
FSName: "readonly",
|
||||
Path: MustAbs("/run/user"),
|
||||
Path: check.MustAbs("/run/user"),
|
||||
Flags: syscall.MS_NOSUID | syscall.MS_NODEV,
|
||||
Size: 1 << 10,
|
||||
Perm: 0755,
|
||||
}, &MountTmpfsOp{
|
||||
FSName: "ephemeral",
|
||||
Path: MustAbs("/run/user"),
|
||||
Path: check.MustAbs("/run/user"),
|
||||
Flags: syscall.MS_NOSUID | syscall.MS_NODEV,
|
||||
Size: 1 << 10,
|
||||
Perm: 0755,
|
||||
@ -93,13 +94,13 @@ func TestMountTmpfsOp(t *testing.T) {
|
||||
|
||||
{"path differs", &MountTmpfsOp{
|
||||
FSName: "ephemeral",
|
||||
Path: MustAbs("/run/user/differs"),
|
||||
Path: check.MustAbs("/run/user/differs"),
|
||||
Flags: syscall.MS_NOSUID | syscall.MS_NODEV,
|
||||
Size: 1 << 10,
|
||||
Perm: 0755,
|
||||
}, &MountTmpfsOp{
|
||||
FSName: "ephemeral",
|
||||
Path: MustAbs("/run/user"),
|
||||
Path: check.MustAbs("/run/user"),
|
||||
Flags: syscall.MS_NOSUID | syscall.MS_NODEV,
|
||||
Size: 1 << 10,
|
||||
Perm: 0755,
|
||||
@ -107,13 +108,13 @@ func TestMountTmpfsOp(t *testing.T) {
|
||||
|
||||
{"flags differs", &MountTmpfsOp{
|
||||
FSName: "ephemeral",
|
||||
Path: MustAbs("/run/user"),
|
||||
Path: check.MustAbs("/run/user"),
|
||||
Flags: syscall.MS_NOSUID | syscall.MS_NODEV | syscall.MS_RDONLY,
|
||||
Size: 1 << 10,
|
||||
Perm: 0755,
|
||||
}, &MountTmpfsOp{
|
||||
FSName: "ephemeral",
|
||||
Path: MustAbs("/run/user"),
|
||||
Path: check.MustAbs("/run/user"),
|
||||
Flags: syscall.MS_NOSUID | syscall.MS_NODEV,
|
||||
Size: 1 << 10,
|
||||
Perm: 0755,
|
||||
@ -121,13 +122,13 @@ func TestMountTmpfsOp(t *testing.T) {
|
||||
|
||||
{"size differs", &MountTmpfsOp{
|
||||
FSName: "ephemeral",
|
||||
Path: MustAbs("/run/user"),
|
||||
Path: check.MustAbs("/run/user"),
|
||||
Flags: syscall.MS_NOSUID | syscall.MS_NODEV,
|
||||
Size: 1,
|
||||
Perm: 0755,
|
||||
}, &MountTmpfsOp{
|
||||
FSName: "ephemeral",
|
||||
Path: MustAbs("/run/user"),
|
||||
Path: check.MustAbs("/run/user"),
|
||||
Flags: syscall.MS_NOSUID | syscall.MS_NODEV,
|
||||
Size: 1 << 10,
|
||||
Perm: 0755,
|
||||
@ -135,13 +136,13 @@ func TestMountTmpfsOp(t *testing.T) {
|
||||
|
||||
{"perm differs", &MountTmpfsOp{
|
||||
FSName: "ephemeral",
|
||||
Path: MustAbs("/run/user"),
|
||||
Path: check.MustAbs("/run/user"),
|
||||
Flags: syscall.MS_NOSUID | syscall.MS_NODEV,
|
||||
Size: 1 << 10,
|
||||
Perm: 0700,
|
||||
}, &MountTmpfsOp{
|
||||
FSName: "ephemeral",
|
||||
Path: MustAbs("/run/user"),
|
||||
Path: check.MustAbs("/run/user"),
|
||||
Flags: syscall.MS_NOSUID | syscall.MS_NODEV,
|
||||
Size: 1 << 10,
|
||||
Perm: 0755,
|
||||
@ -149,13 +150,13 @@ func TestMountTmpfsOp(t *testing.T) {
|
||||
|
||||
{"equals", &MountTmpfsOp{
|
||||
FSName: "ephemeral",
|
||||
Path: MustAbs("/run/user"),
|
||||
Path: check.MustAbs("/run/user"),
|
||||
Flags: syscall.MS_NOSUID | syscall.MS_NODEV,
|
||||
Size: 1 << 10,
|
||||
Perm: 0755,
|
||||
}, &MountTmpfsOp{
|
||||
FSName: "ephemeral",
|
||||
Path: MustAbs("/run/user"),
|
||||
Path: check.MustAbs("/run/user"),
|
||||
Flags: syscall.MS_NOSUID | syscall.MS_NODEV,
|
||||
Size: 1 << 10,
|
||||
Perm: 0755,
|
||||
@ -165,7 +166,7 @@ func TestMountTmpfsOp(t *testing.T) {
|
||||
checkOpMeta(t, []opMetaTestCase{
|
||||
{"runtime", &MountTmpfsOp{
|
||||
FSName: "ephemeral",
|
||||
Path: MustAbs("/run/user"),
|
||||
Path: check.MustAbs("/run/user"),
|
||||
Flags: syscall.MS_NOSUID | syscall.MS_NODEV,
|
||||
Size: 1 << 10,
|
||||
Perm: 0755,
|
||||
|
@ -8,12 +8,17 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
_ "unsafe"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/vfs"
|
||||
)
|
||||
|
||||
/* constants in this file bypass abs check, be extremely careful when changing them! */
|
||||
|
||||
//go:linkname unsafeAbs hakurei.app/container/check.unsafeAbs
|
||||
func unsafeAbs(_ string) *check.Absolute
|
||||
|
||||
const (
|
||||
// FHSRoot points to the file system root.
|
||||
FHSRoot = "/"
|
||||
@ -52,31 +57,31 @@ const (
|
||||
|
||||
var (
|
||||
// AbsFHSRoot is [FHSRoot] as [Absolute].
|
||||
AbsFHSRoot = &Absolute{FHSRoot}
|
||||
AbsFHSRoot = unsafeAbs(FHSRoot)
|
||||
// AbsFHSEtc is [FHSEtc] as [Absolute].
|
||||
AbsFHSEtc = &Absolute{FHSEtc}
|
||||
AbsFHSEtc = unsafeAbs(FHSEtc)
|
||||
// AbsFHSTmp is [FHSTmp] as [Absolute].
|
||||
AbsFHSTmp = &Absolute{FHSTmp}
|
||||
AbsFHSTmp = unsafeAbs(FHSTmp)
|
||||
|
||||
// AbsFHSRun is [FHSRun] as [Absolute].
|
||||
AbsFHSRun = &Absolute{FHSRun}
|
||||
AbsFHSRun = unsafeAbs(FHSRun)
|
||||
// AbsFHSRunUser is [FHSRunUser] as [Absolute].
|
||||
AbsFHSRunUser = &Absolute{FHSRunUser}
|
||||
AbsFHSRunUser = unsafeAbs(FHSRunUser)
|
||||
|
||||
// AbsFHSUsrBin is [FHSUsrBin] as [Absolute].
|
||||
AbsFHSUsrBin = &Absolute{FHSUsrBin}
|
||||
AbsFHSUsrBin = unsafeAbs(FHSUsrBin)
|
||||
|
||||
// AbsFHSVar is [FHSVar] as [Absolute].
|
||||
AbsFHSVar = &Absolute{FHSVar}
|
||||
AbsFHSVar = unsafeAbs(FHSVar)
|
||||
// AbsFHSVarLib is [FHSVarLib] as [Absolute].
|
||||
AbsFHSVarLib = &Absolute{FHSVarLib}
|
||||
AbsFHSVarLib = unsafeAbs(FHSVarLib)
|
||||
|
||||
// AbsFHSDev is [FHSDev] as [Absolute].
|
||||
AbsFHSDev = &Absolute{FHSDev}
|
||||
AbsFHSDev = unsafeAbs(FHSDev)
|
||||
// AbsFHSProc is [FHSProc] as [Absolute].
|
||||
AbsFHSProc = &Absolute{FHSProc}
|
||||
AbsFHSProc = unsafeAbs(FHSProc)
|
||||
// AbsFHSSys is [FHSSys] as [Absolute].
|
||||
AbsFHSSys = &Absolute{FHSSys}
|
||||
AbsFHSSys = unsafeAbs(FHSSys)
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
"sync"
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/helper/proc"
|
||||
)
|
||||
|
||||
@ -17,7 +18,7 @@ import (
|
||||
func New(
|
||||
ctx context.Context,
|
||||
msg container.Msg,
|
||||
pathname *container.Absolute, name string,
|
||||
pathname *check.Absolute, name string,
|
||||
wt io.WriterTo,
|
||||
stat bool,
|
||||
argF func(argsFd, statFd int) []string,
|
||||
|
@ -7,12 +7,13 @@ import (
|
||||
"testing"
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/helper"
|
||||
)
|
||||
|
||||
func TestContainer(t *testing.T) {
|
||||
t.Run("start invalid container", func(t *testing.T) {
|
||||
h := helper.New(t.Context(), nil, container.MustAbs(container.Nonexistent), "hakurei", argsWt, false, argF, nil, nil)
|
||||
h := helper.New(t.Context(), nil, check.MustAbs(container.Nonexistent), "hakurei", argsWt, false, argF, nil, nil)
|
||||
|
||||
wantErr := "container: starting an invalid container"
|
||||
if err := h.Start(); err == nil || err.Error() != wantErr {
|
||||
@ -22,7 +23,7 @@ func TestContainer(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("valid new helper nil check", func(t *testing.T) {
|
||||
if got := helper.New(t.Context(), nil, container.MustAbs(container.Nonexistent), "hakurei", argsWt, false, argF, nil, nil); got == nil {
|
||||
if got := helper.New(t.Context(), nil, check.MustAbs(container.Nonexistent), "hakurei", argsWt, false, argF, nil, nil); got == nil {
|
||||
t.Errorf("New(%q, %q) got nil",
|
||||
argsWt, "hakurei")
|
||||
return
|
||||
@ -31,7 +32,7 @@ func TestContainer(t *testing.T) {
|
||||
|
||||
t.Run("implementation compliance", func(t *testing.T) {
|
||||
testHelper(t, func(ctx context.Context, setOutput func(stdoutP, stderrP *io.Writer), stat bool) helper.Helper {
|
||||
return helper.New(ctx, nil, container.MustAbs(os.Args[0]), "helper", argsWt, stat, argF, func(z *container.Container) {
|
||||
return helper.New(ctx, nil, check.MustAbs(os.Args[0]), "helper", argsWt, stat, argF, func(z *container.Container) {
|
||||
setOutput(&z.Stdout, &z.Stderr)
|
||||
z.
|
||||
Bind(container.AbsFHSRoot, container.AbsFHSRoot, 0).
|
||||
|
@ -5,12 +5,12 @@ import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
)
|
||||
|
||||
const Tmp = "/.hakurei"
|
||||
|
||||
var AbsTmp = container.MustAbs(Tmp)
|
||||
var AbsTmp = check.MustAbs(Tmp)
|
||||
|
||||
const (
|
||||
// WaitDelayDefault is used when WaitDelay has its zero value.
|
||||
@ -107,12 +107,12 @@ type (
|
||||
// Defaults to passwd name of target uid or chronos.
|
||||
Username string `json:"username,omitempty"`
|
||||
// Pathname of shell in the container filesystem to use for the emulated user.
|
||||
Shell *container.Absolute `json:"shell"`
|
||||
Shell *check.Absolute `json:"shell"`
|
||||
// Directory in the container filesystem to enter and use as the home directory of the emulated user.
|
||||
Home *container.Absolute `json:"home"`
|
||||
Home *check.Absolute `json:"home"`
|
||||
|
||||
// Pathname to executable file in the container filesystem.
|
||||
Path *container.Absolute `json:"path,omitempty"`
|
||||
Path *check.Absolute `json:"path,omitempty"`
|
||||
// Final args passed to the initial program.
|
||||
Args []string `json:"args"`
|
||||
}
|
||||
@ -162,7 +162,7 @@ func (config *Config) Validate() error {
|
||||
// ExtraPermConfig describes an acl update op.
|
||||
type ExtraPermConfig struct {
|
||||
Ensure bool `json:"ensure,omitempty"`
|
||||
Path *container.Absolute `json:"path"`
|
||||
Path *check.Absolute `json:"path"`
|
||||
Read bool `json:"r,omitempty"`
|
||||
Write bool `json:"w,omitempty"`
|
||||
Execute bool `json:"x,omitempty"`
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
"reflect"
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
)
|
||||
|
||||
// FilesystemConfig is an abstract representation of a mount point.
|
||||
@ -14,9 +15,9 @@ type FilesystemConfig interface {
|
||||
// Valid returns whether the configuration is valid.
|
||||
Valid() bool
|
||||
// Path returns the target path in the container.
|
||||
Path() *container.Absolute
|
||||
Path() *check.Absolute
|
||||
// Host returns a slice of all host paths used by this operation.
|
||||
Host() []*container.Absolute
|
||||
Host() []*check.Absolute
|
||||
// Apply appends the [container.Op] implementing this operation.
|
||||
Apply(z *ApplyState)
|
||||
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/hst"
|
||||
)
|
||||
|
||||
@ -217,8 +218,8 @@ type stubFS struct {
|
||||
}
|
||||
|
||||
func (s stubFS) Valid() bool { return false }
|
||||
func (s stubFS) Path() *container.Absolute { panic("unreachable") }
|
||||
func (s stubFS) Host() []*container.Absolute { panic("unreachable") }
|
||||
func (s stubFS) Path() *check.Absolute { panic("unreachable") }
|
||||
func (s stubFS) Host() []*check.Absolute { panic("unreachable") }
|
||||
func (s stubFS) Apply(*hst.ApplyState) { panic("unreachable") }
|
||||
func (s stubFS) String() string { return "<invalid " + s.typeName + ">" }
|
||||
|
||||
@ -232,8 +233,8 @@ type fsTestCase struct {
|
||||
fs hst.FilesystemConfig
|
||||
valid bool
|
||||
ops container.Ops
|
||||
path *container.Absolute
|
||||
host []*container.Absolute
|
||||
path *check.Absolute
|
||||
host []*check.Absolute
|
||||
str string
|
||||
}
|
||||
|
||||
@ -287,11 +288,11 @@ func checkFs(t *testing.T, testCases []fsTestCase) {
|
||||
}
|
||||
}
|
||||
|
||||
func m(pathname string) *container.Absolute { return container.MustAbs(pathname) }
|
||||
func ms(pathnames ...string) []*container.Absolute {
|
||||
as := make([]*container.Absolute, len(pathnames))
|
||||
func m(pathname string) *check.Absolute { return check.MustAbs(pathname) }
|
||||
func ms(pathnames ...string) []*check.Absolute {
|
||||
as := make([]*check.Absolute, len(pathnames))
|
||||
for i, pathname := range pathnames {
|
||||
as[i] = container.MustAbs(pathname)
|
||||
as[i] = check.MustAbs(pathname)
|
||||
}
|
||||
return as
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
)
|
||||
|
||||
func init() { gob.Register(new(FSBind)) }
|
||||
@ -15,9 +16,9 @@ const FilesystemBind = "bind"
|
||||
// FSBind represents a host to container bind mount.
|
||||
type FSBind struct {
|
||||
// mount point in container, same as Source if empty
|
||||
Target *container.Absolute `json:"dst,omitempty"`
|
||||
Target *check.Absolute `json:"dst,omitempty"`
|
||||
// host filesystem path to make available to the container
|
||||
Source *container.Absolute `json:"src"`
|
||||
Source *check.Absolute `json:"src"`
|
||||
// do not mount Target read-only
|
||||
Write bool `json:"write,omitempty"`
|
||||
// do not disable device files on Target, implies Write
|
||||
@ -66,7 +67,7 @@ func (b *FSBind) Valid() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (b *FSBind) Path() *container.Absolute {
|
||||
func (b *FSBind) Path() *check.Absolute {
|
||||
if !b.Valid() {
|
||||
return nil
|
||||
}
|
||||
@ -76,11 +77,11 @@ func (b *FSBind) Path() *container.Absolute {
|
||||
return b.Target
|
||||
}
|
||||
|
||||
func (b *FSBind) Host() []*container.Absolute {
|
||||
func (b *FSBind) Host() []*check.Absolute {
|
||||
if !b.Valid() {
|
||||
return nil
|
||||
}
|
||||
return []*container.Absolute{b.Source}
|
||||
return []*check.Absolute{b.Source}
|
||||
}
|
||||
|
||||
func (b *FSBind) Apply(z *ApplyState) {
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
)
|
||||
|
||||
func init() { gob.Register(new(FSEphemeral)) }
|
||||
@ -16,7 +16,7 @@ const FilesystemEphemeral = "ephemeral"
|
||||
// FSEphemeral represents an ephemeral container mount point.
|
||||
type FSEphemeral struct {
|
||||
// mount point in container
|
||||
Target *container.Absolute `json:"dst,omitempty"`
|
||||
Target *check.Absolute `json:"dst,omitempty"`
|
||||
// do not mount filesystem read-only
|
||||
Write bool `json:"write,omitempty"`
|
||||
// upper limit on the size of the filesystem
|
||||
@ -27,14 +27,14 @@ type FSEphemeral struct {
|
||||
|
||||
func (e *FSEphemeral) Valid() bool { return e != nil && e.Target != nil }
|
||||
|
||||
func (e *FSEphemeral) Path() *container.Absolute {
|
||||
func (e *FSEphemeral) Path() *check.Absolute {
|
||||
if !e.Valid() {
|
||||
return nil
|
||||
}
|
||||
return e.Target
|
||||
}
|
||||
|
||||
func (e *FSEphemeral) Host() []*container.Absolute { return nil }
|
||||
func (e *FSEphemeral) Host() []*check.Absolute { return nil }
|
||||
|
||||
const fsEphemeralDefaultPerm = os.FileMode(0755)
|
||||
|
||||
|
@ -4,7 +4,7 @@ import (
|
||||
"encoding/gob"
|
||||
"path"
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
)
|
||||
|
||||
func init() { gob.Register(new(FSLink)) }
|
||||
@ -15,7 +15,7 @@ const FilesystemLink = "link"
|
||||
// FSLink represents a symlink in the container filesystem.
|
||||
type FSLink struct {
|
||||
// link path in container
|
||||
Target *container.Absolute `json:"dst"`
|
||||
Target *check.Absolute `json:"dst"`
|
||||
// linkname the symlink points to
|
||||
Linkname string `json:"linkname"`
|
||||
// whether to dereference linkname before creating the link
|
||||
@ -29,14 +29,14 @@ func (l *FSLink) Valid() bool {
|
||||
return !l.Dereference || path.IsAbs(l.Linkname)
|
||||
}
|
||||
|
||||
func (l *FSLink) Path() *container.Absolute {
|
||||
func (l *FSLink) Path() *check.Absolute {
|
||||
if !l.Valid() {
|
||||
return nil
|
||||
}
|
||||
return l.Target
|
||||
}
|
||||
|
||||
func (l *FSLink) Host() []*container.Absolute { return nil }
|
||||
func (l *FSLink) Host() []*check.Absolute { return nil }
|
||||
|
||||
func (l *FSLink) Apply(z *ApplyState) {
|
||||
if !l.Valid() {
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
)
|
||||
|
||||
func init() { gob.Register(new(FSOverlay)) }
|
||||
@ -15,14 +16,14 @@ const FilesystemOverlay = "overlay"
|
||||
// FSOverlay represents an overlay mount point.
|
||||
type FSOverlay struct {
|
||||
// mount point in container
|
||||
Target *container.Absolute `json:"dst"`
|
||||
Target *check.Absolute `json:"dst"`
|
||||
|
||||
// any filesystem, does not need to be on a writable filesystem, must not be nil
|
||||
Lower []*container.Absolute `json:"lower"`
|
||||
Lower []*check.Absolute `json:"lower"`
|
||||
// the upperdir is normally on a writable filesystem, leave as nil to mount Lower readonly
|
||||
Upper *container.Absolute `json:"upper,omitempty"`
|
||||
Upper *check.Absolute `json:"upper,omitempty"`
|
||||
// the workdir needs to be an empty directory on the same filesystem as Upper, must not be nil if Upper is populated
|
||||
Work *container.Absolute `json:"work,omitempty"`
|
||||
Work *check.Absolute `json:"work,omitempty"`
|
||||
}
|
||||
|
||||
func (o *FSOverlay) Valid() bool {
|
||||
@ -43,18 +44,18 @@ func (o *FSOverlay) Valid() bool {
|
||||
}
|
||||
}
|
||||
|
||||
func (o *FSOverlay) Path() *container.Absolute {
|
||||
func (o *FSOverlay) Path() *check.Absolute {
|
||||
if !o.Valid() {
|
||||
return nil
|
||||
}
|
||||
return o.Target
|
||||
}
|
||||
|
||||
func (o *FSOverlay) Host() []*container.Absolute {
|
||||
func (o *FSOverlay) Host() []*check.Absolute {
|
||||
if !o.Valid() {
|
||||
return nil
|
||||
}
|
||||
p := make([]*container.Absolute, 0, 2+len(o.Lower))
|
||||
p := make([]*check.Absolute, 0, 2+len(o.Lower))
|
||||
if o.Upper != nil && o.Work != nil {
|
||||
p = append(p, o.Upper, o.Work)
|
||||
}
|
||||
|
@ -4,13 +4,14 @@ import (
|
||||
"testing"
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/hst"
|
||||
)
|
||||
|
||||
func TestFSOverlay(t *testing.T) {
|
||||
checkFs(t, []fsTestCase{
|
||||
{"nil", (*hst.FSOverlay)(nil), false, nil, nil, nil, "<invalid>"},
|
||||
{"nil lower", &hst.FSOverlay{Target: m("/etc"), Lower: []*container.Absolute{nil}}, false, nil, nil, nil, "<invalid>"},
|
||||
{"nil lower", &hst.FSOverlay{Target: m("/etc"), Lower: []*check.Absolute{nil}}, false, nil, nil, nil, "<invalid>"},
|
||||
{"zero lower", &hst.FSOverlay{Target: m("/etc"), Upper: m("/"), Work: m("/")}, false, nil, nil, nil, "<invalid>"},
|
||||
{"zero lower ro", &hst.FSOverlay{Target: m("/etc")}, false, nil, nil, nil, "<invalid>"},
|
||||
{"short lower", &hst.FSOverlay{Target: m("/etc"), Lower: ms("/etc")}, false, nil, nil, nil, "<invalid>"},
|
||||
|
23
hst/hst.go
23
hst/hst.go
@ -7,6 +7,7 @@ import (
|
||||
"os"
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
)
|
||||
|
||||
// An AppError is returned while starting an app according to [hst.Config].
|
||||
@ -38,13 +39,13 @@ func (e *AppError) Message() string {
|
||||
// Paths contains environment-dependent paths used by hakurei.
|
||||
type Paths struct {
|
||||
// temporary directory returned by [os.TempDir] (usually `/tmp`)
|
||||
TempDir *container.Absolute `json:"temp_dir"`
|
||||
TempDir *check.Absolute `json:"temp_dir"`
|
||||
// path to shared directory (usually `/tmp/hakurei.%d`, [Info.User])
|
||||
SharePath *container.Absolute `json:"share_path"`
|
||||
SharePath *check.Absolute `json:"share_path"`
|
||||
// XDG_RUNTIME_DIR value (usually `/run/user/%d`, uid)
|
||||
RuntimePath *container.Absolute `json:"runtime_path"`
|
||||
RuntimePath *check.Absolute `json:"runtime_path"`
|
||||
// application runtime directory (usually `/run/user/%d/hakurei`)
|
||||
RunDirPath *container.Absolute `json:"run_dir_path"`
|
||||
RunDirPath *check.Absolute `json:"run_dir_path"`
|
||||
}
|
||||
|
||||
type Info struct {
|
||||
@ -115,22 +116,22 @@ func Template() *Config {
|
||||
{&FSBind{Target: container.AbsFHSEtc, Source: container.AbsFHSEtc, Special: true}},
|
||||
{&FSEphemeral{Target: container.AbsFHSTmp, Write: true, Perm: 0755}},
|
||||
{&FSOverlay{
|
||||
Target: container.MustAbs("/nix/store"),
|
||||
Lower: []*container.Absolute{container.MustAbs("/mnt-root/nix/.ro-store")},
|
||||
Upper: container.MustAbs("/mnt-root/nix/.rw-store/upper"),
|
||||
Work: container.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"),
|
||||
}},
|
||||
{&FSBind{Source: container.MustAbs("/nix/store")}},
|
||||
{&FSBind{Source: check.MustAbs("/nix/store")}},
|
||||
{&FSLink{Target: container.AbsFHSRun.Append("current-system"), Linkname: "/run/current-system", Dereference: true}},
|
||||
{&FSLink{Target: container.AbsFHSRun.Append("opengl-driver"), Linkname: "/run/opengl-driver", Dereference: true}},
|
||||
{&FSBind{Source: container.AbsFHSVarLib.Append("hakurei/u0/org.chromium.Chromium"),
|
||||
Target: container.MustAbs("/data/data/org.chromium.Chromium"), Write: true, Ensure: true}},
|
||||
Target: check.MustAbs("/data/data/org.chromium.Chromium"), Write: true, Ensure: true}},
|
||||
{&FSBind{Source: container.AbsFHSDev.Append("dri"), Device: true, Optional: true}},
|
||||
},
|
||||
|
||||
Username: "chronos",
|
||||
Shell: container.AbsFHSRun.Append("current-system/sw/bin/zsh"),
|
||||
Home: container.MustAbs("/data/data/org.chromium.Chromium"),
|
||||
Home: check.MustAbs("/data/data/org.chromium.Chromium"),
|
||||
|
||||
Path: container.AbsFHSRun.Append("current-system/sw/bin/chromium"),
|
||||
Args: []string{
|
||||
|
@ -16,6 +16,7 @@ import (
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/bits"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/hst"
|
||||
"hakurei.app/internal/app/state"
|
||||
"hakurei.app/system"
|
||||
@ -695,7 +696,7 @@ func (k *stubNixOS) cmdOutput(cmd *exec.Cmd) ([]byte, error) {
|
||||
func (k *stubNixOS) overflowUid(container.Msg) int { return 65534 }
|
||||
func (k *stubNixOS) overflowGid(container.Msg) int { return 65534 }
|
||||
|
||||
func (k *stubNixOS) mustHsuPath() *container.Absolute { return m("/proc/nonexistent/hsu") }
|
||||
func (k *stubNixOS) mustHsuPath() *check.Absolute { return m("/proc/nonexistent/hsu") }
|
||||
|
||||
func (k *stubNixOS) fatalf(format string, v ...any) { panic(fmt.Sprintf(format, v...)) }
|
||||
|
||||
@ -703,8 +704,8 @@ func (k *stubNixOS) isVerbose() bool { return true }
|
||||
func (k *stubNixOS) verbose(v ...any) { log.Print(v...) }
|
||||
func (k *stubNixOS) verbosef(format string, v ...any) { log.Printf(format, v...) }
|
||||
|
||||
func m(pathname string) *container.Absolute {
|
||||
return container.MustAbs(pathname)
|
||||
func m(pathname string) *check.Absolute {
|
||||
return check.MustAbs(pathname)
|
||||
}
|
||||
|
||||
func f(c hst.FilesystemConfig) hst.FilesystemConfigJSON {
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
"path/filepath"
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/internal"
|
||||
)
|
||||
|
||||
@ -57,7 +58,7 @@ type syscallDispatcher interface {
|
||||
overflowGid(msg container.Msg) int
|
||||
|
||||
// mustHsuPath provides [internal.MustHsuPath].
|
||||
mustHsuPath() *container.Absolute
|
||||
mustHsuPath() *check.Absolute
|
||||
|
||||
// fatalf provides [log.Fatalf].
|
||||
fatalf(format string, v ...any)
|
||||
@ -92,6 +93,6 @@ func (direct) cmdOutput(cmd *exec.Cmd) ([]byte, error) { return cmd.Output() }
|
||||
func (direct) overflowUid(msg container.Msg) int { return container.OverflowUid(msg) }
|
||||
func (direct) overflowGid(msg container.Msg) int { return container.OverflowGid(msg) }
|
||||
|
||||
func (direct) mustHsuPath() *container.Absolute { return internal.MustHsuPath() }
|
||||
func (direct) mustHsuPath() *check.Absolute { return internal.MustHsuPath() }
|
||||
|
||||
func (direct) fatalf(format string, v ...any) { log.Fatalf(format, v...) }
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"os/exec"
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
)
|
||||
|
||||
type panicDispatcher struct{}
|
||||
@ -22,5 +23,5 @@ func (panicDispatcher) lookupGroupId(string) (string, error) { panic("unreachab
|
||||
func (panicDispatcher) cmdOutput(*exec.Cmd) ([]byte, error) { panic("unreachable") }
|
||||
func (panicDispatcher) overflowUid(container.Msg) int { panic("unreachable") }
|
||||
func (panicDispatcher) overflowGid(container.Msg) int { panic("unreachable") }
|
||||
func (panicDispatcher) mustHsuPath() *container.Absolute { panic("unreachable") }
|
||||
func (panicDispatcher) mustHsuPath() *check.Absolute { panic("unreachable") }
|
||||
func (panicDispatcher) fatalf(string, ...any) { panic("unreachable") }
|
||||
|
@ -3,16 +3,16 @@ package app
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/hst"
|
||||
)
|
||||
|
||||
// EnvPaths holds paths copied from the environment and is used to create [hst.Paths].
|
||||
type EnvPaths struct {
|
||||
// TempDir is returned by [os.TempDir].
|
||||
TempDir *container.Absolute
|
||||
TempDir *check.Absolute
|
||||
// RuntimePath is copied from $XDG_RUNTIME_DIR.
|
||||
RuntimePath *container.Absolute
|
||||
RuntimePath *check.Absolute
|
||||
}
|
||||
|
||||
// Copy expands [EnvPaths] into [hst.Paths].
|
||||
@ -43,7 +43,7 @@ func copyPaths(k syscallDispatcher) *EnvPaths {
|
||||
|
||||
var env EnvPaths
|
||||
|
||||
if tempDir, err := container.NewAbs(k.tempdir()); err != nil {
|
||||
if tempDir, err := check.NewAbs(k.tempdir()); err != nil {
|
||||
k.fatalf("invalid TMPDIR: %v", err)
|
||||
panic("unreachable")
|
||||
} else {
|
||||
@ -51,7 +51,7 @@ func copyPaths(k syscallDispatcher) *EnvPaths {
|
||||
}
|
||||
|
||||
r, _ := k.lookupEnv(xdgRuntimeDir)
|
||||
if a, err := container.NewAbs(r); err == nil {
|
||||
if a, err := check.NewAbs(r); err == nil {
|
||||
env.RuntimePath = a
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/stub"
|
||||
"hakurei.app/hst"
|
||||
)
|
||||
@ -74,11 +75,11 @@ func TestCopyPaths(t *testing.T) {
|
||||
{"invalid tempdir", nil, "\x00",
|
||||
"invalid TMPDIR: path \"\\x00\" is not absolute", EnvPaths{}},
|
||||
{"empty environment", make(map[string]string), container.Nonexistent,
|
||||
"", EnvPaths{TempDir: container.MustAbs(container.Nonexistent)}},
|
||||
"", EnvPaths{TempDir: check.MustAbs(container.Nonexistent)}},
|
||||
{"invalid XDG_RUNTIME_DIR", map[string]string{"XDG_RUNTIME_DIR": "\x00"}, container.Nonexistent,
|
||||
"", EnvPaths{TempDir: container.MustAbs(container.Nonexistent)}},
|
||||
"", EnvPaths{TempDir: check.MustAbs(container.Nonexistent)}},
|
||||
{"full", map[string]string{"XDG_RUNTIME_DIR": "/\x00"}, container.Nonexistent,
|
||||
"", EnvPaths{TempDir: container.MustAbs(container.Nonexistent), RuntimePath: container.MustAbs("/\x00")}},
|
||||
"", EnvPaths{TempDir: check.MustAbs(container.Nonexistent), RuntimePath: check.MustAbs("/\x00")}},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"strconv"
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/hst"
|
||||
"hakurei.app/internal/app/state"
|
||||
"hakurei.app/system"
|
||||
@ -51,7 +52,7 @@ type outcomeState struct {
|
||||
*EnvPaths
|
||||
|
||||
// Matched paths to cover. Populated by spFilesystemOp.
|
||||
HidePaths []*container.Absolute
|
||||
HidePaths []*check.Absolute
|
||||
|
||||
// Copied via populateLocal.
|
||||
k syscallDispatcher
|
||||
@ -95,14 +96,14 @@ func (s *outcomeState) populateLocal(k syscallDispatcher, msg container.Msg) err
|
||||
// instancePath returns a path formatted for outcomeStateSys.instance.
|
||||
// This method must only be called from outcomeOp.toContainer if
|
||||
// outcomeOp.toSystem has already called outcomeStateSys.instance.
|
||||
func (s *outcomeState) instancePath() *container.Absolute {
|
||||
func (s *outcomeState) instancePath() *check.Absolute {
|
||||
return s.sc.SharePath.Append(s.id.String())
|
||||
}
|
||||
|
||||
// runtimePath returns a path formatted for outcomeStateSys.runtime.
|
||||
// This method must only be called from outcomeOp.toContainer if
|
||||
// outcomeOp.toSystem has already called outcomeStateSys.runtime.
|
||||
func (s *outcomeState) runtimePath() *container.Absolute {
|
||||
func (s *outcomeState) runtimePath() *check.Absolute {
|
||||
return s.sc.RunDirPath.Append(s.id.String())
|
||||
}
|
||||
|
||||
@ -112,9 +113,9 @@ type outcomeStateSys struct {
|
||||
// Whether XDG_RUNTIME_DIR is used post hsu.
|
||||
useRuntimeDir bool
|
||||
// Process-specific directory in TMPDIR, nil if unused.
|
||||
sharePath *container.Absolute
|
||||
sharePath *check.Absolute
|
||||
// Process-specific directory in XDG_RUNTIME_DIR, nil if unused.
|
||||
runtimeSharePath *container.Absolute
|
||||
runtimeSharePath *check.Absolute
|
||||
|
||||
sys *system.I
|
||||
*outcomeState
|
||||
@ -134,7 +135,7 @@ func (state *outcomeStateSys) ensureRuntimeDir() {
|
||||
|
||||
// instance returns the pathname to a process-specific directory within TMPDIR.
|
||||
// This directory must only hold entries bound to [system.Process].
|
||||
func (state *outcomeStateSys) instance() *container.Absolute {
|
||||
func (state *outcomeStateSys) instance() *check.Absolute {
|
||||
if state.sharePath != nil {
|
||||
return state.sharePath
|
||||
}
|
||||
@ -145,7 +146,7 @@ func (state *outcomeStateSys) instance() *container.Absolute {
|
||||
|
||||
// runtime returns the pathname to a process-specific directory within XDG_RUNTIME_DIR.
|
||||
// This directory must only hold entries bound to [system.Process].
|
||||
func (state *outcomeStateSys) runtime() *container.Absolute {
|
||||
func (state *outcomeStateSys) runtime() *check.Absolute {
|
||||
if state.runtimeSharePath != nil {
|
||||
return state.runtimeSharePath
|
||||
}
|
||||
@ -169,7 +170,7 @@ type outcomeStateParams struct {
|
||||
|
||||
// Inner XDG_RUNTIME_DIR default formatting of `/run/user/%d` via mapped uid.
|
||||
// Populated by spRuntimeOp.
|
||||
runtimeDir *container.Absolute
|
||||
runtimeDir *check.Absolute
|
||||
|
||||
as hst.ApplyState
|
||||
*outcomeState
|
||||
|
@ -13,6 +13,7 @@ import (
|
||||
"time"
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/hst"
|
||||
"hakurei.app/internal"
|
||||
"hakurei.app/internal/app/state"
|
||||
@ -215,7 +216,7 @@ type finaliseProcess struct {
|
||||
waitDelay time.Duration
|
||||
|
||||
// Copied from the RunDirPath field of [hst.Paths].
|
||||
runDirPath *container.Absolute
|
||||
runDirPath *check.Absolute
|
||||
|
||||
// Copied from outcomeState.
|
||||
identity *stringPair[int]
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/bits"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/seccomp"
|
||||
"hakurei.app/hst"
|
||||
"hakurei.app/system/dbus"
|
||||
@ -183,7 +184,7 @@ func (s spFilesystemOp) toSystem(state *outcomeStateSys, _ *hst.Config) error {
|
||||
}
|
||||
}
|
||||
|
||||
hidePathSource := make([]*container.Absolute, 0, hidePathSourceCount)
|
||||
hidePathSource := make([]*check.Absolute, 0, hidePathSourceCount)
|
||||
|
||||
// fs append
|
||||
for _, c := range filesystem {
|
||||
@ -234,8 +235,8 @@ func (s spFilesystemOp) toSystem(state *outcomeStateSys, _ *hst.Config) error {
|
||||
// copy matched paths for shim
|
||||
for i, ok := range hidePathMatch {
|
||||
if ok {
|
||||
if a, err := container.NewAbs(hidePaths[i]); err != nil {
|
||||
var absoluteError *container.AbsoluteError
|
||||
if a, err := check.NewAbs(hidePaths[i]); err != nil {
|
||||
var absoluteError *check.AbsoluteError
|
||||
if !errors.As(err, &absoluteError) {
|
||||
return newWithMessageError(absoluteError.Error(), absoluteError)
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import (
|
||||
"os"
|
||||
"syscall"
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/hst"
|
||||
)
|
||||
|
||||
@ -45,13 +45,13 @@ func (s *spPulseOp) toSystem(state *outcomeStateSys, _ *hst.Config) error {
|
||||
state.sys.Link(pulseSocket, state.runtime().Append("pulse"))
|
||||
|
||||
// publish current user's pulse cookie for target user
|
||||
var paCookiePath *container.Absolute
|
||||
var paCookiePath *check.Absolute
|
||||
{
|
||||
const paLocateStep = "locate PulseAudio cookie"
|
||||
|
||||
// from environment
|
||||
if p, ok := state.k.lookupEnv("PULSE_COOKIE"); ok {
|
||||
if a, err := container.NewAbs(p); err != nil {
|
||||
if a, err := check.NewAbs(p); err != nil {
|
||||
return &hst.AppError{Step: paLocateStep, Err: err}
|
||||
} else {
|
||||
// this takes precedence, do not verify whether the file is accessible
|
||||
@ -62,7 +62,7 @@ func (s *spPulseOp) toSystem(state *outcomeStateSys, _ *hst.Config) error {
|
||||
|
||||
// $HOME/.pulse-cookie
|
||||
if p, ok := state.k.lookupEnv("HOME"); ok {
|
||||
if a, err := container.NewAbs(p); err != nil {
|
||||
if a, err := check.NewAbs(p); err != nil {
|
||||
return &hst.AppError{Step: paLocateStep, Err: err}
|
||||
} else {
|
||||
paCookiePath = a.Append(".pulse-cookie")
|
||||
@ -83,7 +83,7 @@ func (s *spPulseOp) toSystem(state *outcomeStateSys, _ *hst.Config) error {
|
||||
|
||||
// $XDG_CONFIG_HOME/pulse/cookie
|
||||
if p, ok := state.k.lookupEnv("XDG_CONFIG_HOME"); ok {
|
||||
if a, err := container.NewAbs(p); err != nil {
|
||||
if a, err := check.NewAbs(p); err != nil {
|
||||
return &hst.AppError{Step: paLocateStep, Err: err}
|
||||
} else {
|
||||
paCookiePath = a.Append("pulse", "cookie")
|
||||
@ -161,7 +161,7 @@ func (s *spPulseOp) toContainer(state *outcomeStateParams) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *spPulseOp) commonPaths(state *outcomeState) (pulseRuntimeDir, pulseSocket *container.Absolute) {
|
||||
func (s *spPulseOp) commonPaths(state *outcomeState) (pulseRuntimeDir, pulseSocket *check.Absolute) {
|
||||
// PulseAudio runtime directory (usually `/run/user/%d/pulse`)
|
||||
pulseRuntimeDir = state.sc.RuntimePath.Append("pulse")
|
||||
// PulseAudio socket (usually `/run/user/%d/pulse/native`)
|
||||
|
@ -2,6 +2,7 @@ package app
|
||||
|
||||
import (
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/hst"
|
||||
"hakurei.app/system"
|
||||
"hakurei.app/system/acl"
|
||||
@ -37,7 +38,7 @@ func (s spRuntimeOp) toContainer(state *outcomeStateParams) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s spRuntimeOp) commonPaths(state *outcomeState) (runtimeDir, runtimeDirInst *container.Absolute) {
|
||||
func (s spRuntimeOp) commonPaths(state *outcomeState) (runtimeDir, runtimeDirInst *check.Absolute) {
|
||||
runtimeDir = state.sc.SharePath.Append("runtime")
|
||||
runtimeDirInst = runtimeDir.Append(state.identity.String())
|
||||
return
|
||||
|
@ -2,6 +2,7 @@ package app
|
||||
|
||||
import (
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/hst"
|
||||
"hakurei.app/system"
|
||||
"hakurei.app/system/acl"
|
||||
@ -26,7 +27,7 @@ func (s spTmpdirOp) toContainer(state *outcomeStateParams) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s spTmpdirOp) commonPaths(state *outcomeState) (tmpdir, tmpdirInst *container.Absolute) {
|
||||
func (s spTmpdirOp) commonPaths(state *outcomeState) (tmpdir, tmpdirInst *check.Absolute) {
|
||||
tmpdir = state.sc.SharePath.Append("tmpdir")
|
||||
tmpdirInst = tmpdir.Append(state.identity.String())
|
||||
return
|
||||
|
@ -1,7 +1,7 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/hst"
|
||||
"hakurei.app/system/acl"
|
||||
"hakurei.app/system/wayland"
|
||||
@ -10,16 +10,16 @@ import (
|
||||
// spWaylandOp exports the Wayland display server to the container.
|
||||
type spWaylandOp struct {
|
||||
// Path to host wayland socket. Populated during toSystem if DirectWayland is true.
|
||||
SocketPath *container.Absolute
|
||||
SocketPath *check.Absolute
|
||||
}
|
||||
|
||||
func (s *spWaylandOp) toSystem(state *outcomeStateSys, config *hst.Config) error {
|
||||
// outer wayland socket (usually `/run/user/%d/wayland-%d`)
|
||||
var socketPath *container.Absolute
|
||||
var socketPath *check.Absolute
|
||||
if name, ok := state.k.lookupEnv(wayland.WaylandDisplay); !ok {
|
||||
state.msg.Verbose(wayland.WaylandDisplay + " is not set, assuming " + wayland.FallbackName)
|
||||
socketPath = state.sc.RuntimePath.Append(wayland.FallbackName)
|
||||
} else if a, err := container.NewAbs(name); err != nil {
|
||||
} else if a, err := check.NewAbs(name); err != nil {
|
||||
socketPath = state.sc.RuntimePath.Append(name)
|
||||
} else {
|
||||
socketPath = a
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/hst"
|
||||
"hakurei.app/system/acl"
|
||||
)
|
||||
@ -29,13 +30,13 @@ func (s *spX11Op) toSystem(state *outcomeStateSys, _ *hst.Config) error {
|
||||
|
||||
// the socket file at `/tmp/.X11-unix/X%d` is typically owned by the priv user
|
||||
// and not accessible by the target user
|
||||
var socketPath *container.Absolute
|
||||
var socketPath *check.Absolute
|
||||
if len(s.Display) > 1 && s.Display[0] == ':' { // `:%d`
|
||||
if n, err := strconv.Atoi(s.Display[1:]); err == nil && n >= 0 {
|
||||
socketPath = absX11SocketDir.Append("X" + strconv.Itoa(n))
|
||||
}
|
||||
} else if len(s.Display) > 5 && strings.HasPrefix(s.Display, "unix:") { // `unix:%s`
|
||||
if a, err := container.NewAbs(s.Display[5:]); err == nil {
|
||||
if a, err := check.NewAbs(s.Display[5:]); err == nil {
|
||||
socketPath = a
|
||||
}
|
||||
}
|
||||
|
@ -6,11 +6,11 @@ var (
|
||||
version = compPoison
|
||||
)
|
||||
|
||||
// check validates string value set at compile time.
|
||||
func check(s string) (string, bool) { return s, s != compPoison && s != "" }
|
||||
// checkComp validates string value set at compile time.
|
||||
func checkComp(s string) (string, bool) { return s, s != compPoison && s != "" }
|
||||
|
||||
func Version() string {
|
||||
if v, ok := check(version); ok {
|
||||
if v, ok := checkComp(version); ok {
|
||||
return v
|
||||
}
|
||||
return "impure"
|
||||
|
@ -3,7 +3,7 @@ package internal
|
||||
import (
|
||||
"log"
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -12,15 +12,15 @@ var (
|
||||
)
|
||||
|
||||
// MustHakureiPath returns the absolute path to hakurei, configured at compile time.
|
||||
func MustHakureiPath() *container.Absolute { return mustCheckPath(log.Fatal, "hakurei", hmain) }
|
||||
func MustHakureiPath() *check.Absolute { return mustCheckPath(log.Fatal, "hakurei", hmain) }
|
||||
|
||||
// MustHsuPath returns the absolute path to hakurei, configured at compile time.
|
||||
func MustHsuPath() *container.Absolute { return mustCheckPath(log.Fatal, "hsu", hsu) }
|
||||
func MustHsuPath() *check.Absolute { return mustCheckPath(log.Fatal, "hsu", hsu) }
|
||||
|
||||
// mustCheckPath checks a pathname against compPoison, then [container.NewAbs], calling fatal if either step fails.
|
||||
func mustCheckPath(fatal func(v ...any), name, pathname string) *container.Absolute {
|
||||
func mustCheckPath(fatal func(v ...any), name, pathname string) *check.Absolute {
|
||||
if pathname != compPoison && pathname != "" {
|
||||
if a, err := container.NewAbs(pathname); err != nil {
|
||||
if a, err := check.NewAbs(pathname); err != nil {
|
||||
fatal(err.Error())
|
||||
return nil // unreachable
|
||||
} else {
|
||||
|
@ -4,7 +4,7 @@ import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
)
|
||||
|
||||
func TestMustCheckPath(t *testing.T) {
|
||||
@ -35,7 +35,7 @@ func TestMustCheckPath(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
if got := mustCheckPath(fatal, "test", tc.pathname); got != nil && !reflect.DeepEqual(got, container.MustAbs(tc.pathname)) {
|
||||
if got := mustCheckPath(fatal, "test", tc.pathname); got != nil && !reflect.DeepEqual(got, check.MustAbs(tc.pathname)) {
|
||||
t.Errorf("mustCheckPath: %q", got)
|
||||
}
|
||||
})
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/bits"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/seccomp"
|
||||
)
|
||||
|
||||
@ -27,10 +28,10 @@ func Exec(ctx context.Context, msg container.Msg, p string) ([]*Entry, error) {
|
||||
c, cancel := context.WithTimeout(ctx, lddTimeout)
|
||||
defer cancel()
|
||||
|
||||
var toolPath *container.Absolute
|
||||
var toolPath *check.Absolute
|
||||
if s, err := exec.LookPath(lddName); err != nil {
|
||||
return nil, err
|
||||
} else if toolPath, err = container.NewAbs(s); err != nil {
|
||||
} else if toolPath, err = check.NewAbs(s); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
14
ldd/path.go
14
ldd/path.go
@ -1,20 +1,20 @@
|
||||
package ldd
|
||||
|
||||
import (
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
)
|
||||
|
||||
// Path returns a deterministic, deduplicated slice of absolute directory paths in entries.
|
||||
func Path(entries []*Entry) []*container.Absolute {
|
||||
p := make([]*container.Absolute, 0, len(entries)*2)
|
||||
func Path(entries []*Entry) []*check.Absolute {
|
||||
p := make([]*check.Absolute, 0, len(entries)*2)
|
||||
for _, entry := range entries {
|
||||
if a, err := container.NewAbs(entry.Path); err == nil {
|
||||
if a, err := check.NewAbs(entry.Path); err == nil {
|
||||
p = append(p, a.Dir())
|
||||
}
|
||||
if a, err := container.NewAbs(entry.Name); err == nil {
|
||||
if a, err := check.NewAbs(entry.Name); err == nil {
|
||||
p = append(p, a.Dir())
|
||||
}
|
||||
}
|
||||
container.SortAbs(p)
|
||||
return container.CompactAbs(p)
|
||||
check.SortAbs(p)
|
||||
return check.CompactAbs(p)
|
||||
}
|
||||
|
@ -6,19 +6,19 @@ import (
|
||||
"os"
|
||||
"slices"
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/hst"
|
||||
"hakurei.app/system/acl"
|
||||
)
|
||||
|
||||
// UpdatePerm calls UpdatePermType with the [Process] criteria.
|
||||
func (sys *I) UpdatePerm(path *container.Absolute, perms ...acl.Perm) *I {
|
||||
func (sys *I) UpdatePerm(path *check.Absolute, perms ...acl.Perm) *I {
|
||||
sys.UpdatePermType(Process, path, perms...)
|
||||
return sys
|
||||
}
|
||||
|
||||
// UpdatePermType maintains [acl.Perms] on a file until its [Enablement] is no longer satisfied.
|
||||
func (sys *I) UpdatePermType(et hst.Enablement, path *container.Absolute, perms ...acl.Perm) *I {
|
||||
func (sys *I) UpdatePermType(et hst.Enablement, path *check.Absolute, perms ...acl.Perm) *I {
|
||||
sys.ops = append(sys.ops, &aclUpdateOp{et, path.String(), perms})
|
||||
return sys
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
"syscall"
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/hst"
|
||||
"hakurei.app/system/dbus"
|
||||
)
|
||||
@ -21,7 +22,7 @@ var (
|
||||
)
|
||||
|
||||
// MustProxyDBus calls ProxyDBus and panics if an error is returned.
|
||||
func (sys *I) MustProxyDBus(sessionPath *container.Absolute, session *hst.BusConfig, systemPath *container.Absolute, system *hst.BusConfig) *I {
|
||||
func (sys *I) MustProxyDBus(sessionPath *check.Absolute, session *hst.BusConfig, systemPath *check.Absolute, system *hst.BusConfig) *I {
|
||||
if err := sys.ProxyDBus(session, system, sessionPath, systemPath); err != nil {
|
||||
panic(err.Error())
|
||||
} else {
|
||||
@ -31,7 +32,7 @@ func (sys *I) MustProxyDBus(sessionPath *container.Absolute, session *hst.BusCon
|
||||
|
||||
// ProxyDBus finalises configuration ahead of time and starts xdg-dbus-proxy via [dbus] and terminates it on revert.
|
||||
// This [Op] is always [Process] scoped.
|
||||
func (sys *I) ProxyDBus(session, system *hst.BusConfig, sessionPath, systemPath *container.Absolute) error {
|
||||
func (sys *I) ProxyDBus(session, system *hst.BusConfig, sessionPath, systemPath *check.Absolute) error {
|
||||
d := new(dbusProxyOp)
|
||||
|
||||
// session bus is required as otherwise this is effectively a very expensive noop
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/bits"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/seccomp"
|
||||
"hakurei.app/helper"
|
||||
"hakurei.app/ldd"
|
||||
@ -41,18 +42,18 @@ func (p *Proxy) Start() error {
|
||||
cmd.Env = make([]string, 0)
|
||||
}, nil)
|
||||
} else {
|
||||
var toolPath *container.Absolute
|
||||
if a, err := container.NewAbs(p.name); err != nil {
|
||||
var toolPath *check.Absolute
|
||||
if a, err := check.NewAbs(p.name); err != nil {
|
||||
if p.name, err = exec.LookPath(p.name); err != nil {
|
||||
return err
|
||||
} else if toolPath, err = container.NewAbs(p.name); err != nil {
|
||||
} else if toolPath, err = check.NewAbs(p.name); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
toolPath = a
|
||||
}
|
||||
|
||||
var libPaths []*container.Absolute
|
||||
var libPaths []*check.Absolute
|
||||
if entries, err := ldd.Exec(ctx, p.msg, toolPath.String()); err != nil {
|
||||
return err
|
||||
} else {
|
||||
@ -76,7 +77,7 @@ func (p *Proxy) Start() error {
|
||||
}
|
||||
|
||||
// upstream bus directories
|
||||
upstreamPaths := make([]*container.Absolute, 0, 2)
|
||||
upstreamPaths := make([]*check.Absolute, 0, 2)
|
||||
for _, addr := range [][]AddrEntry{p.final.SessionUpstream, p.final.SystemUpstream} {
|
||||
for _, ent := range addr {
|
||||
if ent.Method != "unix" {
|
||||
@ -86,7 +87,7 @@ func (p *Proxy) Start() error {
|
||||
if pair[0] != "path" {
|
||||
continue
|
||||
}
|
||||
if a, err := container.NewAbs(pair[1]); err != nil {
|
||||
if a, err := check.NewAbs(pair[1]); err != nil {
|
||||
continue
|
||||
} else {
|
||||
upstreamPaths = append(upstreamPaths, a.Dir())
|
||||
@ -94,8 +95,8 @@ func (p *Proxy) Start() error {
|
||||
}
|
||||
}
|
||||
}
|
||||
container.SortAbs(upstreamPaths)
|
||||
upstreamPaths = container.CompactAbs(upstreamPaths)
|
||||
check.SortAbs(upstreamPaths)
|
||||
upstreamPaths = check.CompactAbs(upstreamPaths)
|
||||
for _, name := range upstreamPaths {
|
||||
z.Bind(name, name, 0)
|
||||
}
|
||||
@ -103,15 +104,15 @@ func (p *Proxy) Start() error {
|
||||
z.HostAbstract = z.HostNet
|
||||
|
||||
// parent directories of bind paths
|
||||
sockDirPaths := make([]*container.Absolute, 0, 2)
|
||||
if a, err := container.NewAbs(p.final.Session[1]); err == nil {
|
||||
sockDirPaths := make([]*check.Absolute, 0, 2)
|
||||
if a, err := check.NewAbs(p.final.Session[1]); err == nil {
|
||||
sockDirPaths = append(sockDirPaths, a.Dir())
|
||||
}
|
||||
if a, err := container.NewAbs(p.final.System[1]); err == nil {
|
||||
if a, err := check.NewAbs(p.final.System[1]); err == nil {
|
||||
sockDirPaths = append(sockDirPaths, a.Dir())
|
||||
}
|
||||
container.SortAbs(sockDirPaths)
|
||||
sockDirPaths = container.CompactAbs(sockDirPaths)
|
||||
check.SortAbs(sockDirPaths)
|
||||
sockDirPaths = check.CompactAbs(sockDirPaths)
|
||||
for _, name := range sockDirPaths {
|
||||
z.Bind(name, name, container.BindWritable)
|
||||
}
|
||||
|
@ -3,17 +3,17 @@ package system
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/hst"
|
||||
)
|
||||
|
||||
// Link calls LinkFileType with the [Process] criteria.
|
||||
func (sys *I) Link(oldname, newname *container.Absolute) *I {
|
||||
func (sys *I) Link(oldname, newname *check.Absolute) *I {
|
||||
return sys.LinkFileType(Process, oldname, newname)
|
||||
}
|
||||
|
||||
// LinkFileType maintains a hardlink until its [Enablement] is no longer satisfied.
|
||||
func (sys *I) LinkFileType(et hst.Enablement, oldname, newname *container.Absolute) *I {
|
||||
func (sys *I) LinkFileType(et hst.Enablement, oldname, newname *check.Absolute) *I {
|
||||
sys.ops = append(sys.ops, &hardlinkOp{et, newname.String(), oldname.String()})
|
||||
return sys
|
||||
}
|
||||
|
@ -5,18 +5,18 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/hst"
|
||||
)
|
||||
|
||||
// Ensure ensures the existence of a directory.
|
||||
func (sys *I) Ensure(name *container.Absolute, perm os.FileMode) *I {
|
||||
func (sys *I) Ensure(name *check.Absolute, perm os.FileMode) *I {
|
||||
sys.ops = append(sys.ops, &mkdirOp{User, name.String(), perm, false})
|
||||
return sys
|
||||
}
|
||||
|
||||
// Ephemeral ensures the existence of a directory until its [Enablement] is no longer satisfied.
|
||||
func (sys *I) Ephemeral(et hst.Enablement, name *container.Absolute, perm os.FileMode) *I {
|
||||
func (sys *I) Ephemeral(et hst.Enablement, name *check.Absolute, perm os.FileMode) *I {
|
||||
sys.ops = append(sys.ops, &mkdirOp{et, name.String(), perm, true})
|
||||
return sys
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/stub"
|
||||
"hakurei.app/hst"
|
||||
"hakurei.app/system/internal/xcb"
|
||||
@ -313,4 +314,4 @@ func TestNop(t *testing.T) {
|
||||
new(noCopy).Lock()
|
||||
}
|
||||
|
||||
func m(pathname string) *container.Absolute { return container.MustAbs(pathname) }
|
||||
func m(pathname string) *check.Absolute { return check.MustAbs(pathname) }
|
||||
|
@ -8,12 +8,12 @@ import (
|
||||
"os"
|
||||
"syscall"
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/hst"
|
||||
)
|
||||
|
||||
// CopyFile reads up to n bytes from src and writes the resulting byte slice to payloadP.
|
||||
func (sys *I) CopyFile(payloadP *[]byte, src *container.Absolute, cap int, n int64) *I {
|
||||
func (sys *I) CopyFile(payloadP *[]byte, src *check.Absolute, cap int, n int64) *I {
|
||||
buf := new(bytes.Buffer)
|
||||
buf.Grow(cap)
|
||||
sys.ops = append(sys.ops, &tmpfileOp{payloadP, src.String(), n, buf})
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/hst"
|
||||
"hakurei.app/system/acl"
|
||||
"hakurei.app/system/wayland"
|
||||
@ -20,7 +20,7 @@ type waylandConn interface {
|
||||
// Wayland maintains a wayland socket with security-context-v1 attached via [wayland].
|
||||
// The socket stops accepting connections once the pipe referred to by sync is closed.
|
||||
// The socket is pathname only and is destroyed on revert.
|
||||
func (sys *I) Wayland(dst, src *container.Absolute, appID, instanceID string) *I {
|
||||
func (sys *I) Wayland(dst, src *check.Absolute, appID, instanceID string) *I {
|
||||
sys.ops = append(sys.ops, &waylandOp{nil,
|
||||
dst.String(), src.String(),
|
||||
appID, instanceID,
|
||||
|
Loading…
x
Reference in New Issue
Block a user