org

package
v1.801.79 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 18, 2026 License: Apache-2.0 Imports: 21 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// NewReplicator binds the DB at key to its store slot.
	NewReplicator = replica.NewReplicator
	// WithEncryption seals every pushed snapshot with the org's per-org key.
	WithEncryption = replica.WithEncryption
	// Owner returns the single writer for orgID (HRW), fail-closed on empty.
	Owner = ha.Owner
	// IsOwner reports whether selfID owns the writer for orgID.
	IsOwner = ha.IsOwner
	// Replicas returns the owner then ordered failover successors.
	Replicas = ha.Replicas
	// DBPath is the canonical object-store location of an org's SQLite DB.
	DBPath = replica.DBPath
	// NewFencedStore wraps a ConditionalStore as the round-fenced per-org ship path.
	NewFencedStore = replica.NewFencedStore
	// StaticFencer is the single-process Fencer (round always 1) for dev and tests.
	StaticFencer = ha.StaticFencer

	// ErrStaleRound is the deposed-writer rejection: a ship below the recorded round.
	ErrStaleRound = replica.ErrStaleRound
)
View Source
var ErrNoMembership = errors.New("org: empty membership — no safe writer")

ErrNoMembership is returned by a Fencer when the live replica set is empty: no safe owner can be named, so the caller fails CLOSED (does not write).

View Source
var ErrNotOwner = errors.New("org: not the elected writer for this org")

ErrNotOwner is returned when this replica is not the HRW-elected writer for the org. The caller does not write; it forwards to, or steps aside for, the owner.

Functions

func ConstantTimeEqual added in v1.786.12

func ConstantTimeEqual(a, b []byte) bool

ConstantTimeEqual compares two secrets without leaking timing — exported for callers verifying wrapped-key material.

Types

type CASFencer added in v1.786.165

type CASFencer struct {
	// contains filtered or unexported fields
}

CASFencer implements ha.Fencer by claiming/renewing a per-org writer lease in a linearizable object store. Acquire returns the caller's monotone lease round; FencedStore then stamps every ship with it.

func NewCASFencer added in v1.786.165

func NewCASFencer(store replica.ConditionalStore, view ownerView) *CASFencer

NewCASFencer builds a CASFencer over an atomic-CAS store and a membership view. The SAME store instance also backs the per-org replica.FencedStore, so the lease and the data ships share one linearizable register.

func (*CASFencer) Acquire added in v1.786.165

func (f *CASFencer) Acquire(ctx context.Context, orgID string) (ha.Lease, error)

Acquire implements ha.Fencer. It fails CLOSED unless this replica is the elected writer over a non-empty membership, then claims (strictly bumping the round) or renews (keeping the round) the org's lease.

type Cipher added in v1.786.12

type Cipher struct {
	// contains filtered or unexported fields
}

Cipher seals each org's SQLite snapshot at rest with a distinct 256-bit key, so the object in SeaweedFS is ciphertext and orgs are cryptographically isolated — a leaked file is useless without the KMS master key.

Envelope model: the KMS master (KMSMasterKeyRef, 32 bytes) never leaves the process. A per-org key is DERIVED from it via HKDF(master, label, orgID); it is held only in-memory, never stored, never on the wire. Rotating the master re-keys every org. AES-256-GCM provides confidentiality + integrity; the orgID is bound in as AAD so a sealed blob cannot be replayed under a different org.

