internal/outcome: populate instance metadata for PipeWire
All checks were successful
Test / Create distribution (push) Successful in 1m10s
Test / Hakurei (push) Successful in 12m25s
Test / Sandbox (push) Successful in 1m40s
Test / Sandbox (race detector) (push) Successful in 2m29s
Test / Hakurei (race detector) (push) Successful in 4m54s
Test / Hpkg (push) Successful in 3m56s
Test / Flake checks (push) Successful in 2m42s

These have similar semantics to equivalent Wayland security-context-v1 fields.

Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
2025-12-10 03:01:30 +09:00
parent f8b3db3f66
commit b72d502f1c
5 changed files with 89 additions and 14 deletions

View File

@@ -68,7 +68,11 @@ func TestOutcomeRun(t *testing.T) {
).
// spPipeWireOp
PipeWire(m("/tmp/hakurei.0/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/pipewire")).
PipeWire(
m("/tmp/hakurei.0/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/pipewire"),
"org.chromium.Chromium",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
).
// spDBusOp
MustProxyDBus(
@@ -335,7 +339,7 @@ func TestOutcomeRun(t *testing.T) {
Ensure(m("/tmp/hakurei.0/tmpdir/9"), 01700).UpdatePermType(system.User, m("/tmp/hakurei.0/tmpdir/9"), acl.Read, acl.Write, acl.Execute).
Ephemeral(system.Process, m("/tmp/hakurei.0/ebf083d1b175911782d413369b64ce7c"), 0711).
Wayland(m("/tmp/hakurei.0/ebf083d1b175911782d413369b64ce7c/wayland"), m("/run/user/1971/wayland-0"), "org.chromium.Chromium", "ebf083d1b175911782d413369b64ce7c").
PipeWire(m("/tmp/hakurei.0/ebf083d1b175911782d413369b64ce7c/pipewire")).
PipeWire(m("/tmp/hakurei.0/ebf083d1b175911782d413369b64ce7c/pipewire"), "org.chromium.Chromium", "ebf083d1b175911782d413369b64ce7c").
MustProxyDBus(&hst.BusConfig{
Talk: []string{
"org.freedesktop.Notifications",
@@ -486,7 +490,7 @@ func TestOutcomeRun(t *testing.T) {
Ensure(m("/run/user/1971/hakurei"), 0700).UpdatePermType(system.User, m("/run/user/1971/hakurei"), acl.Execute).
UpdatePermType(hst.EWayland, m("/run/user/1971/wayland-0"), acl.Read, acl.Write, acl.Execute).
Ephemeral(system.Process, m("/tmp/hakurei.0/8e2c76b066dabe574cf073bdb46eb5c1"), 0711).
PipeWire(m("/tmp/hakurei.0/8e2c76b066dabe574cf073bdb46eb5c1/pipewire")).
PipeWire(m("/tmp/hakurei.0/8e2c76b066dabe574cf073bdb46eb5c1/pipewire"), "org.chromium.Chromium", "8e2c76b066dabe574cf073bdb46eb5c1").
MustProxyDBus(&hst.BusConfig{
Talk: []string{
"org.freedesktop.FileManager1", "org.freedesktop.Notifications",

View File

@@ -18,7 +18,12 @@ func (s spPipeWireOp) toSystem(state *outcomeStateSys) error {
return errNotEnabled
}
state.sys.PipeWire(state.instance().Append("pipewire"))
appId := state.appId
if appId == "" {
// use instance ID in case app id is not set
appId = "app.hakurei." + state.id.String()
}
state.sys.PipeWire(state.instance().Append("pipewire"), appId, state.id.String())
return nil
}

View File

@@ -30,7 +30,9 @@ func TestSpPipeWireOp(t *testing.T) {
Ephemeral(system.Process, m(wantInstancePrefix), 0711).
// toSystem
PipeWire(
m(wantInstancePrefix + "/pipewire"),
m(wantInstancePrefix+"/pipewire"),
"org.chromium.Chromium",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
), sysUsesInstance(nil), nil, insertsOps(afterSpRuntimeOp(nil)), []stub.Call{
// this op configures the container state and does not make calls during toContainer
}, &container.Params{

View File

@@ -14,8 +14,8 @@ import (
// PipeWire maintains a pipewire socket with SecurityContext attached via [pipewire].
// The socket stops accepting connections once the pipe referred to by sync is closed.
// The socket is pathname only and is destroyed on revert.
func (sys *I) PipeWire(dst *check.Absolute) *I {
sys.ops = append(sys.ops, &pipewireOp{nil, dst})
func (sys *I) PipeWire(dst *check.Absolute, appID, instanceID string) *I {
sys.ops = append(sys.ops, &pipewireOp{nil, dst, appID, instanceID})
return sys
}
@@ -23,6 +23,8 @@ func (sys *I) PipeWire(dst *check.Absolute) *I {
type pipewireOp struct {
scc io.Closer
dst *check.Absolute
appID, instanceID string
}
func (p *pipewireOp) Type() hst.Enablement { return Process }
@@ -56,6 +58,8 @@ func (p *pipewireOp) apply(sys *I) (err error) {
if p.scc, err = securityContext.BindAndCreate(p.dst.String(), pipewire.SPADict{
{Key: pipewire.PW_KEY_SEC_ENGINE, Value: "app.hakurei"},
{Key: pipewire.PW_KEY_SEC_APP_ID, Value: p.appID},
{Key: pipewire.PW_KEY_SEC_INSTANCE_ID, Value: p.instanceID},
{Key: pipewire.PW_KEY_ACCESS, Value: "restricted"},
}); err != nil {
return newOpError("pipewire", err, false)
@@ -92,7 +96,9 @@ func (p *pipewireOp) revert(sys *I, _ *Criteria) error {
func (p *pipewireOp) Is(o Op) bool {
target, ok := o.(*pipewireOp)
return ok && p != nil && target != nil &&
p.dst.Is(target.dst)
p.dst.Is(target.dst) &&
p.appID == target.appID &&
p.instanceID == target.instanceID
}
func (p *pipewireOp) Path() string { return p.dst.String() }

View File

@@ -18,6 +18,8 @@ func TestPipeWireOp(t *testing.T) {
checkOpBehaviour(t, checkNoParallel, []opBehaviourTestCase{
{"success", 0xbeef, 0xff, &pipewireOp{nil,
m(path.Join(t.TempDir(), "pipewire")),
"org.chromium.Chromium",
"ebf083d1b175911782d413369b64ce7c",
}, []stub.Call{
call("pipewireConnect", stub.ExpectArgs{}, func() *pipewire.Context {
if ctx, err := pipewire.New(&stubPipeWireConn{sendmsg: []string{
@@ -154,11 +156,11 @@ func TestPipeWireOp(t *testing.T) {
string([]byte{
// header: SecurityContext::Create
3, 0, 0, 0,
0xa8, 0, 0, 1,
0x40, 1, 0, 1,
5, 0, 0, 0,
2, 0, 0, 0,
// Struct
0xa0, 0, 0, 0,
0x38, 1, 0, 0,
0xe, 0, 0, 0,
// Fd: listen_fd = 1
8, 0, 0, 0,
@@ -171,12 +173,12 @@ func TestPipeWireOp(t *testing.T) {
0, 0, 0, 0,
0, 0, 0, 0,
// Struct: spa_dict
0x78, 0, 0, 0,
0x10, 1, 0, 0,
0xe, 0, 0, 0,
// Int: n_items = 2
// Int: n_items = 4
4, 0, 0, 0,
4, 0, 0, 0,
4, 0, 0, 0,
2, 0, 0, 0,
0, 0, 0, 0,
// String: key = "pipewire.sec.engine"
0x14, 0, 0, 0,
@@ -194,6 +196,48 @@ func TestPipeWireOp(t *testing.T) {
0x68, 0x61, 0x6b, 0x75,
0x72, 0x65, 0x69, 0,
0, 0, 0, 0,
// String: key = "pipewire.sec.app-id"
0x14, 0, 0, 0,
8, 0, 0, 0,
0x70, 0x69, 0x70, 0x65,
0x77, 0x69, 0x72, 0x65,
0x2e, 0x73, 0x65, 0x63,
0x2e, 0x61, 0x70, 0x70,
0x2d, 0x69, 0x64, 0,
0, 0, 0, 0,
// String: value = "org.chromium.Chromium"
0x16, 0, 0, 0,
8, 0, 0, 0,
0x6f, 0x72, 0x67, 0x2e,
0x63, 0x68, 0x72, 0x6f,
0x6d, 0x69, 0x75, 0x6d,
0x2e, 0x43, 0x68, 0x72,
0x6f, 0x6d, 0x69, 0x75,
// String: key = "pipewire.sec.instance-id"
0x6d, 0, 0, 0,
0x19, 0, 0, 0,
8, 0, 0, 0,
0x70, 0x69, 0x70, 0x65,
0x77, 0x69, 0x72, 0x65,
0x2e, 0x73, 0x65, 0x63,
0x2e, 0x69, 0x6e, 0x73,
0x74, 0x61, 0x6e, 0x63,
0x65, 0x2d, 0x69, 0x64,
0, 0, 0, 0,
0, 0, 0, 0,
// String: value = "ebf083d1b175911782d413369b64ce7c"
0x21, 0, 0, 0,
8, 0, 0, 0,
0x65, 0x62, 0x66, 0x30,
0x38, 0x33, 0x64, 0x31,
0x62, 0x31, 0x37, 0x35,
0x39, 0x31, 0x31, 0x37,
0x38, 0x32, 0x64, 0x34,
0x31, 0x33, 0x33, 0x36,
0x39, 0x62, 0x36, 0x34,
0x63, 0x65, 0x37, 0x63,
0, 0, 0, 0,
0, 0, 0, 0,
// String: key = "pipewire.access"
0x10, 0, 0, 0,
8, 0, 0, 0,
@@ -386,29 +430,43 @@ func TestPipeWireOp(t *testing.T) {
checkOpsBuilder(t, "PipeWire", []opsBuilderTestCase{
{"sample", 0xcafe, func(_ *testing.T, sys *I) {
sys.PipeWire(m("/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/pipewire"))
sys.PipeWire(m("/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/pipewire"),
"org.chromium.Chromium",
"ebf083d1b175911782d413369b64ce7c")
}, []Op{&pipewireOp{nil,
m("/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/pipewire"),
"org.chromium.Chromium",
"ebf083d1b175911782d413369b64ce7c",
}}, stub.Expect{}},
})
checkOpIs(t, []opIsTestCase{
{"dst differs", &pipewireOp{nil,
m("/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7d/pipewire"),
"org.chromium.Chromium",
"ebf083d1b175911782d413369b64ce7c",
}, &pipewireOp{nil,
m("/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/pipewire"),
"org.chromium.Chromium",
"ebf083d1b175911782d413369b64ce7c",
}, false},
{"equals", &pipewireOp{nil,
m("/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/pipewire"),
"org.chromium.Chromium",
"ebf083d1b175911782d413369b64ce7c",
}, &pipewireOp{nil,
m("/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/pipewire"),
"org.chromium.Chromium",
"ebf083d1b175911782d413369b64ce7c",
}, true},
})
checkOpMeta(t, []opMetaTestCase{
{"sample", &pipewireOp{nil,
m("/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/pipewire"),
"org.chromium.Chromium",
"ebf083d1b175911782d413369b64ce7c",
}, Process, "/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/pipewire",
`pipewire socket at "/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/pipewire"`},
})