feat(auth): coordinate canonical projection publication

This commit is contained in:
User
2026-08-21 23:43:37 +02:00
parent 1e2c4e65c5
commit 903c0b4de5
10 changed files with 1272 additions and 8 deletions
@@ -3,12 +3,14 @@
package authprojection
import (
"context"
"crypto/rand"
"encoding/hex"
"errors"
"path/filepath"
"sync"
"syscall"
"time"
"golang.org/x/sys/unix"
)
@@ -71,14 +73,24 @@ func Inspect(spec Spec) (Status, error) {
}
func Begin(spec Spec, before *Snapshot, requireReadyMatch bool) (*Transaction, error) {
return BeginContext(context.Background(), spec, before, requireReadyMatch)
}
func BeginContext(ctx context.Context, spec Spec, before *Snapshot, requireReadyMatch bool) (*Transaction, error) {
if ctx == nil {
return nil, ErrIntegrity
}
if err := ctx.Err(); err != nil {
return nil, err
}
root, err := openRoot(spec)
if err != nil {
return nil, err
}
rendezvousBeforeFlock(root)
if unix.Flock(root, unix.LOCK_EX) != nil {
if err := flockContext(ctx, root); err != nil {
unix.Close(root)
return nil, ErrIntegrity
return nil, err
}
transaction := &Transaction{spec: spec, before: before, rootFD: root, lockFD: root}
selector, selectorErr := readSelector(root, spec)
@@ -132,6 +144,30 @@ func Begin(spec Spec, before *Snapshot, requireReadyMatch bool) (*Transaction, e
return transaction, nil
}
func flockContext(ctx context.Context, descriptor int) error {
for {
if err := ctx.Err(); err != nil {
return err
}
err := unix.Flock(descriptor, unix.LOCK_EX|unix.LOCK_NB)
if err == nil {
return nil
}
if !errors.Is(err, unix.EWOULDBLOCK) {
return ErrIntegrity
}
timer := time.NewTimer(10 * time.Millisecond)
select {
case <-ctx.Done():
if !timer.Stop() {
<-timer.C
}
return ctx.Err()
case <-timer.C:
}
}
}
func (transaction *Transaction) Commit(after Snapshot) (Status, error) {
if transaction == nil || transaction.closed || !transaction.blocked || validateSnapshot(after) != nil {
return Status{}, ErrIntegrity