The GCM nonce is DERIVED from (key, plaintext) — HMAC(key,"nonce"||plaintext), so identical plaintext seals to identical ciphertext (content-addressable, keeps the Replicator's version-skip working) while distinct plaintexts get distinct nonces (GCM safety: the same (key,nonce) never covers two different messages).

func NewCipher added in v1.786.12

func NewCipher(master []byte) (*Cipher, error)

NewCipher builds a Cipher from the KMS master key. master must be exactly 32 bytes (derive it from KMSMasterKeyRef, e.g. SHA-256 of the raw secret).

func (*Cipher) Open added in v1.786.12

func (c *Cipher) Open(orgID string, sealed []byte) ([]byte, error)

Open decrypts a sealed blob for orgID. It fails (auth error) if the blob was tampered with, or was sealed for a different org.

func (*Cipher) Seal added in v1.786.12

func (c *Cipher) Seal(orgID string, plaintext []byte) ([]byte, error)

Seal encrypts plaintext for orgID, returning nonce||ciphertext(+tag).

type ConditionalStore added in v1.786.165

type ConditionalStore = replica.ConditionalStore

type DB

type DB = replica.DB

DB is the local per-org SQLite (Snapshot/Restore).

type FencedStore added in v1.786.165

type FencedStore = replica.FencedStore

FencedStore admits a per-org-DB ship only at a round >= the recorded one, fencing a deposed writer. ConditionalStore is its atomic-CAS backing seam.

type Fencer added in v1.786.165

type Fencer = ha.Fencer

type Lease added in v1.786.165

type Lease = ha.Lease

Lease binds an elected owner to the monotone round it writes at (the fencing value). Round is that monotone epoch. Fencer issues a Lease from a linearizable round source (CASFencer here; the Lux BFT round later).

type Member

type Member = ha.Member

Member is one replica in the live membership set (HRW election input).

type Membership

type Membership struct {
	// contains filtered or unexported fields
}

Membership caches the latest replica snapshot and refreshes it from a Source on an interval. Reads are lock-free via an atomic snapshot pointer, so the per-request AmOwner hot-path never blocks on the refresher.

func NewMembership

func NewMembership(selfID string, src Source, interval time.Duration) *Membership

NewMembership builds a Membership over src. selfID is this replica's stable id (see Member.ID). interval<=0 defaults to 5s.

func (*Membership) AmOwner

func (m *Membership) AmOwner(orgID string) bool

AmOwner reports whether THIS replica owns orgID's writer right now — the per-write hot-path check. Lock-free.

func (*Membership) Members

func (m *Membership) Members() []Member

Members returns the current membership snapshot (never nil; may be empty).

func (*Membership) OwnerOf

func (m *Membership) OwnerOf(orgID string) (Member, bool)

OwnerOf resolves the writer-owner replica for orgID under the live set.

func (*Membership) Self

func (m *Membership) Self() string

Self is this replica's id.

func (*Membership) Start

func (m *Membership) Start(ctx context.Context) error

Start does an initial synchronous refresh (so Members() is populated before the first request) then refreshes on the interval until Stop or ctx cancel. Returns the initial refresh error, if any; callers may serve with a stale or self-only set regardless.

func (*Membership) Stop

func (m *Membership) Stop()

Stop halts the refresh loop. Idempotent.

type MinioConditionalStore added in v1.786.165

type MinioConditionalStore struct {
	Client *minio.Client
	Bucket string
}

MinioConditionalStore is a replica.ConditionalStore over minio-go's native optimistic-locking extension (SetMatchETag / SetMatchETagExcept). The server — not this process — evaluates the precondition atomically, which is the property the fence's correctness depends on.

func NewMinioConditionalStore added in v1.786.165

func NewMinioConditionalStore(client *minio.Client, bucket string) *MinioConditionalStore

NewMinioConditionalStore builds a ConditionalStore over an already-constructed minio client and bucket. The caller owns the client lifecycle (credentials, TLS, endpoint) — this type adds only the conditional-write semantics.

func (*MinioConditionalStore) Get added in v1.786.165

func (s *MinioConditionalStore) Get(ctx context.Context, key string) ([]byte, string, error)

Get returns the object bytes and its ETag from ONE GET response (obj.Stat reads the header of the same request io.ReadAll drains), so the version is guaranteed consistent with the bytes. Absent key maps to replica.ErrNotFound.

func (*MinioConditionalStore) PutIfVersion added in v1.786.165

func (s *MinioConditionalStore) PutIfVersion(ctx context.Context, key string, data []byte, expectVersion string) (string, error)

PutIfVersion writes data at key iff the store's current ETag still equals expectVersion (SetMatchETag), or iff the object does not exist when expectVersion is "" (SetMatchETagExcept "*"). A failed precondition is mapped to replica.ErrConflict.

type Option added in v1.786.12

type Option = replica.Option

Option configures a Replicator.

type Replicator

type Replicator = replica.Replicator

Replicator binds one per-org SQLite to its object-store slot.

type Round added in v1.786.165

type Round = ha.Round

type Source

type Source func(context.Context) ([]Member, error)

Source yields the current live replica set. It is the ONE thing in the horizontally-scaled cloud that needs a peer view — everything else is a pure function of (org, members). Any discovery mechanism plugs in as a Source without touching the ownership core: a static list (dev), a K8s Endpoints poll (prod), or a zapd gossip view.

func StaticSource

func StaticSource(members ...Member) Source

StaticSource yields a fixed set — single-node / local dev. With no explicit members it reads CLOUD_REPLICAS ("id@addr,id2@addr2", or bare "id" with addr==id).

type Store

type Store = replica.Store

Store is the object-store surface (satisfied by vfsstore.go over deps.VFS).

func NewVFSStore

func NewVFSStore(vfs vfsClient) Store

NewVFSStore builds a Store over the native vfs client (pass deps.VFS).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL