From 0e543a58b36d4ab5d61c02ce93cf72bf2f218857 Mon Sep 17 00:00:00 2001 From: Ophestra Date: Thu, 14 Aug 2025 21:36:22 +0900 Subject: [PATCH] hst/fs: valid method on underlying interface Signed-off-by: Ophestra --- hst/fs.go | 6 +++++- hst/fs_test.go | 18 ++++++++++++++---- hst/fsbind.go | 9 +++++---- hst/fsbind_test.go | 12 ++++++------ hst/fsephemeral.go | 7 ++++--- hst/fsephemeral_test.go | 8 ++++---- 6 files changed, 38 insertions(+), 22 deletions(-) diff --git a/hst/fs.go b/hst/fs.go index f60ca32..ceb0aa4 100644 --- a/hst/fs.go +++ b/hst/fs.go @@ -13,6 +13,8 @@ import ( type FilesystemConfig interface { // Type returns the type of this mount point. Type() string + // Valid returns whether the configuration is valid. + Valid() bool // Target returns the pathname of the mount point in the container. Target() *container.Absolute // Host returns a slice of all host paths used by this mount point. @@ -60,7 +62,9 @@ type FilesystemConfigJSON struct { } // Valid returns whether the [FilesystemConfigJSON] is valid. -func (f *FilesystemConfigJSON) Valid() bool { return f != nil && f.FilesystemConfig != nil } +func (f *FilesystemConfigJSON) Valid() bool { + return f != nil && f.FilesystemConfig != nil && f.FilesystemConfig.Valid() +} func (f *FilesystemConfigJSON) MarshalJSON() ([]byte, error) { if f == nil || f.FilesystemConfig == nil { diff --git a/hst/fs_test.go b/hst/fs_test.go index 46d7cce..c44cd3c 100644 --- a/hst/fs_test.go +++ b/hst/fs_test.go @@ -144,7 +144,7 @@ func TestFilesystemConfigJSON(t *testing.T) { t.Errorf("Valid: %v, want false", got) } - if got := (&hst.FilesystemConfigJSON{FilesystemConfig: new(hst.FSBind)}).Valid(); !got { + if got := (&hst.FilesystemConfigJSON{FilesystemConfig: &hst.FSBind{Src: m("/etc")}}).Valid(); !got { t.Errorf("Valid: %v, want true", got) } }) @@ -192,6 +192,7 @@ type stubFS struct { } func (s stubFS) Type() string { return s.typeName } +func (s stubFS) Valid() bool { return false } func (s stubFS) Target() *container.Absolute { panic("unreachable") } func (s stubFS) Host() []*container.Absolute { panic("unreachable") } func (s stubFS) Apply(*container.Ops) { panic("unreachable") } @@ -205,6 +206,7 @@ type sCheck struct { type fsTestCase struct { name string fs hst.FilesystemConfig + valid bool ops container.Ops target *container.Absolute host []*container.Absolute @@ -214,9 +216,17 @@ type fsTestCase struct { func checkFs(t *testing.T, fstype string, testCases []fsTestCase) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - if got := tc.fs.Type(); got != fstype { - t.Errorf("Type: %q, want %q", got, fstype) - } + t.Run("type", func(t *testing.T) { + if got := tc.fs.Type(); got != fstype { + t.Errorf("Type: %q, want %q", got, fstype) + } + }) + + t.Run("valid", func(t *testing.T) { + if got := tc.fs.Valid(); got != tc.valid { + t.Errorf("Valid: %v, want %v", got, tc.valid) + } + }) t.Run("ops", func(t *testing.T) { ops := new(container.Ops) diff --git a/hst/fsbind.go b/hst/fsbind.go index e95eb7b..18d9cf7 100644 --- a/hst/fsbind.go +++ b/hst/fsbind.go @@ -27,9 +27,10 @@ type FSBind struct { } func (b *FSBind) Type() string { return FilesystemBind } +func (b *FSBind) Valid() bool { return b != nil && b.Src != nil } func (b *FSBind) Target() *container.Absolute { - if b == nil || b.Src == nil { + if !b.Valid() { return nil } if b.Dst == nil { @@ -39,14 +40,14 @@ func (b *FSBind) Target() *container.Absolute { } func (b *FSBind) Host() []*container.Absolute { - if b == nil || b.Src == nil { + if !b.Valid() { return nil } return []*container.Absolute{b.Src} } func (b *FSBind) Apply(ops *container.Ops) { - if b == nil || b.Src == nil { + if !b.Valid() { return } @@ -69,7 +70,7 @@ func (b *FSBind) Apply(ops *container.Ops) { func (b *FSBind) String() string { g := 4 - if b == nil || b.Src == nil { + if !b.Valid() { return "" } diff --git a/hst/fsbind_test.go b/hst/fsbind_test.go index 22a6d9a..48e710c 100644 --- a/hst/fsbind_test.go +++ b/hst/fsbind_test.go @@ -9,14 +9,14 @@ import ( func TestFSBind(t *testing.T) { checkFs(t, "bind", []fsTestCase{ - {"nil", (*hst.FSBind)(nil), nil, nil, nil, ""}, + {"nil", (*hst.FSBind)(nil), false, nil, nil, nil, ""}, {"full", &hst.FSBind{ Dst: m("/dev"), Src: m("/mnt/dev"), Optional: true, Device: true, - }, container.Ops{&container.BindMountOp{ + }, true, container.Ops{&container.BindMountOp{ Source: m("/mnt/dev"), Target: m("/dev"), Flags: container.BindWritable | container.BindDevice | container.BindOptional, @@ -28,7 +28,7 @@ func TestFSBind(t *testing.T) { Src: m("/mnt/dev"), Write: true, Device: true, - }, container.Ops{&container.BindMountOp{ + }, true, container.Ops{&container.BindMountOp{ Source: m("/mnt/dev"), Target: m("/dev"), Flags: container.BindWritable | container.BindDevice, @@ -39,7 +39,7 @@ func TestFSBind(t *testing.T) { Dst: m("/tmp"), Src: m("/mnt/tmp"), Write: true, - }, container.Ops{&container.BindMountOp{ + }, true, container.Ops{&container.BindMountOp{ Source: m("/mnt/tmp"), Target: m("/tmp"), Flags: container.BindWritable, @@ -49,7 +49,7 @@ func TestFSBind(t *testing.T) { {"full no flags", &hst.FSBind{ Dst: m("/etc"), Src: m("/mnt/etc"), - }, container.Ops{&container.BindMountOp{ + }, true, container.Ops{&container.BindMountOp{ Source: m("/mnt/etc"), Target: m("/etc"), }}, m("/etc"), ms("/mnt/etc"), @@ -57,7 +57,7 @@ func TestFSBind(t *testing.T) { {"nil dst", &hst.FSBind{ Src: m("/"), - }, container.Ops{&container.BindMountOp{ + }, true, container.Ops{&container.BindMountOp{ Source: m("/"), Target: m("/"), }}, m("/"), ms("/"), diff --git a/hst/fsephemeral.go b/hst/fsephemeral.go index e3f924c..209b615 100644 --- a/hst/fsephemeral.go +++ b/hst/fsephemeral.go @@ -26,9 +26,10 @@ type FSEphemeral struct { } func (e *FSEphemeral) Type() string { return FilesystemEphemeral } +func (e *FSEphemeral) Valid() bool { return e != nil && e.Dst != nil } func (e *FSEphemeral) Target() *container.Absolute { - if e == nil { + if !e.Valid() { return nil } return e.Dst @@ -39,7 +40,7 @@ func (e *FSEphemeral) Host() []*container.Absolute { return nil } const fsEphemeralDefaultPerm = os.FileMode(0755) func (e *FSEphemeral) Apply(ops *container.Ops) { - if e == nil || e.Dst == nil { + if !e.Valid() { return } @@ -61,7 +62,7 @@ func (e *FSEphemeral) Apply(ops *container.Ops) { } func (e *FSEphemeral) String() string { - if e == nil || e.Dst == nil { + if !e.Valid() { return "" } diff --git a/hst/fsephemeral_test.go b/hst/fsephemeral_test.go index f003a92..320c12f 100644 --- a/hst/fsephemeral_test.go +++ b/hst/fsephemeral_test.go @@ -10,14 +10,14 @@ import ( func TestFSEphemeral(t *testing.T) { checkFs(t, "ephemeral", []fsTestCase{ - {"nil", (*hst.FSEphemeral)(nil), nil, nil, nil, ""}, + {"nil", (*hst.FSEphemeral)(nil), false, nil, nil, nil, ""}, {"full", &hst.FSEphemeral{ Dst: m("/run/user/65534"), Write: true, Size: 1 << 10, Perm: 0700, - }, container.Ops{&container.MountTmpfsOp{ + }, true, container.Ops{&container.MountTmpfsOp{ FSName: "ephemeral", Path: m("/run/user/65534"), Flags: syscall.MS_NOSUID | syscall.MS_NODEV, @@ -26,7 +26,7 @@ func TestFSEphemeral(t *testing.T) { }}, m("/run/user/65534"), nil, "w+ephemeral(-rwx------):/run/user/65534"}, - {"cover ro", &hst.FSEphemeral{Dst: m("/run/nscd")}, + {"cover ro", &hst.FSEphemeral{Dst: m("/run/nscd")}, true, container.Ops{&container.MountTmpfsOp{ FSName: "readonly", Path: m("/run/nscd"), @@ -39,7 +39,7 @@ func TestFSEphemeral(t *testing.T) { Dst: hst.AbsTmp, Write: true, Size: -1, - }, container.Ops{&container.MountTmpfsOp{ + }, true, container.Ops{&container.MountTmpfsOp{ FSName: "ephemeral", Path: hst.AbsTmp, Flags: syscall.MS_NOSUID | syscall.MS_NODEV,