diff --git a/internal/outcome/sppipewire.go b/internal/outcome/sppipewire.go new file mode 100644 index 0000000..b8c855f --- /dev/null +++ b/internal/outcome/sppipewire.go @@ -0,0 +1,31 @@ +package outcome + +import ( + "encoding/gob" + + "hakurei.app/hst" + "hakurei.app/internal/pipewire" +) + +func init() { gob.Register(spPipeWireOp{}) } + +// spPipeWireOp exports the PipeWire server to the container via SecurityContext. +// Runs after spRuntimeOp. +type spPipeWireOp struct{} + +func (s spPipeWireOp) toSystem(state *outcomeStateSys) error { + if state.et&hst.EPipeWire == 0 { + return errNotEnabled + } + + state.sys.PipeWire(state.instance().Append("pipewire")) + return nil +} + +func (s spPipeWireOp) toContainer(state *outcomeStateParams) error { + innerPath := state.runtimeDir.Append(pipewire.PW_DEFAULT_REMOTE) + state.env[pipewire.Remote] = innerPath.String() + state.params.Bind(state.instancePath().Append("pipewire"), innerPath, 0) + + return nil +} diff --git a/internal/outcome/sppipewire_test.go b/internal/outcome/sppipewire_test.go new file mode 100644 index 0000000..d53f6d6 --- /dev/null +++ b/internal/outcome/sppipewire_test.go @@ -0,0 +1,43 @@ +package outcome + +import ( + "testing" + + "hakurei.app/container" + "hakurei.app/container/stub" + "hakurei.app/hst" + "hakurei.app/internal/pipewire" + "hakurei.app/internal/system" +) + +func TestSpPipeWireOp(t *testing.T) { + t.Parallel() + config := hst.Template() + + checkOpBehaviour(t, []opBehaviourTestCase{ + {"not enabled", func(bool, bool) outcomeOp { + return spPipeWireOp{} + }, func() *hst.Config { + c := hst.Template() + *c.Enablements = 0 + return c + }, nil, nil, nil, nil, errNotEnabled, nil, nil, nil, nil, nil}, + + {"success", func(bool, bool) outcomeOp { + return spPipeWireOp{} + }, hst.Template, nil, []stub.Call{}, newI(). + // state.instance + Ephemeral(system.Process, m(wantInstancePrefix), 0711). + // toSystem + PipeWire( + m(wantInstancePrefix + "/pipewire"), + ), sysUsesInstance(nil), nil, insertsOps(afterSpRuntimeOp(nil)), []stub.Call{ + // this op configures the container state and does not make calls during toContainer + }, &container.Params{ + Ops: new(container.Ops). + Bind(m(wantInstancePrefix+"/pipewire"), m("/run/user/1000/pipewire-0"), 0), + }, paramsWantEnv(config, map[string]string{ + pipewire.Remote: "/run/user/1000/pipewire-0", + }, nil), nil}, + }) +}