aboutsummaryrefslogtreecommitdiffhomepage
path: root/hst
diff options
context:
space:
mode:
Diffstat (limited to 'hst')
-rw-r--r--hst/fs.go12
-rw-r--r--hst/fs_test.go14
-rw-r--r--hst/fsdaemon.go48
-rw-r--r--hst/fsdaemon_test.go29
4 files changed, 103 insertions, 0 deletions
diff --git a/hst/fs.go b/hst/fs.go
index 926d6233..3cecac88 100644
--- a/hst/fs.go
+++ b/hst/fs.go
@@ -45,6 +45,9 @@ type Ops interface {
Root(host *check.Absolute, flags int) Ops
// Etc appends an op that expands host /etc into a toplevel symlink mirror with /etc semantics.
Etc(host *check.Absolute, prefix string) Ops
+
+ // Daemon appends an op that starts a daemon in the container and blocks until target appears.
+ Daemon(target, path *check.Absolute, args ...string) Ops
}
// ApplyState holds the address of [Ops] and any relevant application state.
@@ -124,6 +127,12 @@ func (f *FilesystemConfigJSON) MarshalJSON() ([]byte, error) {
*FSLink
}{fsType{FilesystemLink}, cv}
+ case *FSDaemon:
+ v = &struct {
+ fsType
+ *FSDaemon
+ }{fsType{FilesystemDaemon}, cv}
+
default:
return nil, FSImplError{f.FilesystemConfig}
}
@@ -152,6 +161,9 @@ func (f *FilesystemConfigJSON) UnmarshalJSON(data []byte) error {
case FilesystemLink:
*f = FilesystemConfigJSON{new(FSLink)}
+ case FilesystemDaemon:
+ *f = FilesystemConfigJSON{new(FSDaemon)}
+
default:
return FSTypeError(t.Type)
}
diff --git a/hst/fs_test.go b/hst/fs_test.go
index 4b079096..fdef9bc6 100644
--- a/hst/fs_test.go
+++ b/hst/fs_test.go
@@ -84,6 +84,16 @@ func TestFilesystemConfigJSON(t *testing.T) {
}, nil,
`{"type":"link","dst":"/run/current-system","linkname":"/run/current-system","dereference":true}`,
`{"fs":{"type":"link","dst":"/run/current-system","linkname":"/run/current-system","dereference":true},"magic":3236757504}`},
+
+ {"daemon", hst.FilesystemConfigJSON{
+ FilesystemConfig: &hst.FSDaemon{
+ Target: m("/run/user/1971/pulse/native"),
+ Exec: m("/run/current-system/sw/bin/pipewire-pulse"),
+ Args: []string{"-v"},
+ },
+ }, nil,
+ `{"type":"daemon","dst":"/run/user/1971/pulse/native","path":"/run/current-system/sw/bin/pipewire-pulse","args":["-v"]}`,
+ `{"fs":{"type":"daemon","dst":"/run/user/1971/pulse/native","path":"/run/current-system/sw/bin/pipewire-pulse","args":["-v"]},"magic":3236757504}`},
}
for _, tc := range testCases {
@@ -345,6 +355,10 @@ func (p opsAdapter) Etc(host *check.Absolute, prefix string) hst.Ops {
return opsAdapter{p.Ops.Etc(host, prefix)}
}
+func (p opsAdapter) Daemon(target, path *check.Absolute, args ...string) hst.Ops {
+ return opsAdapter{p.Ops.Daemon(target, path, args...)}
+}
+
func m(pathname string) *check.Absolute { return check.MustAbs(pathname) }
func ms(pathnames ...string) []*check.Absolute {
as := make([]*check.Absolute, len(pathnames))
diff --git a/hst/fsdaemon.go b/hst/fsdaemon.go
new file mode 100644
index 00000000..fd3f3758
--- /dev/null
+++ b/hst/fsdaemon.go
@@ -0,0 +1,48 @@
+package hst
+
+import (
+ "encoding/gob"
+
+ "hakurei.app/container/check"
+)
+
+func init() { gob.Register(new(FSDaemon)) }
+
+// FilesystemDaemon is the type string of a daemon.
+const FilesystemDaemon = "daemon"
+
+// FSDaemon represents a daemon to be started in the container.
+type FSDaemon struct {
+ // Pathname indicating readiness of daemon.
+ Target *check.Absolute `json:"dst"`
+ // Absolute pathname to daemon executable file.
+ Exec *check.Absolute `json:"path"`
+ // Arguments (excl. first) passed to daemon.
+ Args []string `json:"args"`
+}
+
+func (d *FSDaemon) Valid() bool { return d != nil && d.Target != nil && d.Exec != nil }
+
+func (d *FSDaemon) Path() *check.Absolute {
+ if !d.Valid() {
+ return nil
+ }
+ return d.Target
+}
+
+func (d *FSDaemon) Host() []*check.Absolute { return nil }
+
+func (d *FSDaemon) Apply(z *ApplyState) {
+ if !d.Valid() {
+ return
+ }
+ z.Daemon(d.Target, d.Exec, d.Args...)
+}
+
+func (d *FSDaemon) String() string {
+ if !d.Valid() {
+ return "<invalid>"
+ }
+
+ return "daemon:" + d.Target.String()
+}
diff --git a/hst/fsdaemon_test.go b/hst/fsdaemon_test.go
new file mode 100644
index 00000000..1e78d62a
--- /dev/null
+++ b/hst/fsdaemon_test.go
@@ -0,0 +1,29 @@
+package hst_test
+
+import (
+ "testing"
+
+ "hakurei.app/container"
+ "hakurei.app/hst"
+)
+
+func TestFSDaemon(t *testing.T) {
+ t.Parallel()
+
+ checkFs(t, []fsTestCase{
+ {"nil", (*hst.FSDaemon)(nil), false, nil, nil, nil, "<invalid>"},
+ {"zero", new(hst.FSDaemon), false, nil, nil, nil, "<invalid>"},
+
+ {"pipewire-pulse", &hst.FSDaemon{
+ Target: m("/run/user/1971/pulse/native"),
+ Exec: m("/run/current-system/sw/bin/pipewire-pulse"),
+ Args: []string{"-v"},
+ }, true, container.Ops{
+ &container.DaemonOp{
+ Target: m("/run/user/1971/pulse/native"),
+ Path: m("/run/current-system/sw/bin/pipewire-pulse"),
+ Args: []string{"-v"},
+ },
+ }, m("/run/user/1971/pulse/native"), nil, `daemon:/run/user/1971/pulse/native`},
+ })
+}