hst: remove enablement json adapter
All checks were successful
Test / Create distribution (push) Successful in 1m2s
Test / Sandbox (push) Successful in 2m46s
Test / Hakurei (push) Successful in 3m48s
Test / ShareFS (push) Successful in 3m49s
Test / Sandbox (race detector) (push) Successful in 5m11s
Test / Hakurei (race detector) (push) Successful in 6m20s
Test / Flake checks (push) Successful in 1m23s
All checks were successful
Test / Create distribution (push) Successful in 1m2s
Test / Sandbox (push) Successful in 2m46s
Test / Hakurei (push) Successful in 3m48s
Test / ShareFS (push) Successful in 3m49s
Test / Sandbox (race detector) (push) Successful in 5m11s
Test / Hakurei (race detector) (push) Successful in 6m20s
Test / Flake checks (push) Successful in 1m23s
The go116 behaviour of built-in new function makes this cleaner. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
@@ -194,7 +194,7 @@ type outcomeStateSys struct {
|
||||
// Copied from [hst.Config]. Safe for read by outcomeOp.toSystem.
|
||||
appId string
|
||||
// Copied from [hst.Config]. Safe for read by outcomeOp.toSystem.
|
||||
et hst.Enablement
|
||||
et hst.Enablements
|
||||
|
||||
// Copied from [hst.Config]. Safe for read by spWaylandOp.toSystem only.
|
||||
directWayland bool
|
||||
|
||||
@@ -297,12 +297,12 @@ func (k *outcome) main(msg message.Msg, identifierFd int) {
|
||||
// accumulate enablements of remaining instances
|
||||
var (
|
||||
// alive enablement bits
|
||||
rt hst.Enablement
|
||||
rt hst.Enablements
|
||||
// alive instance count
|
||||
n int
|
||||
)
|
||||
for eh := range entries {
|
||||
var et hst.Enablement
|
||||
var et hst.Enablements
|
||||
if et, err = eh.Load(nil); err != nil {
|
||||
perror(err, "read state header of instance "+eh.ID.String())
|
||||
} else {
|
||||
|
||||
@@ -288,7 +288,7 @@ func TestOutcomeRun(t *testing.T) {
|
||||
},
|
||||
Filter: true,
|
||||
},
|
||||
Enablements: hst.NewEnablements(hst.EWayland | hst.EDBus | hst.EPipeWire | hst.EPulse),
|
||||
Enablements: new(hst.EWayland | hst.EDBus | hst.EPipeWire | hst.EPulse),
|
||||
|
||||
Container: &hst.ContainerConfig{
|
||||
Filesystem: []hst.FilesystemConfigJSON{
|
||||
@@ -427,7 +427,7 @@ func TestOutcomeRun(t *testing.T) {
|
||||
DirectPipeWire: true,
|
||||
|
||||
ID: "org.chromium.Chromium",
|
||||
Enablements: hst.NewEnablements(hst.EWayland | hst.EDBus | hst.EPipeWire | hst.EPulse),
|
||||
Enablements: new(hst.EWayland | hst.EDBus | hst.EPipeWire | hst.EPulse),
|
||||
Container: &hst.ContainerConfig{
|
||||
Env: nil,
|
||||
Filesystem: []hst.FilesystemConfigJSON{
|
||||
|
||||
@@ -21,7 +21,7 @@ func TestSpPulseOp(t *testing.T) {
|
||||
newConfig := func() *hst.Config {
|
||||
config := hst.Template()
|
||||
config.DirectPulse = true
|
||||
config.Enablements = hst.NewEnablements(hst.EPulse)
|
||||
config.Enablements = new(hst.EPulse)
|
||||
return config
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ func entryEncode(w io.Writer, s *hst.State) error {
|
||||
}
|
||||
|
||||
// entryDecodeHeader calls entryReadHeader, returning [hst.AppError] for a non-nil error.
|
||||
func entryDecodeHeader(r io.Reader) (hst.Enablement, error) {
|
||||
func entryDecodeHeader(r io.Reader) (hst.Enablements, error) {
|
||||
if et, err := entryReadHeader(r); err != nil {
|
||||
return 0, &hst.AppError{Step: "decode state header", Err: err}
|
||||
} else {
|
||||
@@ -32,11 +32,11 @@ func entryDecodeHeader(r io.Reader) (hst.Enablement, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// entryDecode decodes [hst.State] from [io.Reader] and stores the result in the value pointed to by p.
|
||||
// entryDecode validates the embedded [hst.Config] value.
|
||||
// entryDecode decodes [hst.State] from [io.Reader] and stores the result in the
|
||||
// value pointed to by p. entryDecode validates the embedded [hst.Config] value.
|
||||
//
|
||||
// A non-nil error returned by entryDecode is of type [hst.AppError].
|
||||
func entryDecode(r io.Reader, p *hst.State) (hst.Enablement, error) {
|
||||
func entryDecode(r io.Reader, p *hst.State) (hst.Enablements, error) {
|
||||
if et, err := entryDecodeHeader(r); err != nil {
|
||||
return et, err
|
||||
} else if err = gob.NewDecoder(r).Decode(&p); err != nil {
|
||||
@@ -45,7 +45,10 @@ func entryDecode(r io.Reader, p *hst.State) (hst.Enablement, error) {
|
||||
return et, err
|
||||
} else if p.Enablements.Unwrap() != et {
|
||||
return et, &hst.AppError{Step: "validate state enablement", Err: os.ErrInvalid,
|
||||
Msg: fmt.Sprintf("state entry %s has unexpected enablement byte %#x, %#x", p.ID.String(), byte(p.Enablements.Unwrap()), byte(et))}
|
||||
Msg: fmt.Sprintf(
|
||||
"state entry %s has unexpected enablement byte %#x, %#x",
|
||||
p.ID.String(), byte(p.Enablements.Unwrap()), byte(et),
|
||||
)}
|
||||
} else {
|
||||
return et, nil
|
||||
}
|
||||
|
||||
@@ -14,22 +14,25 @@ import (
|
||||
const (
|
||||
// entryHeaderMagic are magic bytes at the beginning of the state entry file.
|
||||
entryHeaderMagic = "\x00\xff\xca\xfe"
|
||||
// entryHeaderRevision follows entryHeaderMagic and is incremented for revisions of the format.
|
||||
// entryHeaderRevision follows entryHeaderMagic and is incremented for
|
||||
// revisions of the format.
|
||||
entryHeaderRevision = "\x00\x00"
|
||||
// entryHeaderSize is the fixed size of the header in bytes, including the enablement byte and its complement.
|
||||
// entryHeaderSize is the fixed size of the header in bytes, including the
|
||||
// enablement byte and its complement.
|
||||
entryHeaderSize = len(entryHeaderMagic+entryHeaderRevision) + 2
|
||||
)
|
||||
|
||||
// entryHeaderEncode encodes a state entry header for a [hst.Enablement] byte.
|
||||
func entryHeaderEncode(et hst.Enablement) *[entryHeaderSize]byte {
|
||||
// entryHeaderEncode encodes a state entry header for a [hst.Enablements] byte.
|
||||
func entryHeaderEncode(et hst.Enablements) *[entryHeaderSize]byte {
|
||||
data := [entryHeaderSize]byte([]byte(
|
||||
entryHeaderMagic + entryHeaderRevision + string([]hst.Enablement{et, ^et}),
|
||||
entryHeaderMagic + entryHeaderRevision + string([]hst.Enablements{et, ^et}),
|
||||
))
|
||||
return &data
|
||||
}
|
||||
|
||||
// entryHeaderDecode validates a state entry header and returns the [hst.Enablement] byte.
|
||||
func entryHeaderDecode(data *[entryHeaderSize]byte) (hst.Enablement, error) {
|
||||
// entryHeaderDecode validates a state entry header and returns the
|
||||
// [hst.Enablements] byte.
|
||||
func entryHeaderDecode(data *[entryHeaderSize]byte) (hst.Enablements, error) {
|
||||
if magic := data[:len(entryHeaderMagic)]; string(magic) != entryHeaderMagic {
|
||||
return 0, errors.New("invalid header " + hex.EncodeToString(magic))
|
||||
}
|
||||
@@ -41,7 +44,7 @@ func entryHeaderDecode(data *[entryHeaderSize]byte) (hst.Enablement, error) {
|
||||
if et != ^data[len(entryHeaderMagic+entryHeaderRevision)+1] {
|
||||
return 0, errors.New("header enablement value is inconsistent")
|
||||
}
|
||||
return hst.Enablement(et), nil
|
||||
return hst.Enablements(et), nil
|
||||
}
|
||||
|
||||
// EntrySizeError is returned for a file too small to hold a state entry header.
|
||||
@@ -68,8 +71,8 @@ func entryCheckFile(fi os.FileInfo) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// entryReadHeader reads [hst.Enablement] from an [io.Reader].
|
||||
func entryReadHeader(r io.Reader) (hst.Enablement, error) {
|
||||
// entryReadHeader reads [hst.Enablements] from an [io.Reader].
|
||||
func entryReadHeader(r io.Reader) (hst.Enablements, error) {
|
||||
var data [entryHeaderSize]byte
|
||||
if n, err := r.Read(data[:]); err != nil {
|
||||
return 0, err
|
||||
@@ -79,8 +82,8 @@ func entryReadHeader(r io.Reader) (hst.Enablement, error) {
|
||||
return entryHeaderDecode(&data)
|
||||
}
|
||||
|
||||
// entryWriteHeader writes [hst.Enablement] header to an [io.Writer].
|
||||
func entryWriteHeader(w io.Writer, et hst.Enablement) error {
|
||||
// entryWriteHeader writes [hst.Enablements] header to an [io.Writer].
|
||||
func entryWriteHeader(w io.Writer, et hst.Enablements) error {
|
||||
_, err := w.Write(entryHeaderEncode(et)[:])
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ func TestEntryHeader(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
data [entryHeaderSize]byte
|
||||
et hst.Enablement
|
||||
et hst.Enablements
|
||||
err error
|
||||
}{
|
||||
{"complement mismatch", [entryHeaderSize]byte{0x00, 0xff, 0xca, 0xfe, 0x00, 0x00,
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
)
|
||||
|
||||
// EntryHandle is a handle on a state entry retrieved from a [Handle].
|
||||
//
|
||||
// Must only be used while its parent [Handle.Lock] is held.
|
||||
type EntryHandle struct {
|
||||
// Error returned while decoding pathname.
|
||||
@@ -27,6 +28,7 @@ type EntryHandle struct {
|
||||
}
|
||||
|
||||
// open opens the underlying state entry file.
|
||||
//
|
||||
// A non-nil error returned by open is of type [hst.AppError].
|
||||
func (eh *EntryHandle) open(flag int, perm os.FileMode) (*os.File, error) {
|
||||
if eh.DecodeErr != nil {
|
||||
@@ -41,6 +43,7 @@ func (eh *EntryHandle) open(flag int, perm os.FileMode) (*os.File, error) {
|
||||
}
|
||||
|
||||
// Destroy removes the underlying state entry.
|
||||
//
|
||||
// A non-nil error returned by Destroy is of type [hst.AppError].
|
||||
func (eh *EntryHandle) Destroy() error {
|
||||
// destroy does not go through open
|
||||
@@ -55,8 +58,10 @@ func (eh *EntryHandle) Destroy() error {
|
||||
}
|
||||
|
||||
// save encodes [hst.State] and writes it to the underlying file.
|
||||
//
|
||||
// An error is returned if a file already exists with the same identifier.
|
||||
// save does not validate the embedded [hst.Config].
|
||||
//
|
||||
// A non-nil error returned by save is of type [hst.AppError].
|
||||
func (eh *EntryHandle) save(state *hst.State) error {
|
||||
f, err := eh.open(os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600)
|
||||
@@ -71,17 +76,19 @@ func (eh *EntryHandle) save(state *hst.State) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Load loads and validates the state entry header, and returns the [hst.Enablement] byte.
|
||||
// for a non-nil v, the full state payload is decoded and stored in the value pointed to by v.
|
||||
// Load validates the embedded [hst.Config] value.
|
||||
// A non-nil error returned by Load is of type [hst.AppError].
|
||||
func (eh *EntryHandle) Load(v *hst.State) (hst.Enablement, error) {
|
||||
// Load loads and validates the state entry header, and returns the
|
||||
// [hst.Enablements] byte. For a non-nil v, the full state payload is decoded
|
||||
// and stored in the value pointed to by v.
|
||||
//
|
||||
// Load validates the embedded [hst.Config] value. A non-nil error returned by
|
||||
// Load is of type [hst.AppError].
|
||||
func (eh *EntryHandle) Load(v *hst.State) (hst.Enablements, error) {
|
||||
f, err := eh.open(os.O_RDONLY, 0)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
var et hst.Enablement
|
||||
var et hst.Enablements
|
||||
if v != nil {
|
||||
et, err = entryDecode(f, v)
|
||||
if err == nil && v.ID != eh.ID {
|
||||
@@ -99,6 +106,7 @@ func (eh *EntryHandle) Load(v *hst.State) (hst.Enablement, error) {
|
||||
}
|
||||
|
||||
// Handle is a handle on a [Store] segment.
|
||||
//
|
||||
// Initialised by [Store.Handle].
|
||||
type Handle struct {
|
||||
// Identity of instances tracked by this segment.
|
||||
@@ -113,8 +121,9 @@ type Handle struct {
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
// Lock attempts to acquire a lock on [Handle].
|
||||
// If successful, Lock returns a non-nil unlock function.
|
||||
// Lock attempts to acquire a lock on [Handle]. If successful, Lock returns a
|
||||
// non-nil unlock function.
|
||||
//
|
||||
// A non-nil error returned by Lock is of type [hst.AppError].
|
||||
func (h *Handle) Lock() (unlock func(), err error) {
|
||||
if unlock, err = h.fileMu.Lock(); err != nil {
|
||||
@@ -123,20 +132,24 @@ func (h *Handle) Lock() (unlock func(), err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// Save attempts to save [hst.State] as a segment entry, and returns its [EntryHandle].
|
||||
// Must be called while holding [Handle.Lock].
|
||||
// Save attempts to save [hst.State] as a segment entry, and returns its
|
||||
// [EntryHandle]. Must be called while holding [Handle.Lock].
|
||||
//
|
||||
// An error is returned if an entry already exists with the same identifier.
|
||||
// Save does not validate the embedded [hst.Config].
|
||||
//
|
||||
// A non-nil error returned by Save is of type [hst.AppError].
|
||||
func (h *Handle) Save(state *hst.State) (*EntryHandle, error) {
|
||||
eh := EntryHandle{nil, h.Path.Append(state.ID.String()), state.ID}
|
||||
return &eh, eh.save(state)
|
||||
}
|
||||
|
||||
// Entries returns an iterator over all [EntryHandle] held in this segment.
|
||||
// Must be called while holding [Handle.Lock].
|
||||
// A non-nil error attached to a [EntryHandle] indicates a malformed identifier and is of type [hst.AppError].
|
||||
// A non-nil error returned by Entries is of type [hst.AppError].
|
||||
// Entries returns an iterator over all [EntryHandle] held in this segment. Must
|
||||
// be called while holding [Handle.Lock].
|
||||
//
|
||||
// A non-nil error attached to a [EntryHandle] indicates a malformed identifier
|
||||
// and is of type [hst.AppError]. A non-nil error returned by Entries is of type
|
||||
// [hst.AppError].
|
||||
func (h *Handle) Entries() (iter.Seq[*EntryHandle], int, error) {
|
||||
// for error reporting
|
||||
const step = "read store segment entries"
|
||||
|
||||
@@ -21,7 +21,7 @@ import (
|
||||
// Made available here for direct validation of state entry files.
|
||||
//
|
||||
//go:linkname entryDecode hakurei.app/internal/store.entryDecode
|
||||
func entryDecode(r io.Reader, p *hst.State) (hst.Enablement, error)
|
||||
func entryDecode(r io.Reader, p *hst.State) (hst.Enablements, error)
|
||||
|
||||
// Made available here for direct access to known segment handles.
|
||||
//
|
||||
|
||||
@@ -17,20 +17,21 @@ func (sys *I) UpdatePerm(path *check.Absolute, perms ...acl.Perm) *I {
|
||||
return sys
|
||||
}
|
||||
|
||||
// UpdatePermType maintains [acl.Perms] on a file until its [Enablement] is no longer satisfied.
|
||||
func (sys *I) UpdatePermType(et hst.Enablement, path *check.Absolute, perms ...acl.Perm) *I {
|
||||
// UpdatePermType maintains [acl.Perms] on a file until its [hst.Enablements] is
|
||||
// no longer satisfied.
|
||||
func (sys *I) UpdatePermType(et hst.Enablements, path *check.Absolute, perms ...acl.Perm) *I {
|
||||
sys.ops = append(sys.ops, &aclUpdateOp{et, path.String(), perms})
|
||||
return sys
|
||||
}
|
||||
|
||||
// aclUpdateOp implements [I.UpdatePermType].
|
||||
type aclUpdateOp struct {
|
||||
et hst.Enablement
|
||||
et hst.Enablements
|
||||
path string
|
||||
perms acl.Perms
|
||||
}
|
||||
|
||||
func (a *aclUpdateOp) Type() hst.Enablement { return a.et }
|
||||
func (a *aclUpdateOp) Type() hst.Enablements { return a.et }
|
||||
|
||||
func (a *aclUpdateOp) apply(sys *I) error {
|
||||
sys.msg.Verbose("applying ACL", a)
|
||||
|
||||
@@ -31,7 +31,9 @@ func (sys *I) MustProxyDBus(
|
||||
}
|
||||
}
|
||||
|
||||
// ProxyDBus finalises configuration ahead of time and starts xdg-dbus-proxy via [dbus] and terminates it on revert.
|
||||
// ProxyDBus finalises configuration ahead of time and starts xdg-dbus-proxy via
|
||||
// [dbus] and terminates it on revert.
|
||||
//
|
||||
// This [Op] is always [Process] scoped.
|
||||
func (sys *I) ProxyDBus(
|
||||
session, system *hst.BusConfig,
|
||||
@@ -84,7 +86,7 @@ type dbusProxyOp struct {
|
||||
system bool
|
||||
}
|
||||
|
||||
func (d *dbusProxyOp) Type() hst.Enablement { return Process }
|
||||
func (d *dbusProxyOp) Type() hst.Enablements { return Process }
|
||||
|
||||
func (d *dbusProxyOp) apply(sys *I) error {
|
||||
sys.msg.Verbosef("session bus proxy on %q for upstream %q", d.final.Session[1], d.final.Session[0])
|
||||
|
||||
@@ -21,12 +21,16 @@ type osFile interface {
|
||||
fs.File
|
||||
}
|
||||
|
||||
// syscallDispatcher provides methods that make state-dependent system calls as part of their behaviour.
|
||||
// syscallDispatcher provides methods that make state-dependent system calls as
|
||||
// part of their behaviour.
|
||||
//
|
||||
// syscallDispatcher is embedded in [I], so all methods must be unexported.
|
||||
type syscallDispatcher interface {
|
||||
// new starts a goroutine with a new instance of syscallDispatcher.
|
||||
// A syscallDispatcher must never be used in any goroutine other than the one owning it,
|
||||
// just synchronising access is not enough, as this is for test instrumentation.
|
||||
//
|
||||
// A syscallDispatcher must never be used in any goroutine other than the
|
||||
// one owning it, just synchronising access is not enough, as this is for
|
||||
// test instrumentation.
|
||||
new(f func(k syscallDispatcher))
|
||||
|
||||
// stat provides os.Stat.
|
||||
|
||||
@@ -27,7 +27,7 @@ func call(name string, args stub.ExpectArgs, ret any, err error) stub.Call {
|
||||
type opBehaviourTestCase struct {
|
||||
name string
|
||||
uid int
|
||||
ec hst.Enablement
|
||||
ec hst.Enablements
|
||||
op Op
|
||||
|
||||
apply []stub.Call
|
||||
@@ -158,7 +158,7 @@ type opMetaTestCase struct {
|
||||
name string
|
||||
op Op
|
||||
|
||||
wantType hst.Enablement
|
||||
wantType hst.Enablements
|
||||
wantPath string
|
||||
wantString string
|
||||
}
|
||||
|
||||
@@ -12,19 +12,19 @@ func (sys *I) Link(oldname, newname *check.Absolute) *I {
|
||||
return sys.LinkFileType(Process, oldname, newname)
|
||||
}
|
||||
|
||||
// LinkFileType maintains a hardlink until its [Enablement] is no longer satisfied.
|
||||
func (sys *I) LinkFileType(et hst.Enablement, oldname, newname *check.Absolute) *I {
|
||||
// LinkFileType maintains a hardlink until its [hst.Enablements] is no longer satisfied.
|
||||
func (sys *I) LinkFileType(et hst.Enablements, oldname, newname *check.Absolute) *I {
|
||||
sys.ops = append(sys.ops, &hardlinkOp{et, newname.String(), oldname.String()})
|
||||
return sys
|
||||
}
|
||||
|
||||
// hardlinkOp implements [I.LinkFileType].
|
||||
type hardlinkOp struct {
|
||||
et hst.Enablement
|
||||
et hst.Enablements
|
||||
dst, src string
|
||||
}
|
||||
|
||||
func (l *hardlinkOp) Type() hst.Enablement { return l.et }
|
||||
func (l *hardlinkOp) Type() hst.Enablements { return l.et }
|
||||
|
||||
func (l *hardlinkOp) apply(sys *I) error {
|
||||
sys.msg.Verbose("linking", l)
|
||||
|
||||
@@ -15,21 +15,22 @@ func (sys *I) Ensure(name *check.Absolute, perm os.FileMode) *I {
|
||||
return sys
|
||||
}
|
||||
|
||||
// Ephemeral ensures the existence of a directory until its [Enablement] is no longer satisfied.
|
||||
func (sys *I) Ephemeral(et hst.Enablement, name *check.Absolute, perm os.FileMode) *I {
|
||||
// Ephemeral ensures the existence of a directory until its [hst.Enablements] is
|
||||
// no longer satisfied.
|
||||
func (sys *I) Ephemeral(et hst.Enablements, name *check.Absolute, perm os.FileMode) *I {
|
||||
sys.ops = append(sys.ops, &mkdirOp{et, name.String(), perm, true})
|
||||
return sys
|
||||
}
|
||||
|
||||
// mkdirOp implements [I.Ensure] and [I.Ephemeral].
|
||||
type mkdirOp struct {
|
||||
et hst.Enablement
|
||||
et hst.Enablements
|
||||
path string
|
||||
perm os.FileMode
|
||||
ephemeral bool
|
||||
}
|
||||
|
||||
func (m *mkdirOp) Type() hst.Enablement { return m.et }
|
||||
func (m *mkdirOp) Type() hst.Enablements { return m.et }
|
||||
|
||||
func (m *mkdirOp) apply(sys *I) error {
|
||||
sys.msg.Verbose("ensuring directory", m)
|
||||
|
||||
@@ -12,8 +12,9 @@ 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.
|
||||
//
|
||||
// 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, appID, instanceID string) *I {
|
||||
sys.ops = append(sys.ops, &pipewireOp{nil, dst, appID, instanceID})
|
||||
return sys
|
||||
@@ -27,7 +28,7 @@ type pipewireOp struct {
|
||||
appID, instanceID string
|
||||
}
|
||||
|
||||
func (p *pipewireOp) Type() hst.Enablement { return Process }
|
||||
func (p *pipewireOp) Type() hst.Enablements { return Process }
|
||||
|
||||
func (p *pipewireOp) apply(sys *I) (err error) {
|
||||
var ctx *pipewire.Context
|
||||
|
||||
@@ -20,21 +20,21 @@ const (
|
||||
)
|
||||
|
||||
// Criteria specifies types of Op to revert.
|
||||
type Criteria hst.Enablement
|
||||
type Criteria hst.Enablements
|
||||
|
||||
func (ec *Criteria) hasType(t hst.Enablement) bool {
|
||||
func (ec *Criteria) hasType(t hst.Enablements) bool {
|
||||
// nil criteria: revert everything except User
|
||||
if ec == nil {
|
||||
return t != User
|
||||
}
|
||||
|
||||
return hst.Enablement(*ec)&t != 0
|
||||
return hst.Enablements(*ec)&t != 0
|
||||
}
|
||||
|
||||
// Op is a reversible system operation.
|
||||
type Op interface {
|
||||
// Type returns [Op]'s enablement type, for matching a revert criteria.
|
||||
Type() hst.Enablement
|
||||
Type() hst.Enablements
|
||||
|
||||
apply(sys *I) error
|
||||
revert(sys *I, ec *Criteria) error
|
||||
@@ -44,8 +44,8 @@ type Op interface {
|
||||
String() string
|
||||
}
|
||||
|
||||
// TypeString extends [hst.Enablement.String] to support [User] and [Process].
|
||||
func TypeString(e hst.Enablement) string {
|
||||
// TypeString extends [hst.Enablements] to support [User] and [Process].
|
||||
func TypeString(e hst.Enablements) string {
|
||||
switch e {
|
||||
case User:
|
||||
return "user"
|
||||
@@ -110,7 +110,9 @@ func (sys *I) Equal(target *I) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// Commit applies all [Op] held by [I] and reverts all successful [Op] on first error encountered.
|
||||
// Commit applies all [Op] held by [I] and reverts all successful [Op] on first
|
||||
// error encountered.
|
||||
//
|
||||
// Commit must not be called more than once.
|
||||
func (sys *I) Commit() error {
|
||||
if sys.committed {
|
||||
|
||||
@@ -20,7 +20,7 @@ func TestCriteria(t *testing.T) {
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
ec, t hst.Enablement
|
||||
ec, t hst.Enablements
|
||||
want bool
|
||||
}{
|
||||
{"nil", 0xff, hst.EWayland, true},
|
||||
@@ -47,7 +47,7 @@ func TestTypeString(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testCases := []struct {
|
||||
e hst.Enablement
|
||||
e hst.Enablements
|
||||
want string
|
||||
}{
|
||||
{hst.EWayland, hst.EWayland.String()},
|
||||
@@ -190,7 +190,7 @@ func TestCommitRevert(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
f func(sys *I)
|
||||
ec hst.Enablement
|
||||
ec hst.Enablements
|
||||
|
||||
commit []stub.Call
|
||||
wantErrCommit error
|
||||
|
||||
@@ -11,8 +11,9 @@ import (
|
||||
)
|
||||
|
||||
// Wayland maintains a wayland socket with security-context-v1 attached via [wayland].
|
||||
// The socket stops accepting connections once the pipe referred to by sync is closed.
|
||||
// The socket is pathname only and is destroyed on revert.
|
||||
//
|
||||
// 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) Wayland(dst, src *check.Absolute, appID, instanceID string) *I {
|
||||
sys.ops = append(sys.ops, &waylandOp{nil,
|
||||
dst, src, appID, instanceID})
|
||||
@@ -26,7 +27,7 @@ type waylandOp struct {
|
||||
appID, instanceID string
|
||||
}
|
||||
|
||||
func (w *waylandOp) Type() hst.Enablement { return Process }
|
||||
func (w *waylandOp) Type() hst.Enablements { return Process }
|
||||
|
||||
func (w *waylandOp) apply(sys *I) (err error) {
|
||||
if w.ctx, err = sys.waylandNew(w.src, w.dst, w.appID, w.instanceID); err != nil {
|
||||
|
||||
@@ -5,7 +5,8 @@ import (
|
||||
"hakurei.app/internal/xcb"
|
||||
)
|
||||
|
||||
// ChangeHosts inserts the target user into X11 hosts and deletes it once its [Enablement] is no longer satisfied.
|
||||
// ChangeHosts inserts the target user into X11 hosts and deletes it once its
|
||||
// [hst.Enablements] is no longer satisfied.
|
||||
func (sys *I) ChangeHosts(username string) *I {
|
||||
sys.ops = append(sys.ops, xhostOp(username))
|
||||
return sys
|
||||
@@ -14,7 +15,7 @@ func (sys *I) ChangeHosts(username string) *I {
|
||||
// xhostOp implements [I.ChangeHosts].
|
||||
type xhostOp string
|
||||
|
||||
func (x xhostOp) Type() hst.Enablement { return hst.EX11 }
|
||||
func (x xhostOp) Type() hst.Enablements { return hst.EX11 }
|
||||
|
||||
func (x xhostOp) apply(sys *I) error {
|
||||
sys.msg.Verbosef("inserting entry %s to X11", x)
|
||||
|
||||
Reference in New Issue
Block a user