From 878b66022e7573ca89fd1fbc266133c7776a98dd Mon Sep 17 00:00:00 2001 From: Ophestra Date: Tue, 26 Aug 2025 00:50:23 +0900 Subject: [PATCH] hst/fsbind: optional ensure source This exposes the BindEnsure flag of BindMountOp. Signed-off-by: Ophestra --- cmd/hakurei/print_test.go | 13 ++++++++----- hst/fsbind.go | 27 ++++++++++++++++++++------- hst/fsbind_test.go | 14 ++++++++++++++ hst/hst.go | 6 +++--- hst/hst_test.go | 3 ++- 5 files changed, 47 insertions(+), 16 deletions(-) diff --git a/cmd/hakurei/print_test.go b/cmd/hakurei/print_test.go index b60c5dc..6feb681 100644 --- a/cmd/hakurei/print_test.go +++ b/cmd/hakurei/print_test.go @@ -53,7 +53,7 @@ Filesystem */nix/store /run/current-system@ /run/opengl-driver@ - w*/var/lib/hakurei/u0/org.chromium.Chromium:/data/data/org.chromium.Chromium + w-/var/lib/hakurei/u0/org.chromium.Chromium:/data/data/org.chromium.Chromium d+/dev/dri Extra ACL @@ -130,7 +130,7 @@ Filesystem */nix/store /run/current-system@ /run/opengl-driver@ - w*/var/lib/hakurei/u0/org.chromium.Chromium:/data/data/org.chromium.Chromium + w-/var/lib/hakurei/u0/org.chromium.Chromium:/data/data/org.chromium.Chromium d+/dev/dri Extra ACL @@ -325,7 +325,8 @@ App "type": "bind", "dst": "/data/data/org.chromium.Chromium", "src": "/var/lib/hakurei/u0/org.chromium.Chromium", - "write": true + "write": true, + "ensure": true }, { "type": "bind", @@ -481,7 +482,8 @@ App "type": "bind", "dst": "/data/data/org.chromium.Chromium", "src": "/var/lib/hakurei/u0/org.chromium.Chromium", - "write": true + "write": true, + "ensure": true }, { "type": "bind", @@ -691,7 +693,8 @@ func Test_printPs(t *testing.T) { "type": "bind", "dst": "/data/data/org.chromium.Chromium", "src": "/var/lib/hakurei/u0/org.chromium.Chromium", - "write": true + "write": true, + "ensure": true }, { "type": "bind", diff --git a/hst/fsbind.go b/hst/fsbind.go index 7aa273c..3769fcd 100644 --- a/hst/fsbind.go +++ b/hst/fsbind.go @@ -14,15 +14,17 @@ const FilesystemBind = "bind" // FSBind represents a host to container bind mount. type FSBind struct { - // mount point in container, same as src if empty + // mount point in container, same as Source if empty Target *container.Absolute `json:"dst,omitempty"` // host filesystem path to make available to the container Source *container.Absolute `json:"src"` - // do not mount filesystem read-only + // do not mount Target read-only Write bool `json:"write,omitempty"` - // do not disable device files, implies Write + // do not disable device files on Target, implies Write Device bool `json:"dev,omitempty"` - // skip this mount point if the host path does not exist + // create Source as a directory if it does not exist + Ensure bool `json:"ensure,omitempty"` + // skip this mount point if Source does not exist Optional bool `json:"optional,omitempty"` // enable special behaviour: @@ -45,6 +47,9 @@ func (b *FSBind) Valid() bool { if b == nil || b.Source == nil { return false } + if b.Ensure && b.Optional { + return false + } if b.Special { if b.Target == nil { return false @@ -94,6 +99,9 @@ func (b *FSBind) Apply(z *ApplyState) { if b.Device { flags |= container.BindDevice | container.BindWritable } + if b.Ensure { + flags |= container.BindEnsure + } if b.Optional { flags |= container.BindOptional } @@ -148,10 +156,15 @@ func (b *FSBind) String() string { expr.Grow(g) expr.WriteString(flagSym) - if !b.Optional { - expr.WriteString("*") - } else { + switch { + case b.Ensure: + expr.WriteString("-") + + case b.Optional: expr.WriteString("+") + + default: + expr.WriteString("*") } expr.WriteString(b.Source.String()) diff --git a/hst/fsbind_test.go b/hst/fsbind_test.go index b2fb0f7..4b9cc19 100644 --- a/hst/fsbind_test.go +++ b/hst/fsbind_test.go @@ -10,6 +10,8 @@ import ( func TestFSBind(t *testing.T) { checkFs(t, []fsTestCase{ {"nil", (*hst.FSBind)(nil), false, nil, nil, nil, ""}, + {"ensure optional", &hst.FSBind{Source: m("/"), Ensure: true, Optional: true}, + false, nil, nil, nil, ""}, {"full", &hst.FSBind{ Target: m("/dev"), @@ -23,6 +25,18 @@ func TestFSBind(t *testing.T) { }}, m("/dev"), ms("/mnt/dev"), "d+/mnt/dev:/dev"}, + {"full ensure", &hst.FSBind{ + Target: m("/dev"), + Source: m("/mnt/dev"), + Ensure: true, + Device: true, + }, true, container.Ops{&container.BindMountOp{ + Source: m("/mnt/dev"), + Target: m("/dev"), + Flags: container.BindWritable | container.BindDevice | container.BindEnsure, + }}, m("/dev"), ms("/mnt/dev"), + "d-/mnt/dev:/dev"}, + {"full write dev", &hst.FSBind{ Target: m("/dev"), Source: m("/mnt/dev"), diff --git a/hst/hst.go b/hst/hst.go index 757c59a..5704904 100644 --- a/hst/hst.go +++ b/hst/hst.go @@ -97,8 +97,8 @@ func Template() *Config { "GOOGLE_DEFAULT_CLIENT_SECRET": "OTJgUOQcT7lO7GsGZq2G4IlT", }, Filesystem: []FilesystemConfigJSON{ - {&FSBind{container.AbsFHSRoot, container.AbsFHSVarLib.Append("hakurei/base/org.debian"), true, false, false, true}}, - {&FSBind{container.AbsFHSEtc, container.AbsFHSEtc, false, false, false, true}}, + {&FSBind{Target: container.AbsFHSRoot, Source: container.AbsFHSVarLib.Append("hakurei/base/org.debian"), Write: true, Special: true}}, + {&FSBind{Target: container.AbsFHSEtc, Source: container.AbsFHSEtc, Special: true}}, {&FSEphemeral{Target: container.AbsFHSTmp, Write: true, Perm: 0755}}, {&FSOverlay{ Target: container.MustAbs("/nix/store"), @@ -110,7 +110,7 @@ func Template() *Config { {&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}}, + Target: container.MustAbs("/data/data/org.chromium.Chromium"), Write: true, Ensure: true}}, {&FSBind{Source: container.AbsFHSDev.Append("dri"), Device: true, Optional: true}}, }, }, diff --git a/hst/hst_test.go b/hst/hst_test.go index fec189a..b36e8d2 100644 --- a/hst/hst_test.go +++ b/hst/hst_test.go @@ -150,7 +150,8 @@ func TestTemplate(t *testing.T) { "type": "bind", "dst": "/data/data/org.chromium.Chromium", "src": "/var/lib/hakurei/u0/org.chromium.Chromium", - "write": true + "write": true, + "ensure": true }, { "type": "bind",