package hst import ( "encoding/json" "fmt" "strings" "syscall" ) // Enablements denotes optional host service to export to the target user. type Enablements byte const ( // EWayland exposes a Wayland pathname socket via security-context-v1. EWayland Enablements = 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 [Enablements]. func (e Enablements) 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 := Enablements(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(), ", ") } } // 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 value pointed to by e. func (e *Enablements) Unwrap() Enablements { if e == nil { return 0 } return *e } func (e Enablements) MarshalJSON() ([]byte, error) { return json.Marshal(&enablementsJSON{ Wayland: e&EWayland != 0, X11: e&EX11 != 0, DBus: e&EDBus != 0, PipeWire: e&EPipeWire != 0, Pulse: 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 } *e = 0 if v.Wayland { *e |= EWayland } if v.X11 { *e |= EX11 } if v.DBus { *e |= EDBus } if v.PipeWire { *e |= EPipeWire } if v.Pulse { *e |= EPulse } return nil }