aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2025-08-25 17:51:08 +0900
committerOphestra <cat@gensokyo.uk>2025-08-25 17:52:57 +0900
commit1438096339f49bdd466f3b057c7e695aa126fc3c (patch)
treea374384097ab7346c0a1cb730edc1c838f5adbc7
parent059164d4fa80047fc50bffc1582424d00cf4c139 (diff)
hst/config: handle filesystem entry targeting root
This allows any fstype supported by hst to be directly mounted on sysroot. A special case in internal/app applies the matching entry early and excludes it from path hiding. Closes #5. Signed-off-by: Ophestra <cat@gensokyo.uk>
-rw-r--r--cmd/hakurei/print.go4
-rw-r--r--cmd/hakurei/print_test.go31
-rw-r--r--hst/config.go9
-rw-r--r--hst/hst.go9
-rw-r--r--hst/hst_test.go9
-rw-r--r--internal/app/container_linux.go29
-rw-r--r--internal/app/seal_linux.go10
7 files changed, 64 insertions, 37 deletions
diff --git a/cmd/hakurei/print.go b/cmd/hakurei/print.go
index d163efc3..3e238d65 100644
--- a/cmd/hakurei/print.go
+++ b/cmd/hakurei/print.go
@@ -110,10 +110,6 @@ func printShowInstance(
}
t.Printf(" Flags:\t%s\n", strings.Join(flags, " "))
- if params.AutoRoot != nil {
- t.Printf(" Root:\t%s (%d)\n", params.AutoRoot, params.RootFlags)
- }
-
etc := params.Etc
if etc == nil {
etc = container.AbsFHSEtc
diff --git a/cmd/hakurei/print_test.go b/cmd/hakurei/print_test.go
index dab4b9ec..b55c1044 100644
--- a/cmd/hakurei/print_test.go
+++ b/cmd/hakurei/print_test.go
@@ -42,12 +42,12 @@ func Test_printShowInstance(t *testing.T) {
Data: /var/lib/hakurei/u0/org.chromium.Chromium
Hostname: localhost
Flags: userns devel net abstract device tty mapuid autoetc
- Root: /var/lib/hakurei/base/org.debian (2)
Etc: /etc/
Path: /run/current-system/sw/bin/chromium
Arguments: chromium --ignore-gpu-blocklist --disable-smooth-scrolling --enable-features=UseOzonePlatform --ozone-platform=wayland
Filesystem
+ autoroot:w:/var/lib/hakurei/base/org.debian
w+ephemeral(-rwxr-xr-x):/tmp/
w*/nix/store:/mnt-root/nix/.rw-store/upper:/mnt-root/nix/.rw-store/work:/mnt-root/nix/.ro-store
*/nix/store
@@ -121,12 +121,12 @@ App
Data: /var/lib/hakurei/u0/org.chromium.Chromium
Hostname: localhost
Flags: userns devel net abstract device tty mapuid autoetc
- Root: /var/lib/hakurei/base/org.debian (2)
Etc: /etc/
Path: /run/current-system/sw/bin/chromium
Arguments: chromium --ignore-gpu-blocklist --disable-smooth-scrolling --enable-features=UseOzonePlatform --ozone-platform=wayland
Filesystem
+ autoroot:w:/var/lib/hakurei/base/org.debian
w+ephemeral(-rwxr-xr-x):/tmp/
w*/nix/store:/mnt-root/nix/.rw-store/upper:/mnt-root/nix/.rw-store/work:/mnt-root/nix/.ro-store
*/nix/store
@@ -280,6 +280,13 @@ App
"device": true,
"filesystem": [
{
+ "type": "bind",
+ "dst": "/",
+ "src": "/var/lib/hakurei/base/org.debian",
+ "write": true,
+ "autoroot": true
+ },
+ {
"type": "ephemeral",
"dst": "/tmp/",
"write": true,
@@ -325,8 +332,6 @@ App
"linkname": "/run/user/150"
}
],
- "auto_root": "/var/lib/hakurei/base/org.debian",
- "root_flags": 2,
"etc": "/etc/",
"auto_etc": true
}
@@ -429,6 +434,13 @@ App
"device": true,
"filesystem": [
{
+ "type": "bind",
+ "dst": "/",
+ "src": "/var/lib/hakurei/base/org.debian",
+ "write": true,
+ "autoroot": true
+ },
+ {
"type": "ephemeral",
"dst": "/tmp/",
"write": true,
@@ -474,8 +486,6 @@ App
"linkname": "/run/user/150"
}
],
- "auto_root": "/var/lib/hakurei/base/org.debian",
- "root_flags": 2,
"etc": "/etc/",
"auto_etc": true
}
@@ -632,6 +642,13 @@ func Test_printPs(t *testing.T) {
"device": true,
"filesystem": [
{
+ "type": "bind",
+ "dst": "/",
+ "src": "/var/lib/hakurei/base/org.debian",
+ "write": true,
+ "autoroot": true
+ },
+ {
"type": "ephemeral",
"dst": "/tmp/",
"write": true,
@@ -677,8 +694,6 @@ func Test_printPs(t *testing.T) {
"linkname": "/run/user/150"
}
],
- "auto_root": "/var/lib/hakurei/base/org.debian",
- "root_flags": 2,
"etc": "/etc/",
"auto_etc": true
}
diff --git a/hst/config.go b/hst/config.go
index 8226a35f..e2f95d14 100644
--- a/hst/config.go
+++ b/hst/config.go
@@ -93,17 +93,12 @@ type (
// pass through all devices
Device bool `json:"device,omitempty"`
- // container mount points
+ // container mount points;
+ // if the first element targets /, it is inserted early and excluded from path hiding
Filesystem []FilesystemConfigJSON `json:"filesystem"`
// create symlinks inside container filesystem
Link []LinkConfig `json:"symlink"`
- // automatically bind mount top-level directories to container root;
- // the zero value disables this behaviour
- AutoRoot *container.Absolute `json:"auto_root,omitempty"`
- // extra flags for AutoRoot
- RootFlags int `json:"root_flags,omitempty"`
-
// read-only /etc directory
Etc *container.Absolute `json:"etc,omitempty"`
// automatically set up /etc symlinks
diff --git a/hst/hst.go b/hst/hst.go
index 6e77dc98..6654a4b7 100644
--- a/hst/hst.go
+++ b/hst/hst.go
@@ -97,6 +97,7 @@ func Template() *Config {
"GOOGLE_DEFAULT_CLIENT_SECRET": "OTJgUOQcT7lO7GsGZq2G4IlT",
},
Filesystem: []FilesystemConfigJSON{
+ {&FSBind{container.AbsFHSRoot, container.AbsFHSVarLib.Append("hakurei/base/org.debian"), true, false, false, true}},
{&FSEphemeral{Target: container.AbsFHSTmp, Write: true, Perm: 0755}},
{&FSOverlay{
Target: container.MustAbs("/nix/store"),
@@ -111,11 +112,9 @@ func Template() *Config {
Target: container.MustAbs("/data/data/org.chromium.Chromium"), Write: true}},
{&FSBind{Source: container.AbsFHSDev.Append("dri"), Device: true, Optional: true}},
},
- Link: []LinkConfig{{container.AbsFHSRunUser.Append("65534"), container.FHSRunUser + "150"}},
- AutoRoot: container.AbsFHSVarLib.Append("hakurei/base/org.debian"),
- RootFlags: container.BindWritable,
- Etc: container.AbsFHSEtc,
- AutoEtc: true,
+ Link: []LinkConfig{{container.AbsFHSRunUser.Append("65534"), container.FHSRunUser + "150"}},
+ Etc: container.AbsFHSEtc,
+ AutoEtc: true,
},
}
}
diff --git a/hst/hst_test.go b/hst/hst_test.go
index a3930f48..b8ec79c9 100644
--- a/hst/hst_test.go
+++ b/hst/hst_test.go
@@ -103,6 +103,13 @@ func TestTemplate(t *testing.T) {
"device": true,
"filesystem": [
{
+ "type": "bind",
+ "dst": "/",
+ "src": "/var/lib/hakurei/base/org.debian",
+ "write": true,
+ "autoroot": true
+ },
+ {
"type": "ephemeral",
"dst": "/tmp/",
"write": true,
@@ -148,8 +155,6 @@ func TestTemplate(t *testing.T) {
"linkname": "/run/user/150"
}
],
- "auto_root": "/var/lib/hakurei/base/org.debian",
- "root_flags": 2,
"etc": "/etc/",
"auto_etc": true
}
diff --git a/internal/app/container_linux.go b/internal/app/container_linux.go
index b82a6b69..33c0c72a 100644
--- a/internal/app/container_linux.go
+++ b/internal/app/container_linux.go
@@ -74,8 +74,19 @@ func newContainer(s *hst.ContainerConfig, os sys.State, prefix string, uid, gid
*gid = container.OverflowGid()
}
- if s.AutoRoot != nil {
- params.Root(s.AutoRoot, s.RootFlags)
+ filesystem := s.Filesystem
+ var autoroot *hst.FSBind
+ // valid happens late, so root mount gets it here
+ if len(filesystem) > 0 && filesystem[0].Valid() && filesystem[0].Path().String() == container.FHSRoot {
+ // if the first element targets /, it is inserted early and excluded from path hiding
+ rootfs := filesystem[0].FilesystemConfig
+ filesystem = filesystem[1:]
+ rootfs.Apply(params.Ops)
+
+ // autoroot requires special handling during path hiding
+ if b, ok := rootfs.(*hst.FSBind); ok && b.Valid() && b.AutoRoot {
+ autoroot = b
+ }
}
params.
@@ -128,7 +139,7 @@ func newContainer(s *hst.ContainerConfig, os sys.State, prefix string, uid, gid
}
var hidePathSourceCount int
- for i, c := range s.Filesystem {
+ for i, c := range filesystem {
if !c.Valid() {
return nil, nil, fmt.Errorf("invalid filesystem at index %d", i)
}
@@ -138,10 +149,10 @@ func newContainer(s *hst.ContainerConfig, os sys.State, prefix string, uid, gid
hidePathSourceCount += len(c.Host())
}
- // AutoRoot is a collection of many BindMountOp internally
+ // AutoRootOp is a collection of many BindMountOp internally
var autoRootEntries []fs.DirEntry
- if s.AutoRoot != nil {
- if d, err := os.ReadDir(s.AutoRoot.String()); err != nil {
+ if autoroot != nil {
+ if d, err := os.ReadDir(autoroot.Source.String()); err != nil {
return nil, nil, err
} else {
// autoroot counter
@@ -153,17 +164,17 @@ func newContainer(s *hst.ContainerConfig, os sys.State, prefix string, uid, gid
hidePathSource := make([]*container.Absolute, 0, hidePathSourceCount)
// fs append
- for _, c := range s.Filesystem {
+ for _, c := range filesystem {
// all entries already checked above
hidePathSource = append(hidePathSource, c.Host()...)
}
// autoroot append
- if s.AutoRoot != nil {
+ if autoroot != nil {
for _, ent := range autoRootEntries {
name := ent.Name()
if container.IsAutoRootBindable(name) {
- hidePathSource = append(hidePathSource, s.AutoRoot.Append(name))
+ hidePathSource = append(hidePathSource, autoroot.Source.Append(name))
}
}
}
diff --git a/internal/app/seal_linux.go b/internal/app/seal_linux.go
index 23d65f95..fb6f39b6 100644
--- a/internal/app/seal_linux.go
+++ b/internal/app/seal_linux.go
@@ -244,8 +244,14 @@ func (seal *outcome) finalise(ctx context.Context, sys sys.State, config *hst.Co
Tty: true,
AutoEtc: true,
- AutoRoot: container.AbsFHSRoot,
- RootFlags: container.BindWritable,
+ Filesystem: []hst.FilesystemConfigJSON{
+ {&hst.FSBind{
+ Target: container.AbsFHSRoot,
+ Source: container.AbsFHSRoot,
+ Write: true,
+ AutoRoot: true,
+ }},
+ },
}
// bind GPU stuff