container: use absolute for pathname
All checks were successful
Test / Flake checks (push) Successful in 1m26s
Test / Create distribution (push) Successful in 33s
Test / Sandbox (push) Successful in 1m59s
Test / Hakurei (push) Successful in 2m58s
Test / Hpkg (push) Successful in 3m45s
Test / Sandbox (race detector) (push) Successful in 4m11s
Test / Hakurei (race detector) (push) Successful in 4m47s

This is simultaneously more efficient and less error-prone. This change caused minor API changes in multiple other packages.

Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
2025-08-11 02:52:32 +09:00
parent 41ac2be965
commit e99d7affb0
37 changed files with 839 additions and 706 deletions

View File

@@ -2,12 +2,15 @@
package hst
import (
"hakurei.app/container"
"hakurei.app/system"
"hakurei.app/system/dbus"
)
const Tmp = "/.hakurei"
var AbsTmp = container.MustAbs(Tmp)
// Config is used to seal an app implementation.
type Config struct {
// reverse-DNS style arbitrary identifier string from config;
@@ -16,7 +19,7 @@ type Config struct {
ID string `json:"id"`
// absolute path to executable file
Path string `json:"path,omitempty"`
Path *container.Absolute `json:"path,omitempty"`
// final args passed to container init
Args []string `json:"args"`
@@ -35,12 +38,12 @@ type Config struct {
// passwd username in container, defaults to passwd name of target uid or chronos
Username string `json:"username,omitempty"`
// absolute path to shell, empty for host shell
Shell string `json:"shell,omitempty"`
// absolute path to shell
Shell *container.Absolute `json:"shell"`
// absolute path to home directory in the init mount namespace
Data string `json:"data"`
// directory to enter and use as home in the container mount namespace, empty for Data
Dir string `json:"dir"`
Data *container.Absolute `json:"data"`
// directory to enter and use as home in the container mount namespace, nil for Data
Dir *container.Absolute `json:"dir,omitempty"`
// extra acl ops, dispatches before container init
ExtraPerms []*ExtraPermConfig `json:"extra_perms,omitempty"`
@@ -55,21 +58,24 @@ type Config struct {
// ExtraPermConfig describes an acl update op.
type ExtraPermConfig struct {
Ensure bool `json:"ensure,omitempty"`
Path string `json:"path"`
Read bool `json:"r,omitempty"`
Write bool `json:"w,omitempty"`
Execute bool `json:"x,omitempty"`
Ensure bool `json:"ensure,omitempty"`
Path *container.Absolute `json:"path"`
Read bool `json:"r,omitempty"`
Write bool `json:"w,omitempty"`
Execute bool `json:"x,omitempty"`
}
func (e *ExtraPermConfig) String() string {
buf := make([]byte, 0, 5+len(e.Path))
if e.Path == nil {
return "<invalid>"
}
buf := make([]byte, 0, 5+len(e.Path.String()))
buf = append(buf, '-', '-', '-')
if e.Ensure {
buf = append(buf, '+')
}
buf = append(buf, ':')
buf = append(buf, []byte(e.Path)...)
buf = append(buf, []byte(e.Path.String())...)
if e.Read {
buf[0] = 'r'
}

View File

@@ -3,14 +3,11 @@ package hst
import (
"time"
"hakurei.app/container"
"hakurei.app/container/seccomp"
)
const (
// SourceTmpfs causes tmpfs to be mounted on [FilesystemConfig.Dst]
// when assigned to [FilesystemConfig.Src].
SourceTmpfs = "tmpfs"
// TmpfsPerm is the permission bits for tmpfs mount points
// configured through [FilesystemConfig].
TmpfsPerm = 0755
@@ -55,18 +52,18 @@ type (
// pass through all devices
Device bool `json:"device,omitempty"`
// container host filesystem bind mounts
Filesystem []*FilesystemConfig `json:"filesystem"`
Filesystem []FilesystemConfig `json:"filesystem"`
// create symlinks inside container filesystem
Link [][2]string `json:"symlink"`
Link []LinkConfig `json:"symlink"`
// automatically bind mount top-level directories to container root;
// the zero value disables this behaviour
AutoRoot string `json:"auto_root,omitempty"`
AutoRoot *container.Absolute `json:"auto_root,omitempty"`
// extra flags for AutoRoot
RootFlags int `json:"root_flags,omitempty"`
// read-only /etc directory
Etc string `json:"etc,omitempty"`
Etc *container.Absolute `json:"etc,omitempty"`
// automatically set up /etc symlinks
AutoEtc bool `json:"auto_etc"`
}
@@ -74,9 +71,9 @@ type (
// FilesystemConfig is an abstract representation of a bind mount.
FilesystemConfig struct {
// mount point in container, same as src if empty
Dst string `json:"dst,omitempty"`
Dst *container.Absolute `json:"dst,omitempty"`
// host filesystem path to make available to the container
Src string `json:"src"`
Src *container.Absolute `json:"src"`
// do not mount filesystem read-only
Write bool `json:"write,omitempty"`
// do not disable device files
@@ -84,4 +81,12 @@ type (
// fail if the bind mount cannot be established for any reason
Must bool `json:"require,omitempty"`
}
LinkConfig struct {
// symlink target in container
Target *container.Absolute `json:"target"`
// linkname the symlink points to;
// prepend '*' to dereference an absolute pathname on host
Linkname string `json:"linkname"`
}
)

View File

@@ -1,11 +1,15 @@
package hst
import "hakurei.app/container"
// 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"`
// path to shared directory (usually `/tmp/hakurei.%d`)
SharePath string `json:"share_path"`
SharePath *container.Absolute `json:"share_path"`
// XDG_RUNTIME_DIR value (usually `/run/user/%d`)
RuntimePath string `json:"runtime_path"`
RuntimePath *container.Absolute `json:"runtime_path"`
// application runtime directory (usually `/run/user/%d/hakurei`)
RunDirPath string `json:"run_dir_path"`
RunDirPath *container.Absolute `json:"run_dir_path"`
}

View File

@@ -12,7 +12,7 @@ func Template() *Config {
return &Config{
ID: "org.chromium.Chromium",
Path: container.FHSRun + "current-system/sw/bin/chromium",
Path: container.AbsFHSRun.Append("current-system/sw/bin/chromium"),
Args: []string{
"chromium",
"--ignore-gpu-blocklist",
@@ -46,12 +46,12 @@ func Template() *Config {
DirectWayland: false,
Username: "chronos",
Shell: container.FHSRun + "current-system/sw/bin/zsh",
Data: container.FHSVarLib + "hakurei/u0/org.chromium.Chromium",
Dir: "/data/data/org.chromium.Chromium",
Shell: container.AbsFHSRun.Append("current-system/sw/bin/zsh"),
Data: container.AbsFHSVarLib.Append("hakurei/u0/org.chromium.Chromium"),
Dir: container.MustAbs("/data/data/org.chromium.Chromium"),
ExtraPerms: []*ExtraPermConfig{
{Path: container.FHSVarLib + "hakurei/u0", Ensure: true, Execute: true},
{Path: container.FHSVarLib + "hakurei/u0/org.chromium.Chromium", Read: true, Write: true, Execute: true},
{Path: container.AbsFHSVarLib.Append("hakurei/u0"), Ensure: true, Execute: true},
{Path: container.AbsFHSVarLib.Append("hakurei/u0/org.chromium.Chromium"), Read: true, Write: true, Execute: true},
},
Identity: 9,
@@ -77,20 +77,20 @@ func Template() *Config {
"GOOGLE_DEFAULT_CLIENT_ID": "77185425430.apps.googleusercontent.com",
"GOOGLE_DEFAULT_CLIENT_SECRET": "OTJgUOQcT7lO7GsGZq2G4IlT",
},
Filesystem: []*FilesystemConfig{
{Dst: container.FHSTmp, Src: SourceTmpfs, Write: true},
{Src: "/nix/store"},
{Src: container.FHSRun + "current-system"},
{Src: container.FHSRun + "opengl-driver"},
{Src: container.FHSVar + "db/nix-channels"},
{Src: container.FHSVarLib + "hakurei/u0/org.chromium.Chromium",
Dst: "/data/data/org.chromium.Chromium", Write: true, Must: true},
{Src: container.FHSDev + "dri", Device: true},
Filesystem: []FilesystemConfig{
{Dst: container.AbsFHSTmp, Src: container.AbsNonexistent, Write: true},
{Src: container.MustAbs("/nix/store")},
{Src: container.AbsFHSRun.Append("current-system")},
{Src: container.AbsFHSRun.Append("opengl-driver")},
{Src: container.AbsFHSVar.Append("db/nix-channels")},
{Src: container.AbsFHSVarLib.Append("hakurei/u0/org.chromium.Chromium"),
Dst: container.MustAbs("/data/data/org.chromium.Chromium"), Write: true, Must: true},
{Src: container.AbsFHSDev.Append("dri"), Device: true},
},
Link: [][2]string{{container.FHSRunUser + "65534", container.FHSRunUser + "150"}},
AutoRoot: container.FHSVarLib + "hakurei/base/org.debian",
Link: []LinkConfig{{container.AbsFHSRunUser.Append("65534"), container.FHSRunUser + "150"}},
AutoRoot: container.AbsFHSVarLib.Append("hakurei/base/org.debian"),
RootFlags: container.BindWritable,
Etc: container.FHSEtc,
Etc: container.AbsFHSEtc,
AutoEtc: true,
},
}

View File

@@ -99,7 +99,7 @@ func TestTemplate(t *testing.T) {
"filesystem": [
{
"dst": "/tmp/",
"src": "tmpfs",
"src": "/proc/nonexistent",
"write": true
},
{
@@ -126,10 +126,10 @@ func TestTemplate(t *testing.T) {
}
],
"symlink": [
[
"/run/user/65534",
"/run/user/150"
]
{
"target": "/run/user/65534",
"linkname": "/run/user/150"
}
],
"auto_root": "/var/lib/hakurei/base/org.debian",
"root_flags": 2,