hakurei/hst/enablement.go
Ophestra 1931b54600
All checks were successful
Test / Create distribution (push) Successful in 36s
Test / Sandbox (push) Successful in 2m36s
Test / Sandbox (race detector) (push) Successful in 4m47s
Test / Hpkg (push) Successful in 4m55s
Test / Hakurei (push) Successful in 4m59s
Test / Hakurei (race detector) (push) Successful in 6m26s
Test / Flake checks (push) Successful in 1m31s
hst: add pipewire flag
These are for #26. None of them are implemented yet. This fixes up test cases for the change to happen. Existing source code and JSON configuration continue to have the same effect. Existing flags get its EPulse bit replaced by EPipeWire.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2025-12-07 22:34:40 +09:00

126 lines
2.6 KiB
Go

package hst
import (
"encoding/json"
"fmt"
"strings"
"syscall"
)
// Enablement represents an optional host service to export to the target user.
type Enablement byte
const (
// EWayland exposes a wayland pathname socket via security-context-v1.
EWayland Enablement = 1 << iota
// EX11 adds the target user via X11 ChangeHosts and exposes the X11 pathname socket.
EX11
// EDBus enables the per-container xdg-dbus-proxy daemon.
EDBus
// EPipeWire exposes a pipewire pathname socket via SecurityContext.
EPipeWire
// EPulse copies the PulseAudio cookie to [hst.PrivateTmp] and exposes the PulseAudio socket.
EPulse
// EM is a noop.
EM
)
// String returns a string representation of the flags set on [Enablement].
func (e Enablement) String() string {
switch e {
case 0:
return "(no enablements)"
case EWayland:
return "wayland"
case EX11:
return "x11"
case EDBus:
return "dbus"
case EPipeWire:
return "pipewire"
case EPulse:
return "pulseaudio"
default:
buf := new(strings.Builder)
buf.Grow(32)
for i := Enablement(1); i < EM; i <<= 1 {
if e&i != 0 {
buf.WriteString(", " + i.String())
}
}
if buf.Len() == 0 {
return fmt.Sprintf("e%x", byte(e))
}
return strings.TrimPrefix(buf.String(), ", ")
}
}
// NewEnablements returns the address of [Enablement] as [Enablements].
func NewEnablements(e Enablement) *Enablements { return (*Enablements)(&e) }
// Enablements is the [json] adapter for [Enablement].
type Enablements Enablement
// enablementsJSON is the [json] representation of [Enablements].
type enablementsJSON = struct {
Wayland bool `json:"wayland,omitempty"`
X11 bool `json:"x11,omitempty"`
DBus bool `json:"dbus,omitempty"`
PipeWire bool `json:"pipewire,omitempty"`
Pulse bool `json:"pulse,omitempty"`
}
// Unwrap returns the underlying [Enablement].
func (e *Enablements) Unwrap() Enablement {
if e == nil {
return 0
}
return Enablement(*e)
}
func (e *Enablements) MarshalJSON() ([]byte, error) {
if e == nil {
return nil, syscall.EINVAL
}
return json.Marshal(&enablementsJSON{
Wayland: Enablement(*e)&EWayland != 0,
X11: Enablement(*e)&EX11 != 0,
DBus: Enablement(*e)&EDBus != 0,
PipeWire: Enablement(*e)&EPipeWire != 0,
Pulse: Enablement(*e)&EPulse != 0,
})
}
func (e *Enablements) UnmarshalJSON(data []byte) error {
if e == nil {
return syscall.EINVAL
}
v := new(enablementsJSON)
if err := json.Unmarshal(data, &v); err != nil {
return err
}
var ve Enablement
if v.Wayland {
ve |= EWayland
}
if v.X11 {
ve |= EX11
}
if v.DBus {
ve |= EDBus
}
if v.PipeWire {
ve |= EPipeWire
}
if v.Pulse {
ve |= EPulse
}
*e = Enablements(ve)
return nil
}