aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal/app
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2025-10-07 20:06:26 +0900
committerOphestra <cat@gensokyo.uk>2025-10-07 20:57:58 +0900
commit0e6c1a50260de141c50bb50fd3f2b2bcf9a3fe64 (patch)
treedfe9c40ceb8c1be8d2728a2db9017bffef174d3d /internal/app
parentd23b4dc9e64d3f00e746c65f3038a1a6de44b8f5 (diff)
container/check: move absolute pathname
This allows use of absolute pathname values without importing container. Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'internal/app')
-rw-r--r--internal/app/app_test.go7
-rw-r--r--internal/app/dispatcher.go5
-rw-r--r--internal/app/dispatcher_test.go3
-rw-r--r--internal/app/env.go10
-rw-r--r--internal/app/env_test.go7
-rw-r--r--internal/app/outcome.go17
-rw-r--r--internal/app/process.go3
-rw-r--r--internal/app/spcontainer.go7
-rw-r--r--internal/app/sppulse.go12
-rw-r--r--internal/app/spruntime.go3
-rw-r--r--internal/app/sptmpdir.go3
-rw-r--r--internal/app/spwayland.go8
-rw-r--r--internal/app/spx11.go5
13 files changed, 50 insertions, 40 deletions
diff --git a/internal/app/app_test.go b/internal/app/app_test.go
index d966b6cc..851d7c24 100644
--- a/internal/app/app_test.go
+++ b/internal/app/app_test.go
@@ -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 {
diff --git a/internal/app/dispatcher.go b/internal/app/dispatcher.go
index 3c5e25c4..f3759023 100644
--- a/internal/app/dispatcher.go
+++ b/internal/app/dispatcher.go
@@ -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...) }
diff --git a/internal/app/dispatcher_test.go b/internal/app/dispatcher_test.go
index 934ab769..834b11b6 100644
--- a/internal/app/dispatcher_test.go
+++ b/internal/app/dispatcher_test.go
@@ -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") }
diff --git a/internal/app/env.go b/internal/app/env.go
index 4305c665..e6d137fc 100644
--- a/internal/app/env.go
+++ b/internal/app/env.go
@@ -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
}
diff --git a/internal/app/env_test.go b/internal/app/env_test.go
index 04e21344..cf6a18b3 100644
--- a/internal/app/env_test.go
+++ b/internal/app/env_test.go
@@ -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) {
diff --git a/internal/app/outcome.go b/internal/app/outcome.go
index f850d773..e2673e45 100644
--- a/internal/app/outcome.go
+++ b/internal/app/outcome.go
@@ -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
diff --git a/internal/app/process.go b/internal/app/process.go
index 63f424f6..80a256c1 100644
--- a/internal/app/process.go
+++ b/internal/app/process.go
@@ -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]
diff --git a/internal/app/spcontainer.go b/internal/app/spcontainer.go
index ffbee7db..6dd2bca3 100644
--- a/internal/app/spcontainer.go
+++ b/internal/app/spcontainer.go
@@ -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)
}
diff --git a/internal/app/sppulse.go b/internal/app/sppulse.go
index d3742db0..a6dba590 100644
--- a/internal/app/sppulse.go
+++ b/internal/app/sppulse.go
@@ -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`)
diff --git a/internal/app/spruntime.go b/internal/app/spruntime.go
index c2e5518d..05597181 100644
--- a/internal/app/spruntime.go
+++ b/internal/app/spruntime.go
@@ -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
diff --git a/internal/app/sptmpdir.go b/internal/app/sptmpdir.go
index 00680ffb..0e5cfe9f 100644
--- a/internal/app/sptmpdir.go
+++ b/internal/app/sptmpdir.go
@@ -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
diff --git a/internal/app/spwayland.go b/internal/app/spwayland.go
index 130a2ed2..91ce1ac3 100644
--- a/internal/app/spwayland.go
+++ b/internal/app/spwayland.go
@@ -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
diff --git a/internal/app/spx11.go b/internal/app/spx11.go
index 0d287e05..b21eb48d 100644
--- a/internal/app/spx11.go
+++ b/internal/app/spx11.go
@@ -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
}
}